diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-19 08:47:57 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-19 08:47:57 -0400 |
commit | 40d743b8c16a8cf6e30c1d941aa6147f9550ea75 (patch) | |
tree | 9fcdf9a06b18a275253048d1ea7c9803cec38845 /arch/blackfin/mach-common/interrupt.S | |
parent | 7da18afa423f167e7ef3c9728e584d8bf05bd55a (diff) | |
parent | 83e686ea0291ee93b87dcdc00b96443b80de56c9 (diff) |
Merge branch 'for-rmk' of git://linux-arm.org/linux-2.6
Diffstat (limited to 'arch/blackfin/mach-common/interrupt.S')
-rw-r--r-- | arch/blackfin/mach-common/interrupt.S | 78 |
1 files changed, 38 insertions, 40 deletions
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 9c46680186e4..82d417ef4b5b 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S | |||
@@ -119,14 +119,8 @@ __common_int_entry: | |||
119 | fp = 0; | 119 | fp = 0; |
120 | #endif | 120 | #endif |
121 | 121 | ||
122 | #if ANOMALY_05000283 || ANOMALY_05000315 | 122 | ANOMALY_283_315_WORKAROUND(p5, r7) |
123 | cc = r7 == r7; | 123 | |
124 | p5.h = HI(CHIPID); | ||
125 | p5.l = LO(CHIPID); | ||
126 | if cc jump 1f; | ||
127 | r7.l = W[p5]; | ||
128 | 1: | ||
129 | #endif | ||
130 | r1 = sp; | 124 | r1 = sp; |
131 | SP += -12; | 125 | SP += -12; |
132 | #ifdef CONFIG_IPIPE | 126 | #ifdef CONFIG_IPIPE |
@@ -158,14 +152,7 @@ ENTRY(_evt_ivhw) | |||
158 | fp = 0; | 152 | fp = 0; |
159 | #endif | 153 | #endif |
160 | 154 | ||
161 | #if ANOMALY_05000283 || ANOMALY_05000315 | 155 | ANOMALY_283_315_WORKAROUND(p5, r7) |
162 | cc = r7 == r7; | ||
163 | p5.h = HI(CHIPID); | ||
164 | p5.l = LO(CHIPID); | ||
165 | if cc jump 1f; | ||
166 | r7.l = W[p5]; | ||
167 | 1: | ||
168 | #endif | ||
169 | 156 | ||
170 | /* Handle all stacked hardware errors | 157 | /* Handle all stacked hardware errors |
171 | * To make sure we don't hang forever, only do it 10 times | 158 | * To make sure we don't hang forever, only do it 10 times |
@@ -261,6 +248,31 @@ ENTRY(_evt_system_call) | |||
261 | ENDPROC(_evt_system_call) | 248 | ENDPROC(_evt_system_call) |
262 | 249 | ||
263 | #ifdef CONFIG_IPIPE | 250 | #ifdef CONFIG_IPIPE |
251 | /* | ||
252 | * __ipipe_call_irqtail: lowers the current priority level to EVT15 | ||
253 | * before running a user-defined routine, then raises the priority | ||
254 | * level to EVT14 to prepare the caller for a normal interrupt | ||
255 | * return through RTI. | ||
256 | * | ||
257 | * We currently use this facility in two occasions: | ||
258 | * | ||
259 | * - to branch to __ipipe_irq_tail_hook as requested by a high | ||
260 | * priority domain after the pipeline delivered an interrupt, | ||
261 | * e.g. such as Xenomai, in order to start its rescheduling | ||
262 | * procedure, since we may not switch tasks when IRQ levels are | ||
263 | * nested on the Blackfin, so we have to fake an interrupt return | ||
264 | * so that we may reschedule immediately. | ||
265 | * | ||
266 | * - to branch to sync_root_irqs, in order to play any interrupt | ||
267 | * pending for the root domain (i.e. the Linux kernel). This lowers | ||
268 | * the core priority level enough so that Linux IRQ handlers may | ||
269 | * never delay interrupts handled by high priority domains; we defer | ||
270 | * those handlers until this point instead. This is a substitute | ||
271 | * to using a threaded interrupt model for the Linux kernel. | ||
272 | * | ||
273 | * r0: address of user-defined routine | ||
274 | * context: caller must have preempted EVT15, hw interrupts must be off. | ||
275 | */ | ||
264 | ENTRY(___ipipe_call_irqtail) | 276 | ENTRY(___ipipe_call_irqtail) |
265 | p0 = r0; | 277 | p0 = r0; |
266 | r0.l = 1f; | 278 | r0.l = 1f; |
@@ -276,33 +288,19 @@ ENTRY(___ipipe_call_irqtail) | |||
276 | ( r7:4, p5:3 ) = [sp++]; | 288 | ( r7:4, p5:3 ) = [sp++]; |
277 | rets = [sp++]; | 289 | rets = [sp++]; |
278 | 290 | ||
279 | [--sp] = reti; | 291 | #ifdef CONFIG_DEBUG_HWERR |
280 | reti = [sp++]; /* IRQs are off. */ | 292 | /* enable irq14 & hwerr interrupt, until we transition to _evt_evt14 */ |
281 | r0.h = 3f; | 293 | r0 = (EVT_IVG14 | EVT_IVHW | \ |
282 | r0.l = 3f; | 294 | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); |
283 | p0.l = lo(EVT14); | 295 | #else |
284 | p0.h = hi(EVT14); | 296 | /* Only enable irq14 interrupt, until we transition to _evt_evt14 */ |
285 | [p0] = r0; | 297 | r0 = (EVT_IVG14 | \ |
286 | csync; | 298 | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); |
287 | r0 = 0x401f (z); | 299 | #endif |
288 | sti r0; | 300 | sti r0; |
289 | raise 14; | 301 | raise 14; /* Branches to _evt_evt14 */ |
290 | [--sp] = reti; /* IRQs on. */ | ||
291 | 2: | 302 | 2: |
292 | jump 2b; /* Likely paranoid. */ | 303 | jump 2b; /* Likely paranoid. */ |
293 | 3: | ||
294 | sp += 4; /* Discard saved RETI */ | ||
295 | r0.h = _evt14_softirq; | ||
296 | r0.l = _evt14_softirq; | ||
297 | p0.l = lo(EVT14); | ||
298 | p0.h = hi(EVT14); | ||
299 | [p0] = r0; | ||
300 | csync; | ||
301 | p0.l = _bfin_irq_flags; | ||
302 | p0.h = _bfin_irq_flags; | ||
303 | r0 = [p0]; | ||
304 | sti r0; | ||
305 | rts; | ||
306 | ENDPROC(___ipipe_call_irqtail) | 304 | ENDPROC(___ipipe_call_irqtail) |
307 | 305 | ||
308 | #endif /* CONFIG_IPIPE */ | 306 | #endif /* CONFIG_IPIPE */ |