Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / blackfin / kernel / ipipe.c
index 1a496cd..f37019c 100644 (file)
@@ -154,7 +154,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
         * pending for it.
         */
        if (test_bit(IPIPE_AHEAD_FLAG, &this_domain->flags) &&
-           ipipe_head_cpudom_var(irqpend_himask) == 0)
+           !__ipipe_ipending_p(ipipe_head_cpudom_ptr()))
                goto out;
 
        __ipipe_walk_pipeline(head);
@@ -185,25 +185,21 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
 }
 EXPORT_SYMBOL(__ipipe_disable_irqdesc);
 
-int __ipipe_syscall_root(struct pt_regs *regs)
+asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)
 {
        struct ipipe_percpu_domain_data *p;
-       unsigned long flags;
+       void (*hook)(void);
        int ret;
 
+       WARN_ON_ONCE(irqs_disabled_hw());
+
        /*
-        * We need to run the IRQ tail hook whenever we don't
-        * propagate a syscall to higher domains, because we know that
-        * important operations might be pending there (e.g. Xenomai
-        * deferred rescheduling).
+        * We need to run the IRQ tail hook each time we intercept a
+        * syscall, because we know that important operations might be
+        * pending there (e.g. Xenomai deferred rescheduling).
         */
-
-       if (regs->orig_p0 < NR_syscalls) {
-               void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
-               hook();
-               if ((current->flags & PF_EVNOTIFY) == 0)
-                       return 0;
-       }
+       hook = (__typeof__(hook))__ipipe_irq_tail_hook;
+       hook();
 
        /*
         * This routine either returns:
@@ -214,51 +210,47 @@ int __ipipe_syscall_root(struct pt_regs *regs)
         * tail work has to be performed (for handling signals etc).
         */
 
-       if (!__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL))
+       if (!__ipipe_syscall_watched_p(current, regs->orig_p0) ||
+           !__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL))
                return 0;
 
        ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs);
 
-       local_irq_save_hw(flags);
+       hard_local_irq_disable();
 
-       if (!__ipipe_root_domain_p) {
-               local_irq_restore_hw(flags);
-               return 1;
+       /*
+        * This is the end of the syscall path, so we may
+        * safely assume a valid Linux task stack here.
+        */
+       if (current->ipipe_flags & PF_EVTRET) {
+               current->ipipe_flags &= ~PF_EVTRET;
+               __ipipe_dispatch_event(IPIPE_EVENT_RETURN, regs);
        }
 
-       p = ipipe_root_cpudom_ptr();
-       if ((p->irqpend_himask & IPIPE_IRQMASK_VIRT) != 0)
-               __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
+       if (!__ipipe_root_domain_p)
+               ret = -1;
+       else {
+               p = ipipe_root_cpudom_ptr();
+               if (__ipipe_ipending_p(p))
+                       __ipipe_sync_pipeline();
+       }
 
-       local_irq_restore_hw(flags);
+       hard_local_irq_enable();
 
        return -ret;
 }
 
-unsigned long ipipe_critical_enter(void (*syncfn) (void))
-{
-       unsigned long flags;
-
-       local_irq_save_hw(flags);
-
-       return flags;
-}
-
-void ipipe_critical_exit(unsigned long flags)
-{
-       local_irq_restore_hw(flags);
-}
-
 static void __ipipe_no_irqtail(void)
 {
 }
 
 int ipipe_get_sysinfo(struct ipipe_sysinfo *info)
 {
-       info->ncpus = num_online_cpus();
-       info->cpufreq = ipipe_cpu_freq();
-       info->archdep.tmirq = IPIPE_TIMER_IRQ;
-       info->archdep.tmfreq = info->cpufreq;
+       info->sys_nr_cpus = num_online_cpus();
+       info->sys_cpu_freq = ipipe_cpu_freq();
+       info->sys_hrtimer_irq = IPIPE_TIMER_IRQ;
+       info->sys_hrtimer_freq = __ipipe_core_clock;
+       info->sys_hrclock_freq = __ipipe_core_clock;
 
        return 0;
 }
@@ -279,9 +271,9 @@ int ipipe_trigger_irq(unsigned irq)
                return -EINVAL;
 #endif
 
-       local_irq_save_hw(flags);
+       flags = hard_local_irq_save();
        __ipipe_handle_irq(irq, NULL);
-       local_irq_restore_hw(flags);
+       hard_local_irq_restore(flags);
 
        return 1;
 }
@@ -289,30 +281,32 @@ int ipipe_trigger_irq(unsigned irq)
 asmlinkage void __ipipe_sync_root(void)
 {
        void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
+       struct ipipe_percpu_domain_data *p;
        unsigned long flags;
 
        BUG_ON(irqs_disabled());
 
-       local_irq_save_hw(flags);
+       flags = hard_local_irq_save();
 
        if (irq_tail_hook)
                irq_tail_hook();
 
        clear_thread_flag(TIF_IRQ_SYNC);
 
-       if (ipipe_root_cpudom_var(irqpend_himask) != 0)
-               __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+       p = ipipe_root_cpudom_ptr();
+       if (__ipipe_ipending_p(p))
+               __ipipe_sync_pipeline();
 
-       local_irq_restore_hw(flags);
+       hard_local_irq_restore(flags);
 }
 
-void ___ipipe_sync_pipeline(unsigned long syncmask)
+void ___ipipe_sync_pipeline(void)
 {
        if (__ipipe_root_domain_p &&
            test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)))
                return;
 
-       __ipipe_sync_stage(syncmask);
+       __ipipe_sync_stage();
 }
 
 void __ipipe_disable_root_irqs_hw(void)
@@ -344,10 +338,10 @@ void __ipipe_stall_root(void)
 {
        unsigned long *p, flags;
 
-       local_irq_save_hw(flags);
+       flags = hard_local_irq_save();
        p = &__ipipe_root_status;
        __set_bit(IPIPE_STALL_FLAG, p);
-       local_irq_restore_hw(flags);
+       hard_local_irq_restore(flags);
 }
 EXPORT_SYMBOL(__ipipe_stall_root);
 
@@ -356,10 +350,10 @@ unsigned long __ipipe_test_and_stall_root(void)
        unsigned long *p, flags;
        int x;
 
-       local_irq_save_hw(flags);
+       flags = hard_local_irq_save();
        p = &__ipipe_root_status;
        x = __test_and_set_bit(IPIPE_STALL_FLAG, p);
-       local_irq_restore_hw(flags);
+       hard_local_irq_restore(flags);
 
        return x;
 }
@@ -371,10 +365,10 @@ unsigned long __ipipe_test_root(void)
        unsigned long flags;
        int x;
 
-       local_irq_save_hw_smp(flags);
+       flags = hard_local_irq_save_smp();
        p = &__ipipe_root_status;
        x = test_bit(IPIPE_STALL_FLAG, p);
-       local_irq_restore_hw_smp(flags);
+       hard_local_irq_restore_smp(flags);
 
        return x;
 }
@@ -384,10 +378,10 @@ void __ipipe_lock_root(void)
 {
        unsigned long *p, flags;
 
-       local_irq_save_hw(flags);
+       flags = hard_local_irq_save();
        p = &__ipipe_root_status;
        __set_bit(IPIPE_SYNCDEFER_FLAG, p);
-       local_irq_restore_hw(flags);
+       hard_local_irq_restore(flags);
 }
 EXPORT_SYMBOL(__ipipe_lock_root);
 
@@ -395,9 +389,9 @@ void __ipipe_unlock_root(void)
 {
        unsigned long *p, flags;
 
-       local_irq_save_hw(flags);
+       flags = hard_local_irq_save();
        p = &__ipipe_root_status;
        __clear_bit(IPIPE_SYNCDEFER_FLAG, p);
-       local_irq_restore_hw(flags);
+       hard_local_irq_restore(flags);
 }
 EXPORT_SYMBOL(__ipipe_unlock_root);