Module: xenomai-2.6 Branch: master Commit: 55b9e698bd427225863875c4d61975efb3954cf0 URL: http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=55b9e698bd427225863875c4d61975efb3954cf0
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Thu Jun 7 19:58:20 2012 +0200 hal/arm: update adeos patches --- ...atch => adeos-ipipe-2.6.38.8-arm-1.18-08.patch} | 371 ++--------- ....patch => adeos-ipipe-3.0.13-arm-1.18-09.patch} | 699 +++++++++++++++----- 2 files changed, 580 insertions(+), 490 deletions(-) diff --git a/ksrc/arch/arm/patches/adeos-ipipe-2.6.38.8-arm-1.18-06.patch b/ksrc/arch/arm/patches/adeos-ipipe-2.6.38.8-arm-1.18-08.patch similarity index 98% rename from ksrc/arch/arm/patches/adeos-ipipe-2.6.38.8-arm-1.18-06.patch rename to ksrc/arch/arm/patches/adeos-ipipe-2.6.38.8-arm-1.18-08.patch index f7898a2..f72eae2 100644 --- a/ksrc/arch/arm/patches/adeos-ipipe-2.6.38.8-arm-1.18-06.patch +++ b/ksrc/arch/arm/patches/adeos-ipipe-2.6.38.8-arm-1.18-08.patch @@ -1146,10 +1146,10 @@ index 21e75e3..2cae6e8 100644 void sp804_clockevents_init(void __iomem *, unsigned int); diff --git a/arch/arm/include/asm/ipipe.h b/arch/arm/include/asm/ipipe.h new file mode 100644 -index 0000000..82f9f50 +index 0000000..e098d44 --- /dev/null +++ b/arch/arm/include/asm/ipipe.h -@@ -0,0 +1,340 @@ +@@ -0,0 +1,341 @@ +/* -*- linux-c -*- + * arch/arm/include/asm/ipipe.h + * @@ -1182,10 +1182,10 @@ index 0000000..82f9f50 +#include <linux/ipipe_percpu.h> +#include <linux/ipipe_trace.h> + -+#define IPIPE_ARCH_STRING "1.18-06" ++#define IPIPE_ARCH_STRING "1.18-08" +#define IPIPE_MAJOR_NUMBER 1 +#define IPIPE_MINOR_NUMBER 18 -+#define IPIPE_PATCH_NUMBER 6 ++#define IPIPE_PATCH_NUMBER 8 + +#ifdef CONFIG_SMP +#define ipipe_processor_id() hard_smp_processor_id() @@ -1437,14 +1437,15 @@ index 0000000..82f9f50 + +void __ipipe_exit_irq(struct pt_regs *regs); + -+void __ipipe_handle_irq(int irq, struct pt_regs *regs); ++#define IPIPE_IRQF_NOACK 0x1 ++#define IPIPE_IRQF_NOSYNC 0x2 ++ ++void __ipipe_handle_irq(int irq, int flags); + +static inline void ipipe_handle_chained_irq(unsigned int irq) +{ -+ struct pt_regs regs; /* dummy */ -+ + ipipe_trace_irq_entry(irq); -+ __ipipe_handle_irq(irq, ®s); ++ __ipipe_handle_irq(irq, IPIPE_IRQF_NOSYNC); + ipipe_trace_irq_exit(irq); +} + @@ -2395,7 +2396,7 @@ index 734b581..6579eec 100644 #endif diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h -index fed9981..b49c8ac 100644 +index fed9981..f655b27 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -22,7 +22,61 @@ struct clock_event_device; @@ -2435,7 +2436,7 @@ index fed9981..b49c8ac 100644 +#define __ipipe_mach_relay_ipi(ipi, thiscpu) \ + ({ \ + (void)(thiscpu); \ -+ __ipipe_handle_irq(ipi, NULL); \ ++ __ipipe_handle_irq(ipi, IPIPE_IRQF_NOACK); \ + }) + +struct irq_desc; @@ -3078,10 +3079,10 @@ index ae94649..98af3e1 100644 * have in theory up to 7 arguments to a function - r0 to r6. diff --git a/arch/arm/kernel/ipipe.c b/arch/arm/kernel/ipipe.c new file mode 100644 -index 0000000..f2f618c +index 0000000..ff93fa9 --- /dev/null +++ b/arch/arm/kernel/ipipe.c -@@ -0,0 +1,677 @@ +@@ -0,0 +1,681 @@ +/* -*- linux-c -*- + * linux/arch/arm/kernel/ipipe.c + * @@ -3338,7 +3339,7 @@ index 0000000..f2f618c + return -EINVAL; +#endif + local_irq_save_hw(flags); -+ __ipipe_handle_irq(irq, NULL); ++ __ipipe_handle_irq(irq, IPIPE_IRQF_NOACK); + local_irq_restore_hw(flags); + + return 1; @@ -3546,7 +3547,7 @@ index 0000000..f2f618c + * interrupt protection log is maintained here for each domain. Hw + * interrupts are off on entry. + */ -+void __ipipe_handle_irq(int irq, struct pt_regs *regs) ++void __ipipe_handle_irq(int irq, int flags) +{ + struct ipipe_domain *this_domain, *next_domain; + struct list_head *head, *pos; @@ -3554,7 +3555,7 @@ index 0000000..f2f618c + int m_ack; + + /* Software-triggered IRQs do not need any ack. */ -+ m_ack = (regs == NULL); ++ m_ack = (flags & IPIPE_IRQF_NOACK) != 0; + +#ifdef CONFIG_IPIPE_DEBUG + if (unlikely(irq >= IPIPE_NR_IRQS) || @@ -3574,7 +3575,11 @@ index 0000000..f2f618c + desc = ipipe_virtual_irq_p(irq) ? NULL : irq_to_desc(irq); + next_domain->irqs[irq].acknowledge(irq, desc); + } -+ __ipipe_dispatch_wired(next_domain, irq); ++ if ((flags & IPIPE_IRQF_NOSYNC) == 0) ++ __ipipe_dispatch_wired(next_domain, irq); ++ else ++ __ipipe_set_irq_pending(next_domain, irq); ++ + return; + } + } @@ -3688,7 +3693,7 @@ index 0000000..f2f618c + ipipe_trace_begin(regs->ARM_ORIG_r0); +#endif + -+ __ipipe_handle_irq(irq, regs); ++ __ipipe_handle_irq(irq, 0); + +#ifdef CONFIG_IPIPE_TRACE_IRQSOFF + ipipe_trace_end(regs->ARM_ORIG_r0); @@ -4191,7 +4196,7 @@ index b13e70f..d7b21f9 100644 return 0; } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index 4539ebc..9ea207d 100644 +index 4539ebc..af02caa 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -53,6 +53,25 @@ enum ipi_msg_type { @@ -4283,7 +4288,7 @@ index 4539ebc..9ea207d 100644 + __ipipe_do_vnmi(IPIPE_SERVICE_VNMI, NULL); + else if ((1 << svc) & IPI_IPIPE_ALL) { + virq = svc - IPI_IPIPE_CRITICAL + IPIPE_FIRST_IPI; -+ __ipipe_handle_irq(virq, NULL); ++ __ipipe_handle_irq(virq, IPIPE_IRQF_NOACK); + } else + __ipipe_mach_relay_ipi(svc, cpu); + @@ -5280,7 +5285,7 @@ index 6a9d24e..fc8cd68 100644 void __init at91sam9rl_init_interrupts(unsigned int priority[NR_AIC_IRQS]) diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c -index af818a2..caf2226 100644 +index af818a2..698166b 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -19,12 +19,20 @@ @@ -5326,39 +5331,27 @@ index af818a2..caf2226 100644 .irq_mask = gpio_irq_mask, .irq_unmask = gpio_irq_unmask, .irq_set_type = gpio_irq_type, -@@ -394,6 +410,13 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +@@ -394,6 +410,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) /* temporarily mask (level sensitive) parent IRQ */ desc->irq_data.chip->irq_ack(&desc->irq_data); -+#ifdef CONFIG_IPIPE -+ if (!(*at91_gpio->nonroot_gpios)) { -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+ } -+#endif /* CONFIG_IPIPE */ + for (;;) { /* Reading ISR acks pending (edge triggered) GPIO interrupts. * When there none are pending, we're finished unless we need -@@ -420,9 +443,15 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +@@ -420,9 +437,9 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) * here to be disabled on the GPIO controller. */ gpio_irq_mask(irq_get_irq_data(pin)); + } else { + ipipe_handle_chained_irq(pin); -+#ifdef CONFIG_IPIPE -+ if (!(*at91_gpio->nonroot_gpios)) { -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+ } -+#endif /* CONFIG_IPIPE */ } - else - generic_handle_irq(pin); } pin++; gpio++; -@@ -433,6 +462,79 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +@@ -433,6 +450,79 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) /* now it may re-trigger */ } @@ -5438,7 +5431,7 @@ index af818a2..caf2226 100644 /*--------------------------------------------------------------------------*/ #ifdef CONFIG_DEBUG_FS -@@ -631,13 +733,19 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) +@@ -631,13 +721,19 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) at91_gpio->chip.base = PIN_BASE + i * 32; at91_gpio->regbase = at91_gpio->bank->offset + (void __iomem *)AT91_VA_BASE_SYS; @@ -8795,7 +8788,7 @@ index e9bcefe..98f03c4 100644 + +postcore_initcall(post_cpu_init); diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c -index d17b3c9..3ef2e4f 100644 +index d17b3c9..9454b5b 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -24,6 +24,7 @@ @@ -8828,35 +8821,7 @@ index d17b3c9..3ef2e4f 100644 return 0; } -@@ -159,13 +163,35 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) - { - u32 gpio_irq_no_base = port->virtual_irq_start; - -+#ifdef CONFIG_IPIPE -+ /* Handle high priority domains interrupts first */ -+ u32 nonroot_gpios = irq_stat & port->nonroot_gpios; -+ -+ irq_stat &= ~nonroot_gpios; -+ while (nonroot_gpios != 0) { -+ int irqoffset = fls(nonroot_gpios) - 1; -+ -+ if (port->both_edges & (1 << irqoffset)) -+ mxc_flip_edge(port, irqoffset); -+ -+ ipipe_handle_chained_irq(gpio_irq_no_base + irqoffset); -+ -+ nonroot_gpios &= ~(1 << irqoffset); -+ } -+#endif -+ - while (irq_stat != 0) { - int irqoffset = fls(irq_stat) - 1; - -+#ifdef CONFIG_IPIPE -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+#endif /* CONFIG_IPIPE */ -+ +@@ -165,7 +169,7 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) if (port->both_edges & (1 << irqoffset)) mxc_flip_edge(port, irqoffset); @@ -8865,48 +8830,7 @@ index d17b3c9..3ef2e4f 100644 irq_stat &= ~(1 << irqoffset); } -@@ -177,10 +203,18 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) - u32 irq_stat; - struct mxc_gpio_port *port = get_irq_data(irq); - -+#ifdef CONFIG_IPIPE -+ desc->irq_data.chip->irq_mask_ack(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ -+ - irq_stat = __raw_readl(port->base + GPIO_ISR) & - __raw_readl(port->base + GPIO_IMR); - - mxc_gpio_irq_handler(port, irq_stat); -+ -+#ifdef CONFIG_IPIPE -+ desc->irq_data.chip->irq_unmask(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ - } - - /* MX2 has one interrupt *for all* gpio ports */ -@@ -190,6 +224,10 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) - u32 irq_msk, irq_stat; - struct mxc_gpio_port *port = get_irq_data(irq); - -+#ifdef CONFIG_IPIPE -+ desc->irq_data.chip->irq_mask_ack(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ -+ - /* walk through all interrupt status registers */ - for (i = 0; i < gpio_table_size; i++) { - irq_msk = __raw_readl(port[i].base + GPIO_IMR); -@@ -200,6 +238,10 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) - if (irq_stat) - mxc_gpio_irq_handler(&port[i], irq_stat); - } -+ -+#ifdef CONFIG_IPIPE -+ desc->irq_data.chip->irq_unmask(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ - } - - /* -@@ -459,3 +501,48 @@ static struct mxc_gpio_port imx50_gpio_ports[] = { +@@ -459,3 +463,48 @@ static struct mxc_gpio_port imx50_gpio_ports[] = { DEFINE_REGISTER_FUNCTION(imx50) #endif /* if defined(CONFIG_SOC_IMX50) */ @@ -9383,7 +9307,7 @@ index 1d706cf..ac1c1fd 100644 u32 l; diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c -index 971d186..25c17a3 100644 +index 971d186..3ed3224 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -20,9 +20,11 @@ @@ -9407,103 +9331,25 @@ index 971d186..25c17a3 100644 struct gpio_chip chip; struct clk *dbck; u32 mod_usage; -@@ -159,8 +161,95 @@ struct gpio_bank { +@@ -159,8 +161,17 @@ struct gpio_bank { struct device *dev; bool dbck_flag; int stride; +#ifdef CONFIG_IPIPE + unsigned nonroot_gpios; +#endif -+}; -+ -+#define METHOD_MPUIO 0 -+#define METHOD_GPIO_1510 1 -+#define METHOD_GPIO_1610 2 -+#define METHOD_GPIO_7XX 3 -+#define METHOD_GPIO_24XX 5 -+#define METHOD_GPIO_44XX 6 -+ + }; + +#if !defined(MULTI_OMAP1) && !defined(MULTI_OMAP2) +#define inline_single inline +#else +#define inline_single +#endif + -+#ifdef CONFIG_ARCH_OMAP16XX -+static struct gpio_bank gpio_bank_1610[5] = { -+ { OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE, -+ METHOD_MPUIO }, -+ { OMAP1610_GPIO1_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE, -+ METHOD_GPIO_1610 }, -+ { OMAP1610_GPIO2_BASE, NULL, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, -+ METHOD_GPIO_1610 }, -+ { OMAP1610_GPIO3_BASE, NULL, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, -+ METHOD_GPIO_1610 }, -+ { OMAP1610_GPIO4_BASE, NULL, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48, -+ METHOD_GPIO_1610 }, -+}; -+#endif -+ -+#ifdef CONFIG_ARCH_OMAP15XX -+static struct gpio_bank gpio_bank_1510[2] = { -+ { OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE, -+ METHOD_MPUIO }, -+ { OMAP1510_GPIO_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE, -+ METHOD_GPIO_1510 } -+}; -+#endif -+ -+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) -+static struct gpio_bank gpio_bank_7xx[7] = { -+ { OMAP1_MPUIO_VBASE, NULL, INT_7XX_MPUIO, IH_MPUIO_BASE, -+ METHOD_MPUIO }, -+ { OMAP7XX_GPIO1_BASE, NULL, INT_7XX_GPIO_BANK1, IH_GPIO_BASE, -+ METHOD_GPIO_7XX }, -+ { OMAP7XX_GPIO2_BASE, NULL, INT_7XX_GPIO_BANK2, IH_GPIO_BASE + 32, -+ METHOD_GPIO_7XX }, -+ { OMAP7XX_GPIO3_BASE, NULL, INT_7XX_GPIO_BANK3, IH_GPIO_BASE + 64, -+ METHOD_GPIO_7XX }, -+ { OMAP7XX_GPIO4_BASE, NULL, INT_7XX_GPIO_BANK4, IH_GPIO_BASE + 96, -+ METHOD_GPIO_7XX }, -+ { OMAP7XX_GPIO5_BASE, NULL, INT_7XX_GPIO_BANK5, IH_GPIO_BASE + 128, -+ METHOD_GPIO_7XX }, -+ { OMAP7XX_GPIO6_BASE, NULL, INT_7XX_GPIO_BANK6, IH_GPIO_BASE + 160, -+ METHOD_GPIO_7XX }, -+}; -+#endif -+ -+#ifdef CONFIG_ARCH_OMAP2 -+ -+static struct gpio_bank gpio_bank_242x[4] = { -+ { OMAP242X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, -+ METHOD_GPIO_24XX }, -+ { OMAP242X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, -+ METHOD_GPIO_24XX }, -+ { OMAP242X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, -+ METHOD_GPIO_24XX }, -+ { OMAP242X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, -+ METHOD_GPIO_24XX }, -+}; -+ -+static struct gpio_bank gpio_bank_243x[5] = { -+ { OMAP243X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, -+ METHOD_GPIO_24XX }, -+ { OMAP243X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, -+ METHOD_GPIO_24XX }, -+ { OMAP243X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, -+ METHOD_GPIO_24XX }, -+ { OMAP243X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, -+ METHOD_GPIO_24XX }, -+ { OMAP243X_GPIO5_BASE, NULL, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128, -+ METHOD_GPIO_24XX }, - }; - -+#endif -+ #ifdef CONFIG_ARCH_OMAP3 struct omap3_gpio_regs { u32 irqenable1; -@@ -189,6 +278,12 @@ static int bank_width; +@@ -189,6 +200,12 @@ static int bank_width; /* TODO: Analyze removing gpio_bank_count usage from driver code */ int gpio_bank_count; @@ -9516,7 +9362,7 @@ index 971d186..25c17a3 100644 static inline struct gpio_bank *get_gpio_bank(int gpio) { if (cpu_is_omap15xx()) { -@@ -249,7 +344,7 @@ static inline int gpio_valid(int gpio) +@@ -249,7 +266,7 @@ static inline int gpio_valid(int gpio) return -1; } @@ -9525,7 +9371,7 @@ index 971d186..25c17a3 100644 { if (unlikely(gpio_valid(gpio) < 0)) { printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio); -@@ -613,7 +708,7 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, +@@ -613,7 +630,7 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, * This only applies to chips that can't do both rising and falling edge * detection at once. For all other chips, this function is a noop. */ @@ -9534,7 +9380,7 @@ index 971d186..25c17a3 100644 { void __iomem *reg = bank->base; u32 l = 0; -@@ -646,7 +741,7 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) +@@ -646,7 +663,7 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) } #endif @@ -9543,7 +9389,7 @@ index 971d186..25c17a3 100644 { void __iomem *reg = bank->base; u32 l = 0; -@@ -771,7 +866,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) +@@ -771,7 +788,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) return retval; } @@ -9552,7 +9398,7 @@ index 971d186..25c17a3 100644 { void __iomem *reg = bank->base; -@@ -832,7 +927,7 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) +@@ -832,7 +849,7 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio)); } @@ -9561,7 +9407,7 @@ index 971d186..25c17a3 100644 { void __iomem *reg = bank->base; int inv = 0; -@@ -891,7 +986,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) +@@ -891,7 +908,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) return l; } @@ -9570,128 +9416,17 @@ index 971d186..25c17a3 100644 { void __iomem *reg = bank->base; u32 l; -@@ -1126,6 +1221,40 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) - spin_unlock_irqrestore(&bank->lock, flags); - } - -+static void gpio_demux_inner(struct gpio_bank *bank, u32 isr, int nonroot) -+{ -+ unsigned int gpio_irq, gpio_index; -+ -+ gpio_irq = bank->virtual_irq_start; -+ for (; isr != 0; isr >>= 1, gpio_irq++) { -+ if (!(isr & 1)) -+ continue; -+ -+#ifdef CONFIG_IPIPE -+ if (!nonroot) { -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+ } -+#endif /* CONFIG_IPIPE */ -+ -+#ifdef CONFIG_ARCH_OMAP1 -+ gpio_index = get_gpio_index(irq_to_gpio(gpio_irq)); -+ -+ /* -+ * Some chips can't respond to both rising and falling -+ * at the same time. If this irq was requested with -+ * both flags, we need to flip the ICR data for the IRQ -+ * to respond to the IRQ for the opposite direction. -+ * This will be indicated in the bank toggle_mask. -+ */ -+ if (bank->toggle_mask & (1 << gpio_index)) -+ _toggle_gpio_edge_triggering(bank, gpio_index); -+#endif -+ ipipe_handle_chained_irq(gpio_irq); -+ } -+} -+ -+ - /* - * We need to unmask the GPIO bank interrupt as soon as possible to - * avoid missing GPIO interrupts for other lines in the bank. -@@ -1139,12 +1268,15 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) - { - void __iomem *isr_reg = NULL; - u32 isr; -- unsigned int gpio_irq, gpio_index; - struct gpio_bank *bank; - u32 retrigger = 0; - int unmasked = 0; - -+#ifndef CONFIG_IPIPE - desc->irq_data.chip->irq_ack(&desc->irq_data); -+#else /* CONFIG_IPIPE */ -+ desc->irq_data.chip->irq_mask_ack(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ - - bank = get_irq_data(irq); - #ifdef CONFIG_ARCH_OMAP1 -@@ -1180,6 +1312,13 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) - u32 isr_saved, level_mask = 0; - u32 enabled; - -+#ifdef CONFIG_IPIPE -+ if (!bank->nonroot_gpios) { -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+ } -+#endif /* CONFIG_IPIPE */ -+ - enabled = _get_gpio_irqbank_mask(bank); - isr_saved = isr = __raw_readl(isr_reg) & enabled; - -@@ -1197,39 +1336,28 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) - _clear_gpio_irqbank(bank, isr_saved & ~level_mask); - _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1); - -+#ifndef CONFIG_IPIPE - /* if there is only edge sensitive GPIO pin interrupts - configured, we could unmask GPIO bank interrupt immediately */ - if (!level_mask && !unmasked) { - unmasked = 1; - desc->irq_data.chip->irq_unmask(&desc->irq_data); - } -+#endif /* !CONFIG_IPIPE */ - - isr |= retrigger; - retrigger = 0; - if (!isr) - break; - -- gpio_irq = bank->virtual_irq_start; -- for (; isr != 0; isr >>= 1, gpio_irq++) { -- gpio_index = get_gpio_index(irq_to_gpio(gpio_irq)); -- -- if (!(isr & 1)) -- continue; -+#ifdef CONFIG_IPIPE -+ if (bank->nonroot_gpios) -+ gpio_demux_inner(bank, isr & bank->nonroot_gpios, 1); -+ gpio_demux_inner(bank, isr & ~bank->nonroot_gpios, 0); -+#else /* !CONFIG_IPIPE */ -+ gpio_demux_inner(bank, isr, 0); -+#endif /* !CONFIG_IPIPE */ - --#ifdef CONFIG_ARCH_OMAP1 -- /* -- * Some chips can't respond to both rising and falling -- * at the same time. If this irq was requested with -- * both flags, we need to flip the ICR data for the IRQ -- * to respond to the IRQ for the opposite direction. -- * This will be indicated in the bank toggle_mask. -- */ -- if (bank->toggle_mask & (1 << gpio_index)) -- _toggle_gpio_edge_triggering(bank, gpio_index); --#endif +@@ -1227,8 +1244,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) + if (bank->toggle_mask & (1 << gpio_index)) + _toggle_gpio_edge_triggering(bank, gpio_index); + #endif - - generic_handle_irq(gpio_irq); -- } ++ ipipe_handle_chained_irq(gpio_irq); + } } /* if bank has any level sensitive GPIO pin interrupt - configured, we must unmask the bank interrupt only after -@@ -1265,6 +1393,16 @@ static void gpio_mask_irq(struct irq_data *d) +@@ -1265,6 +1281,16 @@ static void gpio_mask_irq(struct irq_data *d) _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); } @@ -9708,7 +9443,7 @@ index 971d186..25c17a3 100644 static void gpio_unmask_irq(struct irq_data *d) { unsigned int gpio = d->irq - IH_GPIO_BASE; -@@ -1291,6 +1429,7 @@ static struct irq_chip gpio_irq_chip = { +@@ -1291,6 +1317,7 @@ static struct irq_chip gpio_irq_chip = { .irq_shutdown = gpio_irq_shutdown, .irq_ack = gpio_ack_irq, .irq_mask = gpio_mask_irq, @@ -9716,7 +9451,7 @@ index 971d186..25c17a3 100644 .irq_unmask = gpio_unmask_irq, .irq_set_type = gpio_irq_type, .irq_set_wake = gpio_wake_enable, -@@ -1682,7 +1821,14 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank) +@@ -1682,7 +1709,14 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank) set_irq_chip(j, &gpio_irq_chip); set_irq_handler(j, handle_simple_irq); set_irq_flags(j, IRQF_VALID); @@ -9731,7 +9466,7 @@ index 971d186..25c17a3 100644 set_irq_chained_handler(bank->irq, gpio_irq_handler); set_irq_data(bank->irq, bank); } -@@ -1753,6 +1899,166 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) +@@ -1753,6 +1787,166 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) return 0; } diff --git a/ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-08.patch b/ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-09.patch similarity index 97% rename from ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-08.patch rename to ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-09.patch index 361079d..05c7e42 100644 --- a/ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-08.patch +++ b/ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-09.patch @@ -1,5 +1,5 @@ diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 2456bad..48e52a3 100644 +index 2456bad..8ee9c4c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -52,6 +52,9 @@ config HAVE_SCHED_CLOCK @@ -36,6 +36,17 @@ index 2456bad..48e52a3 100644 source kernel/Kconfig.preempt config HZ +@@ -2023,6 +2036,10 @@ config NEON + Say Y to include support code for NEON, the ARMv7 Advanced SIMD + Extension. + ++config VFP_3_2_BACKPORT ++ bool ++ default y if VFP ++ + endmenu + + menu "Userspace binary formats" diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 940b201..d1a1c64 100644 --- a/arch/arm/boot/compressed/head.S @@ -995,7 +1006,7 @@ index 4384d81..f4efd23 100644 void sp804_clockevents_init(void __iomem *, unsigned int, const char *); diff --git a/arch/arm/include/asm/ipipe.h b/arch/arm/include/asm/ipipe.h new file mode 100644 -index 0000000..6e12980 +index 0000000..2528d43 --- /dev/null +++ b/arch/arm/include/asm/ipipe.h @@ -0,0 +1,341 @@ @@ -1031,10 +1042,10 @@ index 0000000..6e12980 +#include <linux/ipipe_percpu.h> +#include <linux/ipipe_trace.h> + -+#define IPIPE_ARCH_STRING "1.18-08" ++#define IPIPE_ARCH_STRING "1.18-09" +#define IPIPE_MAJOR_NUMBER 1 +#define IPIPE_MINOR_NUMBER 18 -+#define IPIPE_PATCH_NUMBER 8 ++#define IPIPE_PATCH_NUMBER 9 + +#ifdef CONFIG_SMP +#define ipipe_processor_id() hard_smp_processor_id() @@ -2482,8 +2493,38 @@ index a5b31af..9d7ece5 100644 +obj-$(CONFIG_IPIPE_ARM_KUSER_TSC) += ipipe_tsc.o ipipe_tsc_asm.o extra-y := $(head-y) init_task.o vmlinux.lds +diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c +index 927522c..30d1ad6 100644 +--- a/arch/arm/kernel/asm-offsets.c ++++ b/arch/arm/kernel/asm-offsets.c +@@ -1,7 +1,7 @@ + /* + * Copyright (C) 1995-2003 Russell King + * 2001-2002 Keith Owens +- * ++ * + * Generate definitions needed by assembly language modules. + * This code generates raw asm output which is post-processed to extract + * and format the required data. +@@ -59,6 +59,9 @@ int main(void) + DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); + DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate)); + DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); ++#ifdef CONFIG_SMP ++ DEFINE(VFP_CPU, offsetof(union vfp_state, hard.cpu)); ++#endif + #ifdef CONFIG_ARM_THUMBEE + DEFINE(TI_THUMBEE_STATE, offsetof(struct thread_info, thumbee_state)); + #endif +@@ -129,5 +132,5 @@ int main(void) + DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL); + DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE); + DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE); +- return 0; ++ return 0; + } diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S -index 90c62cd..11c5064 100644 +index 90c62cd..a376727 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -4,6 +4,7 @@ @@ -2681,6 +2722,7 @@ index 90c62cd..11c5064 100644 UNWIND(.fnstart ) UNWIND(.cantunwind ) +#ifdef CONFIG_IPIPE ++ disable_irq +#if !defined(CONFIG_SMP) + ldr r0, =ipipe_percpu_domain + ldr r1, =ipipe_root @@ -2691,7 +2733,6 @@ index 90c62cd..11c5064 100644 + cmp r0, #1 +#endif /* CONFIG_SMP */ + beq 1f -+ disable_irq + slow_restore_user_regs @ Fast exit path over non-root domains +1: +#endif /* CONFIG_IPIPE */ @@ -2964,10 +3005,10 @@ index 051166c..043ca62 100644 * have in theory up to 7 arguments to a function - r0 to r6. diff --git a/arch/arm/kernel/ipipe.c b/arch/arm/kernel/ipipe.c new file mode 100644 -index 0000000..6cb7401 +index 0000000..aea4782 --- /dev/null +++ b/arch/arm/kernel/ipipe.c -@@ -0,0 +1,676 @@ +@@ -0,0 +1,678 @@ +/* -*- linux-c -*- + * linux/arch/arm/kernel/ipipe.c + * @@ -3347,7 +3388,7 @@ index 0000000..6cb7401 +#ifdef CONFIG_SMP +asmlinkage int __ipipe_check_root(void) +{ -+ return ipipe_root_domain_p; ++ return __ipipe_root_domain_p; +} + +asmlinkage int __ipipe_check_root_interruptible(void) @@ -3453,13 +3494,15 @@ index 0000000..6cb7401 + else { + head = __ipipe_pipeline.next; + next_domain = list_entry(head, struct ipipe_domain, p_link); -+ if (!(flags & IPIPE_IRQF_NOSYNC) -+ && likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { ++ if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { + if (!m_ack && next_domain->irqs[irq].acknowledge) { + desc = ipipe_virtual_irq_p(irq) ? NULL : irq_to_desc(irq); + next_domain->irqs[irq].acknowledge(irq, desc); + } -+ __ipipe_dispatch_wired(next_domain, irq); ++ if ((flags & IPIPE_IRQF_NOSYNC) == 0) ++ __ipipe_dispatch_wired(next_domain, irq); ++ else ++ __ipipe_set_irq_pending(next_domain, irq); + return; + } + } @@ -4191,7 +4234,7 @@ index e7f92a4..3b968bf 100644 static void smp_timer_broadcast(const struct cpumask *mask) { diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c -index 2c277d4..461b25c 100644 +index 2c277d4..054873d 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -17,15 +17,143 @@ @@ -4228,7 +4271,7 @@ index 2c277d4..461b25c 100644 + +void __ipipe_ack_localtimer(unsigned irq, struct irq_desc *desc) +{ -+ writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT); ++ __raw_writel(1, twd_base + TWD_TIMER_INTSTAT); +} + +asmlinkage void __ipipe_grab_localtimer(struct pt_regs *regs) @@ -4243,7 +4286,7 @@ index 2c277d4..461b25c 100644 + return; + } + -+ writel_relaxed(delay, twd_base + TWD_TIMER_COUNTER); ++ __raw_writel(delay, twd_base + TWD_TIMER_COUNTER); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + @@ -5237,7 +5280,7 @@ index 29dff18..11d868e 100644 void __init at91sam9rl_init_interrupts(unsigned int priority[NR_AIC_IRQS]) diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c -index 4615528..620b6c1 100644 +index 4615528..37a3e82 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -19,12 +19,20 @@ @@ -5283,39 +5326,24 @@ index 4615528..620b6c1 100644 .irq_mask = gpio_irq_mask, .irq_unmask = gpio_irq_unmask, .irq_set_type = gpio_irq_type, -@@ -393,6 +409,13 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +@@ -393,6 +409,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) /* temporarily mask (level sensitive) parent IRQ */ chip->irq_ack(idata); -+#ifdef CONFIG_IPIPE -+ if (!(*at91_gpio->nonroot_gpios)) { -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+ } -+#endif /* CONFIG_IPIPE */ + for (;;) { /* Reading ISR acks pending (edge triggered) GPIO interrupts. * When there none are pending, we're finished unless we need -@@ -410,8 +433,15 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) - pin = at91_gpio->chip.base; +@@ -411,7 +428,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) while (isr) { -- if (isr & 1) + if (isr & 1) - generic_handle_irq(pin); -+ if (isr & 1) { + ipipe_handle_chained_irq(pin); -+#ifdef CONFIG_IPIPE -+ if (!(*at91_gpio->nonroot_gpios)) { -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+ } -+#endif /* CONFIG_IPIPE */ -+ } pin++; isr >>= 1; } -@@ -420,6 +450,84 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +@@ -420,6 +437,84 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) /* now it may re-trigger */ } @@ -5400,7 +5428,7 @@ index 4615528..620b6c1 100644 /*--------------------------------------------------------------------------*/ #ifdef CONFIG_DEBUG_FS -@@ -618,13 +726,19 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) +@@ -618,13 +713,19 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) at91_gpio->chip.base = PIN_BASE + i * 32; at91_gpio->regbase = at91_gpio->bank->offset + (void __iomem *)AT91_VA_BASE_SYS; @@ -9781,6 +9809,19 @@ index f0cc8e1..c9360e6 100644 f->chip.irq_unmask = fpga_irq_unmask; if (parent_irq != -1) { +diff --git a/arch/arm/vfp/Makefile b/arch/arm/vfp/Makefile +index 6de73aa..a81404c 100644 +--- a/arch/arm/vfp/Makefile ++++ b/arch/arm/vfp/Makefile +@@ -7,7 +7,7 @@ + # ccflags-y := -DDEBUG + # asflags-y := -DDEBUG + +-KBUILD_AFLAGS :=$(KBUILD_AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp) ++KBUILD_AFLAGS :=$(KBUILD_AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp -mfloat-abi=soft) + LDFLAGS +=--no-warn-mismatch + + obj-y += vfp.o diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index 4fa9903..e46bae3 100644 --- a/arch/arm/vfp/entry.S @@ -9810,7 +9851,7 @@ index 4fa9903..e46bae3 100644 get_thread_info r10 ldr r4, [r10, #TI_PREEMPT] @ get preempt count diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S -index 9897dcf..de4ae09 100644 +index 9897dcf..7ffd505 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -19,7 +19,7 @@ @@ -9818,7 +9859,7 @@ index 9897dcf..de4ae09 100644 .macro DBGSTR, str -#ifdef DEBUG -+#if defined(DEBUG) && !defined(CONFIG_IPIPE) ++#if defined(DEBUG) stmfd sp!, {r0-r3, ip, lr} add r0, pc, #4 bl printk @@ -9827,7 +9868,7 @@ index 9897dcf..de4ae09 100644 .macro DBGSTR1, str, arg -#ifdef DEBUG -+#if defined(DEBUG) && !defined(CONFIG_IPIPE) ++#if defined(DEBUG) stmfd sp!, {r0-r3, ip, lr} mov r1, \arg add r0, pc, #4 @@ -9836,26 +9877,142 @@ index 9897dcf..de4ae09 100644 .macro DBGSTR3, str, arg1, arg2, arg3 -#ifdef DEBUG -+#if defined(DEBUG) && !defined(CONFIG_IPIPE) ++#if defined(DEBUG) stmfd sp!, {r0-r3, ip, lr} mov r3, \arg3 mov r2, \arg2 -@@ -87,6 +87,14 @@ ENTRY(vfp_support_entry) - @ still there. In this case, we do - @ not want to drop a pending exception. +@@ -58,6 +58,23 @@ + #endif + .endm ++ .macro TRACE_SAVE, arg ++#ifdef CONFIG_FPU_TRACE ++ stmfd sp!, {r0-r3, ip, lr} ++ mov r0, \arg ++ bl fp_trace_save ++ ldmfd sp!, {r0-r3, ip, lr} ++#endif /* CONFIG_FPU_TRACE */ ++ .endm ++ ++ .macro TRACE_RESTORE, arg ++#ifdef CONFIG_FPU_TRACE ++ stmfd sp!, {r0-r3, ip, lr} ++ mov r0, \arg ++ bl fp_trace_restore ++ ldmfd sp!, {r0-r3, ip, lr} ++#endif /* CONFIG_FPU_TRACE */ ++ .endm + + @ VFP hardware support entry point. + @ +@@ -77,27 +94,32 @@ ENTRY(vfp_support_entry) + bne look_for_VFP_exceptions @ VFP is already enabled + + DBGSTR1 "enable %x", r10 +- ldr r3, last_VFP_context_address ++ ldr r3, vfp_current_hw_state_address + orr r1, r1, #FPEXC_EN @ user FPEXC has the enable bit set +- ldr r4, [r3, r11, lsl #2] @ last_VFP_context pointer ++ ldr r4, [r3, r11, lsl #2] @ vfp_current_hw_state pointer + bic r5, r1, #FPEXC_EX @ make sure exceptions are disabled +- cmp r4, r10 +- beq check_for_exception @ we are returning to the same +- @ process, so the registers are +- @ still there. In this case, we do +- @ not want to drop a pending exception. ++ cmp r4, r10 @ this thread owns the hw context? ++#ifndef CONFIG_SMP ++ @ For UP, checking that this thread owns the hw context is ++ @ sufficient to determine that the hardware state is valid. ++ beq vfp_hw_state_valid + ++ @ On UP, we lazily save the VFP context. As a different ++ @ thread wants ownership of the VFP hardware, save the old ++ @ state if there was a previous (valid) owner. ++ + enable_irq +#ifdef CONFIG_IPIPE + disable_irq -+#ifdef CONFIG_SMP -+ mrc p15, 0, r11, c0, c0, 5 @ reload current CPU number -+#endif -+ ldr r4, [r3, r11, lsl #2] @ reload last_VFP_context pointer ++ ldr r4, [r3, r11, lsl #2] @ reload vfp_current_hw_state pointer +#endif VFPFMXR FPEXC, r5 @ enable VFP, disable any pending @ exceptions, so we can get at the @ rest of it -@@ -139,6 +147,7 @@ check_for_exception: + +-#ifndef CONFIG_SMP +- @ Save out the current registers to the old thread state +- @ No need for SMP since this is not done lazily +- + DBGSTR1 "save old state %p", r4 +- cmp r4, #0 +- beq no_old_VFP_process ++ cmp r4, #0 @ if the vfp_current_hw_state is NULL ++ beq vfp_reload_hw @ then the hw state needs reloading + VFPFSTMIA r4, r5 @ save the working registers + VFPFMRX r5, FPSCR @ current status + #ifndef CONFIG_CPU_FEROCEON +@@ -110,13 +132,47 @@ ENTRY(vfp_support_entry) + 1: + #endif + stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2 +- @ and point r4 at the word at the +- @ start of the register dump ++vfp_reload_hw: ++ ++#else ++ @ For SMP, if this thread does not own the hw context, then we ++ @ need to reload it. No need to save the old state as on SMP, ++ @ we always save the state when we switch away from a thread. ++ bne vfp_reload_hw ++ ++ @ This thread has ownership of the current hardware context. ++ @ However, it may have been migrated to another CPU, in which ++ @ case the saved state is newer than the hardware context. ++ @ Check this by looking at the CPU number which the state was ++ @ last loaded onto. ++ ldr ip, [r10, #VFP_CPU] ++ teq ip, r11 ++ beq vfp_hw_state_valid ++ ++#if 0 ++vfp_reload_hw: ++ enable_irq ++#ifdef CONFIG_IPIPE ++ disable_irq ++ mrc p15, 0, ip, c0, c0, 5 @ reload current CPU number ++ and r11, ip, #15 ++#endif ++#else ++vfp_reload_hw: ++#endif ++ ++ @ We're loading this threads state into the VFP hardware. Update ++ @ the CPU number which contains the most up to date VFP context. ++ str r11, [r10, #VFP_CPU] ++ ++ VFPFMXR FPEXC, r5 @ enable VFP, disable any pending ++ @ exceptions, so we can get at the ++ @ rest of it + #endif + +-no_old_VFP_process: + DBGSTR1 "load state %p", r10 +- str r10, [r3, r11, lsl #2] @ update the last_VFP_context pointer ++ str r10, [r3, r11, lsl #2] @ update the vfp_current_hw_state pointer ++ TRACE_RESTORE r10 + @ Load the saved state back into the VFP + VFPFLDMIA r10, r5 @ reload the working registers while + @ FPEXC is in a safe state +@@ -132,13 +188,15 @@ no_old_VFP_process: + #endif + VFPFMXR FPSCR, r5 @ restore status + +-check_for_exception: ++@ The context stored in the VFP hardware is up to date with this thread ++vfp_hw_state_valid: + tst r1, #FPEXC_EX + bne process_exception @ might as well handle the pending + @ exception before retrying branch @ out before setting an FPEXC that @ stops us reading stuff VFPFMXR FPEXC, r1 @ restore FPEXC last @@ -9863,7 +10020,7 @@ index 9897dcf..de4ae09 100644 sub r2, r2, #4 str r2, [sp, #S_PC] @ retry the instruction #ifdef CONFIG_PREEMPT -@@ -164,6 +173,7 @@ look_for_VFP_exceptions: +@@ -164,6 +222,7 @@ look_for_VFP_exceptions: @ Fall into hand on to next handler - appropriate coproc instr @ not recognised by VFP @@ -9871,28 +10028,130 @@ index 9897dcf..de4ae09 100644 DBGSTR "not VFP" #ifdef CONFIG_PREEMPT get_thread_info r10 +@@ -193,7 +252,9 @@ ENTRY(vfp_save_state) + @ r0 - save location + @ r1 - FPEXC + DBGSTR1 "save VFP state %p", r0 ++ mov r3, r0 + VFPFSTMIA r0, r2 @ save the working registers ++ TRACE_SAVE r3 + VFPFMRX r2, FPSCR @ current status + tst r1, #FPEXC_EX @ is there additional state to save? + beq 1f +@@ -207,8 +268,8 @@ ENTRY(vfp_save_state) + ENDPROC(vfp_save_state) + + .align +-last_VFP_context_address: +- .word last_VFP_context ++vfp_current_hw_state_address: ++ .word vfp_current_hw_state + + .macro tbl_branch, base, tmp, shift + #ifdef CONFIG_THUMB2_KERNEL diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c -index f25e7ec..28f09ea 100644 +index f25e7ec..eaf6547 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c -@@ -48,6 +48,7 @@ unsigned int VFP_arch; +@@ -8,7 +8,6 @@ + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +-#include <linux/module.h> + #include <linux/types.h> + #include <linux/cpu.h> + #include <linux/kernel.h> +@@ -33,7 +32,6 @@ void vfp_support_entry(void); + void vfp_null_entry(void); + + void (*vfp_vector)(void) = vfp_null_entry; +-union vfp_state *last_VFP_context[NR_CPUS]; + + /* + * Dual-use variable. +@@ -43,39 +41,87 @@ union vfp_state *last_VFP_context[NR_CPUS]; + unsigned int VFP_arch; + + /* ++ * The pointer to the vfpstate structure of the thread which currently ++ * owns the context held in the VFP hardware, or NULL if the hardware ++ * context is invalid. ++ * ++ * For UP, this is sufficient to tell which thread owns the VFP context. ++ * However, for SMP, we also need to check the CPU number stored in the ++ * saved state too to catch migrations. ++ */ ++union vfp_state *vfp_current_hw_state[NR_CPUS]; ++ ++/* ++ * Is 'thread's most up to date state stored in this CPUs hardware? ++ * Must be called from non-preemptible context. ++ */ ++static bool vfp_state_in_hw(unsigned int cpu, struct thread_info *thread) ++{ ++#ifdef CONFIG_SMP ++ if (thread->vfpstate.hard.cpu != cpu) ++ return false; ++#endif ++ return vfp_current_hw_state[cpu] == &thread->vfpstate; ++} ++ ++/* ++ * Force a reload of the VFP context from the thread structure. We do ++ * this by ensuring that access to the VFP hardware is disabled, and ++ * clear vfp_current_hw_state. Must be called from non-preemptible context. ++ */ ++static void vfp_force_reload(unsigned int cpu, struct thread_info *thread) ++{ ++ if (vfp_state_in_hw(cpu, thread)) { ++ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); ++ vfp_current_hw_state[cpu] = NULL; ++ } ++#ifdef CONFIG_SMP ++ thread->vfpstate.hard.cpu = NR_CPUS; ++#endif ++} ++ ++/* + * Per-thread VFP initialization. + */ static void vfp_thread_flush(struct thread_info *thread) { union vfp_state *vfp = &thread->vfpstate; + unsigned long flags; unsigned int cpu; - memset(vfp, 0, sizeof(union vfp_state)); -@@ -60,22 +61,23 @@ static void vfp_thread_flush(struct thread_info *thread) - * that the modification of last_VFP_context[] and hardware disable - * are done for the same CPU and without preemption. +- memset(vfp, 0, sizeof(union vfp_state)); +- +- vfp->hard.fpexc = FPEXC_EN; +- vfp->hard.fpscr = FPSCR_ROUND_NEAREST; +- + /* + * Disable VFP to ensure we initialize it first. We must ensure +- * that the modification of last_VFP_context[] and hardware disable +- * are done for the same CPU and without preemption. ++ * that the modification of vfp_current_hw_state[] and hardware ++ * disable are done for the same CPU and without preemption. ++ * ++ * Do this first to ensure that preemption won't overwrite our ++ * state saving should access to the VFP be enabled at this point. */ - cpu = get_cpu(); +- if (last_VFP_context[cpu] == vfp) +- last_VFP_context[cpu] = NULL; + cpu = ipipe_get_cpu(flags); - if (last_VFP_context[cpu] == vfp) - last_VFP_context[cpu] = NULL; ++ if (vfp_current_hw_state[cpu] == vfp) ++ vfp_current_hw_state[cpu] = NULL; fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); - put_cpu(); ++ ++ memset(vfp, 0, sizeof(union vfp_state)); ++ ++ vfp->hard.fpexc = FPEXC_EN; ++ vfp->hard.fpscr = FPSCR_ROUND_NEAREST; ++#ifdef CONFIG_SMP ++ vfp->hard.cpu = NR_CPUS; ++#endif + ipipe_put_cpu(flags); } @@ -9904,14 +10163,26 @@ index f25e7ec..28f09ea 100644 + unsigned long flags; + unsigned int cpu = ipipe_get_cpu(flags); - if (last_VFP_context[cpu] == vfp) - last_VFP_context[cpu] = NULL; +- if (last_VFP_context[cpu] == vfp) +- last_VFP_context[cpu] = NULL; - put_cpu(); ++ if (vfp_current_hw_state[cpu] == vfp) ++ vfp_current_hw_state[cpu] = NULL; + ipipe_put_cpu(flags); } static void vfp_thread_copy(struct thread_info *thread) -@@ -112,6 +114,7 @@ static void vfp_thread_copy(struct thread_info *thread) +@@ -84,6 +130,9 @@ static void vfp_thread_copy(struct thread_info *thread) + + vfp_sync_hwstate(parent); + thread->vfpstate = parent->vfpstate; ++#ifdef CONFIG_SMP ++ thread->vfpstate.hard.cpu = NR_CPUS; ++#endif + } + + /* +@@ -112,6 +161,7 @@ static void vfp_thread_copy(struct thread_info *thread) static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) { struct thread_info *thread = v; @@ -9919,7 +10190,7 @@ index f25e7ec..28f09ea 100644 u32 fpexc; #ifdef CONFIG_SMP unsigned int cpu; -@@ -119,8 +122,9 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) +@@ -119,8 +169,9 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) switch (cmd) { case THREAD_NOTIFY_SWITCH: @@ -9930,7 +10201,27 @@ index f25e7ec..28f09ea 100644 #ifdef CONFIG_SMP cpu = thread->cpu; -@@ -147,6 +151,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) +@@ -129,17 +180,8 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) + * case the thread migrates to a different CPU. The + * restoring is done lazily. + */ +- if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) { +- vfp_save_state(last_VFP_context[cpu], fpexc); +- last_VFP_context[cpu]->hard.cpu = cpu; +- } +- /* +- * Thread migration, just force the reloading of the +- * state on the new CPU in case the VFP registers +- * contain stale data. +- */ +- if (thread->vfpstate.hard.cpu != cpu) +- last_VFP_context[cpu] = NULL; ++ if ((fpexc & FPEXC_EN) && vfp_current_hw_state[cpu]) ++ vfp_save_state(vfp_current_hw_state[cpu], fpexc); + #endif + + /* +@@ -147,6 +189,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) * old state. */ fmxr(FPEXC, fpexc & ~FPEXC_EN); @@ -9938,7 +10229,17 @@ index f25e7ec..28f09ea 100644 break; case THREAD_NOTIFY_FLUSH: -@@ -290,7 +295,7 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) +@@ -158,7 +201,9 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) + break; + + case THREAD_NOTIFY_COPY: ++ local_irq_save_hw_cond(flags); + vfp_thread_copy(thread); ++ local_irq_restore_hw_cond(flags); + break; + } + +@@ -290,7 +335,7 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) */ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) { @@ -9947,7 +10248,7 @@ index f25e7ec..28f09ea 100644 pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); -@@ -320,6 +325,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) +@@ -320,6 +365,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) /* * Synchronous exception, emulate the trigger instruction */ @@ -9955,7 +10256,7 @@ index f25e7ec..28f09ea 100644 goto emulate; } -@@ -332,7 +338,18 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) +@@ -332,7 +378,18 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) trigger = fmrx(FPINST); regs->ARM_pc -= 4; #endif @@ -9975,7 +10276,7 @@ index f25e7ec..28f09ea 100644 /* * Illegal combination of bits. It can be caused by an * unallocated VFP instruction but with FPSCR.IXE set and not -@@ -372,18 +389,14 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) +@@ -372,18 +429,14 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) if (fpexc ^ (FPEXC_EX | FPEXC_FP2V)) goto exit; @@ -9996,17 +10297,83 @@ index f25e7ec..28f09ea 100644 preempt_enable(); } -@@ -445,7 +458,8 @@ static inline void vfp_pm_init(void) { } +@@ -397,9 +450,7 @@ static void vfp_enable(void *unused) + set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11)); + } + +-#ifdef CONFIG_PM +-#include <linux/syscore_ops.h> +- ++#ifdef CONFIG_CPU_PM + static int vfp_pm_suspend(void) + { + struct thread_info *ti = current_thread_info(); +@@ -415,7 +466,7 @@ static int vfp_pm_suspend(void) + } + + /* clear any information we had about last context state */ +- memset(last_VFP_context, 0, sizeof(last_VFP_context)); ++ memset(vfp_current_hw_state, 0, sizeof(vfp_current_hw_state)); + return 0; + } +@@ -429,29 +480,44 @@ static void vfp_pm_resume(void) + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); + } + +-static struct syscore_ops vfp_pm_syscore_ops = { +- .suspend = vfp_pm_suspend, +- .resume = vfp_pm_resume, ++static int vfp_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, ++ void *v) ++{ ++ switch (cmd) { ++ case CPU_PM_ENTER: ++ vfp_pm_suspend(); ++ break; ++ case CPU_PM_ENTER_FAILED: ++ case CPU_PM_EXIT: ++ vfp_pm_resume(); ++ break; ++ } ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block vfp_cpu_pm_notifier_block = { ++ .notifier_call = vfp_cpu_pm_notifier, + }; + + static void vfp_pm_init(void) + { +- register_syscore_ops(&vfp_pm_syscore_ops); ++ cpu_pm_register_notifier(&vfp_cpu_pm_notifier_block); + } + + #else + static inline void vfp_pm_init(void) { } +-#endif /* CONFIG_PM */ ++#endif /* CONFIG_CPU_PM */ + ++/* ++ * Ensure that the VFP state stored in 'thread->vfpstate' is up to date ++ * with the hardware state. ++ */ void vfp_sync_hwstate(struct thread_info *thread) { - unsigned int cpu = get_cpu(); + unsigned long flags; + unsigned int cpu = ipipe_get_cpu(flags); - /* - * If the thread we're interested in is the current owner of the -@@ -462,12 +476,13 @@ void vfp_sync_hwstate(struct thread_info *thread) +- /* +- * If the thread we're interested in is the current owner of the +- * hardware VFP state, then we need to save its state. +- */ +- if (last_VFP_context[cpu] == &thread->vfpstate) { ++ if (vfp_state_in_hw(cpu, thread)) { + u32 fpexc = fmrx(FPEXC); + + /* +@@ -462,40 +528,18 @@ void vfp_sync_hwstate(struct thread_info *thread) fmxr(FPEXC, fpexc); } @@ -10014,25 +10381,82 @@ index f25e7ec..28f09ea 100644 + ipipe_put_cpu(flags); } ++/* Ensure that the thread reloads the hardware VFP state on the next use. */ void vfp_flush_hwstate(struct thread_info *thread) { - unsigned int cpu = get_cpu(); +- +- /* +- * If the thread we're interested in is the current owner of the +- * hardware VFP state, then we need to save its state. +- */ +- if (last_VFP_context[cpu] == &thread->vfpstate) { +- u32 fpexc = fmrx(FPEXC); + unsigned long flags; + unsigned int cpu = ipipe_get_cpu(flags); - /* - * If the thread we're interested in is the current owner of the -@@ -495,7 +510,7 @@ void vfp_flush_hwstate(struct thread_info *thread) - */ - thread->vfpstate.hard.cpu = NR_CPUS; - #endif +- fmxr(FPEXC, fpexc & ~FPEXC_EN); +- +- /* +- * Set the context to NULL to force a reload the next time +- * the thread uses the VFP. +- */ +- last_VFP_context[cpu] = NULL; +- } ++ vfp_force_reload(cpu, thread); + +-#ifdef CONFIG_SMP +- /* +- * For SMP we still have to take care of the case where the thread +- * migrates to another CPU and then back to the original CPU on which +- * the last VFP user is still the same thread. Mark the thread VFP +- * state as belonging to a non-existent CPU so that the saved one will +- * be reloaded in the above case. +- */ +- thread->vfpstate.hard.cpu = NR_CPUS; +-#endif - put_cpu(); + ipipe_put_cpu(flags); } /* +@@ -513,8 +557,7 @@ static int vfp_hotplug(struct notifier_block *b, unsigned long action, + void *hcpu) + { + if (action == CPU_DYING || action == CPU_DYING_FROZEN) { +- unsigned int cpu = (long)hcpu; +- last_VFP_context[cpu] = NULL; ++ vfp_force_reload((long)hcpu, current_thread_info()); + } else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) + vfp_enable(NULL); + return NOTIFY_OK; +@@ -582,7 +625,6 @@ static int __init vfp_init(void) + elf_hwcap |= HWCAP_VFPv3D16; + } + #endif +-#ifdef CONFIG_NEON + /* + * Check for the presence of the Advanced SIMD + * load/store instructions, integer and single +@@ -590,10 +632,15 @@ static int __init vfp_init(void) + * for NEON if the hardware has the MVFR registers. + */ + if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { ++#ifdef CONFIG_NEON + if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) + elf_hwcap |= HWCAP_NEON; +- } + #endif ++#if 0 ++ if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) ++ elf_hwcap |= HWCAP_VFPv4; ++#endif ++ } + } + return 0; + } diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c -index 35bebde..5be24b3 100644 +index 35bebde..cf7b714 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -21,6 +21,7 @@ @@ -10142,56 +10566,23 @@ index 35bebde..5be24b3 100644 { void __iomem *reg = bank->base; u32 l; -@@ -1008,6 +1024,41 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) +@@ -1008,6 +1024,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) spin_unlock_irqrestore(&bank->lock, flags); } + -+static void gpio_demux_inner(struct gpio_bank *bank, u32 isr, int nonroot) -+{ -+ unsigned int gpio_irq, gpio_index; -+ -+ gpio_irq = bank->virtual_irq_start; -+ for (; isr != 0; isr >>= 1, gpio_irq++) { -+ if (!(isr & 1)) -+ continue; -+ -+#ifdef CONFIG_IPIPE -+ if (!nonroot) { -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+ } -+#endif /* CONFIG_IPIPE */ -+ -+#ifdef CONFIG_ARCH_OMAP1 -+ gpio_index = get_gpio_index(irq_to_gpio(gpio_irq)); -+ -+ /* -+ * Some chips can't respond to both rising and falling -+ * at the same time. If this irq was requested with -+ * both flags, we need to flip the ICR data for the IRQ -+ * to respond to the IRQ for the opposite direction. -+ * This will be indicated in the bank toggle_mask. -+ */ -+ if (bank->toggle_mask & (1 << gpio_index)) -+ _toggle_gpio_edge_triggering(bank, gpio_index); -+#endif -+ ipipe_handle_chained_irq(gpio_irq); -+ } -+} -+ -+ /* * We need to unmask the GPIO bank interrupt as soon as possible to * avoid missing GPIO interrupts for other lines in the bank. -@@ -1019,13 +1070,12 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) +@@ -1019,13 +1036,13 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) */ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { -+ struct irq_chip *chip = irq_desc_get_chip(desc); - void __iomem *isr_reg = NULL; +- void __iomem *isr_reg = NULL; - u32 isr; -- unsigned int gpio_irq, gpio_index; ++ struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int gpio_irq, gpio_index; ++ void __iomem *isr_reg = NULL; struct gpio_bank *bank; u32 retrigger = 0; int unmasked = 0; @@ -10200,46 +10591,10 @@ index 35bebde..5be24b3 100644 chained_irq_enter(chip, desc); -@@ -1063,6 +1113,13 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) - u32 isr_saved, level_mask = 0; - u32 enabled; - -+#ifdef CONFIG_IPIPE -+ if (!bank->nonroot_gpios) { -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+ } -+#endif /* CONFIG_IPIPE */ -+ - enabled = _get_gpio_irqbank_mask(bank); - isr_saved = isr = __raw_readl(isr_reg) & enabled; - -@@ -1080,39 +1137,27 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) - _clear_gpio_irqbank(bank, isr_saved & ~level_mask); - _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1); - -+#ifndef CONFIG_IPIPE - /* if there is only edge sensitive GPIO pin interrupts - configured, we could unmask GPIO bank interrupt immediately */ - if (!level_mask && !unmasked) { - unmasked = 1; - chained_irq_exit(chip, desc); - } -+#endif /* CONFIG_IPIPE */ +@@ -1100,18 +1117,17 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) + continue; - isr |= retrigger; - retrigger = 0; - if (!isr) - break; - -- gpio_irq = bank->virtual_irq_start; -- for (; isr != 0; isr >>= 1, gpio_irq++) { -- gpio_index = get_gpio_index(irq_to_gpio(gpio_irq)); -- -- if (!(isr & 1)) -- continue; -- --#ifdef CONFIG_ARCH_OMAP1 + #ifdef CONFIG_ARCH_OMAP1 - /* - * Some chips can't respond to both rising and falling - * at the same time. If this irq was requested with @@ -10247,23 +10602,23 @@ index 35bebde..5be24b3 100644 - * to respond to the IRQ for the opposite direction. - * This will be indicated in the bank toggle_mask. - */ -- if (bank->toggle_mask & (1 << gpio_index)) -- _toggle_gpio_edge_triggering(bank, gpio_index); --#endif ++ /* ++ * Some chips can't respond to both rising and falling ++ * at the same time. If this irq was requested with ++ * both flags, we need to flip the ICR data for the IRQ ++ * to respond to the IRQ for the opposite direction. ++ * This will be indicated in the bank toggle_mask. ++ */ + if (bank->toggle_mask & (1 << gpio_index)) + _toggle_gpio_edge_triggering(bank, gpio_index); + #endif - - generic_handle_irq(gpio_irq); -- } -+#ifdef CONFIG_IPIPE -+ if (bank->nonroot_gpios) -+ gpio_demux_inner(bank, isr & bank->nonroot_gpios, 1); -+ gpio_demux_inner(bank, isr & ~bank->nonroot_gpios, 0); -+#else /* !CONFIG_IPIPE */ -+ gpio_demux_inner(bank, isr, 0); -+#endif /* !CONFIG_IPIPE */ ++ ipipe_handle_chained_irq(gpio_irq); + } } /* if bank has any level sensitive GPIO pin interrupt - configured, we must unmask the bank interrupt only after -@@ -1154,6 +1199,19 @@ static void gpio_mask_irq(struct irq_data *d) +@@ -1154,6 +1170,19 @@ static void gpio_mask_irq(struct irq_data *d) spin_unlock_irqrestore(&bank->lock, flags); } @@ -10283,7 +10638,7 @@ index 35bebde..5be24b3 100644 static void gpio_unmask_irq(struct irq_data *d) { unsigned int gpio = d->irq - IH_GPIO_BASE; -@@ -1182,6 +1240,7 @@ static struct irq_chip gpio_irq_chip = { +@@ -1182,6 +1211,7 @@ static struct irq_chip gpio_irq_chip = { .irq_shutdown = gpio_irq_shutdown, .irq_ack = gpio_ack_irq, .irq_mask = gpio_mask_irq, @@ -10291,7 +10646,7 @@ index 35bebde..5be24b3 100644 .irq_unmask = gpio_unmask_irq, .irq_set_type = gpio_irq_type, .irq_set_wake = gpio_wake_enable, -@@ -1570,6 +1629,12 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) +@@ -1570,6 +1600,12 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) irq_set_handler(j, handle_simple_irq); set_irq_flags(j, IRQF_VALID); } @@ -10304,7 +10659,7 @@ index 35bebde..5be24b3 100644 irq_set_chained_handler(bank->irq, gpio_irq_handler); irq_set_handler_data(bank->irq, bank); } -@@ -1640,6 +1705,171 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) +@@ -1640,6 +1676,171 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) return 0; } @@ -10529,7 +10884,7 @@ index eb3b5f8..cd3c867 100644 } - diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 56c05ef..4ef0ba47 100644 +index 56c05ef..4ef0ba4 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -89,7 +89,7 @@ config ATMEL_TCLIB _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git