Module: xenomai-2.6 Branch: master Commit: 5630d7e1df797ca801be7c722b694ff7bb49416b URL: http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=5630d7e1df797ca801be7c722b694ff7bb49416b
Author: Stefan Roese <s...@denx.de> Date: Tue Jan 21 16:36:06 2014 +0100 hal/arm: Add Zynq v3.5.7 patches Xilinx Zynq is already supported in the mainline Xenomai git repository. This patch adds support for the v3.5.7 Linux Kernel with the latest arm-6 i-pipe patch additionally to the already present v3.8 support. Signed-off-by: Stefan Roese <s...@denx.de> --- ksrc/arch/arm/patches/README | 11 +- .../patches/zynq/ipipe-core-3.5.7-zynq-post.patch | 271 ++++++++++++++++++++ .../patches/zynq/ipipe-core-3.5.7-zynq-pre.patch | 28 ++ 3 files changed, 309 insertions(+), 1 deletion(-) diff --git a/ksrc/arch/arm/patches/README b/ksrc/arch/arm/patches/README index de47f32..ed406d9 100644 --- a/ksrc/arch/arm/patches/README +++ b/ksrc/arch/arm/patches/README @@ -76,7 +76,7 @@ From [5]: 2- apply raspberry/ipipe-core-3.8.13-raspberry-post-2.patch 3- you can resume to generic installation instructions. ----- Zynq +---- Zynq (v3.8) 1- Checkout the xilinx-v14.5 tag (6a0bedad60e2bca8d9b50bf81b9895e29e31a6d7) from [6] @@ -85,6 +85,15 @@ From [5]: 4- apply ipipe-core-3.8-zynq-post.patch 5- you can resume to generic installation instructions. +---- Zynq (v3.5.7) + +1- Checkout the "xilinx-zynq-v3.5.7" branch from the DENX Linux git + repository [2] +2- apply ipipe-core-3.5.7-zynq-pre.patch +3- apply ipipe-core-3.5.7-arm-6.patch +4- apply ipipe-core-3.5.7-zynq-post.patch +5- you can resume to generic installation instructions. + -- External links [1] http://opensource.freescale.com/pub/scm/imx/linux-2.6-imx.git diff --git a/ksrc/arch/arm/patches/zynq/ipipe-core-3.5.7-zynq-post.patch b/ksrc/arch/arm/patches/zynq/ipipe-core-3.5.7-zynq-post.patch new file mode 100644 index 0000000..97a9fdf --- /dev/null +++ b/ksrc/arch/arm/patches/zynq/ipipe-core-3.5.7-zynq-post.patch @@ -0,0 +1,271 @@ +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index eebf8bb..f2b7782 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -992,6 +992,7 @@ config ARCH_ZYNQ + select COMMON_CLK + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP ++ select IPIPE_ARM_KUSER_TSC if IPIPE + help + Support for Xilinx Zynq ARM Cortex A9 Platform + endchoice +diff --git a/arch/arm/kernel/ipipe.c b/arch/arm/kernel/ipipe.c +index ff4ad1a..12bb964 100644 +--- a/arch/arm/kernel/ipipe.c ++++ b/arch/arm/kernel/ipipe.c +@@ -574,7 +574,6 @@ EXPORT_SYMBOL_GPL(__ipipe_serial_debug); + + EXPORT_SYMBOL_GPL(do_munmap); + EXPORT_SYMBOL_GPL(show_stack); +-EXPORT_SYMBOL_GPL(init_mm); + EXPORT_SYMBOL_GPL(cpu_architecture); + #ifndef MULTI_CPU + EXPORT_SYMBOL_GPL(cpu_do_switch_mm); +diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c +index f77ef11..1a19807 100644 +--- a/arch/arm/kernel/smp.c ++++ b/arch/arm/kernel/smp.c +@@ -239,6 +239,9 @@ asmlinkage void __cpuinit secondary_start_kernel(void) + { + struct mm_struct *mm = &init_mm; + unsigned int cpu; ++#ifdef CONFIG_ARCH_ZYNQ ++ static bool booted; ++#endif + + cpu_switch_mm(mm->pgd, mm, 1); + enter_lazy_tlb(mm, current); +@@ -266,7 +269,13 @@ asmlinkage void __cpuinit secondary_start_kernel(void) + + notify_cpu_starting(cpu); + ++#ifdef CONFIG_ARCH_ZYNQ ++ if (!booted) ++ calibrate_delay(); ++ booted = true; ++#else + calibrate_delay(); ++#endif + + smp_store_cpu_info(cpu); + +diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c +index 38faf0f..6f90595 100644 +--- a/arch/arm/mach-zynq/timer.c ++++ b/arch/arm/mach-zynq/timer.c +@@ -28,6 +28,8 @@ + #include <linux/of_irq.h> + #include <linux/clk.h> + #include <linux/err.h> ++#include <linux/ipipe.h> ++#include <linux/ipipe_tickdev.h> + + #include <asm/mach/time.h> + #include <asm/smp_twd.h> +@@ -73,9 +75,15 @@ + /* Setup the timers to use pre-scaling, using a fixed value for now that will work + * across most input frequency, but it may need to be more dynamic + */ +-#define PRESCALE_EXPONENT 11 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */ +-#define PRESCALE 2048 /* The exponent must match this */ +-#define CLK_CNTRL_PRESCALE (((PRESCALE_EXPONENT - 1) << 1) | 0x1) ++#define PRESCALE_EXPONENT 8 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */ ++#define PRESCALE (2 << (PRESCALE_EXPONENT - 1)) ++#define CLK_CNTRL_PRESCALE (((PRESCALE_EXPONENT - 1) << 1) | 0x1) ++ ++#define PRESCALE_EXPONENT_EV 5 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */ ++#define PRESCALE_EV (2 << (PRESCALE_EXPONENT_EV - 1)) ++#define CLK_CNTRL_PRESCALE_EV (((PRESCALE_EXPONENT_EV - 1) << 1) | 0x1) ++ ++unsigned max_delta_ticks; + + /** + * struct xttcpss_timer - This definition defines local timer structure +@@ -117,6 +125,13 @@ static void xttcpss_set_interval(struct xttcpss_timer *timer, + __raw_writel(ctrl_reg, timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET); + } + ++static void xttcpss_timer_ack(void) ++{ ++ struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT]; ++ ++ __raw_readl(timer->base_addr + XTTCPSS_ISR_OFFSET); ++} ++ + /** + * xttcpss_clock_event_interrupt - Clock event timer interrupt handler + * +@@ -128,11 +143,13 @@ static void xttcpss_set_interval(struct xttcpss_timer *timer, + static irqreturn_t xttcpss_clock_event_interrupt(int irq, void *dev_id) + { + struct clock_event_device *evt = &xttcpss_clockevent; +- struct xttcpss_timer *timer = dev_id; + + /* Acknowledge the interrupt and call event handler */ +- __raw_writel(__raw_readl(timer->base_addr + XTTCPSS_ISR_OFFSET), +- timer->base_addr + XTTCPSS_ISR_OFFSET); ++ if (!clockevent_ipipe_stolen(evt)) ++ xttcpss_timer_ack(); ++ ++ if (num_possible_cpus() == 1) ++ __ipipe_tsc_update(); + + evt->event_handler(evt); + +@@ -145,6 +162,17 @@ static struct irqaction event_timer_irq = { + .handler = xttcpss_clock_event_interrupt, + }; + ++#ifdef CONFIG_IPIPE ++static struct __ipipe_tscinfo tsc_info = { ++ .type = IPIPE_TSC_TYPE_FREERUNNING, ++ .u = { ++ { ++ .mask = 0x0000ffff, ++ }, ++ }, ++}; ++#endif /* CONFIG_IPIPE */ ++ + /** + * xttcpss_timer_hardware_init - Initialize the timer hardware + * +@@ -171,7 +199,7 @@ static void __init xttcpss_timer_hardware_init(void) + */ + __raw_writel(0x23, timers[XTTCPSS_CLOCKEVENT].base_addr + + XTTCPSS_CNT_CNTRL_OFFSET); +- __raw_writel(CLK_CNTRL_PRESCALE, ++ __raw_writel(CLK_CNTRL_PRESCALE_EV, + timers[XTTCPSS_CLOCKEVENT].base_addr + + XTTCPSS_CLK_CNTRL_OFFSET); + __raw_writel(0x1, timers[XTTCPSS_CLOCKEVENT].base_addr + +@@ -216,6 +244,13 @@ static int xttcpss_set_next_event(unsigned long cycles, + { + struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT]; + ++#ifdef CONFIG_IPIPE ++ if (cycles > max_delta_ticks) ++ cycles = max_delta_ticks; ++#endif ++ ++ __ipipe_tsc_update(); ++ + xttcpss_set_interval(timer, cycles); + return 0; + } +@@ -255,6 +290,12 @@ static void xttcpss_set_mode(enum clock_event_mode mode, + } + } + ++#ifdef CONFIG_IPIPE ++static struct ipipe_timer xttcpss_itimer = { ++ .ack = xttcpss_timer_ack, ++}; ++#endif /* CONFIG_IPIPE */ ++ + /* + * Instantiate and initialize the clock event structure + */ +@@ -264,6 +305,9 @@ static struct clock_event_device xttcpss_clockevent = { + .set_next_event = xttcpss_set_next_event, + .set_mode = xttcpss_set_mode, + .rating = 200, ++#ifdef CONFIG_IPIPE ++ .ipipe_timer = &xttcpss_itimer, ++#endif /* CONFIG_IPIPE */ + }; + + static int xttcpss_timer_rate_change_cb(struct notifier_block *nb, +@@ -279,7 +323,7 @@ static int xttcpss_timer_rate_change_cb(struct notifier_block *nb, + timers[XTTCPSS_CLOCKSOURCE].frequency = + ndata->new_rate / PRESCALE; + timers[XTTCPSS_CLOCKEVENT].frequency = +- ndata->new_rate / PRESCALE; ++ ndata->new_rate / PRESCALE_EV; + + /* Do whatever is necessare to maintain a proper time base */ + /* +@@ -400,11 +444,11 @@ static void __init xttcpss_timer_init(void) + } + if (prop2) { + timers[XTTCPSS_CLOCKEVENT].frequency = +- be32_to_cpup(prop2) / PRESCALE; ++ be32_to_cpup(prop2) / PRESCALE_EV; + } else { + pr_err("Error, no clock-frequency specified for timer\n"); + timers[XTTCPSS_CLOCKEVENT].frequency = +- PERIPHERAL_CLOCK_RATE / PRESCALE; ++ PERIPHERAL_CLOCK_RATE / PRESCALE_EV; + } + } else { + clk_prepare_enable(clk); +@@ -419,7 +463,7 @@ static void __init xttcpss_timer_init(void) + timers[XTTCPSS_CLOCKSOURCE].frequency = + clk_get_rate(clk) / PRESCALE; + timers[XTTCPSS_CLOCKEVENT].frequency = +- clk_get_rate(clk) / PRESCALE; ++ clk_get_rate(clk) / PRESCALE_EV; + if (clk_notifier_register(clk, + &timers[XTTCPSS_CLOCKSOURCE].clk_rate_change_nb)) + pr_warn("Unable to register clock notifier.\n"); +@@ -429,6 +473,29 @@ static void __init xttcpss_timer_init(void) + clocksource_register_hz(&clocksource_xttcpss, + timers[XTTCPSS_CLOCKSOURCE].frequency); + ++#ifdef CONFIG_IPIPE ++ if (num_possible_cpus() == 1) { ++ struct resource res; ++ ++ tsc_info.freq = timers[XTTCPSS_CLOCKSOURCE].frequency; ++ tsc_info.counter_vaddr = ++ (unsigned long)timers[XTTCPSS_CLOCKSOURCE].base_addr + ++ XTTCPSS_COUNT_VAL_OFFSET; ++ of_address_to_resource(timer, 0, &res); ++ tsc_info.u.counter_paddr = res.start + XTTCPSS_COUNT_VAL_OFFSET; ++ ++ __ipipe_tsc_register(&tsc_info); ++ } ++ ++ xttcpss_itimer.irq = irq; ++ xttcpss_itimer.freq = timers[XTTCPSS_CLOCKEVENT].frequency; ++ max_delta_ticks = 0xffff - xttcpss_itimer.freq / 1000; ++ xttcpss_itimer.min_delay_ticks = 1; ++ printk(KERN_INFO "I-pipe, %lu.%03lu MHz timer\n", ++ xttcpss_itimer.freq / 1000000, ++ (xttcpss_itimer.freq % 1000000) / 1000); ++#endif /* CONFIG_IPIPE */ ++ + /* Indicate that clock event is on 1st CPU as SMP boot needs it */ + xttcpss_clockevent.cpumask = cpumask_of(0); + clockevents_config_and_register(&xttcpss_clockevent, +diff --git a/drivers/gpio/gpio-xilinxps.c b/drivers/gpio/gpio-xilinxps.c +index cbccfa1..b0c9162 100644 +--- a/drivers/gpio/gpio-xilinxps.c ++++ b/drivers/gpio/gpio-xilinxps.c +@@ -27,6 +27,7 @@ + #include <linux/pm_wakeup.h> + #include <linux/err.h> + #include <linux/clk.h> ++#include <linux/ipipe.h> + #include <linux/irqdomain.h> + #include <asm/mach/irq.h> + +@@ -88,7 +89,7 @@ struct xgpiops { + void __iomem *base_addr; + unsigned int irq; + struct clk *clk; +- spinlock_t gpio_lock; ++ ipipe_spinlock_t gpio_lock; + }; + + static struct irq_domain *irq_domain; +@@ -428,7 +429,7 @@ 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.5.7-zynq-pre.patch b/ksrc/arch/arm/patches/zynq/ipipe-core-3.5.7-zynq-pre.patch new file mode 100644 index 0000000..acde6c7 --- /dev/null +++ b/ksrc/arch/arm/patches/zynq/ipipe-core-3.5.7-zynq-pre.patch @@ -0,0 +1,28 @@ +diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c +index 4d7130c1..ea73045 100644 +--- a/arch/arm/kernel/smp.c ++++ b/arch/arm/kernel/smp.c +@@ -223,9 +223,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) + { + struct mm_struct *mm = &init_mm; + unsigned int cpu = smp_processor_id(); +-#ifdef CONFIG_ARCH_ZYNQ +- static bool booted; +-#endif + + /* + * All kernel threads share the same mm context; grab a +@@ -251,13 +248,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) + + notify_cpu_starting(cpu); + +-#ifdef CONFIG_ARCH_ZYNQ +- if (!booted) +- calibrate_delay(); +- booted = true; +-#else + calibrate_delay(); +-#endif + + smp_store_cpu_info(cpu); + _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git