Module: xenomai-2.5
Branch: master
Commit: 7b7054e59e50d44bffc6e0aa52af6eb737ea7cc7
URL:    
http://git.xenomai.org/?p=xenomai-2.5.git;a=commit;h=7b7054e59e50d44bffc6e0aa52af6eb737ea7cc7

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Oct  5 15:47:58 2010 +0200

blackfin: upgrade I-pipe support to 2.6.34-blackfin-1.15-01, 
2.6.35.7-blackfin-1.15-01

---

 ...h => adeos-ipipe-2.6.34-blackfin-1.15-01.patch} |  186 ++++----
 ...=> adeos-ipipe-2.6.35.7-blackfin-1.15-01.patch} |  464 ++++++++++++++++----
 2 files changed, 479 insertions(+), 171 deletions(-)

diff --git 
a/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.14-02.patch 
b/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.15-01.patch
similarity index 98%
rename from ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.14-02.patch
rename to ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.15-01.patch
index 1668422..0af5f58 100644
--- a/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.14-02.patch
+++ b/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.15-01.patch
@@ -12,7 +12,7 @@ index c078849..799b1c0 100644
  
  choice
 diff --git a/arch/blackfin/include/asm/ipipe.h 
b/arch/blackfin/include/asm/ipipe.h
-index d3b4044..4530dfa 100644
+index d3b4044..70b409f 100644
 --- a/arch/blackfin/include/asm/ipipe.h
 +++ b/arch/blackfin/include/asm/ipipe.h
 @@ -34,11 +34,12 @@
@@ -22,12 +22,12 @@ index d3b4044..4530dfa 100644
 +#include <asm/bitsperlong.h>
  
 -#define IPIPE_ARCH_STRING     "1.12-00"
-+#define IPIPE_ARCH_STRING     "1.14-02"
++#define IPIPE_ARCH_STRING     "1.15-01"
  #define IPIPE_MAJOR_NUMBER    1
 -#define IPIPE_MINOR_NUMBER    12
 -#define IPIPE_PATCH_NUMBER    0
-+#define IPIPE_MINOR_NUMBER    14
-+#define IPIPE_PATCH_NUMBER    2
++#define IPIPE_MINOR_NUMBER    15
++#define IPIPE_PATCH_NUMBER    1
  
  #ifdef CONFIG_SMP
  #error "I-pipe/blackfin: SMP not implemented"
@@ -36,7 +36,7 @@ index d3b4044..4530dfa 100644
  
  #define __ipipe_sync_pipeline  ___ipipe_sync_pipeline
 -void ___ipipe_sync_pipeline(unsigned long syncmask);
-+void ___ipipe_sync_pipeline(int dovirt);
++void ___ipipe_sync_pipeline(void);
  
  void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs);
  
@@ -136,7 +136,7 @@ index 813a1af..325e532 100644
        } while (0)
  
 diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
-index 1a496cd..d953572 100644
+index 1a496cd..aa96aa2 100644
 --- a/arch/blackfin/kernel/ipipe.c
 +++ b/arch/blackfin/kernel/ipipe.c
 @@ -154,7 +154,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
@@ -148,7 +148,7 @@ index 1a496cd..d953572 100644
                goto out;
  
        __ipipe_walk_pipeline(head);
-@@ -185,11 +185,13 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, 
unsigned irq)
+@@ -185,25 +185,21 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, 
unsigned irq)
  }
  EXPORT_SYMBOL(__ipipe_disable_irqdesc);
  
@@ -164,22 +164,27 @@ index 1a496cd..d953572 100644
 +      WARN_ON_ONCE(irqs_disabled_hw());
  
        /*
-        * We need to run the IRQ tail hook whenever we don't
-@@ -197,12 +199,9 @@ int __ipipe_syscall_root(struct pt_regs *regs)
-        * important operations might be pending there (e.g. Xenomai
-        * deferred rescheduling).
+-       * 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) {
+-      if (regs->orig_p0 < NR_syscalls) {
 -              void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
-+              hook = (__typeof__(hook))__ipipe_irq_tail_hook;
-               hook();
+-              hook();
 -              if ((current->flags & PF_EVNOTIFY) == 0)
 -                      return 0;
-       }
+-      }
++      hook = (__typeof__(hook))__ipipe_irq_tail_hook;
++      hook();
  
        /*
-@@ -214,23 +213,32 @@ int __ipipe_syscall_root(struct pt_regs *regs)
+        * This routine either returns:
+@@ -214,23 +210,32 @@ int __ipipe_syscall_root(struct pt_regs *regs)
         * tail work has to be performed (for handling signals etc).
         */
  
@@ -214,7 +219,7 @@ index 1a496cd..d953572 100644
 +      else {
 +              p = ipipe_root_cpudom_ptr();
 +              if (__ipipe_ipending_p(p))
-+                      __ipipe_sync_pipeline(IPIPE_IRQ_DOVIRT);
++                      __ipipe_sync_pipeline();
 +      }
  
 -      local_irq_restore_hw(flags);
@@ -222,7 +227,7 @@ index 1a496cd..d953572 100644
  
        return -ret;
  }
-@@ -289,6 +297,7 @@ int ipipe_trigger_irq(unsigned irq)
+@@ -289,6 +294,7 @@ int ipipe_trigger_irq(unsigned irq)
  asmlinkage void __ipipe_sync_root(void)
  {
        void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
@@ -230,7 +235,7 @@ index 1a496cd..d953572 100644
        unsigned long flags;
  
        BUG_ON(irqs_disabled());
-@@ -300,19 +309,20 @@ asmlinkage void __ipipe_sync_root(void)
+@@ -300,19 +306,20 @@ asmlinkage void __ipipe_sync_root(void)
  
        clear_thread_flag(TIF_IRQ_SYNC);
  
@@ -238,20 +243,20 @@ index 1a496cd..d953572 100644
 -              __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
 +      p = ipipe_root_cpudom_ptr();
 +      if (__ipipe_ipending_p(p))
-+              __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++              __ipipe_sync_pipeline();
  
        local_irq_restore_hw(flags);
  }
  
 -void ___ipipe_sync_pipeline(unsigned long syncmask)
-+void ___ipipe_sync_pipeline(int dovirt)
++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(dovirt);
++      __ipipe_sync_stage();
  }
  
  void __ipipe_disable_root_irqs_hw(void)
@@ -619,10 +624,10 @@ index d5b3876..010aa8b 100644
  #endif /* LINUX_HARDIRQ_H */
 diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
 new file mode 100644
-index 0000000..c458883
+index 0000000..9af86be
 --- /dev/null
 +++ b/include/linux/ipipe.h
-@@ -0,0 +1,715 @@
+@@ -0,0 +1,724 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe.h
 + *
@@ -654,6 +659,7 @@ index 0000000..c458883
 +#include <linux/linkage.h>
 +#include <linux/ipipe_base.h>
 +#include <asm/ipipe.h>
++#include <asm/bug.h>
 +
 +#ifdef CONFIG_IPIPE_DEBUG_CONTEXT
 +
@@ -690,6 +696,14 @@ index 0000000..c458883
 +
 +#endif        /* !CONFIG_IPIPE_DEBUG_CONTEXT */
 +
++#ifdef CONFIG_IPIPE_DEBUG_INTERNAL
++#define IPIPE_WARN(c)         WARN_ON(c)
++#define IPIPE_WARN_ONCE(c)    WARN_ON_ONCE(c)
++#else
++#define IPIPE_WARN(c)         do { (void)(c); } while (0)
++#define IPIPE_WARN_ONCE(c)    do { (void)(c); } while (0)
++#endif
++
 +#ifdef CONFIG_IPIPE
 +
 +#define IPIPE_VERSION_STRING  IPIPE_ARCH_STRING
@@ -848,7 +862,7 @@ index 0000000..c458883
 +
 +void __ipipe_dispatch_wired(struct ipipe_domain *head, unsigned irq);
 +
-+void __ipipe_sync_stage(int dovirt);
++void __ipipe_sync_stage(void);
 +
 +void __ipipe_set_irq_pending(struct ipipe_domain *ipd, unsigned irq);
 +
@@ -871,7 +885,7 @@ index 0000000..c458883
 +}
 +
 +#ifndef __ipipe_sync_pipeline
-+#define __ipipe_sync_pipeline(dovirt) __ipipe_sync_stage(dovirt)
++#define __ipipe_sync_pipeline() __ipipe_sync_stage()
 +#endif
 +
 +#ifndef __ipipe_run_irqtail
@@ -1340,10 +1354,10 @@ index 0000000..c458883
 +#endif        /* !__LINUX_IPIPE_H */
 diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h
 new file mode 100644
-index 0000000..fa1a951
+index 0000000..4167616
 --- /dev/null
 +++ b/include/linux/ipipe_base.h
-@@ -0,0 +1,133 @@
+@@ -0,0 +1,130 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe_base.h
 + *
@@ -1397,9 +1411,6 @@ index 0000000..fa1a951
 +#define __IPIPE_2LEVEL_IRQMAP 1
 +#endif
 +
-+#define IPIPE_IRQ_DOALL               0
-+#define IPIPE_IRQ_DOVIRT      1
-+
 +/* Per-cpu pipeline status */
 +#define IPIPE_STALL_FLAG      0       /* Stalls a pipeline stage -- 
guaranteed at bit #0 */
 +#define IPIPE_SYNC_FLAG               1       /* The interrupt syncer is 
running for the domain */
@@ -1479,10 +1490,10 @@ index 0000000..fa1a951
 +#endif        /* !__LINUX_IPIPE_BASE_H */
 diff --git a/include/linux/ipipe_lock.h b/include/linux/ipipe_lock.h
 new file mode 100644
-index 0000000..73ed46a
+index 0000000..032080f
 --- /dev/null
 +++ b/include/linux/ipipe_lock.h
-@@ -0,0 +1,215 @@
+@@ -0,0 +1,230 @@
 +/*   -*- linux-c -*-
 + *   include/linux/ipipe_lock.h
 + *
@@ -1548,6 +1559,19 @@ index 0000000..73ed46a
 +              __ret__;                                                \
 +       })
 +
++#define PICK_SPINTRYLOCK_IRQ(lock)                                    \
++      ({                                                              \
++              int __ret__;                                            \
++              if (ipipe_spinlock_p(lock))                             \
++                      __ret__ = 
__ipipe_spin_trylock_irq(ipipe_spinlock(lock)); \
++              else if (std_spinlock_raw_p(lock))                              
\
++                      __ret__ = 
__real_raw_spin_trylock_irq(std_spinlock_raw(lock)); \
++              else if (std_spinlock_p(lock))                          \
++                      __ret__ = 
__real_raw_spin_trylock_irq(&std_spinlock(lock)->rlock); \
++              else __bad_lock_type();                                 \
++              __ret__;                                                \
++       })
++
 +#define PICK_SPINUNLOCK_IRQRESTORE(lock, flags)                               
\
 +      do {                                                            \
 +              if (ipipe_spinlock_p(lock))                             \
@@ -1643,6 +1667,8 @@ index 0000000..73ed46a
 +
 +void __ipipe_spin_lock_irq(ipipe_spinlock_t *lock);
 +
++int __ipipe_spin_trylock_irq(ipipe_spinlock_t *lock);
++
 +void __ipipe_spin_unlock_irq(ipipe_spinlock_t *lock);
 +
 +unsigned long __ipipe_spin_lock_irqsave(ipipe_spinlock_t *lock);
@@ -1700,7 +1726,7 @@ index 0000000..73ed46a
 +#endif /* !__LINUX_IPIPE_LOCK_H */
 diff --git a/include/linux/ipipe_percpu.h b/include/linux/ipipe_percpu.h
 new file mode 100644
-index 0000000..f6727e3
+index 0000000..0b42e8c
 --- /dev/null
 +++ b/include/linux/ipipe_percpu.h
 @@ -0,0 +1,89 @@
@@ -1779,7 +1805,7 @@ index 0000000..f6727e3
 +DECLARE_PER_CPU(int, ipipe_saved_context_check_state);
 +#endif
 +
-+#define ipipe_root_cpudom_ptr(var)    \
++#define ipipe_root_cpudom_ptr()               \
 +      (&__ipipe_get_cpu_var(ipipe_percpu_darray)[IPIPE_ROOT_SLOT])
 +
 +#define ipipe_root_cpudom_var(var)    ipipe_root_cpudom_ptr()->var
@@ -2179,7 +2205,7 @@ index 2b7b81d..05cbf77 100644
   * tasks can access tsk->flags in readonly mode for example
   * with tsk_used_math (like during threaded core dumping).
 diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
-index 89fac6a..771e701 100644
+index 89fac6a..6135280 100644
 --- a/include/linux/spinlock.h
 +++ b/include/linux/spinlock.h
 @@ -88,10 +88,12 @@
@@ -2280,7 +2306,7 @@ index 89fac6a..771e701 100644
 +      __real_raw_spin_trylock(lock) ? \
        1 : ({ local_irq_enable(); 0;  }); \
  })
-+#define raw_spin_trylock_irq(lock)    PICK_SPINOP(_trylock_irq, lock)
++#define raw_spin_trylock_irq(lock)    PICK_SPINTRYLOCK_IRQ(lock)
  
 -#define raw_spin_trylock_irqsave(lock, flags) \
 +#define __real_raw_spin_trylock_irqsave(lock, flags) \
@@ -2700,10 +2726,10 @@ index 0000000..6257dfa
 +obj-$(CONFIG_IPIPE_TRACE) += tracer.o
 diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
 new file mode 100644
-index 0000000..e2503bd
+index 0000000..539ec20
 --- /dev/null
 +++ b/kernel/ipipe/core.c
-@@ -0,0 +1,1977 @@
+@@ -0,0 +1,1960 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/core.c
 + *
@@ -2737,7 +2763,6 @@ index 0000000..e2503bd
 +#include <linux/interrupt.h>
 +#include <linux/bitops.h>
 +#include <linux/tick.h>
-+#include <linux/prefetch.h>
 +#ifdef CONFIG_PROC_FS
 +#include <linux/proc_fs.h>
 +#include <linux/seq_file.h>
@@ -3022,7 +3047,7 @@ index 0000000..e2503bd
 +        __clear_bit(IPIPE_STALL_FLAG, &p->status);
 +
 +        if (unlikely(__ipipe_ipending_p(p)))
-+                __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++                __ipipe_sync_pipeline();
 +
 +        local_irq_enable_hw();
 +}
@@ -3115,7 +3140,7 @@ index 0000000..e2503bd
 +      if (unlikely(__ipipe_ipending_p(p))) {
 +              head_domain = __ipipe_pipeline_head();
 +              if (likely(head_domain == __ipipe_current_domain))
-+                      __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++                      __ipipe_sync_pipeline();
 +              else
 +                      __ipipe_walk_pipeline(&head_domain->p_link);
 +        }
@@ -3152,7 +3177,7 @@ index 0000000..e2503bd
 +              if (unlikely(__ipipe_ipending_p(p))) {
 +                      head_domain = __ipipe_pipeline_head();
 +                      if (likely(head_domain == __ipipe_current_domain))
-+                              __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++                              __ipipe_sync_pipeline();
 +                      else
 +                              __ipipe_walk_pipeline(&head_domain->p_link);
 +              }
@@ -3254,9 +3279,10 @@ index 0000000..e2503bd
 +      struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(ipd);
 +      int l0b, l1b;
 +
++      IPIPE_WARN_ONCE(!irqs_disabled_hw());
++
 +      l0b = irq / (BITS_PER_LONG * BITS_PER_LONG);
 +      l1b = irq / BITS_PER_LONG;
-+      prefetchw(p);
 +
 +      if (likely(!test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))) {
 +              __set_bit(irq, p->irqpend_lomap);
@@ -3274,6 +3300,8 @@ index 0000000..e2503bd
 +      struct ipipe_percpu_domain_data *p;
 +      int l0b, l1b;
 +
++      IPIPE_WARN_ONCE(!irqs_disabled_hw());
++
 +      /* Wired interrupts cannot be locked (it is useless). */
 +      if (test_bit(IPIPE_WIRED_FLAG, &ipd->irqs[irq].control) ||
 +          test_and_set_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))
@@ -3299,6 +3327,8 @@ index 0000000..e2503bd
 +      struct ipipe_percpu_domain_data *p;
 +      int l0b, l1b, cpu;
 +
++      IPIPE_WARN_ONCE(!irqs_disabled_hw());
++
 +      if (unlikely(!test_and_clear_bit(IPIPE_LOCK_FLAG,
 +                                       &ipd->irqs[irq].control)))
 +              return;
@@ -3317,36 +3347,18 @@ index 0000000..e2503bd
 +      }
 +}
 +
-+static inline int __ipipe_next_irq(struct ipipe_percpu_domain_data *p,
-+                                 int dovirt)
++static inline int __ipipe_next_irq(struct ipipe_percpu_domain_data *p)
 +{
-+      unsigned long l0m, l1m, l2m, himask, mdmask;
 +      int l0b, l1b, l2b, vl0b, vl1b;
++      unsigned long l0m, l1m, l2m;
 +      unsigned int irq;
 +
-+      if (dovirt) {
-+              /*
-+               * All virtual IRQs are mapped by a single long word.
-+               * There is exactly BITS_PER_LONG virqs, and they are
-+               * always last in the interrupt map, starting at
-+               * IPIPE_VIRQ_BASE. Therefore, we only need to test a
-+               * single bit within the high and middle maps to check
-+               * whether a virtual IRQ is pending (the computations
-+               * below are constant).
-+               */
-+              vl0b = IPIPE_VIRQ_BASE / (BITS_PER_LONG * BITS_PER_LONG);
-+              himask = (1L << vl0b);
-+              vl1b = IPIPE_VIRQ_BASE / BITS_PER_LONG;
-+              mdmask = (1L << (vl1b & (BITS_PER_LONG-1)));
-+      } else
-+              himask = mdmask = ~0L;
-+
-+      l0m = p->irqpend_himap & himask;
++      l0m = p->irqpend_himap;
 +      if (unlikely(l0m == 0))
 +              return -1;
 +
 +      l0b = __ipipe_ffnz(l0m);
-+      l1m = p->irqpend_mdmap[l0b] & mdmask;
++      l1m = p->irqpend_mdmap[l0b];
 +      if (unlikely(l1m == 0))
 +              return -1;
 +
@@ -3384,7 +3396,7 @@ index 0000000..e2503bd
 +      struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(ipd);
 +      int l0b = irq / BITS_PER_LONG;
 +
-+      prefetchw(p);
++      IPIPE_WARN_ONCE(!irqs_disabled_hw());
 +      
 +      if (likely(!test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))) {
 +              __set_bit(irq, p->irqpend_lomap);
@@ -3401,6 +3413,8 @@ index 0000000..e2503bd
 +      struct ipipe_percpu_domain_data *p;
 +      int l0b = irq / BITS_PER_LONG;
 +
++      IPIPE_WARN_ONCE(!irqs_disabled_hw());
++
 +      /* Wired interrupts cannot be locked (it is useless). */
 +      if (test_bit(IPIPE_WIRED_FLAG, &ipd->irqs[irq].control) ||
 +          test_and_set_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))
@@ -3420,6 +3434,8 @@ index 0000000..e2503bd
 +      struct ipipe_percpu_domain_data *p;
 +      int l0b = irq / BITS_PER_LONG, cpu;
 +
++      IPIPE_WARN_ONCE(!irqs_disabled_hw());
++
 +      if (unlikely(!test_and_clear_bit(IPIPE_LOCK_FLAG,
 +                                       &ipd->irqs[irq].control)))
 +              return;
@@ -3434,15 +3450,12 @@ index 0000000..e2503bd
 +      }
 +}
 +
-+static inline int __ipipe_next_irq(struct ipipe_percpu_domain_data *p,
-+                                 int dovirt)
++static inline int __ipipe_next_irq(struct ipipe_percpu_domain_data *p)
 +{
-+      unsigned long l0m, l1m, himask = ~0L;
++      unsigned long l0m, l1m;
 +      int l0b, l1b;
 +
-+      himask <<= dovirt ? IPIPE_VIRQ_BASE/BITS_PER_LONG : 0;
-+
-+      l0m = p->irqpend_himap & himask;
++      l0m = p->irqpend_himap;
 +      if (unlikely(l0m == 0))
 +              return -1;
 +
@@ -3482,7 +3495,7 @@ index 0000000..e2503bd
 +
 +              if (__ipipe_ipending_p(np)) {
 +                      if (next_domain == this_domain)
-+                              __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++                              __ipipe_sync_pipeline();
 +                      else {
 +
 +                              p->evsync = 0;
@@ -3499,7 +3512,7 @@ index 0000000..e2503bd
 +
 +                              if (__ipipe_ipending_p(p) &&
 +                                  !test_bit(IPIPE_STALL_FLAG, &p->status))
-+                                      __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++                                      __ipipe_sync_pipeline();
 +                      }
 +                      break;
 +              } else if (next_domain == this_domain)
@@ -3546,7 +3559,7 @@ index 0000000..e2503bd
 +
 +              __ipipe_current_domain = next_domain;
 +sync_stage:
-+              __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++              __ipipe_sync_pipeline();
 +
 +              if (__ipipe_current_domain != next_domain)
 +                      /*
@@ -3648,7 +3661,7 @@ index 0000000..e2503bd
 +                  ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK |
 +                    IPIPE_EXCLUSIVE_MASK | IPIPE_WIRED_MASK);
 +
-+      if (acknowledge == NULL && !ipipe_virtual_irq_p(irq))
++      if (acknowledge == NULL)
 +              /*
 +               * Acknowledge handler unspecified for a hw interrupt:
 +               * use the Linux-defined handler instead.
@@ -3798,7 +3811,7 @@ index 0000000..e2503bd
 +                  __ipipe_ipending_p(np) &&
 +                  !test_bit(IPIPE_STALL_FLAG, &np->status)) {
 +                      __ipipe_current_domain = next_domain;
-+                      __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++                      __ipipe_sync_pipeline();
 +                      if (__ipipe_current_domain != next_domain)
 +                              this_domain = __ipipe_current_domain;
 +              }
@@ -3842,8 +3855,6 @@ index 0000000..e2503bd
 +{
 +      struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(head);
 +
-+      prefetchw(p);
-+
 +      if (test_bit(IPIPE_STALL_FLAG, &p->status)) {
 +              __ipipe_set_irq_pending(head, irq);
 +              return;
@@ -3857,8 +3868,6 @@ index 0000000..e2503bd
 +      struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(head);
 +      struct ipipe_domain *old;
 +
-+      prefetchw(p);
-+
 +      old = __ipipe_current_domain;
 +      __ipipe_current_domain = head; /* Switch to the head domain. */
 +
@@ -3872,7 +3881,7 @@ index 0000000..e2503bd
 +              __ipipe_current_domain = old;
 +              if (old == head) {
 +                      if (__ipipe_ipending_p(p))
-+                              __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++                              __ipipe_sync_pipeline();
 +                      return;
 +              }
 +      }
@@ -3891,7 +3900,7 @@ index 0000000..e2503bd
 + *
 + * This routine must be called with hw interrupts off.
 + */
-+void __ipipe_sync_stage(int dovirt)
++void __ipipe_sync_stage(void)
 +{
 +      struct ipipe_percpu_domain_data *p;
 +      struct ipipe_domain *ipd;
@@ -3914,7 +3923,7 @@ index 0000000..e2503bd
 +      cpu = ipipe_processor_id();
 +
 +      for (;;) {
-+              irq = __ipipe_next_irq(p, dovirt);
++              irq = __ipipe_next_irq(p);
 +              if (irq < 0)
 +                      break;
 +              /*
@@ -4074,7 +4083,7 @@ index 0000000..e2503bd
 +
 +      if (__ipipe_ipending_p(p) &&
 +          !test_bit(IPIPE_STALL_FLAG, &p->status))
-+              __ipipe_sync_pipeline(IPIPE_IRQ_DOALL);
++              __ipipe_sync_pipeline();
 +
 +      local_irq_restore_hw(flags);
 +
@@ -4683,10 +4692,10 @@ index 0000000..e2503bd
 +EXPORT_SYMBOL(ipipe_get_sysinfo);
 diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c
 new file mode 100644
-index 0000000..001a83e
+index 0000000..f013ef4
 --- /dev/null
 +++ b/kernel/ipipe/tracer.c
-@@ -0,0 +1,1441 @@
+@@ -0,0 +1,1442 @@
 +/* -*- linux-c -*-
 + * kernel/ipipe/tracer.c
 + *
@@ -6093,6 +6102,7 @@ index 0000000..001a83e
 +#ifdef CONFIG_IPIPE_TRACE_ENABLE
 +      ipipe_trace_enable = 1;
 +#ifdef CONFIG_IPIPE_TRACE_MCOUNT
++      ftrace_enabled = 1;
 +      register_ftrace_function(&ipipe_trace_ops);
 +#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
 +#endif /* CONFIG_IPIPE_TRACE_ENABLE */
diff --git 
a/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.2-blackfin-1.15-00.patch 
b/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.7-blackfin-1.15-01.patch
similarity index 95%
rename from 
ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.2-blackfin-1.15-00.patch
rename to ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.7-blackfin-1.15-01.patch
index 7bf07f3..2c67b19 100644
--- a/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.2-blackfin-1.15-00.patch
+++ b/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.7-blackfin-1.15-01.patch
@@ -12,23 +12,25 @@ index f66294b..5bad536 100644
  
  choice
 diff --git a/arch/blackfin/include/asm/ipipe.h 
b/arch/blackfin/include/asm/ipipe.h
-index d3b4044..bb310c5 100644
+index d3b4044..9d910bd 100644
 --- a/arch/blackfin/include/asm/ipipe.h
 +++ b/arch/blackfin/include/asm/ipipe.h
-@@ -34,10 +34,11 @@
+@@ -34,11 +34,12 @@
  #include <asm/bitops.h>
  #include <asm/atomic.h>
  #include <asm/traps.h>
 +#include <asm/bitsperlong.h>
  
 -#define IPIPE_ARCH_STRING     "1.12-00"
-+#define IPIPE_ARCH_STRING     "1.15-00"
++#define IPIPE_ARCH_STRING     "1.15-01"
  #define IPIPE_MAJOR_NUMBER    1
 -#define IPIPE_MINOR_NUMBER    12
+-#define IPIPE_PATCH_NUMBER    0
 +#define IPIPE_MINOR_NUMBER    15
- #define IPIPE_PATCH_NUMBER    0
++#define IPIPE_PATCH_NUMBER    1
  
  #ifdef CONFIG_SMP
+ #error "I-pipe/blackfin: SMP not implemented"
 @@ -64,16 +65,11 @@ do {                                               \
  struct ipipe_domain;
  
@@ -163,7 +165,7 @@ index 813a1af..325e532 100644
        } while (0)
  
 diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
-index 1a496cd..1c20192 100644
+index 1a496cd..dbbe1d4 100644
 --- a/arch/blackfin/kernel/ipipe.c
 +++ b/arch/blackfin/kernel/ipipe.c
 @@ -154,7 +154,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
@@ -175,7 +177,7 @@ index 1a496cd..1c20192 100644
                goto out;
  
        __ipipe_walk_pipeline(head);
-@@ -185,11 +185,13 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, 
unsigned irq)
+@@ -185,25 +185,21 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, 
unsigned irq)
  }
  EXPORT_SYMBOL(__ipipe_disable_irqdesc);
  
@@ -191,22 +193,27 @@ index 1a496cd..1c20192 100644
 +      WARN_ON_ONCE(irqs_disabled_hw());
  
        /*
-        * We need to run the IRQ tail hook whenever we don't
-@@ -197,12 +199,9 @@ int __ipipe_syscall_root(struct pt_regs *regs)
-        * important operations might be pending there (e.g. Xenomai
-        * deferred rescheduling).
+-       * 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) {
+-      if (regs->orig_p0 < NR_syscalls) {
 -              void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
-+              hook = (__typeof__(hook))__ipipe_irq_tail_hook;
-               hook();
+-              hook();
 -              if ((current->flags & PF_EVNOTIFY) == 0)
 -                      return 0;
-       }
+-      }
++      hook = (__typeof__(hook))__ipipe_irq_tail_hook;
++      hook();
  
        /*
-@@ -214,23 +213,32 @@ int __ipipe_syscall_root(struct pt_regs *regs)
+        * 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).
         */
  
@@ -249,7 +256,24 @@ index 1a496cd..1c20192 100644
  
        return -ret;
  }
-@@ -255,10 +263,11 @@ static void __ipipe_no_irqtail(void)
+ 
+-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)
  {
@@ -265,7 +289,7 @@ index 1a496cd..1c20192 100644
  
        return 0;
  }
-@@ -289,6 +298,7 @@ int ipipe_trigger_irq(unsigned irq)
+@@ -289,6 +281,7 @@ int ipipe_trigger_irq(unsigned irq)
  asmlinkage void __ipipe_sync_root(void)
  {
        void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
@@ -273,7 +297,7 @@ index 1a496cd..1c20192 100644
        unsigned long flags;
  
        BUG_ON(irqs_disabled());
-@@ -300,19 +310,20 @@ asmlinkage void __ipipe_sync_root(void)
+@@ -300,19 +293,20 @@ asmlinkage void __ipipe_sync_root(void)
  
        clear_thread_flag(TIF_IRQ_SYNC);
  
@@ -376,10 +400,10 @@ index 98abf8b..7cb0a86 100644
  struct ht_irq_cfg {
        struct pci_dev *dev;
 diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
-index 891e1dd..c24f9f6 100644
+index 891e1dd..95f42db 100644
 --- a/drivers/serial/8250.c
 +++ b/drivers/serial/8250.c
-@@ -3051,6 +3051,51 @@ static int serial8250_resume(struct platform_device 
*dev)
+@@ -3051,6 +3051,53 @@ static int serial8250_resume(struct platform_device 
*dev)
        return 0;
  }
  
@@ -426,6 +450,8 @@ index 891e1dd..c24f9f6 100644
 +        local_irq_restore_hw(flags);
 +}
 +
++EXPORT_SYMBOL(__ipipe_serial_debug);
++
 +#endif
 +
  static struct platform_driver serial8250_isa_driver = {
@@ -662,10 +688,10 @@ index d5b3876..010aa8b 100644
  #endif /* LINUX_HARDIRQ_H */
 diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
 new file mode 100644
-index 0000000..9af86be
+index 0000000..8d82852
 --- /dev/null
 +++ b/include/linux/ipipe.h
-@@ -0,0 +1,724 @@
+@@ -0,0 +1,769 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe.h
 + *
@@ -863,8 +889,15 @@ index 0000000..9af86be
 +
 +extern int __ipipe_event_monitors[];
 +
++typedef void (*ipipe_root_preempt_handler_t)(void *cookie);
++
++DECLARE_PER_CPU(ipipe_root_preempt_handler_t, __ipipe_root_preempt_handler);
++DECLARE_PER_CPU(void *, __ipipe_root_preempt_cookie);
++
 +/* Private interface */
 +
++void ipipe_init_early(void);
++
 +void ipipe_init(void);
 +
 +#ifdef CONFIG_PROC_FS
@@ -1195,7 +1228,10 @@ index 0000000..9af86be
 +
 +static inline void ipipe_restore_pipeline_head(unsigned long x)
 +{
-+      local_irq_disable_hw();
++#ifdef CONFIG_IPIPE_DEBUG
++      if (WARN_ON_ONCE(!irqs_disabled_hw()))
++              local_irq_disable_hw();
++#endif
 +      if ((x ^ test_bit(IPIPE_STALL_FLAG, &ipipe_head_cpudom_var(status))) & 
1)
 +              __ipipe_restore_pipeline_head(x);
 +}
@@ -1222,10 +1258,14 @@ index 0000000..9af86be
 +
 +int ipipe_get_sysinfo(struct ipipe_sysinfo *sysinfo);
 +
++void __ipipe_do_critical_sync(unsigned irq, void *cookie);
++
 +unsigned long ipipe_critical_enter(void (*syncfn) (void));
 +
 +void ipipe_critical_exit(unsigned long flags);
 +
++void ipipe_prepare_panic(void);
++
 +static inline void ipipe_set_printk_sync(struct ipipe_domain *ipd)
 +{
 +      set_bit(IPIPE_SPRINTK_FLAG, &ipd->flags);
@@ -1339,8 +1379,35 @@ index 0000000..9af86be
 +                      (p)->ipipe_flags |= PF_EVTRET;                  \
 +      } while (0)
 +
++static inline void
++ipipe_register_root_preempt_handler(ipipe_root_preempt_handler_t handler,
++                                  void *cookie)
++{
++      int cpu = ipipe_processor_id();
++
++      per_cpu(__ipipe_root_preempt_cookie, cpu) = cookie;
++      barrier();
++      per_cpu(__ipipe_root_preempt_handler, cpu) = handler;
++}
++
++static inline void ipipe_unregister_root_preempt_handler(void)
++{
++      per_cpu(__ipipe_root_preempt_handler, ipipe_processor_id()) = NULL;
++}
++
++static inline void ipipe_root_preempt_notify(void)
++{
++      ipipe_root_preempt_handler_t handler;
++      int cpu = ipipe_processor_id();
++
++      handler = per_cpu(__ipipe_root_preempt_handler, cpu);
++      if (unlikely(handler))
++              handler(per_cpu(__ipipe_root_preempt_cookie, cpu));
++}
++
 +#else /* !CONFIG_IPIPE */
 +
++#define ipipe_init_early()            do { } while(0)
 +#define ipipe_init()                  do { } while(0)
 +#define ipipe_suspend_domain()                do { } while(0)
 +#define ipipe_sigwake_notify(p)               do { } while(0)
@@ -1351,6 +1418,10 @@ index 0000000..9af86be
 +#define ipipe_trap_notify(t,r)                0
 +#define ipipe_init_proc()             do { } while(0)
 +
++#define ipipe_register_root_preempt_handler(h, c)     do { } while (0)
++#define ipipe_unregister_root_preempt_handler()               do { } while (0)
++#define ipipe_root_preempt_notify()                   do { } while (0)
++
 +static inline void __ipipe_pin_range_globally(unsigned long start,
 +                                            unsigned long end)
 +{
@@ -1373,7 +1444,7 @@ index 0000000..9af86be
 +
 +#define __ipipe_root_domain_p         1
 +#define ipipe_root_domain_p           1
-+#define ipipe_safe_current            current
++#define ipipe_safe_current()          current
 +#define ipipe_processor_id()          smp_processor_id()
 +
 +#define ipipe_nmi_enter()             do { } while (0)
@@ -1392,10 +1463,10 @@ index 0000000..9af86be
 +#endif        /* !__LINUX_IPIPE_H */
 diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h
 new file mode 100644
-index 0000000..4167616
+index 0000000..5260e8b
 --- /dev/null
 +++ b/include/linux/ipipe_base.h
-@@ -0,0 +1,130 @@
+@@ -0,0 +1,135 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe_base.h
 + *
@@ -1498,12 +1569,17 @@ index 0000000..4167616
 +/* Generic features */
 +
 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
-+#define __IPIPE_FEATURE_REQUEST_TICKDEV    1
++#define __IPIPE_FEATURE_REQUEST_TICKDEV               1
++#endif
++#define __IPIPE_FEATURE_DELAYED_ATOMICSW      1
++#define __IPIPE_FEATURE_FASTPEND_IRQ          1
++#define __IPIPE_FEATURE_TRACE_EVENT           1
++#define __IPIPE_FEATURE_ENABLE_NOTIFIER               1
++#ifdef CONFIG_HAVE_IPIPE_HOSTRT
++#define __IPIPE_FEATURE_HOSTRT                        1
 +#endif
-+#define __IPIPE_FEATURE_DELAYED_ATOMICSW   1
-+#define __IPIPE_FEATURE_FASTPEND_IRQ       1
-+#define __IPIPE_FEATURE_TRACE_EVENT      1
-+#define __IPIPE_FEATURE_ENABLE_NOTIFIER          1
++#define __IPIPE_FEATURE_PREPARE_PANIC         1
++#define __IPIPE_FEATURE_ROOT_PREEMPT_NOTIFIER 1
 +
 +#else /* !CONFIG_IPIPE */
 +
@@ -1859,10 +1935,10 @@ index 0000000..0b42e8c
 +#endif        /* !__LINUX_IPIPE_PERCPU_H */
 diff --git a/include/linux/ipipe_tickdev.h b/include/linux/ipipe_tickdev.h
 new file mode 100644
-index 0000000..4a1cb1b
+index 0000000..df17444
 --- /dev/null
 +++ b/include/linux/ipipe_tickdev.h
-@@ -0,0 +1,58 @@
+@@ -0,0 +1,83 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe_tickdev.h
 + *
@@ -1890,6 +1966,7 @@ index 0000000..4a1cb1b
 +#if defined(CONFIG_IPIPE) && defined(CONFIG_GENERIC_CLOCKEVENTS)
 +
 +#include <linux/clockchips.h>
++#include <linux/clocksource.h>
 +
 +struct tick_device;
 +
@@ -1909,6 +1986,22 @@ index 0000000..4a1cb1b
 +      int real_shift;
 +};
 +
++/*
++ * NOTE: When modifying this structure, make sure to keep the Xenomai
++ * definition include/nucleus/vdso.h in sync.
++ */
++struct ipipe_hostrt_data {
++      short live;
++      seqcount_t seqcount;
++      time_t wall_time_sec;
++      u32 wall_time_nsec;
++      struct timespec wall_to_monotonic;
++      cycle_t cycle_last;
++      cycle_t mask;
++      u32 mult;
++      u32 shift;
++};
++
 +int ipipe_request_tickdev(const char *devname,
 +                        void (*emumode)(enum clock_event_mode mode,
 +                                        struct clock_event_device *cdev),
@@ -1920,6 +2013,14 @@ index 0000000..4a1cb1b
 +
 +#endif /* CONFIG_IPIPE && CONFIG_GENERIC_CLOCKEVENTS */
 +
++#ifdef CONFIG_HAVE_IPIPE_HOSTRT
++void ipipe_update_hostrt(struct timespec *wall_time,
++                       struct clocksource *clock);
++#else /* !CONFIG_IPIPE_HOSTRT */
++static inline void
++ipipe_update_hostrt(struct timespec *wall_time, struct clocksource *clock) {};
++#endif
++
 +#endif /* !__LINUX_IPIPE_TICKDEV_H */
 diff --git a/include/linux/ipipe_trace.h b/include/linux/ipipe_trace.h
 new file mode 100644
@@ -2518,7 +2619,7 @@ index 5cff9a9..6ce2285 100644
          Append an extra string to the end of your kernel version.
          This will show up when you type uname, for example.
 diff --git a/init/main.c b/init/main.c
-index a42fdf4..d00419b 100644
+index a42fdf4..149d8ea 100644
 --- a/init/main.c
 +++ b/init/main.c
 @@ -557,7 +557,7 @@ asmlinkage void __init start_kernel(void)
@@ -2530,7 +2631,15 @@ index a42fdf4..d00419b 100644
        early_boot_irqs_off();
        early_init_irq_lock_class();
  
-@@ -621,6 +621,11 @@ asmlinkage void __init start_kernel(void)
+@@ -592,6 +592,7 @@ asmlinkage void __init start_kernel(void)
+       pidhash_init();
+       vfs_caches_init_early();
+       sort_main_extable();
++      ipipe_init_early();
+       trap_init();
+       mm_init();
+       /*
+@@ -621,6 +622,11 @@ asmlinkage void __init start_kernel(void)
        softirq_init();
        timekeeping_init();
        time_init();
@@ -2542,7 +2651,7 @@ index a42fdf4..d00419b 100644
        profile_init();
        if (!irqs_disabled())
                printk(KERN_CRIT "start_kernel(): bug: interrupts were "
-@@ -802,6 +807,7 @@ static void __init do_basic_setup(void)
+@@ -802,6 +808,7 @@ static void __init do_basic_setup(void)
        init_tmpfs();
        driver_init();
        init_irq_proc();
@@ -2563,7 +2672,7 @@ index 057472f..c456c33 100644
  obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
  obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
 diff --git a/kernel/exit.c b/kernel/exit.c
-index ceffc67..2710991 100644
+index ac90425..a491bc3 100644
 --- a/kernel/exit.c
 +++ b/kernel/exit.c
 @@ -966,6 +966,7 @@ NORET_TYPE void do_exit(long code)
@@ -2575,10 +2684,10 @@ index ceffc67..2710991 100644
        exit_files(tsk);
        exit_fs(tsk);
 diff --git a/kernel/fork.c b/kernel/fork.c
-index b6cce14..9f70852 100644
+index e96c0cd..9be0e42 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -537,6 +537,7 @@ void mmput(struct mm_struct *mm)
+@@ -540,6 +540,7 @@ void mmput(struct mm_struct *mm)
                exit_aio(mm);
                ksm_exit(mm);
                exit_mmap(mm);
@@ -2586,7 +2695,7 @@ index b6cce14..9f70852 100644
                set_mm_exe_file(mm, NULL);
                if (!list_empty(&mm->mmlist)) {
                        spin_lock(&mmlist_lock);
-@@ -907,7 +908,7 @@ static void copy_flags(unsigned long clone_flags, struct 
task_struct *p)
+@@ -910,7 +911,7 @@ static void copy_flags(unsigned long clone_flags, struct 
task_struct *p)
  {
        unsigned long new_flags = p->flags;
  
@@ -2595,7 +2704,7 @@ index b6cce14..9f70852 100644
        new_flags |= PF_FORKNOEXEC;
        new_flags |= PF_STARTING;
        p->flags = new_flags;
-@@ -1283,6 +1284,10 @@ static struct task_struct *copy_process(unsigned long 
clone_flags,
+@@ -1286,6 +1287,10 @@ static struct task_struct *copy_process(unsigned long 
clone_flags,
        write_unlock_irq(&tasklist_lock);
        proc_fork_connector(p);
        cgroup_post_fork(p);
@@ -2606,7 +2715,7 @@ index b6cce14..9f70852 100644
        perf_event_fork(p);
        return p;
  
-@@ -1685,11 +1690,14 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
+@@ -1688,11 +1693,14 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
                }
  
                if (new_mm) {
@@ -2623,10 +2732,10 @@ index b6cce14..9f70852 100644
  
 diff --git a/kernel/ipipe/Kconfig b/kernel/ipipe/Kconfig
 new file mode 100644
-index 0000000..8ff9d37
+index 0000000..693a7d2
 --- /dev/null
 +++ b/kernel/ipipe/Kconfig
-@@ -0,0 +1,23 @@
+@@ -0,0 +1,26 @@
 +config IPIPE
 +      bool "Interrupt pipeline"
 +      default y
@@ -2650,6 +2759,9 @@ index 0000000..8ff9d37
 +       bool
 +       depends on IPIPE
 +       default n
++
++config HAVE_IPIPE_HOSTRT
++       bool
 diff --git a/kernel/ipipe/Kconfig.debug b/kernel/ipipe/Kconfig.debug
 new file mode 100644
 index 0000000..32160fc
@@ -2762,10 +2874,10 @@ index 0000000..6257dfa
 +obj-$(CONFIG_IPIPE_TRACE) += tracer.o
 diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
 new file mode 100644
-index 0000000..cd4952c
+index 0000000..17479dc
 --- /dev/null
 +++ b/kernel/ipipe/core.c
-@@ -0,0 +1,1968 @@
+@@ -0,0 +1,2153 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/core.c
 + *
@@ -2799,7 +2911,6 @@ index 0000000..cd4952c
 +#include <linux/interrupt.h>
 +#include <linux/bitops.h>
 +#include <linux/tick.h>
-+#include <linux/prefetch.h>
 +#ifdef CONFIG_PROC_FS
 +#include <linux/proc_fs.h>
 +#include <linux/seq_file.h>
@@ -2816,7 +2927,26 @@ index 0000000..cd4952c
 +
 +struct ipipe_domain ipipe_root;
 +
-+#ifndef CONFIG_SMP
++#ifdef CONFIG_SMP
++
++#define IPIPE_CRITICAL_TIMEOUT        1000000
++
++static cpumask_t __ipipe_cpu_sync_map;
++
++static cpumask_t __ipipe_cpu_lock_map;
++
++static cpumask_t __ipipe_cpu_pass_map;
++
++static unsigned long __ipipe_critical_lock;
++
++static IPIPE_DEFINE_SPINLOCK(__ipipe_cpu_barrier);
++
++static atomic_t __ipipe_critical_count = ATOMIC_INIT(0);
++
++static void (*__ipipe_cpu_sync) (void);
++
++#else /* !CONFIG_SMP */
++
 +/*
 + * Create an alias to the unique root status, so that arch-dep code
 + * may get simple and easy access to this percpu variable.  We also
@@ -2864,6 +2994,12 @@ index 0000000..cd4952c
 +
 +int __ipipe_event_monitors[IPIPE_NR_EVENTS];
 +
++DEFINE_PER_CPU(ipipe_root_preempt_handler_t, __ipipe_root_preempt_handler);
++EXPORT_PER_CPU_SYMBOL_GPL(__ipipe_root_preempt_handler);
++
++DEFINE_PER_CPU(void *, __ipipe_root_preempt_cookie);
++EXPORT_PER_CPU_SYMBOL_GPL(__ipipe_root_preempt_cookie);
++
 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
 +
 +DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
@@ -2973,15 +3109,15 @@ index 0000000..cd4952c
 +
 +#endif /* CONFIG_GENERIC_CLOCKEVENTS */
 +
-+/*
-+ * ipipe_init() -- Initialization routine of the IPIPE layer. Called
-+ * by the host kernel early during the boot procedure.
-+ */
-+void __init ipipe_init(void)
++void __init ipipe_init_early(void)
 +{
 +      struct ipipe_domain *ipd = &ipipe_root;
 +
-+      __ipipe_check_platform();       /* Do platform dependent checks first. 
*/
++      /*
++       * Do the early init stuff. At this point, the kernel does not
++       * provide much services yet: be careful.
++       */
++      __ipipe_check_platform(); /* Do platform dependent checks first. */
 +
 +      /*
 +       * A lightweight registration code for the root domain. We are
@@ -2999,7 +3135,6 @@ index 0000000..cd4952c
 +
 +      __ipipe_init_stage(ipd);
 +
-+      INIT_LIST_HEAD(&ipd->p_link);
 +      list_add_tail(&ipd->p_link, &__ipipe_pipeline);
 +
 +      __ipipe_init_platform();
@@ -3011,7 +3146,11 @@ index 0000000..cd4952c
 +      ipd->irqs[__ipipe_printk_virq].acknowledge = NULL;
 +      ipd->irqs[__ipipe_printk_virq].control = IPIPE_HANDLE_MASK;
 +#endif /* CONFIG_PRINTK */
++}
 +
++void __init ipipe_init(void)
++{
++      /* Now we may engage the pipeline. */
 +      __ipipe_enable_pipeline();
 +
 +      printk(KERN_INFO "I-pipe %s: pipeline enabled.\n",
@@ -3074,10 +3213,8 @@ index 0000000..cd4952c
 +
 +        local_irq_disable_hw();
 +
-+#ifdef CONFIG_IPIPE_DEBUG_INTERNAL
 +      /* This helps catching bad usage from assembly call sites. */
-+      BUG_ON(!__ipipe_root_domain_p);
-+#endif
++      ipipe_check_context(ipipe_root_domain);
 +
 +      p = ipipe_root_cpudom_ptr();
 +
@@ -3091,9 +3228,7 @@ index 0000000..cd4952c
 +
 +void __ipipe_restore_root(unsigned long x)
 +{
-+#ifdef CONFIG_IPIPE_DEBUG_INTERNAL
-+      BUG_ON(!ipipe_root_domain_p);
-+#endif
++      ipipe_check_context(ipipe_root_domain);
 +
 +      if (x)
 +              __ipipe_stall_root();
@@ -3320,7 +3455,6 @@ index 0000000..cd4952c
 +
 +      l0b = irq / (BITS_PER_LONG * BITS_PER_LONG);
 +      l1b = irq / BITS_PER_LONG;
-+      prefetchw(p);
 +
 +      if (likely(!test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))) {
 +              __set_bit(irq, p->irqpend_lomap);
@@ -3435,8 +3569,6 @@ index 0000000..cd4952c
 +      int l0b = irq / BITS_PER_LONG;
 +
 +      IPIPE_WARN_ONCE(!irqs_disabled_hw());
-+
-+      prefetchw(p);
 +      
 +      if (likely(!test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))) {
 +              __set_bit(irq, p->irqpend_lomap);
@@ -3701,7 +3833,7 @@ index 0000000..cd4952c
 +                  ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK |
 +                    IPIPE_EXCLUSIVE_MASK | IPIPE_WIRED_MASK);
 +
-+      if (acknowledge == NULL && !ipipe_virtual_irq_p(irq))
++      if (acknowledge == NULL)
 +              /*
 +               * Acknowledge handler unspecified for a hw interrupt:
 +               * use the Linux-defined handler instead.
@@ -3895,8 +4027,6 @@ index 0000000..cd4952c
 +{
 +      struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(head);
 +
-+      prefetchw(p);
-+
 +      if (test_bit(IPIPE_STALL_FLAG, &p->status)) {
 +              __ipipe_set_irq_pending(head, irq);
 +              return;
@@ -3910,8 +4040,6 @@ index 0000000..cd4952c
 +      struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(head);
 +      struct ipipe_domain *old;
 +
-+      prefetchw(p);
-+
 +      old = __ipipe_current_domain;
 +      __ipipe_current_domain = head; /* Switch to the head domain. */
 +
@@ -4357,12 +4485,172 @@ index 0000000..cd4952c
 +
 +{
 +#ifdef CONFIG_SMP
++      if (!ipipe_ipi_p(ipi))
++              return -EINVAL;
 +      return __ipipe_send_ipi(ipi,cpumask);
 +#else /* !CONFIG_SMP */
 +      return -EINVAL;
 +#endif /* CONFIG_SMP */
 +}
 +
++#ifdef CONFIG_SMP
++
++/* Always called with hw interrupts off. */
++void __ipipe_do_critical_sync(unsigned irq, void *cookie)
++{
++      int cpu = ipipe_processor_id();
++
++      cpu_set(cpu, __ipipe_cpu_sync_map);
++
++      /* Now we are in sync with the lock requestor running on another
++         CPU. Enter a spinning wait until he releases the global
++         lock. */
++      spin_lock(&__ipipe_cpu_barrier);
++
++      /* Got it. Now get out. */
++
++      if (__ipipe_cpu_sync)
++              /* Call the sync routine if any. */
++              __ipipe_cpu_sync();
++
++      cpu_set(cpu, __ipipe_cpu_pass_map);
++
++      spin_unlock(&__ipipe_cpu_barrier);
++
++      cpu_clear(cpu, __ipipe_cpu_sync_map);
++}
++#endif        /* CONFIG_SMP */
++
++/*
++ * ipipe_critical_enter() -- Grab the superlock excluding all CPUs but
++ * the current one from a critical section. This lock is used when we
++ * must enforce a global critical section for a single CPU in a
++ * possibly SMP system whichever context the CPUs are running.
++ */
++unsigned long ipipe_critical_enter(void (*syncfn)(void))
++{
++      unsigned long flags;
++
++      local_irq_save_hw(flags);
++
++#ifdef CONFIG_SMP
++      if (num_online_cpus() > 1) {
++              int cpu = ipipe_processor_id();
++              cpumask_t allbutself;
++              unsigned long loops;
++
++              if (!cpu_test_and_set(cpu, __ipipe_cpu_lock_map)) {
++                      while (test_and_set_bit(0, &__ipipe_critical_lock)) {
++                              int n = 0;
++
++                              local_irq_enable_hw();
++
++                              do {
++                                      cpu_relax();
++                              } while (++n < cpu);
++
++                              local_irq_disable_hw();
++                      }
++
++restart:
++                      spin_lock(&__ipipe_cpu_barrier);
++
++                      __ipipe_cpu_sync = syncfn;
++
++                      cpus_clear(__ipipe_cpu_pass_map);
++                      cpu_set(cpu, __ipipe_cpu_pass_map);
++
++                      /*
++                       * Send the sync IPI to all processors but the current
++                       * one.
++                       */
++                      cpus_andnot(allbutself, cpu_online_map,
++                                  __ipipe_cpu_pass_map);
++                      __ipipe_send_ipi(IPIPE_CRITICAL_IPI, allbutself);
++
++                      loops = IPIPE_CRITICAL_TIMEOUT;
++
++                      while (!cpus_equal(__ipipe_cpu_sync_map, allbutself)) {
++                              cpu_relax();
++
++                              if (--loops == 0) {
++                                      /*
++                                       * We ran into a deadlock due to a
++                                       * contended rwlock. Cancel this round
++                                       * and retry.
++                                       */
++                                      __ipipe_cpu_sync = NULL;
++
++                                      spin_unlock(&__ipipe_cpu_barrier);
++
++                                      /*
++                                       * Ensure all CPUs consumed the IPI to
++                                       * avoid running __ipipe_cpu_sync
++                                       * prematurely. This usually resolves
++                                       * the deadlock reason too.
++                                       */
++                                      while (!cpus_equal(cpu_online_map,
++                                                         
__ipipe_cpu_pass_map))
++                                              cpu_relax();
++
++                                      goto restart;
++                              }
++                      }
++              }
++
++              atomic_inc(&__ipipe_critical_count);
++      }
++#endif        /* CONFIG_SMP */
++
++      return flags;
++}
++
++/* ipipe_critical_exit() -- Release the superlock. */
++
++void ipipe_critical_exit(unsigned long flags)
++{
++#ifdef CONFIG_SMP
++      if (num_online_cpus() > 1 &&
++          atomic_dec_and_test(&__ipipe_critical_count)) {
++              spin_unlock(&__ipipe_cpu_barrier);
++
++              while (!cpus_empty(__ipipe_cpu_sync_map))
++                      cpu_relax();
++
++              cpu_clear(ipipe_processor_id(), __ipipe_cpu_lock_map);
++              clear_bit(0, &__ipipe_critical_lock);
++              smp_mb__after_clear_bit();
++      }
++#endif        /* CONFIG_SMP */
++
++      local_irq_restore_hw(flags);
++}
++
++#ifdef CONFIG_HAVE_IPIPE_HOSTRT
++/*
++ * NOTE: The architecture specific code must only call this function
++ * when a clocksource suitable for CLOCK_HOST_REALTIME is enabled.
++ */
++void ipipe_update_hostrt(struct timespec *wall_time, struct clocksource 
*clock)
++{
++      struct ipipe_hostrt_data hostrt_data;
++
++      hostrt_data.live = 1;
++      hostrt_data.cycle_last = clock->cycle_last;
++      hostrt_data.mask = clock->mask;
++      hostrt_data.mult = clock->mult;
++      hostrt_data.shift = clock->shift;
++      hostrt_data.wall_time_sec = wall_time->tv_sec;
++      hostrt_data.wall_time_nsec = wall_time->tv_nsec;
++      hostrt_data.wall_to_monotonic = wall_to_monotonic;
++
++      /* Note: The event receiver is responsible for providing
++         proper locking */
++      if (__ipipe_event_monitored_p(IPIPE_EVENT_HOSTRT))
++              __ipipe_dispatch_event(IPIPE_EVENT_HOSTRT, &hostrt_data);
++}
++#endif /* CONFIG_HAVE_IPIPE_HOSTRT */
++
 +int ipipe_alloc_ptdkey (void)
 +{
 +      unsigned long flags;
@@ -4684,6 +4972,15 @@ index 0000000..cd4952c
 +
 +#endif /* CONFIG_IPIPE_DEBUG_INTERNAL && CONFIG_SMP */
 +
++
++void ipipe_prepare_panic(void)
++{
++      ipipe_set_printk_sync(ipipe_current_domain);
++      ipipe_context_check_off();
++}
++
++EXPORT_SYMBOL_GPL(ipipe_prepare_panic);
++
 +EXPORT_SYMBOL(ipipe_virtualize_irq);
 +EXPORT_SYMBOL(ipipe_control_irq);
 +EXPORT_SYMBOL(ipipe_suspend_domain);
@@ -4736,10 +5033,10 @@ index 0000000..cd4952c
 +EXPORT_SYMBOL(ipipe_get_sysinfo);
 diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c
 new file mode 100644
-index 0000000..001a83e
+index 0000000..f013ef4
 --- /dev/null
 +++ b/kernel/ipipe/tracer.c
-@@ -0,0 +1,1441 @@
+@@ -0,0 +1,1442 @@
 +/* -*- linux-c -*-
 + * kernel/ipipe/tracer.c
 + *
@@ -6146,6 +6443,7 @@ index 0000000..001a83e
 +#ifdef CONFIG_IPIPE_TRACE_ENABLE
 +      ipipe_trace_enable = 1;
 +#ifdef CONFIG_IPIPE_TRACE_MCOUNT
++      ftrace_enabled = 1;
 +      register_ftrace_function(&ipipe_trace_ops);
 +#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
 +#endif /* CONFIG_IPIPE_TRACE_ENABLE */
@@ -6635,7 +6933,7 @@ index 444b770..60e2a08 100644
  /* cpu currently holding logbuf_lock */
  static volatile unsigned int printk_cpu = UINT_MAX;
 diff --git a/kernel/sched.c b/kernel/sched.c
-index 63b4a14..7812a8c 100644
+index 4fa520b..c5cabba 100644
 --- a/kernel/sched.c
 +++ b/kernel/sched.c
 @@ -2283,7 +2283,8 @@ static int try_to_wake_up(struct task_struct *p, 
unsigned int state,
@@ -6762,7 +7060,7 @@ index 63b4a14..7812a8c 100644
  }
  EXPORT_SYMBOL(schedule);
  
-@@ -3729,7 +3754,8 @@ asmlinkage void __sched preempt_schedule(void)
+@@ -3737,7 +3762,8 @@ asmlinkage void __sched preempt_schedule(void)
  
        do {
                add_preempt_count(PREEMPT_ACTIVE);
@@ -6772,7 +7070,7 @@ index 63b4a14..7812a8c 100644
                sub_preempt_count(PREEMPT_ACTIVE);
  
                /*
-@@ -4514,6 +4540,7 @@ recheck:
+@@ -4522,6 +4548,7 @@ recheck:
        oldprio = p->prio;
        prev_class = p->sched_class;
        __setscheduler(rq, p, policy, param->sched_priority);
@@ -6780,7 +7078,7 @@ index 63b4a14..7812a8c 100644
  
        if (running)
                p->sched_class->set_curr_task(rq);
-@@ -5170,6 +5197,7 @@ void __cpuinit init_idle(struct task_struct *idle, int 
cpu)
+@@ -5178,6 +5205,7 @@ void __cpuinit init_idle(struct task_struct *idle, int 
cpu)
  #else
        task_thread_info(idle)->preempt_count = 0;
  #endif
@@ -6788,7 +7086,7 @@ index 63b4a14..7812a8c 100644
        /*
         * The idle tasks have their own, simple scheduling class:
         */
-@@ -8969,3 +8997,65 @@ void synchronize_sched_expedited(void)
+@@ -8977,3 +9005,65 @@ void synchronize_sched_expedited(void)
  EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
  
  #endif /* #else #ifndef CONFIG_SMP */
@@ -6958,7 +7256,7 @@ index ee305c8..f595adb 100644
   * This function runs timers and the timer-tq in bottom half context.
   */
 diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
-index 6d2cb14..016a0a2 100644
+index 6b316b3..ad342e8 100644
 --- a/kernel/trace/ftrace.c
 +++ b/kernel/trace/ftrace.c
 @@ -29,6 +29,7 @@
@@ -6969,7 +7267,7 @@ index 6d2cb14..016a0a2 100644
  
  #include <trace/events/sched.h>
  
-@@ -1150,6 +1151,9 @@ static int __ftrace_modify_code(void *data)
+@@ -1157,6 +1158,9 @@ static int __ftrace_modify_code(void *data)
  
  static void ftrace_run_update_code(int command)
  {
@@ -6979,7 +7277,7 @@ index 6d2cb14..016a0a2 100644
        int ret;
  
        ret = ftrace_arch_code_modify_prepare();
-@@ -1157,7 +1161,13 @@ static void ftrace_run_update_code(int command)
+@@ -1164,7 +1168,13 @@ static void ftrace_run_update_code(int command)
        if (ret)
                return;
  
@@ -6993,7 +7291,7 @@ index 6d2cb14..016a0a2 100644
  
        ret = ftrace_arch_code_modify_post_process();
        FTRACE_WARN_ON(ret);
-@@ -2675,9 +2685,9 @@ static int ftrace_process_locs(struct module *mod,
+@@ -2684,9 +2694,9 @@ static int ftrace_process_locs(struct module *mod,
        }
  
        /* disable interrupts to prevent kstop machine */
@@ -7005,7 +7303,7 @@ index 6d2cb14..016a0a2 100644
        mutex_unlock(&ftrace_lock);
  
        return 0;
-@@ -2756,9 +2766,9 @@ void __init ftrace_init(void)
+@@ -2765,9 +2775,9 @@ void __init ftrace_init(void)
        /* Keep the ftrace pointer to the stub */
        addr = (unsigned long)ftrace_stub;
  
@@ -7085,7 +7383,7 @@ index 4689cb0..3d12764 100644
  
        /*
 diff --git a/mm/memory.c b/mm/memory.c
-index aaaedbd..4fa38b5 100644
+index 7550758..e96effb 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
 @@ -642,6 +642,32 @@ out:
@@ -7244,7 +7542,7 @@ index aaaedbd..4fa38b5 100644
  /*
   * This routine handles present pages, when users try to write
   * to a shared page. It is done by copying the page to a new address
-@@ -3545,3 +3591,111 @@ void might_fault(void)
+@@ -3589,3 +3635,111 @@ void might_fault(void)
  }
  EXPORT_SYMBOL(might_fault);
  #endif


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to