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

Author: Matthew Fornero <mforn...@aanddtech.com>
Date:   Wed Apr 24 17:43:52 2013 -0400

hal/arm: Add Zynq patches

---

 ksrc/arch/arm/patches/README                       |    9 +
 .../patches/zynq/ipipe-core-3.8-zynq-post.patch    |  113 +++++++++
 .../arm/patches/zynq/ipipe-core-3.8-zynq-pre.patch |  249 ++++++++++++++++++++
 3 files changed, 371 insertions(+), 0 deletions(-)

diff --git a/ksrc/arch/arm/patches/README b/ksrc/arch/arm/patches/README
index 11f78ee..b9b0b01 100644
--- a/ksrc/arch/arm/patches/README
+++ b/ksrc/arch/arm/patches/README
@@ -74,6 +74,14 @@ From [5]:
 2- apply raspberry/ipipe-core-3.5.7-raspberry-post.patch
 3- you can resume to generic installation instructions.
 
+---- Zynq
+
+1- Checkout the xilinx-v14.5 tag (6a0bedad60e2bca8d9b50bf81b9895e29e31a6d7)
+   from [6]
+2- apply ipipe-core-3.8-zynq-pre.patch
+3- apply ipipe-core-3.8-arm-3.patch
+4- apply ipipe-core-3.8-zynq-post.patch
+5- you can resume to generic installation instructions.
 
 -- External links
 
@@ -82,3 +90,4 @@ From [5]:
 [3] git://github.com/koenkooi/linux
 [4] http://www.xenomai.org/pipermail/xenomai/2013-February/027584.html
 [5] http://www.xenomai.org/pipermail/xenomai/2013-February/027752.html
+[6] git://github.com/Xilinx/linux-xlnx.git
diff --git a/ksrc/arch/arm/patches/zynq/ipipe-core-3.8-zynq-post.patch 
b/ksrc/arch/arm/patches/zynq/ipipe-core-3.8-zynq-post.patch
new file mode 100644
index 0000000..66bb3c8
--- /dev/null
+++ b/ksrc/arch/arm/patches/zynq/ipipe-core-3.8-zynq-post.patch
@@ -0,0 +1,113 @@
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 6d6c9f0..0fa6c66 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -22,6 +22,7 @@
+  * As such, the enable set/clear, pending set/clear and active bit
+  * registers are banked per-cpu for these sources.
+  */
++#include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/err.h>
+@@ -282,10 +283,15 @@ static int gic_set_affinity(struct irq_data *d, const 
struct cpumask *mask_val,
+ {
+       void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & 
~3);
+       unsigned int shift = (gic_irq(d) % 4) * 8;
+-      unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
++      unsigned int cpu;
+       unsigned long flags;
+       u32 val, mask, bit;
+ 
++      if (force)
++              cpu = cpumask_any_and(mask_val, cpu_possible_mask);
++      else
++              cpu = cpumask_any_and(mask_val, cpu_online_mask);
++
+       if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
+               return -EINVAL;
+ 
+@@ -299,6 +305,17 @@ static int gic_set_affinity(struct irq_data *d, const 
struct cpumask *mask_val,
+ 
+       return IRQ_SET_MASK_OK;
+ }
++
++void gic_set_cpu(unsigned int cpu, unsigned int irq)
++{
++      struct irq_data *d = irq_get_irq_data(irq);
++      struct cpumask mask;
++
++      cpumask_clear(&mask);
++      cpumask_set_cpu(cpu, &mask);
++      gic_set_affinity(d, &mask, true);
++}
++EXPORT_SYMBOL(gic_set_cpu);
+ #endif
+ 
+ #ifdef CONFIG_PM
+@@ -875,6 +892,7 @@ void gic_raise_softirq(const struct cpumask *mask, 
unsigned int irq)
+       /* this always happens on GIC0 */
+       writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + 
GIC_DIST_SOFTINT);
+ }
++EXPORT_SYMBOL(gic_raise_softirq);
+ #endif
+ 
+ #ifdef CONFIG_OF
+diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
+index 96e1668..0ebcf90 100644
+--- a/arch/arm/mach-zynq/Kconfig
++++ b/arch/arm/mach-zynq/Kconfig
+@@ -15,6 +15,7 @@ config ARCH_ZYNQ
+       select COMMON_CLK
+       select ARCH_HAS_CPUFREQ
+       select ARCH_HAS_OPP
++      select IPIPE_ARM_KUSER_TSC if IPIPE
+       select MIGHT_HAVE_PCI
+       help
+         Support for Xilinx Zynq ARM Cortex A9 Platform
+diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c
+index 9bef11c..8aab5d1 100644
+--- a/arch/arm/mach-zynq/timer.c
++++ b/arch/arm/mach-zynq/timer.c
+@@ -419,7 +419,10 @@ static void __init xttcps_timer_init(struct device_node 
*timer)
+ 
+       zynq_ttc_setup_clocksource(clk, timer_baseaddr);
+       zynq_ttc_setup_clockevent(clk, timer_baseaddr + 4, irq);
+-
++#ifdef CONFIG_IPIPE
++      if (num_possible_cpus() == 1)
++              pr_err("I-pipe: not supported on Zynq without SMP\n");
++#endif
+ #ifdef CONFIG_HAVE_ARM_TWD
+       twd_local_timer_of_register();
+ #endif
+diff --git a/drivers/gpio/gpio-xilinxps.c b/drivers/gpio/gpio-xilinxps.c
+index 8c51700..b2f5871 100644
+--- a/drivers/gpio/gpio-xilinxps.c
++++ b/drivers/gpio/gpio-xilinxps.c
+@@ -21,6 +21,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/irq.h>
++#include <linux/ipipe.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+@@ -90,7 +91,7 @@ struct xgpiops {
+       unsigned int irq;
+       unsigned int irq_base;
+       struct clk *clk;
+-      spinlock_t gpio_lock;
++      ipipe_spinlock_t gpio_lock;
+ };
+ 
+ /**
+@@ -423,7 +424,7 @@ static void xgpiops_irqhandler(unsigned int irq, struct 
irq_desc *desc)
+                       chip->irq_ack(&gpio_irq_desc->irq_data);
+ 
+                       /* call the pin specific handler */
+-                      generic_handle_irq(gpio_irq);
++                      ipipe_handle_demuxed_irq(gpio_irq);
+               }
+               /* shift to first virtual irq of next bank */
+               gpio_irq = (int)irq_get_handler_data(irq) +
diff --git a/ksrc/arch/arm/patches/zynq/ipipe-core-3.8-zynq-pre.patch 
b/ksrc/arch/arm/patches/zynq/ipipe-core-3.8-zynq-pre.patch
new file mode 100644
index 0000000..612d051
--- /dev/null
+++ b/ksrc/arch/arm/patches/zynq/ipipe-core-3.8-zynq-pre.patch
@@ -0,0 +1,249 @@
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index d4a9a45..87dfa90 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -22,7 +22,6 @@
+  * As such, the enable set/clear, pending set/clear and active bit
+  * registers are banked per-cpu for these sources.
+  */
+-#include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/err.h>
+@@ -244,14 +243,9 @@ static int gic_set_affinity(struct irq_data *d, const 
struct cpumask *mask_val,
+ {
+       void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & 
~3);
+       unsigned int shift = (gic_irq(d) % 4) * 8;
+-      unsigned int cpu;
++      unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+       u32 val, mask, bit;
+ 
+-      if (force)
+-              cpu = cpumask_any_and(mask_val, cpu_possible_mask);
+-      else
+-              cpu = cpumask_any_and(mask_val, cpu_online_mask);
+-
+       if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
+               return -EINVAL;
+ 
+@@ -265,17 +259,6 @@ static int gic_set_affinity(struct irq_data *d, const 
struct cpumask *mask_val,
+ 
+       return IRQ_SET_MASK_OK;
+ }
+-
+-void gic_set_cpu(unsigned int cpu, unsigned int irq)
+-{
+-      struct irq_data *d = irq_get_irq_data(irq);
+-      struct cpumask mask;
+-
+-      cpumask_clear(&mask);
+-      cpumask_set_cpu(cpu, &mask);
+-      gic_set_affinity(d, &mask, true);
+-}
+-EXPORT_SYMBOL(gic_set_cpu);
+ #endif
+ 
+ #ifdef CONFIG_PM
+@@ -813,7 +796,6 @@ void gic_raise_softirq(const struct cpumask *mask, 
unsigned int irq)
+       /* this always happens on GIC0 */
+       writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + 
GIC_DIST_SOFTINT);
+ }
+-EXPORT_SYMBOL(gic_raise_softirq);
+ #endif
+ 
+ #ifdef CONFIG_OF
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index e694e23..84f4cbf 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -434,24 +434,14 @@ void arch_send_call_function_single_ipi(int cpu)
+       smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+ }
+ 
+-struct ipi {
+-      const char *desc;
+-      void (*handler)(void);
+-};
+-
+-static void ipi_timer(void);
+-static void ipi_cpu_stop(void);
+-
+-static struct ipi ipi_types[NR_IPI] = {
+-#define S(x, s, f)    [x].desc = s, [x].handler = f
+-      S(IPI_WAKEUP, "CPU wakeup interrupts", NULL),
+-      S(IPI_TIMER, "Timer broadcast interrupts", ipi_timer),
+-      S(IPI_RESCHEDULE, "Rescheduling interrupts", scheduler_ipi),
+-      S(IPI_CALL_FUNC, "Function call interrupts",
+-                                      generic_smp_call_function_interrupt),
+-      S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts",
+-                              generic_smp_call_function_single_interrupt),
+-      S(IPI_CPU_STOP, "CPU stop interrupts", ipi_cpu_stop),
++static const char *ipi_types[NR_IPI] = {
++#define S(x,s)        [x] = s
++      S(IPI_WAKEUP, "CPU wakeup interrupts"),
++      S(IPI_TIMER, "Timer broadcast interrupts"),
++      S(IPI_RESCHEDULE, "Rescheduling interrupts"),
++      S(IPI_CALL_FUNC, "Function call interrupts"),
++      S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
++      S(IPI_CPU_STOP, "CPU stop interrupts"),
+ };
+ 
+ void show_ipi_list(struct seq_file *p, int prec)
+@@ -459,13 +449,13 @@ void show_ipi_list(struct seq_file *p, int prec)
+       unsigned int cpu, i;
+ 
+       for (i = 0; i < NR_IPI; i++) {
+-              if (ipi_types[i].handler) {
+-                      seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
+-                      for_each_present_cpu(cpu)
+-                              seq_printf(p, "%10u ",
+-                                      __get_irq_stat(cpu, ipi_irqs[i]));
+-                      seq_printf(p, " %s\n", ipi_types[i].desc);
+-              }
++              seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
++
++              for_each_online_cpu(cpu)
++                      seq_printf(p, "%10u ",
++                                 __get_irq_stat(cpu, ipi_irqs[i]));
++
++              seq_printf(p, " %s\n", ipi_types[i]);
+       }
+ }
+ 
+@@ -567,10 +557,8 @@ static DEFINE_RAW_SPINLOCK(stop_lock);
+ /*
+  * ipi_cpu_stop - handle IPI from smp_send_stop()
+  */
+-static void ipi_cpu_stop(void)
++static void ipi_cpu_stop(unsigned int cpu)
+ {
+-      unsigned int cpu = smp_processor_id();
+-
+       if (system_state == SYSTEM_BOOTING ||
+           system_state == SYSTEM_RUNNING) {
+               raw_spin_lock(&stop_lock);
+@@ -601,48 +589,48 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
+       unsigned int cpu = smp_processor_id();
+       struct pt_regs *old_regs = set_irq_regs(regs);
+ 
+-      if (ipi_types[ipinr].handler) {
++      if (ipinr < NR_IPI)
+               __inc_irq_stat(cpu, ipi_irqs[ipinr]);
++
++      switch (ipinr) {
++      case IPI_WAKEUP:
++              break;
++
++      case IPI_TIMER:
+               irq_enter();
+-              (*ipi_types[ipinr].handler)();
++              ipi_timer();
+               irq_exit();
+-      } else
+-              pr_debug("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
+-
+-      set_irq_regs(old_regs);
+-}
++              break;
+ 
+-/*
+- * set_ipi_handler:
+- * Interface provided for a kernel module to specify an IPI handler function.
+- */
+-int set_ipi_handler(int ipinr, void *handler, char *desc)
+-{
+-      unsigned int cpu = smp_processor_id();
++      case IPI_RESCHEDULE:
++              scheduler_ipi();
++              break;
+ 
+-      if (ipi_types[ipinr].handler) {
+-              pr_crit("CPU%u: IPI handler 0x%x already registered to %pf\n",
+-                                      cpu, ipinr, ipi_types[ipinr].handler);
+-              return -1;
+-      }
++      case IPI_CALL_FUNC:
++              irq_enter();
++              generic_smp_call_function_interrupt();
++              irq_exit();
++              break;
+ 
+-      ipi_types[ipinr].handler = handler;
+-      ipi_types[ipinr].desc = desc;
++      case IPI_CALL_FUNC_SINGLE:
++              irq_enter();
++              generic_smp_call_function_single_interrupt();
++              irq_exit();
++              break;
+ 
+-      return 0;
+-}
+-EXPORT_SYMBOL(set_ipi_handler);
++      case IPI_CPU_STOP:
++              irq_enter();
++              ipi_cpu_stop(cpu);
++              irq_exit();
++              break;
+ 
+-/*
+- * clear_ipi_handler:
+- * Interface provided for a kernel module to clear an IPI handler function.
+- */
+-void clear_ipi_handler(int ipinr)
+-{
+-      ipi_types[ipinr].handler = NULL;
+-      ipi_types[ipinr].desc = NULL;
++      default:
++              printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
++                     cpu, ipinr);
++              break;
++      }
++      set_irq_regs(old_regs);
+ }
+-EXPORT_SYMBOL(clear_ipi_handler);
+ 
+ void smp_send_reschedule(int cpu)
+ {
+diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
+index 9ce310a..e0ada05 100644
+--- a/arch/powerpc/kernel/fpu.S
++++ b/arch/powerpc/kernel/fpu.S
+@@ -58,21 +58,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX);                         
        \
+  * enable the FPU for the current task and return to the task.
+  */
+ _GLOBAL(load_up_fpu)
+-#if defined(CONFIG_XILINX_VIRTEX_5_FXT) && defined(CONFIG_PPC_FPU)
+-      li      r3,0
+-      lis     r5,excep_state@h
+-      ori     r5,r5,excep_state@l
+-      stw     r3,0(r5)
+-
+-      mfspr   r5,SPRN_CCR0
+-      /* set CCR0[9] to disable the load miss queue inside the ppc440 */
+-      oris    r5,r5, (1<<6)
+-      /* set CCR0[26] to ... */
+-      ori     r5,r5, (1<<5)
+-      mtspr   SPRN_CCR0,r5
+-      isync
+-#endif
+-
+       mfmsr   r5
+       ori     r5,r5,MSR_FP
+ #ifdef CONFIG_VSX
+@@ -140,16 +125,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
+  * Enables the FPU for use in the kernel on return.
+  */
+ _GLOBAL(giveup_fpu)
+-#if defined(CONFIG_XILINX_VIRTEX_5_FXT) && defined(CONFIG_PPC_FPU)
+-      mfspr   r5,SPRN_CCR0
+-      /* set CCR0[9] to disable the load miss queue inside the ppc440 */
+-      oris    r5,r5, (1<<6)
+-      /* set CCR0[26] to ... */
+-      ori     r5,r5, (1<<5)
+-      mtspr   SPRN_CCR0,r5
+-      isync
+-#endif
+-
+       mfmsr   r5
+       ori     r5,r5,MSR_FP
+ #ifdef CONFIG_VSX


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to