diff options
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/include/asm/ipipe.h | 28 | ||||
-rw-r--r-- | arch/blackfin/kernel/ipipe.c | 42 |
2 files changed, 37 insertions, 33 deletions
diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h index 51d0bf5e2899..bbe1c3726b69 100644 --- a/arch/blackfin/include/asm/ipipe.h +++ b/arch/blackfin/include/asm/ipipe.h | |||
@@ -35,10 +35,10 @@ | |||
35 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
36 | #include <asm/traps.h> | 36 | #include <asm/traps.h> |
37 | 37 | ||
38 | #define IPIPE_ARCH_STRING "1.9-01" | 38 | #define IPIPE_ARCH_STRING "1.10-00" |
39 | #define IPIPE_MAJOR_NUMBER 1 | 39 | #define IPIPE_MAJOR_NUMBER 1 |
40 | #define IPIPE_MINOR_NUMBER 9 | 40 | #define IPIPE_MINOR_NUMBER 10 |
41 | #define IPIPE_PATCH_NUMBER 1 | 41 | #define IPIPE_PATCH_NUMBER 0 |
42 | 42 | ||
43 | #ifdef CONFIG_SMP | 43 | #ifdef CONFIG_SMP |
44 | #error "I-pipe/blackfin: SMP not implemented" | 44 | #error "I-pipe/blackfin: SMP not implemented" |
@@ -54,10 +54,11 @@ do { \ | |||
54 | 54 | ||
55 | #define task_hijacked(p) \ | 55 | #define task_hijacked(p) \ |
56 | ({ \ | 56 | ({ \ |
57 | int __x__ = ipipe_current_domain != ipipe_root_domain; \ | 57 | int __x__ = __ipipe_root_domain_p; \ |
58 | /* We would need to clear the SYNC flag for the root domain */ \ | 58 | __clear_bit(IPIPE_SYNC_FLAG, &ipipe_root_cpudom_var(status)); \ |
59 | /* over the current processor in SMP mode. */ \ | 59 | if (__x__) \ |
60 | local_irq_enable_hw(); __x__; \ | 60 | local_irq_enable_hw(); \ |
61 | !__x__; \ | ||
61 | }) | 62 | }) |
62 | 63 | ||
63 | struct ipipe_domain; | 64 | struct ipipe_domain; |
@@ -179,23 +180,24 @@ static inline unsigned long __ipipe_ffnz(unsigned long ul) | |||
179 | 180 | ||
180 | #define __ipipe_run_isr(ipd, irq) \ | 181 | #define __ipipe_run_isr(ipd, irq) \ |
181 | do { \ | 182 | do { \ |
182 | if (ipd == ipipe_root_domain) { \ | 183 | if (!__ipipe_pipeline_head_p(ipd)) \ |
183 | local_irq_enable_hw(); \ | 184 | local_irq_enable_hw(); \ |
184 | if (ipipe_virtual_irq_p(irq)) \ | 185 | if (ipd == ipipe_root_domain) { \ |
186 | if (unlikely(ipipe_virtual_irq_p(irq))) { \ | ||
187 | irq_enter(); \ | ||
185 | ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \ | 188 | ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \ |
186 | else \ | 189 | irq_exit(); \ |
190 | } else \ | ||
187 | ipd->irqs[irq].handler(irq, &__raw_get_cpu_var(__ipipe_tick_regs)); \ | 191 | ipd->irqs[irq].handler(irq, &__raw_get_cpu_var(__ipipe_tick_regs)); \ |
188 | local_irq_disable_hw(); \ | ||
189 | } else { \ | 192 | } else { \ |
190 | __clear_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \ | 193 | __clear_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \ |
191 | local_irq_enable_nohead(ipd); \ | ||
192 | ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \ | 194 | ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \ |
193 | /* Attempt to exit the outer interrupt level before \ | 195 | /* Attempt to exit the outer interrupt level before \ |
194 | * starting the deferred IRQ processing. */ \ | 196 | * starting the deferred IRQ processing. */ \ |
195 | local_irq_disable_nohead(ipd); \ | ||
196 | __ipipe_run_irqtail(); \ | 197 | __ipipe_run_irqtail(); \ |
197 | __set_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \ | 198 | __set_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \ |
198 | } \ | 199 | } \ |
200 | local_irq_disable_hw(); \ | ||
199 | } while (0) | 201 | } while (0) |
200 | 202 | ||
201 | #define __ipipe_syscall_watched_p(p, sc) \ | 203 | #define __ipipe_syscall_watched_p(p, sc) \ |
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index 5fc424803a17..d8cde1fc5cb9 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c | |||
@@ -99,7 +99,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) | |||
99 | * interrupt. | 99 | * interrupt. |
100 | */ | 100 | */ |
101 | m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR); | 101 | m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR); |
102 | this_domain = ipipe_current_domain; | 102 | this_domain = __ipipe_current_domain; |
103 | 103 | ||
104 | if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))) | 104 | if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))) |
105 | head = &this_domain->p_link; | 105 | head = &this_domain->p_link; |
@@ -212,7 +212,9 @@ void __ipipe_unstall_root_raw(void) | |||
212 | 212 | ||
213 | int __ipipe_syscall_root(struct pt_regs *regs) | 213 | int __ipipe_syscall_root(struct pt_regs *regs) |
214 | { | 214 | { |
215 | struct ipipe_percpu_domain_data *p; | ||
215 | unsigned long flags; | 216 | unsigned long flags; |
217 | int ret; | ||
216 | 218 | ||
217 | /* | 219 | /* |
218 | * We need to run the IRQ tail hook whenever we don't | 220 | * We need to run the IRQ tail hook whenever we don't |
@@ -231,29 +233,31 @@ int __ipipe_syscall_root(struct pt_regs *regs) | |||
231 | /* | 233 | /* |
232 | * This routine either returns: | 234 | * This routine either returns: |
233 | * 0 -- if the syscall is to be passed to Linux; | 235 | * 0 -- if the syscall is to be passed to Linux; |
234 | * 1 -- if the syscall should not be passed to Linux, and no | 236 | * >0 -- if the syscall should not be passed to Linux, and no |
235 | * tail work should be performed; | 237 | * tail work should be performed; |
236 | * -1 -- if the syscall should not be passed to Linux but the | 238 | * <0 -- if the syscall should not be passed to Linux but the |
237 | * tail work has to be performed (for handling signals etc). | 239 | * tail work has to be performed (for handling signals etc). |
238 | */ | 240 | */ |
239 | 241 | ||
240 | if (__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) && | 242 | if (!__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL)) |
241 | __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs) > 0) { | 243 | return 0; |
242 | if (ipipe_root_domain_p && !in_atomic()) { | 244 | |
243 | /* | 245 | ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs); |
244 | * Sync pending VIRQs before _TIF_NEED_RESCHED | 246 | |
245 | * is tested. | 247 | local_irq_save_hw(flags); |
246 | */ | 248 | |
247 | local_irq_save_hw(flags); | 249 | if (!__ipipe_root_domain_p) { |
248 | if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0) | 250 | local_irq_restore_hw(flags); |
249 | __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT); | ||
250 | local_irq_restore_hw(flags); | ||
251 | return -1; | ||
252 | } | ||
253 | return 1; | 251 | return 1; |
254 | } | 252 | } |
255 | 253 | ||
256 | return 0; | 254 | p = ipipe_root_cpudom_ptr(); |
255 | if ((p->irqpend_himask & IPIPE_IRQMASK_VIRT) != 0) | ||
256 | __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT); | ||
257 | |||
258 | local_irq_restore_hw(flags); | ||
259 | |||
260 | return -ret; | ||
257 | } | 261 | } |
258 | 262 | ||
259 | unsigned long ipipe_critical_enter(void (*syncfn) (void)) | 263 | unsigned long ipipe_critical_enter(void (*syncfn) (void)) |
@@ -329,9 +333,7 @@ asmlinkage void __ipipe_sync_root(void) | |||
329 | 333 | ||
330 | void ___ipipe_sync_pipeline(unsigned long syncmask) | 334 | void ___ipipe_sync_pipeline(unsigned long syncmask) |
331 | { | 335 | { |
332 | struct ipipe_domain *ipd = ipipe_current_domain; | 336 | if (__ipipe_root_domain_p) { |
333 | |||
334 | if (ipd == ipipe_root_domain) { | ||
335 | if (test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status))) | 337 | if (test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status))) |
336 | return; | 338 | return; |
337 | } | 339 | } |