aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/ints-priority.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority.c')
-rw-r--r--arch/blackfin/mach-common/ints-priority.c137
1 files changed, 54 insertions, 83 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 1bba6030dce9..a7d7b2dd4059 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -161,11 +161,15 @@ static void bfin_core_unmask_irq(unsigned int irq)
161 161
162static void bfin_internal_mask_irq(unsigned int irq) 162static void bfin_internal_mask_irq(unsigned int irq)
163{ 163{
164 unsigned long flags;
165
164#ifdef CONFIG_BF53x 166#ifdef CONFIG_BF53x
167 local_irq_save_hw(flags);
165 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & 168 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
166 ~(1 << SIC_SYSIRQ(irq))); 169 ~(1 << SIC_SYSIRQ(irq)));
167#else 170#else
168 unsigned mask_bank, mask_bit; 171 unsigned mask_bank, mask_bit;
172 local_irq_save_hw(flags);
169 mask_bank = SIC_SYSIRQ(irq) / 32; 173 mask_bank = SIC_SYSIRQ(irq) / 32;
170 mask_bit = SIC_SYSIRQ(irq) % 32; 174 mask_bit = SIC_SYSIRQ(irq) % 32;
171 bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & 175 bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
@@ -175,15 +179,20 @@ static void bfin_internal_mask_irq(unsigned int irq)
175 ~(1 << mask_bit)); 179 ~(1 << mask_bit));
176#endif 180#endif
177#endif 181#endif
182 local_irq_restore_hw(flags);
178} 183}
179 184
180static void bfin_internal_unmask_irq(unsigned int irq) 185static void bfin_internal_unmask_irq(unsigned int irq)
181{ 186{
187 unsigned long flags;
188
182#ifdef CONFIG_BF53x 189#ifdef CONFIG_BF53x
190 local_irq_save_hw(flags);
183 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 191 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
184 (1 << SIC_SYSIRQ(irq))); 192 (1 << SIC_SYSIRQ(irq)));
185#else 193#else
186 unsigned mask_bank, mask_bit; 194 unsigned mask_bank, mask_bit;
195 local_irq_save_hw(flags);
187 mask_bank = SIC_SYSIRQ(irq) / 32; 196 mask_bank = SIC_SYSIRQ(irq) / 32;
188 mask_bit = SIC_SYSIRQ(irq) % 32; 197 mask_bit = SIC_SYSIRQ(irq) % 32;
189 bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | 198 bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
@@ -193,6 +202,7 @@ static void bfin_internal_unmask_irq(unsigned int irq)
193 (1 << mask_bit)); 202 (1 << mask_bit));
194#endif 203#endif
195#endif 204#endif
205 local_irq_restore_hw(flags);
196} 206}
197 207
198#ifdef CONFIG_PM 208#ifdef CONFIG_PM
@@ -390,7 +400,7 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
390static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) 400static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)
391{ 401{
392#ifdef CONFIG_IPIPE 402#ifdef CONFIG_IPIPE
393 _set_irq_handler(irq, handle_edge_irq); 403 _set_irq_handler(irq, handle_level_irq);
394#else 404#else
395 struct irq_desc *desc = irq_desc + irq; 405 struct irq_desc *desc = irq_desc + irq;
396 /* May not call generic set_irq_handler() due to spinlock 406 /* May not call generic set_irq_handler() due to spinlock
@@ -1055,13 +1065,18 @@ int __init init_arch_irq(void)
1055#endif 1065#endif
1056 default: 1066 default:
1057#ifdef CONFIG_IPIPE 1067#ifdef CONFIG_IPIPE
1058 /* 1068 /*
1059 * We want internal interrupt sources to be masked, because 1069 * We want internal interrupt sources to be
1060 * ISRs may trigger interrupts recursively (e.g. DMA), but 1070 * masked, because ISRs may trigger interrupts
1061 * interrupts are _not_ masked at CPU level. So let's handle 1071 * recursively (e.g. DMA), but interrupts are
1062 * them as level interrupts. 1072 * _not_ masked at CPU level. So let's handle
1063 */ 1073 * most of them as level interrupts, except
1064 set_irq_handler(irq, handle_level_irq); 1074 * the timer interrupt which is special.
1075 */
1076 if (irq == IRQ_SYSTMR || irq == IRQ_CORETMR)
1077 set_irq_handler(irq, handle_simple_irq);
1078 else
1079 set_irq_handler(irq, handle_level_irq);
1065#else /* !CONFIG_IPIPE */ 1080#else /* !CONFIG_IPIPE */
1066 set_irq_handler(irq, handle_simple_irq); 1081 set_irq_handler(irq, handle_simple_irq);
1067#endif /* !CONFIG_IPIPE */ 1082#endif /* !CONFIG_IPIPE */
@@ -1101,10 +1116,9 @@ int __init init_arch_irq(void)
1101 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | 1116 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
1102 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; 1117 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
1103 1118
1104#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \ 1119#ifdef SIC_IWR0
1105 || defined(BF538_FAMILY) || defined(CONFIG_BF51x)
1106 bfin_write_SIC_IWR0(IWR_DISABLE_ALL); 1120 bfin_write_SIC_IWR0(IWR_DISABLE_ALL);
1107#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x) 1121# ifdef SIC_IWR1
1108 /* BF52x/BF51x system reset does not properly reset SIC_IWR1 which 1122 /* BF52x/BF51x system reset does not properly reset SIC_IWR1 which
1109 * will screw up the bootrom as it relies on MDMA0/1 waking it 1123 * will screw up the bootrom as it relies on MDMA0/1 waking it
1110 * up from IDLE instructions. See this report for more info: 1124 * up from IDLE instructions. See this report for more info:
@@ -1114,10 +1128,8 @@ int __init init_arch_irq(void)
1114 bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); 1128 bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11));
1115 else 1129 else
1116 bfin_write_SIC_IWR1(IWR_DISABLE_ALL); 1130 bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
1117#else 1131# endif
1118 bfin_write_SIC_IWR1(IWR_DISABLE_ALL); 1132# ifdef SIC_IWR2
1119#endif
1120# ifdef CONFIG_BF54x
1121 bfin_write_SIC_IWR2(IWR_DISABLE_ALL); 1133 bfin_write_SIC_IWR2(IWR_DISABLE_ALL);
1122# endif 1134# endif
1123#else 1135#else
@@ -1126,9 +1138,8 @@ int __init init_arch_irq(void)
1126 1138
1127#ifdef CONFIG_IPIPE 1139#ifdef CONFIG_IPIPE
1128 for (irq = 0; irq < NR_IRQS; irq++) { 1140 for (irq = 0; irq < NR_IRQS; irq++) {
1129 struct irq_desc *desc = irq_desc + irq; 1141 struct irq_desc *desc = irq_to_desc(irq);
1130 desc->ic_prio = __ipipe_get_irq_priority(irq); 1142 desc->ic_prio = __ipipe_get_irq_priority(irq);
1131 desc->thr_prio = __ipipe_get_irqthread_priority(irq);
1132 } 1143 }
1133#endif /* CONFIG_IPIPE */ 1144#endif /* CONFIG_IPIPE */
1134 1145
@@ -1211,76 +1222,21 @@ int __ipipe_get_irq_priority(unsigned irq)
1211 return IVG15; 1222 return IVG15;
1212} 1223}
1213 1224
1214int __ipipe_get_irqthread_priority(unsigned irq)
1215{
1216 int ient, prio;
1217 int demux_irq;
1218
1219 /* The returned priority value is rescaled to [0..IVG13+1]
1220 * with 0 being the lowest effective priority level. */
1221
1222 if (irq <= IRQ_CORETMR)
1223 return IVG13 - irq + 1;
1224
1225 /* GPIO IRQs are given the priority of the demux
1226 * interrupt. */
1227 if (IS_GPIOIRQ(irq)) {
1228#if defined(CONFIG_BF54x)
1229 u32 bank = PINT_2_BANK(irq2pint_lut[irq - SYS_IRQS]);
1230 demux_irq = (bank == 0 ? IRQ_PINT0 :
1231 bank == 1 ? IRQ_PINT1 :
1232 bank == 2 ? IRQ_PINT2 :
1233 IRQ_PINT3);
1234#elif defined(CONFIG_BF561)
1235 demux_irq = (irq >= IRQ_PF32 ? IRQ_PROG2_INTA :
1236 irq >= IRQ_PF16 ? IRQ_PROG1_INTA :
1237 IRQ_PROG0_INTA);
1238#elif defined(CONFIG_BF52x)
1239 demux_irq = (irq >= IRQ_PH0 ? IRQ_PORTH_INTA :
1240 irq >= IRQ_PG0 ? IRQ_PORTG_INTA :
1241 IRQ_PORTF_INTA);
1242#else
1243 demux_irq = irq;
1244#endif
1245 return IVG13 - PRIO_GPIODEMUX(demux_irq) + 1;
1246 }
1247
1248 /* The GPIO demux interrupt is given a lower priority
1249 * than the GPIO IRQs, so that its threaded handler
1250 * unmasks the interrupt line after the decoded IRQs
1251 * have been processed. */
1252 prio = PRIO_GPIODEMUX(irq);
1253 /* demux irq? */
1254 if (prio != -1)
1255 return IVG13 - prio;
1256
1257 for (ient = 0; ient < NR_PERI_INTS; ient++) {
1258 struct ivgx *ivg = ivg_table + ient;
1259 if (ivg->irqno == irq) {
1260 for (prio = 0; prio <= IVG13-IVG7; prio++) {
1261 if (ivg7_13[prio].ifirst <= ivg &&
1262 ivg7_13[prio].istop > ivg)
1263 return IVG7 - prio;
1264 }
1265 }
1266 }
1267
1268 return 0;
1269}
1270
1271/* Hw interrupts are disabled on entry (check SAVE_CONTEXT). */ 1225/* Hw interrupts are disabled on entry (check SAVE_CONTEXT). */
1272#ifdef CONFIG_DO_IRQ_L1 1226#ifdef CONFIG_DO_IRQ_L1
1273__attribute__((l1_text)) 1227__attribute__((l1_text))
1274#endif 1228#endif
1275asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs) 1229asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
1276{ 1230{
1231 struct ipipe_percpu_domain_data *p = ipipe_root_cpudom_ptr();
1232 struct ipipe_domain *this_domain = ipipe_current_domain;
1277 struct ivgx *ivg_stop = ivg7_13[vec-IVG7].istop; 1233 struct ivgx *ivg_stop = ivg7_13[vec-IVG7].istop;
1278 struct ivgx *ivg = ivg7_13[vec-IVG7].ifirst; 1234 struct ivgx *ivg = ivg7_13[vec-IVG7].ifirst;
1279 int irq; 1235 int irq, s;
1280 1236
1281 if (likely(vec == EVT_IVTMR_P)) { 1237 if (likely(vec == EVT_IVTMR_P)) {
1282 irq = IRQ_CORETMR; 1238 irq = IRQ_CORETMR;
1283 goto handle_irq; 1239 goto core_tick;
1284 } 1240 }
1285 1241
1286 SSYNC(); 1242 SSYNC();
@@ -1322,24 +1278,39 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
1322 irq = ivg->irqno; 1278 irq = ivg->irqno;
1323 1279
1324 if (irq == IRQ_SYSTMR) { 1280 if (irq == IRQ_SYSTMR) {
1281#ifdef CONFIG_GENERIC_CLOCKEVENTS
1282core_tick:
1283#else
1325 bfin_write_TIMER_STATUS(1); /* Latch TIMIL0 */ 1284 bfin_write_TIMER_STATUS(1); /* Latch TIMIL0 */
1285#endif
1326 /* This is basically what we need from the register frame. */ 1286 /* This is basically what we need from the register frame. */
1327 __raw_get_cpu_var(__ipipe_tick_regs).ipend = regs->ipend; 1287 __raw_get_cpu_var(__ipipe_tick_regs).ipend = regs->ipend;
1328 __raw_get_cpu_var(__ipipe_tick_regs).pc = regs->pc; 1288 __raw_get_cpu_var(__ipipe_tick_regs).pc = regs->pc;
1329 if (!ipipe_root_domain_p) 1289 if (this_domain != ipipe_root_domain)
1330 __raw_get_cpu_var(__ipipe_tick_regs).ipend |= 0x10;
1331 else
1332 __raw_get_cpu_var(__ipipe_tick_regs).ipend &= ~0x10; 1290 __raw_get_cpu_var(__ipipe_tick_regs).ipend &= ~0x10;
1291 else
1292 __raw_get_cpu_var(__ipipe_tick_regs).ipend |= 0x10;
1333 } 1293 }
1334 1294
1335handle_irq: 1295#ifndef CONFIG_GENERIC_CLOCKEVENTS
1296core_tick:
1297#endif
1298 if (this_domain == ipipe_root_domain) {
1299 s = __test_and_set_bit(IPIPE_SYNCDEFER_FLAG, &p->status);
1300 barrier();
1301 }
1336 1302
1337 ipipe_trace_irq_entry(irq); 1303 ipipe_trace_irq_entry(irq);
1338 __ipipe_handle_irq(irq, regs); 1304 __ipipe_handle_irq(irq, regs);
1339 ipipe_trace_irq_exit(irq); 1305 ipipe_trace_irq_exit(irq);
1340 1306
1341 if (ipipe_root_domain_p) 1307 if (this_domain == ipipe_root_domain) {
1342 return !test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); 1308 set_thread_flag(TIF_IRQ_SYNC);
1309 if (!s) {
1310 __clear_bit(IPIPE_SYNCDEFER_FLAG, &p->status);
1311 return !test_bit(IPIPE_STALL_FLAG, &p->status);
1312 }
1313 }
1343 1314
1344 return 0; 1315 return 0;
1345} 1316}