diff options
Diffstat (limited to 'arch/blackfin/include/asm/irq.h')
-rw-r--r-- | arch/blackfin/include/asm/irq.h | 223 |
1 files changed, 196 insertions, 27 deletions
diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h index 21e25f778a63..3d977909ce7d 100644 --- a/arch/blackfin/include/asm/irq.h +++ b/arch/blackfin/include/asm/irq.h @@ -22,11 +22,176 @@ #include <asm/pda.h> #include <asm/processor.h> -static __inline__ int irq_canonicalize(int irq) +#ifdef CONFIG_SMP +/* Forward decl needed due to cdef inter dependencies */ +static inline uint32_t __pure bfin_dspid(void); +# define blackfin_core_id() (bfin_dspid() & 0xff) +# define bfin_irq_flags cpu_pda[blackfin_core_id()].imask +#else +extern unsigned long bfin_irq_flags; +#endif + +#ifdef CONFIG_IPIPE + +#include <linux/ipipe_trace.h> + +void __ipipe_unstall_root(void); + +void __ipipe_restore_root(unsigned long flags); + +#ifdef CONFIG_DEBUG_HWERR +# define __all_masked_irq_flags 0x3f +# define __save_and_cli_hw(x) \ + __asm__ __volatile__( \ + "cli %0;" \ + "sti %1;" \ + : "=&d"(x) \ + : "d" (0x3F) \ + ) +#else +# define __all_masked_irq_flags 0x1f +# define __save_and_cli_hw(x) \ + __asm__ __volatile__( \ + "cli %0;" \ + : "=&d"(x) \ + ) +#endif + +#define irqs_enabled_from_flags_hw(x) ((x) != __all_masked_irq_flags) +#define raw_irqs_disabled_flags(flags) (!irqs_enabled_from_flags_hw(flags)) +#define local_test_iflag_hw(x) irqs_enabled_from_flags_hw(x) + +#define local_save_flags(x) \ + do { \ + (x) = __ipipe_test_root() ? \ + __all_masked_irq_flags : bfin_irq_flags; \ + } while (0) + +#define local_irq_save(x) \ + do { \ + (x) = __ipipe_test_and_stall_root(); \ + } while (0) + +#define local_irq_restore(x) __ipipe_restore_root(x) +#define local_irq_disable() __ipipe_stall_root() +#define local_irq_enable() __ipipe_unstall_root() +#define irqs_disabled() __ipipe_test_root() + +#define local_save_flags_hw(x) \ + __asm__ __volatile__( \ + "cli %0;" \ + "sti %0;" \ + : "=d"(x) \ + ) + +#define irqs_disabled_hw() \ + ({ \ + unsigned long flags; \ + local_save_flags_hw(flags); \ + !irqs_enabled_from_flags_hw(flags); \ + }) + +static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real) { - return irq; + /* Merge virtual and real interrupt mask bits into a single + 32bit word. */ + return (real & ~(1 << 31)) | ((virt != 0) << 31); } +static inline int raw_demangle_irq_bits(unsigned long *x) +{ + int virt = (*x & (1 << 31)) != 0; + *x &= ~(1L << 31); + return virt; +} + +#ifdef CONFIG_IPIPE_TRACE_IRQSOFF + +#define local_irq_disable_hw() \ + do { \ + int _tmp_dummy; \ + if (!irqs_disabled_hw()) \ + ipipe_trace_begin(0x80000000); \ + __asm__ __volatile__ ("cli %0;" : "=d" (_tmp_dummy) : ); \ + } while (0) + +#define local_irq_enable_hw() \ + do { \ + if (irqs_disabled_hw()) \ + ipipe_trace_end(0x80000000); \ + __asm__ __volatile__ ("sti %0;" : : "d"(bfin_irq_flags)); \ + } while (0) + +#define local_irq_save_hw(x) \ + do { \ + __save_and_cli_hw(x); \ + if (local_test_iflag_hw(x)) \ + ipipe_trace_begin(0x80000001); \ + } while (0) + +#define local_irq_restore_hw(x) \ + do { \ + if (local_test_iflag_hw(x)) { \ + ipipe_trace_end(0x80000001); \ + local_irq_enable_hw_notrace(); \ + } \ + } while (0) + +#define local_irq_disable_hw_notrace() \ + do { \ + int _tmp_dummy; \ + __asm__ __volatile__ ("cli %0;" : "=d" (_tmp_dummy) : ); \ + } while (0) + +#define local_irq_enable_hw_notrace() \ + __asm__ __volatile__( \ + "sti %0;" \ + : \ + : "d"(bfin_irq_flags) \ + ) + +#define local_irq_save_hw_notrace(x) __save_and_cli_hw(x) + +#define local_irq_restore_hw_notrace(x) \ + do { \ + if (local_test_iflag_hw(x)) \ + local_irq_enable_hw_notrace(); \ + } while (0) + +#else /* CONFIG_IPIPE_TRACE_IRQSOFF */ + +#define local_irq_enable_hw() \ + __asm__ __volatile__( \ + "sti %0;" \ + : \ + : "d"(bfin_irq_flags) \ + ) + +#define local_irq_disable_hw() \ + do { \ + int _tmp_dummy; \ + __asm__ __volatile__ ( \ + "cli %0;" \ + : "=d" (_tmp_dummy)); \ + } while (0) + +#define local_irq_restore_hw(x) \ + do { \ + if (irqs_enabled_from_flags_hw(x)) \ + local_irq_enable_hw(); \ + } while (0) + +#define local_irq_save_hw(x) __save_and_cli_hw(x) + +#define local_irq_disable_hw_notrace() local_irq_disable_hw() +#define local_irq_enable_hw_notrace() local_irq_enable_hw() +#define local_irq_save_hw_notrace(x) local_irq_save_hw(x) +#define local_irq_restore_hw_notrace(x) local_irq_restore_hw(x) + +#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */ + +#else /* !CONFIG_IPIPE */ + /* * Interrupt configuring macros. */ @@ -39,21 +204,6 @@ static __inline__ int irq_canonicalize(int irq) ); \ } while (0) -#if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE) -# define NOP_PAD_ANOMALY_05000244 "nop; nop;" -#else -# define NOP_PAD_ANOMALY_05000244 -#endif - -#ifdef CONFIG_SMP -/* Forward decl needed due to cdef inter dependencies */ -static inline uint32_t __pure bfin_dspid(void); -# define blackfin_core_id() (bfin_dspid() & 0xff) -# define bfin_irq_flags cpu_pda[blackfin_core_id()].imask -#else -extern unsigned long bfin_irq_flags; -#endif - #define local_irq_enable() \ __asm__ __volatile__( \ "sti %0;" \ @@ -61,16 +211,6 @@ extern unsigned long bfin_irq_flags; : "d" (bfin_irq_flags) \ ) -#define idle_with_irq_disabled() \ - __asm__ __volatile__( \ - NOP_PAD_ANOMALY_05000244 \ - ".align 8;" \ - "sti %0;" \ - "idle;" \ - : \ - : "d" (bfin_irq_flags) \ - ) - #ifdef CONFIG_DEBUG_HWERR # define __save_and_cli(x) \ __asm__ __volatile__( \ @@ -116,4 +256,33 @@ extern unsigned long bfin_irq_flags; !irqs_enabled_from_flags(flags); \ }) +#define local_irq_save_hw(x) local_irq_save(x) +#define local_irq_restore_hw(x) local_irq_restore(x) +#define local_irq_enable_hw() local_irq_enable() +#define local_irq_disable_hw() local_irq_disable() +#define irqs_disabled_hw() irqs_disabled() + +#endif /* !CONFIG_IPIPE */ + +#if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE) +# define NOP_PAD_ANOMALY_05000244 "nop; nop;" +#else +# define NOP_PAD_ANOMALY_05000244 +#endif + +#define idle_with_irq_disabled() \ + __asm__ __volatile__( \ + NOP_PAD_ANOMALY_05000244 \ + ".align 8;" \ + "sti %0;" \ + "idle;" \ + : \ + : "d" (bfin_irq_flags) \ + ) + +static inline int irq_canonicalize(int irq) +{ + return irq; +} + #endif /* _BFIN_IRQ_H_ */ |