1/* 2 * interface to Blackfin CEC 3 * 4 * Copyright 2009 Analog Devices Inc. 5 * Licensed under the GPL-2 or later. 6 */ 7 8#ifndef __ASM_BFIN_IRQFLAGS_H__ 9#define __ASM_BFIN_IRQFLAGS_H__ 10 11#ifdef CONFIG_SMP 12# include <asm/pda.h> 13# include <asm/processor.h> 14/* Forward decl needed due to cdef inter dependencies */ 15static inline uint32_t __pure bfin_dspid(void); 16# define blackfin_core_id() (bfin_dspid() & 0xff) 17# define bfin_irq_flags cpu_pda[blackfin_core_id()].imask 18#else 19extern unsigned long bfin_irq_flags; 20#endif 21 22static inline void bfin_sti(unsigned long flags) 23{ 24 asm volatile("sti %0;" : : "d" (flags)); 25} 26 27static inline unsigned long bfin_cli(void) 28{ 29 unsigned long flags; 30 asm volatile("cli %0;" : "=d" (flags)); 31 return flags; 32} 33 34#ifdef CONFIG_IPIPE 35 36#include <linux/compiler.h> 37#include <linux/ipipe_base.h> 38#include <linux/ipipe_trace.h> 39 40#ifdef CONFIG_DEBUG_HWERR 41# define bfin_no_irqs 0x3f 42#else 43# define bfin_no_irqs 0x1f 44#endif 45 46#define raw_local_irq_disable() \ 47 do { \ 48 ipipe_check_context(ipipe_root_domain); \ 49 __ipipe_stall_root(); \ 50 barrier(); \ 51 } while (0) 52 53#define raw_local_irq_enable() \ 54 do { \ 55 barrier(); \ 56 ipipe_check_context(ipipe_root_domain); \ 57 __ipipe_unstall_root(); \ 58 } while (0) 59 60#define raw_local_save_flags_ptr(x) \ 61 do { \ 62 *(x) = __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags; \ 63 } while (0) 64 65#define raw_local_save_flags(x) raw_local_save_flags_ptr(&(x)) 66 67#define raw_irqs_disabled_flags(x) ((x) == bfin_no_irqs) 68 69#define raw_local_irq_save_ptr(x) \ 70 do { \ 71 *(x) = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags; \ 72 barrier(); \ 73 } while (0) 74 75#define raw_local_irq_save(x) \ 76 do { \ 77 ipipe_check_context(ipipe_root_domain); \ 78 raw_local_irq_save_ptr(&(x)); \ 79 } while (0) 80 81static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real) 82{ 83 /* 84 * Merge virtual and real interrupt mask bits into a single 85 * 32bit word. 86 */ 87 return (real & ~(1 << 31)) | ((virt != 0) << 31); 88} 89 90static inline int raw_demangle_irq_bits(unsigned long *x) 91{ 92 int virt = (*x & (1 << 31)) != 0; 93 *x &= ~(1L << 31); 94 return virt; 95} 96 97static inline void local_irq_disable_hw_notrace(void) 98{ 99 bfin_cli(); 100} 101 102static inline void local_irq_enable_hw_notrace(void) 103{ 104 bfin_sti(bfin_irq_flags); 105} 106 107#define local_save_flags_hw(flags) \ 108 do { \ 109 (flags) = bfin_read_IMASK(); \ 110 } while (0) 111 112#define irqs_disabled_flags_hw(flags) (((flags) & ~0x3f) == 0) 113 114#define irqs_disabled_hw() \ 115 ({ \ 116 unsigned long flags; \ 117 local_save_flags_hw(flags); \ 118 irqs_disabled_flags_hw(flags); \ 119 }) 120 121static inline void local_irq_save_ptr_hw(unsigned long *flags) 122{ 123 *flags = bfin_cli(); 124#ifdef CONFIG_DEBUG_HWERR 125 bfin_sti(0x3f); 126#endif 127} 128 129#define local_irq_save_hw_notrace(flags) \ 130 do { \ 131 local_irq_save_ptr_hw(&(flags)); \ 132 } while (0) 133 134static inline void local_irq_restore_hw_notrace(unsigned long flags) 135{ 136 if (!irqs_disabled_flags_hw(flags)) 137 local_irq_enable_hw_notrace(); 138} 139 140#ifdef CONFIG_IPIPE_TRACE_IRQSOFF 141# define local_irq_disable_hw() \ 142 do { \ 143 if (!irqs_disabled_hw()) { \ 144 local_irq_disable_hw_notrace(); \ 145 ipipe_trace_begin(0x80000000); \ 146 } \ 147 } while (0) 148# define local_irq_enable_hw() \ 149 do { \ 150 if (irqs_disabled_hw()) { \ 151 ipipe_trace_end(0x80000000); \ 152 local_irq_enable_hw_notrace(); \ 153 } \ 154 } while (0) 155# define local_irq_save_hw(flags) \ 156 do { \ 157 local_save_flags_hw(flags); \ 158 if (!irqs_disabled_flags_hw(flags)) { \ 159 local_irq_disable_hw_notrace(); \ 160 ipipe_trace_begin(0x80000001); \ 161 } \ 162 } while (0) 163# define local_irq_restore_hw(flags) \ 164 do { \ 165 if (!irqs_disabled_flags_hw(flags)) { \ 166 ipipe_trace_end(0x80000001); \ 167 local_irq_enable_hw_notrace(); \ 168 } \ 169 } while (0) 170#else /* !CONFIG_IPIPE_TRACE_IRQSOFF */ 171# define local_irq_disable_hw() local_irq_disable_hw_notrace() 172# define local_irq_enable_hw() local_irq_enable_hw_notrace() 173# define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags) 174# define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags) 175#endif /* !CONFIG_IPIPE_TRACE_IRQSOFF */ 176 177#else /* CONFIG_IPIPE */ 178 179static inline void raw_local_irq_disable(void) 180{ 181 bfin_cli(); 182} 183static inline void raw_local_irq_enable(void) 184{ 185 bfin_sti(bfin_irq_flags); 186} 187 188#define raw_local_save_flags(flags) do { (flags) = bfin_read_IMASK(); } while (0) 189 190#define raw_irqs_disabled_flags(flags) (((flags) & ~0x3f) == 0) 191 192static inline unsigned long __raw_local_irq_save(void) 193{ 194 unsigned long flags = bfin_cli(); 195#ifdef CONFIG_DEBUG_HWERR 196 bfin_sti(0x3f); 197#endif 198 return flags; 199} 200#define raw_local_irq_save(flags) do { (flags) = __raw_local_irq_save(); } while (0) 201 202#define local_irq_save_hw(flags) raw_local_irq_save(flags) 203#define local_irq_restore_hw(flags) raw_local_irq_restore(flags) 204#define local_irq_enable_hw() raw_local_irq_enable() 205#define local_irq_disable_hw() raw_local_irq_disable() 206#define irqs_disabled_hw() irqs_disabled() 207 208#endif /* !CONFIG_IPIPE */ 209 210static inline void raw_local_irq_restore(unsigned long flags) 211{ 212 if (!raw_irqs_disabled_flags(flags)) 213 raw_local_irq_enable(); 214} 215 216#endif 217