2021-01-30 23:08:36 +10:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
# ifndef _ASM_POWERPC_INTERRUPT_H
# define _ASM_POWERPC_INTERRUPT_H
# include <linux/context_tracking.h>
# include <asm/ftrace.h>
2021-01-30 23:08:37 +10:00
struct interrupt_state {
} ;
static inline void interrupt_enter_prepare ( struct pt_regs * regs , struct interrupt_state * state )
{
}
/*
* Care should be taken to note that interrupt_exit_prepare and
* interrupt_async_exit_prepare do not necessarily return immediately to
* regs context ( e . g . , if regs is usermode , we don ' t necessarily return to
* user mode ) . Other interrupts might be taken between here and return ,
* context switch / preemption may occur in the exit path after this , or a
* signal may be delivered , etc .
*
* The real interrupt exit code is platform specific , e . g . ,
* interrupt_exit_user_prepare / interrupt_exit_kernel_prepare for 64 s .
*
* However interrupt_nmi_exit_prepare does return directly to regs , because
* NMIs do not do " exit work " or replay soft - masked interrupts .
*/
static inline void interrupt_exit_prepare ( struct pt_regs * regs , struct interrupt_state * state )
{
}
static inline void interrupt_async_enter_prepare ( struct pt_regs * regs , struct interrupt_state * state )
{
}
static inline void interrupt_async_exit_prepare ( struct pt_regs * regs , struct interrupt_state * state )
{
}
struct interrupt_nmi_state {
} ;
static inline void interrupt_nmi_enter_prepare ( struct pt_regs * regs , struct interrupt_nmi_state * state )
{
}
static inline void interrupt_nmi_exit_prepare ( struct pt_regs * regs , struct interrupt_nmi_state * state )
{
}
2021-01-30 23:08:36 +10:00
/**
* DECLARE_INTERRUPT_HANDLER_RAW - Declare raw interrupt handler function
* @ func : Function name of the entry point
* @ returns : Returns a value back to asm caller
*/
# define DECLARE_INTERRUPT_HANDLER_RAW(func) \
__visible long func ( struct pt_regs * regs )
/**
* DEFINE_INTERRUPT_HANDLER_RAW - Define raw interrupt handler function
* @ func : Function name of the entry point
* @ returns : Returns a value back to asm caller
*
* @ func is called from ASM entry code .
*
* This is a plain function which does no tracing , reconciling , etc .
* The macro is written so it acts as function definition . Append the
* body with a pair of curly brackets .
*
* raw interrupt handlers must not enable or disable interrupts , or
* schedule , tracing and instrumentation ( ftrace , lockdep , etc ) would
* not be advisable either , although may be possible in a pinch , the
* trace will look odd at least .
*
* A raw handler may call one of the other interrupt handler functions
* to be converted into that interrupt context without these restrictions .
*
* On PPC64 , _RAW handlers may return with fast_interrupt_return .
*
* Specific handlers may have additional restrictions .
*/
# define DEFINE_INTERRUPT_HANDLER_RAW(func) \
static __always_inline long ____ # # func ( struct pt_regs * regs ) ; \
\
__visible noinstr long func ( struct pt_regs * regs ) \
{ \
long ret ; \
\
ret = ____ # # func ( regs ) ; \
\
return ret ; \
} \
\
static __always_inline long ____ # # func ( struct pt_regs * regs )
/**
* DECLARE_INTERRUPT_HANDLER - Declare synchronous interrupt handler function
* @ func : Function name of the entry point
*/
# define DECLARE_INTERRUPT_HANDLER(func) \
__visible void func ( struct pt_regs * regs )
/**
* DEFINE_INTERRUPT_HANDLER - Define synchronous interrupt handler function
* @ func : Function name of the entry point
*
* @ func is called from ASM entry code .
*
* The macro is written so it acts as function definition . Append the
* body with a pair of curly brackets .
*/
# define DEFINE_INTERRUPT_HANDLER(func) \
static __always_inline void ____ # # func ( struct pt_regs * regs ) ; \
\
__visible noinstr void func ( struct pt_regs * regs ) \
{ \
2021-01-30 23:08:37 +10:00
struct interrupt_state state ; \
\
interrupt_enter_prepare ( regs , & state ) ; \
\
2021-01-30 23:08:36 +10:00
____ # # func ( regs ) ; \
2021-01-30 23:08:37 +10:00
\
interrupt_exit_prepare ( regs , & state ) ; \
2021-01-30 23:08:36 +10:00
} \
\
static __always_inline void ____ # # func ( struct pt_regs * regs )
/**
* DECLARE_INTERRUPT_HANDLER_RET - Declare synchronous interrupt handler function
* @ func : Function name of the entry point
* @ returns : Returns a value back to asm caller
*/
# define DECLARE_INTERRUPT_HANDLER_RET(func) \
__visible long func ( struct pt_regs * regs )
/**
* DEFINE_INTERRUPT_HANDLER_RET - Define synchronous interrupt handler function
* @ func : Function name of the entry point
* @ returns : Returns a value back to asm caller
*
* @ func is called from ASM entry code .
*
* The macro is written so it acts as function definition . Append the
* body with a pair of curly brackets .
*/
# define DEFINE_INTERRUPT_HANDLER_RET(func) \
static __always_inline long ____ # # func ( struct pt_regs * regs ) ; \
\
__visible noinstr long func ( struct pt_regs * regs ) \
{ \
2021-01-30 23:08:37 +10:00
struct interrupt_state state ; \
2021-01-30 23:08:36 +10:00
long ret ; \
\
2021-01-30 23:08:37 +10:00
interrupt_enter_prepare ( regs , & state ) ; \
\
2021-01-30 23:08:36 +10:00
ret = ____ # # func ( regs ) ; \
\
2021-01-30 23:08:37 +10:00
interrupt_exit_prepare ( regs , & state ) ; \
\
2021-01-30 23:08:36 +10:00
return ret ; \
} \
\
static __always_inline long ____ # # func ( struct pt_regs * regs )
/**
* DECLARE_INTERRUPT_HANDLER_ASYNC - Declare asynchronous interrupt handler function
* @ func : Function name of the entry point
*/
# define DECLARE_INTERRUPT_HANDLER_ASYNC(func) \
__visible void func ( struct pt_regs * regs )
/**
* DEFINE_INTERRUPT_HANDLER_ASYNC - Define asynchronous interrupt handler function
* @ func : Function name of the entry point
*
* @ func is called from ASM entry code .
*
* The macro is written so it acts as function definition . Append the
* body with a pair of curly brackets .
*/
# define DEFINE_INTERRUPT_HANDLER_ASYNC(func) \
static __always_inline void ____ # # func ( struct pt_regs * regs ) ; \
\
__visible noinstr void func ( struct pt_regs * regs ) \
{ \
2021-01-30 23:08:37 +10:00
struct interrupt_state state ; \
\
interrupt_async_enter_prepare ( regs , & state ) ; \
\
2021-01-30 23:08:36 +10:00
____ # # func ( regs ) ; \
2021-01-30 23:08:37 +10:00
\
interrupt_async_exit_prepare ( regs , & state ) ; \
2021-01-30 23:08:36 +10:00
} \
\
static __always_inline void ____ # # func ( struct pt_regs * regs )
/**
* DECLARE_INTERRUPT_HANDLER_NMI - Declare NMI interrupt handler function
* @ func : Function name of the entry point
* @ returns : Returns a value back to asm caller
*/
# define DECLARE_INTERRUPT_HANDLER_NMI(func) \
__visible long func ( struct pt_regs * regs )
/**
* DEFINE_INTERRUPT_HANDLER_NMI - Define NMI interrupt handler function
* @ func : Function name of the entry point
* @ returns : Returns a value back to asm caller
*
* @ func is called from ASM entry code .
*
* The macro is written so it acts as function definition . Append the
* body with a pair of curly brackets .
*/
# define DEFINE_INTERRUPT_HANDLER_NMI(func) \
static __always_inline long ____ # # func ( struct pt_regs * regs ) ; \
\
__visible noinstr long func ( struct pt_regs * regs ) \
{ \
2021-01-30 23:08:37 +10:00
struct interrupt_nmi_state state ; \
2021-01-30 23:08:36 +10:00
long ret ; \
\
2021-01-30 23:08:37 +10:00
interrupt_nmi_enter_prepare ( regs , & state ) ; \
\
2021-01-30 23:08:36 +10:00
ret = ____ # # func ( regs ) ; \
\
2021-01-30 23:08:37 +10:00
interrupt_nmi_exit_prepare ( regs , & state ) ; \
\
2021-01-30 23:08:36 +10:00
return ret ; \
} \
\
static __always_inline long ____ # # func ( struct pt_regs * regs )
# endif /* _ASM_POWERPC_INTERRUPT_H */