From f36a3bb1a1b73a60f4df1d4c38c686cc173f50b3 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 18 Jan 2013 15:20:06 +0000 Subject: arm: Move the set_handle_irq and handle_arch_irq declarations to asm/irq.h This patch prepares the removal of include in the GIC and VIC irqchip drivers. Signed-off-by: Catalin Marinas Tested-by: Marc Zyngier Cc: Russell King Cc: Thomas Gleixner Cc: Rob Herring --- drivers/irqchip/irq-vic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 3cf97aaebe40..e38cb00ee784 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -33,7 +33,7 @@ #include #include -#include +#include #include "irqchip.h" -- cgit v1.2.3 From de88cbb7b244f3bcd61d49fd6dec35c19192545a Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 18 Jan 2013 15:31:37 +0000 Subject: arm: Move chained_irq_(enter|exit) to a generic file These functions have been introduced by commit 10a8c383 (irq: introduce entry and exit functions for chained handlers) in asm/mach/irq.h. This patch moves them to linux/irqchip/chained_irq.h so that generic irqchip drivers do not rely on architecture specific header files. Signed-off-by: Catalin Marinas Tested-by: Marc Zyngier Cc: Russell King Cc: Thomas Gleixner Cc: Rob Herring --- arch/arm/include/asm/mach/irq.h | 31 ----------------- arch/arm/mach-at91/gpio.c | 3 +- arch/arm/mach-exynos/common.c | 1 + arch/arm/mach-s3c24xx/irq.c | 1 + arch/arm/plat-samsung/irq-vic-timer.c | 3 +- arch/arm/plat-samsung/s5p-irq-gpioint.c | 3 +- drivers/gpio/gpio-msm-v2.c | 3 +- drivers/gpio/gpio-mxc.c | 2 +- drivers/gpio/gpio-omap.c | 3 +- drivers/gpio/gpio-pl061.c | 2 +- drivers/gpio/gpio-pxa.c | 3 +- drivers/gpio/gpio-tegra.c | 3 +- drivers/irqchip/exynos-combiner.c | 1 + drivers/irqchip/irq-gic.c | 1 + drivers/pinctrl/pinctrl-at91.c | 3 +- drivers/pinctrl/pinctrl-exynos.c | 3 +- drivers/pinctrl/pinctrl-nomadik.c | 2 +- drivers/pinctrl/pinctrl-sirf.c | 2 +- drivers/pinctrl/spear/pinctrl-plgpio.c | 2 +- drivers/staging/imx-drm/ipu-v3/ipu-common.c | 2 +- include/linux/irqchip/chained_irq.h | 52 +++++++++++++++++++++++++++++ 21 files changed, 71 insertions(+), 55 deletions(-) create mode 100644 include/linux/irqchip/chained_irq.h (limited to 'drivers/irqchip') diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h index 749d5052fbb7..2092ee1e1300 100644 --- a/arch/arm/include/asm/mach/irq.h +++ b/arch/arm/include/asm/mach/irq.h @@ -30,35 +30,4 @@ do { \ raw_spin_unlock(&desc->lock); \ } while(0) -#ifndef __ASSEMBLY__ -/* - * Entry/exit functions for chained handlers where the primary IRQ chip - * may implement either fasteoi or level-trigger flow control. - */ -static inline void chained_irq_enter(struct irq_chip *chip, - struct irq_desc *desc) -{ - /* FastEOI controllers require no action on entry. */ - if (chip->irq_eoi) - return; - - if (chip->irq_mask_ack) { - chip->irq_mask_ack(&desc->irq_data); - } else { - chip->irq_mask(&desc->irq_data); - if (chip->irq_ack) - chip->irq_ack(&desc->irq_data); - } -} - -static inline void chained_irq_exit(struct irq_chip *chip, - struct irq_desc *desc) -{ - if (chip->irq_eoi) - chip->irq_eoi(&desc->irq_data); - else - chip->irq_unmask(&desc->irq_data); -} -#endif - #endif diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index c5d7e1e9d757..a5afcf76550e 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -22,10 +22,9 @@ #include #include #include +#include #include -#include - #include #include diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index d63d399c7bae..7bc0f9aa8b33 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index cb9f5e011e73..b6fac28a0034 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c @@ -25,6 +25,7 @@ #include #include #include +#include #include diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index f980cf3d2baa..5d205e74e495 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -23,8 +24,6 @@ #include #include -#include - static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) { struct irq_chip *chip = irq_get_chip(irq); diff --git a/arch/arm/plat-samsung/s5p-irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c index bae56131a50a..fafdb059043a 100644 --- a/arch/arm/plat-samsung/s5p-irq-gpioint.c +++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -22,8 +23,6 @@ #include #include -#include - #define GPIO_BASE(chip) ((void __iomem *)((unsigned long)((chip)->base) & 0xFFFFF000u)) #define CON_OFFSET 0x700 diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c index 55a7e7769af6..dd2eddeb1e0c 100644 --- a/drivers/gpio/gpio-msm-v2.c +++ b/drivers/gpio/gpio-msm-v2.c @@ -23,13 +23,12 @@ #include #include #include +#include #include #include #include #include -#include - #include #include diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 7877335c4cc8..7176743915d3 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,6 @@ #include #include #include -#include enum mxc_gpio_hwtype { IMX1_GPIO, /* runs on i.mx1 */ diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 159f5c57eb45..a612ea1c53cb 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -25,11 +25,10 @@ #include #include #include +#include #include #include -#include - #define OFF_MODE 1 static LIST_HEAD(omap_gpio_list); diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index b820869ca93c..29763361d13c 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,6 @@ #include #include #include -#include #define GPIODIR 0x400 #define GPIOIS 0x404 diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 9cc108d2b770..7523b6d108d0 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -26,8 +27,6 @@ #include #include -#include - #include /* diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 414ad912232f..8e2155548888 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -27,11 +27,10 @@ #include #include #include +#include #include #include -#include - #define GPIO_BANK(x) ((x) >> 5) #define GPIO_PORT(x) (((x) >> 3) & 0x3) #define GPIO_BIT(x) ((x) & 0x7) diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index 04d86a9803f4..6a5201351507 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index a32e0d5aa45f..0b1c0af646de 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 75933a6aa828..5cbadc9ad2e8 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -27,8 +28,6 @@ /* Since we request GPIOs from ourself */ #include -#include - #include #include diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 538b9ddaadf7..7265e551dddb 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c @@ -23,13 +23,12 @@ #include #include #include +#include #include #include #include #include -#include - #include "pinctrl-samsung.h" #include "pinctrl-exynos.h" diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 36d20293de5c..93eba9715e62 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,6 @@ /* Since we request GPIOs from ourself */ #include #include -#include #include "pinctrl-nomadik.h" #include "core.h" diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index d02498b30c6e..ab26b4b669d5 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,6 @@ #include #include #include -#include #define DRIVER_NAME "pinmux-sirf" diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index 295b349a05cf..a4908ecd74fb 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -15,12 +15,12 @@ #include #include #include +#include #include #include #include #include #include -#include #define MAX_GPIO_PER_REG 32 #define PIN_OFFSET(pin) (pin % MAX_GPIO_PER_REG) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index 366f259e3756..6efe4e1b499f 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -25,8 +25,8 @@ #include #include #include +#include #include -#include #include "imx-ipu-v3.h" #include "ipu-prv.h" diff --git a/include/linux/irqchip/chained_irq.h b/include/linux/irqchip/chained_irq.h new file mode 100644 index 000000000000..adf4c30f3af6 --- /dev/null +++ b/include/linux/irqchip/chained_irq.h @@ -0,0 +1,52 @@ +/* + * Chained IRQ handlers support. + * + * Copyright (C) 2011 ARM Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __IRQCHIP_CHAINED_IRQ_H +#define __IRQCHIP_CHAINED_IRQ_H + +#include + +/* + * Entry/exit functions for chained handlers where the primary IRQ chip + * may implement either fasteoi or level-trigger flow control. + */ +static inline void chained_irq_enter(struct irq_chip *chip, + struct irq_desc *desc) +{ + /* FastEOI controllers require no action on entry. */ + if (chip->irq_eoi) + return; + + if (chip->irq_mask_ack) { + chip->irq_mask_ack(&desc->irq_data); + } else { + chip->irq_mask(&desc->irq_data); + if (chip->irq_ack) + chip->irq_ack(&desc->irq_data); + } +} + +static inline void chained_irq_exit(struct irq_chip *chip, + struct irq_desc *desc) +{ + if (chip->irq_eoi) + chip->irq_eoi(&desc->irq_data); + else + chip->irq_unmask(&desc->irq_data); +} + +#endif /* __IRQCHIP_CHAINED_IRQ_H */ -- cgit v1.2.3 From aec0095653cd9812b9a15df0315364cc6d094c59 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 14 Jan 2013 17:53:39 +0000 Subject: irqchip: gic: Call handle_bad_irq() directly Previously, the gic_handle_cascade_irq() function was calling the ARM-specific do_bad_IRQ() function which calls handle_bad_irq() after acquiring the desk->lock. Locking the cascaded IRQ desc is not needed for error reporting, so just call handle_bad_irq() directly. Signed-off-by: Catalin Marinas Tested-by: Marc Zyngier Cc: Russell King Cc: Thomas Gleixner Cc: Rob Herring --- drivers/irqchip/irq-gic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 0b1c0af646de..974f77c887b8 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -44,7 +44,6 @@ #include #include #include -#include #include "irqchip.h" @@ -324,7 +323,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) cascade_irq = irq_find_mapping(chip_data->domain, gic_irq); if (unlikely(gic_irq < 32 || gic_irq > 1020)) - do_bad_IRQ(cascade_irq, desc); + handle_bad_irq(cascade_irq, desc); else generic_handle_irq(cascade_irq); -- cgit v1.2.3 From c0114709ed85a5693eb74acdfa03d94f7f12e5b8 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 14 Jan 2013 18:05:37 +0000 Subject: irqchip: gic: Perform the gic_secondary_init() call via CPU notifier All the calls to gic_secondary_init() pass 0 as the first argument. Since this function is called on each CPU when starting, it can be done in a platform-independent way via a CPU notifier registered by the GIC code. Signed-off-by: Catalin Marinas Acked-by: Stephen Warren Acked-by: Viresh Kumar Acked-by: Santosh Shilimkar Acked-by: Rob Herring Acked-by: Simon Horman Tested-by: Simon Horman Acked-by: Srinidhi Kasagar Tested-by: Dinh Nguyen Acked-by: Nicolas Pitre Tested-by: Marc Zyngier Cc: Russell King Cc: Thomas Gleixner Cc: Kukjin Kim Cc: Sascha Hauer Cc: David Brown Cc: Bryan Huntsman Cc: Tony Lindgren Cc: Magnus Damm Cc: Shiraz Hashim Cc: Linus Walleij Cc: Will Deacon Cc: Kukjin Kim Cc: Barry Song --- arch/arm/mach-exynos/platsmp.c | 8 -------- arch/arm/mach-highbank/platsmp.c | 7 ------- arch/arm/mach-imx/platsmp.c | 12 ------------ arch/arm/mach-msm/platsmp.c | 8 -------- arch/arm/mach-omap2/omap-smp.c | 7 ------- arch/arm/mach-prima2/platsmp.c | 8 -------- arch/arm/mach-shmobile/smp-emev2.c | 7 ------- arch/arm/mach-shmobile/smp-r8a7779.c | 7 ------- arch/arm/mach-shmobile/smp-sh73a0.c | 7 ------- arch/arm/mach-socfpga/platsmp.c | 12 ------------ arch/arm/mach-spear13xx/platsmp.c | 8 -------- arch/arm/mach-tegra/platsmp.c | 8 -------- arch/arm/mach-ux500/platsmp.c | 8 -------- arch/arm/mach-virt/platsmp.c | 8 -------- arch/arm/plat-versatile/platsmp.c | 8 -------- drivers/irqchip/irq-gic.c | 28 +++++++++++++++++++++------- include/linux/irqchip/arm-gic.h | 1 - 17 files changed, 21 insertions(+), 131 deletions(-) (limited to 'drivers/irqchip') diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 60f7c5be057d..95e04bd5813f 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -75,13 +74,6 @@ static DEFINE_SPINLOCK(boot_lock); static void __cpuinit exynos_secondary_init(unsigned int cpu) { - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - /* * let the primary processor know we're out of the * pen, then head off into the C entry point diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c index 8797a7001720..a984573e0d02 100644 --- a/arch/arm/mach-highbank/platsmp.c +++ b/arch/arm/mach-highbank/platsmp.c @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -25,11 +24,6 @@ extern void secondary_startup(void); -static void __cpuinit highbank_secondary_init(unsigned int cpu) -{ - gic_secondary_init(0); -} - static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle) { highbank_set_cpu_jump(cpu, secondary_startup); @@ -67,7 +61,6 @@ static void __init highbank_smp_prepare_cpus(unsigned int max_cpus) struct smp_operations highbank_smp_ops __initdata = { .smp_init_cpus = highbank_smp_init_cpus, .smp_prepare_cpus = highbank_smp_prepare_cpus, - .smp_secondary_init = highbank_secondary_init, .smp_boot_secondary = highbank_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_die = highbank_cpu_die, diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 7c0b03f67b05..77e9a25ed0f6 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -52,16 +51,6 @@ void imx_scu_standby_enable(void) writel_relaxed(val, scu_base); } -static void __cpuinit imx_secondary_init(unsigned int cpu) -{ - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); -} - static int __cpuinit imx_boot_secondary(unsigned int cpu, struct task_struct *idle) { imx_set_cpu_jump(cpu, v7_secondary_startup); @@ -96,7 +85,6 @@ static void __init imx_smp_prepare_cpus(unsigned int max_cpus) struct smp_operations imx_smp_ops __initdata = { .smp_init_cpus = imx_smp_init_cpus, .smp_prepare_cpus = imx_smp_prepare_cpus, - .smp_secondary_init = imx_secondary_init, .smp_boot_secondary = imx_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_die = imx_cpu_die, diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index 42932865416a..00cdb0a5dac8 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -41,13 +40,6 @@ static inline int get_core_count(void) static void __cpuinit msm_secondary_init(unsigned int cpu) { - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - /* * let the primary processor know we're out of the * pen, then head off into the C entry point diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index d9727218dd0a..e7a449758ab5 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -66,13 +66,6 @@ static void __cpuinit omap4_secondary_init(unsigned int cpu) omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, 4, 0, 0, 0, 0, 0); - /* - * If any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - /* * Synchronise with the boot thread. */ diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c index 4b788310f6a6..c7c92e78f0cf 100644 --- a/arch/arm/mach-prima2/platsmp.c +++ b/arch/arm/mach-prima2/platsmp.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -48,13 +47,6 @@ void __init sirfsoc_map_scu(void) static void __cpuinit sirfsoc_secondary_init(unsigned int cpu) { - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - /* * let the primary processor know we're out of the * pen, then head off into the C entry point diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 953eb1f9388d..384e27dd3601 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -85,11 +84,6 @@ static int __maybe_unused emev2_cpu_kill(unsigned int cpu) } -static void __cpuinit emev2_secondary_init(unsigned int cpu) -{ - gic_secondary_init(0); -} - static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) { cpu = cpu_logical_map(cpu); @@ -124,7 +118,6 @@ static void __init emev2_smp_init_cpus(void) struct smp_operations emev2_smp_ops __initdata = { .smp_init_cpus = emev2_smp_init_cpus, .smp_prepare_cpus = emev2_smp_prepare_cpus, - .smp_secondary_init = emev2_secondary_init, .smp_boot_secondary = emev2_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_kill = emev2_cpu_kill, diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 3a4acf23edcf..994906560edd 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -132,11 +131,6 @@ static int __maybe_unused r8a7779_cpu_kill(unsigned int cpu) } -static void __cpuinit r8a7779_secondary_init(unsigned int cpu) -{ - gic_secondary_init(0); -} - static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) { struct r8a7779_pm_ch *ch = NULL; @@ -186,7 +180,6 @@ static void __init r8a7779_smp_init_cpus(void) struct smp_operations r8a7779_smp_ops __initdata = { .smp_init_cpus = r8a7779_smp_init_cpus, .smp_prepare_cpus = r8a7779_smp_prepare_cpus, - .smp_secondary_init = r8a7779_secondary_init, .smp_boot_secondary = r8a7779_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_kill = r8a7779_cpu_kill, diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index acb46a94ccdf..d0f9aca22477 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -59,11 +58,6 @@ static unsigned int __init sh73a0_get_core_count(void) return scu_get_core_count(scu_base); } -static void __cpuinit sh73a0_secondary_init(unsigned int cpu) -{ - gic_secondary_init(0); -} - static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle) { cpu = cpu_logical_map(cpu); @@ -138,7 +132,6 @@ static void sh73a0_cpu_die(unsigned int cpu) struct smp_operations sh73a0_smp_ops __initdata = { .smp_init_cpus = sh73a0_smp_init_cpus, .smp_prepare_cpus = sh73a0_smp_prepare_cpus, - .smp_secondary_init = sh73a0_secondary_init, .smp_boot_secondary = sh73a0_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_kill = sh73a0_cpu_kill, diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c index 84c60fa8daa0..ca14d1d5ac7f 100644 --- a/arch/arm/mach-socfpga/platsmp.c +++ b/arch/arm/mach-socfpga/platsmp.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -33,16 +32,6 @@ extern void __iomem *sys_manager_base_addr; extern void __iomem *rst_manager_base_addr; -static void __cpuinit socfpga_secondary_init(unsigned int cpu) -{ - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); -} - static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) { int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; @@ -109,7 +98,6 @@ static void socfpga_cpu_die(unsigned int cpu) struct smp_operations socfpga_smp_ops __initdata = { .smp_init_cpus = socfpga_smp_init_cpus, .smp_prepare_cpus = socfpga_smp_prepare_cpus, - .smp_secondary_init = socfpga_secondary_init, .smp_boot_secondary = socfpga_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_die = socfpga_cpu_die, diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c index af4ade61cd95..551c69c9a228 100644 --- a/arch/arm/mach-spear13xx/platsmp.c +++ b/arch/arm/mach-spear13xx/platsmp.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -27,13 +26,6 @@ static void __iomem *scu_base = IOMEM(VA_SCU_BASE); static void __cpuinit spear13xx_secondary_init(unsigned int cpu) { - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - /* * let the primary processor know we're out of the * pen, then head off into the C entry point diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 2c6b3d55213b..9348d3c496a9 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -44,13 +43,6 @@ static cpumask_t tegra_cpu_init_mask; static void __cpuinit tegra_secondary_init(unsigned int cpu) { - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - cpumask_set_cpu(cpu, &tegra_cpu_init_mask); } diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 18f7af339dc9..152b1309b9af 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -57,13 +56,6 @@ static DEFINE_SPINLOCK(boot_lock); static void __cpuinit ux500_secondary_init(unsigned int cpu) { - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - /* * let the primary processor know we're out of the * pen, then head off into the C entry point diff --git a/arch/arm/mach-virt/platsmp.c b/arch/arm/mach-virt/platsmp.c index 8badaabe70a1..f4143f5bfa5b 100644 --- a/arch/arm/mach-virt/platsmp.c +++ b/arch/arm/mach-virt/platsmp.c @@ -21,8 +21,6 @@ #include #include -#include - #include #include @@ -45,14 +43,8 @@ static int __cpuinit virt_boot_secondary(unsigned int cpu, return -ENODEV; } -static void __cpuinit virt_secondary_init(unsigned int cpu) -{ - gic_secondary_init(0); -} - struct smp_operations __initdata virt_smp_ops = { .smp_init_cpus = virt_smp_init_cpus, .smp_prepare_cpus = virt_smp_prepare_cpus, - .smp_secondary_init = virt_secondary_init, .smp_boot_secondary = virt_boot_secondary, }; diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c index f2ac15561778..1e1b2d769748 100644 --- a/arch/arm/plat-versatile/platsmp.c +++ b/arch/arm/plat-versatile/platsmp.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -36,13 +35,6 @@ static DEFINE_SPINLOCK(boot_lock); void __cpuinit versatile_secondary_init(unsigned int cpu) { - /* - * if any interrupts are already enabled for the primary - * core (e.g. timer irq), then they will not have been enabled - * for us: do so - */ - gic_secondary_init(0); - /* * let the primary processor know we're out of the * pen, then head off into the C entry point diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 974f77c887b8..add1fd84fc4b 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -699,6 +700,25 @@ static int gic_irq_domain_xlate(struct irq_domain *d, return 0; } +#ifdef CONFIG_SMP +static int __cpuinit gic_secondary_init(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + if (action == CPU_STARTING) + gic_cpu_init(&gic_data[0]); + return NOTIFY_OK; +} + +/* + * Notifier for enabling the GIC CPU interface. Set an arbitrarily high + * priority because the GIC needs to be up before the ARM generic timers. + */ +static struct notifier_block __cpuinitdata gic_cpu_notifier = { + .notifier_call = gic_secondary_init, + .priority = 100, +}; +#endif + const struct irq_domain_ops gic_irq_domain_ops = { .map = gic_irq_domain_map, .xlate = gic_irq_domain_xlate, @@ -789,6 +809,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, #ifdef CONFIG_SMP set_smp_cross_call(gic_raise_softirq); + register_cpu_notifier(&gic_cpu_notifier); #endif set_handle_irq(gic_handle_irq); @@ -799,13 +820,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic_pm_init(gic); } -void __cpuinit gic_secondary_init(unsigned int gic_nr) -{ - BUG_ON(gic_nr >= MAX_GIC_NR); - - gic_cpu_init(&gic_data[gic_nr]); -} - #ifdef CONFIG_OF static int gic_cnt __initdata = 0; diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 3fd8e4290a1c..3e203eb23cc7 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -65,7 +65,6 @@ extern struct irq_chip gic_arch_extn; void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, u32 offset, struct device_node *); -void gic_secondary_init(unsigned int); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); static inline void gic_init(unsigned int nr, int start, -- cgit v1.2.3 From 6a8e95b071ecf7357d294782b6ef4e707ce0fbbd Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 25 Mar 2013 21:34:51 +0800 Subject: ARM: mxs: move icoll driver into drivers/irqchip Move icoll.c into drivers/irqchip as irq-mxs.c, and along with the renaming, change the driver to use IRQCHIP_DECLARE. Signed-off-by: Shawn Guo --- arch/arm/mach-mxs/Makefile | 2 +- arch/arm/mach-mxs/icoll.c | 128 -------------------------------- arch/arm/mach-mxs/include/mach/common.h | 3 - arch/arm/mach-mxs/mach-mxs.c | 6 +- drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-mxs.c | 121 ++++++++++++++++++++++++++++++ include/linux/irqchip/mxs.h | 14 ++++ 7 files changed, 141 insertions(+), 134 deletions(-) delete mode 100644 arch/arm/mach-mxs/icoll.c create mode 100644 drivers/irqchip/irq-mxs.c create mode 100644 include/linux/irqchip/mxs.h (limited to 'drivers/irqchip') diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile index 76c336e6f5b5..b934603e2765 100644 --- a/arch/arm/mach-mxs/Makefile +++ b/arch/arm/mach-mxs/Makefile @@ -1,5 +1,5 @@ # Common support -obj-y := icoll.o ocotp.o system.o mm.o +obj-y := ocotp.o system.o mm.o obj-$(CONFIG_PM) += pm.o diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c deleted file mode 100644 index b4d620765cf1..000000000000 --- a/arch/arm/mach-mxs/icoll.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define HW_ICOLL_VECTOR 0x0000 -#define HW_ICOLL_LEVELACK 0x0010 -#define HW_ICOLL_CTRL 0x0020 -#define HW_ICOLL_STAT_OFFSET 0x0070 -#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10) -#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10) -#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004 -#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1 - -#define ICOLL_NUM_IRQS 128 - -static void __iomem *icoll_base; -static struct irq_domain *icoll_domain; - -static void icoll_ack_irq(struct irq_data *d) -{ - /* - * The Interrupt Collector is able to prioritize irqs. - * Currently only level 0 is used. So acking can use - * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally. - */ - __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0, - icoll_base + HW_ICOLL_LEVELACK); -} - -static void icoll_mask_irq(struct irq_data *d) -{ - __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, - icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq)); -} - -static void icoll_unmask_irq(struct irq_data *d) -{ - __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, - icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq)); -} - -static struct irq_chip mxs_icoll_chip = { - .irq_ack = icoll_ack_irq, - .irq_mask = icoll_mask_irq, - .irq_unmask = icoll_unmask_irq, -}; - -asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs) -{ - u32 irqnr; - - do { - irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET); - if (irqnr != 0x7f) { - __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR); - irqnr = irq_find_mapping(icoll_domain, irqnr); - handle_IRQ(irqnr, regs); - continue; - } - break; - } while (1); -} - -static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) -{ - irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq); - set_irq_flags(virq, IRQF_VALID); - - return 0; -} - -static struct irq_domain_ops icoll_irq_domain_ops = { - .map = icoll_irq_domain_map, - .xlate = irq_domain_xlate_onecell, -}; - -static void __init icoll_of_init(struct device_node *np, - struct device_node *interrupt_parent) -{ - icoll_base = of_iomap(np, 0); - WARN_ON(!icoll_base); - - /* - * Interrupt Collector reset, which initializes the priority - * for each irq to level 0. - */ - stmp_reset_block(icoll_base + HW_ICOLL_CTRL); - - icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS, - &icoll_irq_domain_ops, NULL); - WARN_ON(!icoll_domain); -} - -static const struct of_device_id icoll_of_match[] __initconst = { - {.compatible = "fsl,icoll", .data = icoll_of_init}, - { /* sentinel */ } -}; - -void __init icoll_init_irq(void) -{ - of_irq_init(icoll_of_match); -} diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h index e043c4735b5a..df2a4ef14dae 100644 --- a/arch/arm/mach-mxs/include/mach/common.h +++ b/arch/arm/mach-mxs/include/mach/common.h @@ -22,7 +22,4 @@ extern void mx23_map_io(void); extern int mx28_clocks_init(void); extern void mx28_map_io(void); -extern void icoll_init_irq(void); -extern void icoll_handle_irq(struct pt_regs *); - #endif /* __MACH_MXS_COMMON_H__ */ diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index c1c0fb414c28..10506381b446 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -469,7 +471,7 @@ static const char *imx28_dt_compat[] __initdata = { DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)") .map_io = mx23_map_io, - .init_irq = icoll_init_irq, + .init_irq = irqchip_init, .handle_irq = icoll_handle_irq, .init_time = imx23_timer_init, .init_machine = mxs_machine_init, @@ -479,7 +481,7 @@ MACHINE_END DT_MACHINE_START(IMX28, "Freescale i.MX28 (Device Tree)") .map_io = mx28_map_io, - .init_irq = icoll_init_irq, + .init_irq = irqchip_init, .handle_irq = icoll_handle_irq, .init_time = imx28_timer_init, .init_machine = mxs_machine_init, diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 98e3b87bdf1b..9d8f4f1c6e39 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o +obj-$(CONFIG_ARCH_MXS) += irq-mxs.o obj-$(CONFIG_METAG) += irq-metag-ext.o obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c new file mode 100644 index 000000000000..29889bbdcc6d --- /dev/null +++ b/drivers/irqchip/irq-mxs.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "irqchip.h" + +#define HW_ICOLL_VECTOR 0x0000 +#define HW_ICOLL_LEVELACK 0x0010 +#define HW_ICOLL_CTRL 0x0020 +#define HW_ICOLL_STAT_OFFSET 0x0070 +#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10) +#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10) +#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004 +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1 + +#define ICOLL_NUM_IRQS 128 + +static void __iomem *icoll_base; +static struct irq_domain *icoll_domain; + +static void icoll_ack_irq(struct irq_data *d) +{ + /* + * The Interrupt Collector is able to prioritize irqs. + * Currently only level 0 is used. So acking can use + * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally. + */ + __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0, + icoll_base + HW_ICOLL_LEVELACK); +} + +static void icoll_mask_irq(struct irq_data *d) +{ + __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, + icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq)); +} + +static void icoll_unmask_irq(struct irq_data *d) +{ + __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, + icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq)); +} + +static struct irq_chip mxs_icoll_chip = { + .irq_ack = icoll_ack_irq, + .irq_mask = icoll_mask_irq, + .irq_unmask = icoll_unmask_irq, +}; + +asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs) +{ + u32 irqnr; + + do { + irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET); + if (irqnr != 0x7f) { + __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR); + irqnr = irq_find_mapping(icoll_domain, irqnr); + handle_IRQ(irqnr, regs); + continue; + } + break; + } while (1); +} + +static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq); + set_irq_flags(virq, IRQF_VALID); + + return 0; +} + +static struct irq_domain_ops icoll_irq_domain_ops = { + .map = icoll_irq_domain_map, + .xlate = irq_domain_xlate_onecell, +}; + +static void __init icoll_of_init(struct device_node *np, + struct device_node *interrupt_parent) +{ + icoll_base = of_iomap(np, 0); + WARN_ON(!icoll_base); + + /* + * Interrupt Collector reset, which initializes the priority + * for each irq to level 0. + */ + stmp_reset_block(icoll_base + HW_ICOLL_CTRL); + + icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS, + &icoll_irq_domain_ops, NULL); + WARN_ON(!icoll_domain); +} +IRQCHIP_DECLARE(mxs, "fsl,icoll", icoll_of_init); diff --git a/include/linux/irqchip/mxs.h b/include/linux/irqchip/mxs.h new file mode 100644 index 000000000000..9039a538a919 --- /dev/null +++ b/include/linux/irqchip/mxs.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_IRQCHIP_MXS_H +#define __LINUX_IRQCHIP_MXS_H + +extern void icoll_handle_irq(struct pt_regs *); + +#endif -- cgit v1.2.3 From 46f101df788b38fafa08e85dcbf85d3bff6c1ea3 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 13 Mar 2013 15:05:15 +0530 Subject: irqchip: irq-gic: Fix checkpatch errors Fixes the following errors: ERROR: do not initialise statics to 0 or NULL ERROR: space required after that ',' (ctx:VxV) Signed-off-by: Sachin Kamat Signed-off-by: Olof Johansson --- drivers/irqchip/irq-gic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 644d72468423..80a4f7a7d7b8 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -127,7 +127,7 @@ static inline void gic_set_base_accessor(struct gic_chip_data *data, #else #define gic_data_dist_base(d) ((d)->dist_base.common_base) #define gic_data_cpu_base(d) ((d)->cpu_base.common_base) -#define gic_set_base_accessor(d,f) +#define gic_set_base_accessor(d, f) #endif static inline void __iomem *gic_dist_base(struct irq_data *d) @@ -807,7 +807,7 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr) } #ifdef CONFIG_OF -static int gic_cnt __initdata = 0; +static int gic_cnt __initdata; int __init gic_of_init(struct device_node *node, struct device_node *parent) { -- cgit v1.2.3 From bc895b5987dd5fad89c0e9693b38104679b647c4 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 2 Apr 2013 15:07:37 -0700 Subject: irqchip: vic: add include of linux/irq.h With the include of removed, the implicit include of linux/irq.h also disappeared. Add it back. Signed-off-by: Olof Johansson --- drivers/irqchip/irq-vic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index e38cb00ee784..884d11c7355f 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From f1dc6c4f77678979868fe220c6913890e13473d8 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Sun, 10 Mar 2013 15:54:46 +0100 Subject: irqchip: sunxi: Make use of the IRQCHIP_DECLARE macro This allows to remove some boilerplate code. At the same time, call the set_handle_irq function in the initialization function of the irqchip, so that we can remove it from the machine declaration. Signed-off-by: Maxime Ripard --- arch/arm/mach-sunxi/sunxi.c | 5 ++--- drivers/irqchip/irq-sunxi.c | 22 ++++++++++------------ include/linux/irqchip/sunxi.h | 27 --------------------------- 3 files changed, 12 insertions(+), 42 deletions(-) delete mode 100644 include/linux/irqchip/sunxi.h (limited to 'drivers/irqchip') diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index b26748d82045..c99ab1bdee4d 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c @@ -14,13 +14,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include @@ -104,8 +104,7 @@ static const char * const sunxi_board_dt_compat[] = { DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)") .init_machine = sunxi_dt_init, .map_io = sunxi_map_io, - .init_irq = sunxi_init_irq, - .handle_irq = sunxi_handle_irq, + .init_irq = irqchip_init, .restart = sunxi_restart, .init_time = sunxi_timer_init, .dt_compat = sunxi_board_dt_compat, diff --git a/drivers/irqchip/irq-sunxi.c b/drivers/irqchip/irq-sunxi.c index 10974fa42653..0fc49c577033 100644 --- a/drivers/irqchip/irq-sunxi.c +++ b/drivers/irqchip/irq-sunxi.c @@ -20,7 +20,10 @@ #include #include -#include +#include +#include + +#include "irqchip.h" #define SUNXI_IRQ_VECTOR_REG 0x00 #define SUNXI_IRQ_PROTECTION_REG 0x08 @@ -33,6 +36,8 @@ static void __iomem *sunxi_irq_base; static struct irq_domain *sunxi_irq_domain; +static asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs); + void sunxi_irq_ack(struct irq_data *irqd) { unsigned int irq = irqd_to_hwirq(irqd); @@ -125,20 +130,13 @@ static int __init sunxi_of_init(struct device_node *node, if (!sunxi_irq_domain) panic("%s: unable to create IRQ domain\n", node->full_name); - return 0; -} - -static struct of_device_id sunxi_irq_dt_ids[] __initconst = { - { .compatible = "allwinner,sunxi-ic", .data = sunxi_of_init }, - { } -}; + set_handle_irq(sunxi_handle_irq); -void __init sunxi_init_irq(void) -{ - of_irq_init(sunxi_irq_dt_ids); + return 0; } +IRQCHIP_DECLARE(allwinner_sunxi_ic, "allwinner,sunxi-ic", sunxi_of_init); -asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs) +static asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs) { u32 irq, hwirq; diff --git a/include/linux/irqchip/sunxi.h b/include/linux/irqchip/sunxi.h deleted file mode 100644 index 1fe2c2260e2b..000000000000 --- a/include/linux/irqchip/sunxi.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2012 Maxime Ripard - * - * Maxime Ripard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __LINUX_IRQCHIP_SUNXI_H -#define __LINUX_IRQCHIP_SUNXI_H - -#include - -extern void sunxi_init_irq(void); - -extern asmlinkage void __exception_irq_entry sunxi_handle_irq( - struct pt_regs *regs); - -#endif -- cgit v1.2.3 From d7fbc6ca35db027345a0e066c54b367e31d4fed3 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Sun, 24 Mar 2013 10:10:04 +0100 Subject: irqchip: sunxi: Rename sunxi to sun4i During the introduction of the Allwinner SoC platforms, sunxi was initially meant as a generic name for all the variants of the Allwinner SoC. It was ok at the time of the support of only the A10 and A13 that looks pretty much the same, but it's beginning to be troublesome with the future addition of the Allwinner A31 (sun6i) that is quite different, and would introduce some weird logic, where sunxi would actually mean in some case sun4i and sun5i but without sun6i... Moreover, it makes the compatible strings naming scheme not consistent with other architectures, where usually for this kind of compability, we just use the oldest SoC name that has this IP, so let's do just this. Signed-off-by: Maxime Ripard --- .../interrupt-controller/allwinner,sun4i-ic.txt | 104 ++++++++++++++ .../interrupt-controller/allwinner,sunxi-ic.txt | 104 -------------- drivers/irqchip/Makefile | 2 +- drivers/irqchip/irq-sun4i.c | 149 +++++++++++++++++++++ drivers/irqchip/irq-sunxi.c | 149 --------------------- 5 files changed, 254 insertions(+), 254 deletions(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt create mode 100644 drivers/irqchip/irq-sun4i.c delete mode 100644 drivers/irqchip/irq-sunxi.c (limited to 'drivers/irqchip') diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt new file mode 100644 index 000000000000..e7f4dc14eff2 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt @@ -0,0 +1,104 @@ +Allwinner Sunxi Interrupt Controller + +Required properties: + +- compatible : should be "allwinner,sun4i-ic" +- reg : Specifies base physical address and size of the registers. +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value shall be 1. + +The interrupt sources are as follows: + +0: ENMI +1: UART0 +2: UART1 +3: UART2 +4: UART3 +5: IR0 +6: IR1 +7: I2C0 +8: I2C1 +9: I2C2 +10: SPI0 +11: SPI1 +12: SPI2 +13: SPDIF +14: AC97 +15: TS +16: I2S +17: UART4 +18: UART5 +19: UART6 +20: UART7 +21: KEYPAD +22: TIMER0 +23: TIMER1 +24: TIMER2 +25: TIMER3 +26: CAN +27: DMA +28: PIO +29: TOUCH_PANEL +30: AUDIO_CODEC +31: LRADC +32: SDMC0 +33: SDMC1 +34: SDMC2 +35: SDMC3 +36: MEMSTICK +37: NAND +38: USB0 +39: USB1 +40: USB2 +41: SCR +42: CSI0 +43: CSI1 +44: LCDCTRL0 +45: LCDCTRL1 +46: MP +47: DEFEBE0 +48: DEFEBE1 +49: PMU +50: SPI3 +51: TZASC +52: PATA +53: VE +54: SS +55: EMAC +56: SATA +57: GPS +58: HDMI +59: TVE +60: ACE +61: TVD +62: PS2_0 +63: PS2_1 +64: USB3 +65: USB4 +66: PLE_PFM +67: TIMER4 +68: TIMER5 +69: GPU_GP +70: GPU_GPMMU +71: GPU_PP0 +72: GPU_PPMMU0 +73: GPU_PMU +74: GPU_RSV0 +75: GPU_RSV1 +76: GPU_RSV2 +77: GPU_RSV3 +78: GPU_RSV4 +79: GPU_RSV5 +80: GPU_RSV6 +82: SYNC_TIMER0 +83: SYNC_TIMER1 + +Example: + +intc: interrupt-controller { + compatible = "allwinner,sun4i-ic"; + reg = <0x01c20400 0x400>; + interrupt-controller; + #interrupt-cells = <2>; +}; diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt deleted file mode 100644 index 7f9fb85f5456..000000000000 --- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt +++ /dev/null @@ -1,104 +0,0 @@ -Allwinner Sunxi Interrupt Controller - -Required properties: - -- compatible : should be "allwinner,sunxi-ic" -- reg : Specifies base physical address and size of the registers. -- interrupt-controller : Identifies the node as an interrupt controller -- #interrupt-cells : Specifies the number of cells needed to encode an - interrupt source. The value shall be 1. - -The interrupt sources are as follows: - -0: ENMI -1: UART0 -2: UART1 -3: UART2 -4: UART3 -5: IR0 -6: IR1 -7: I2C0 -8: I2C1 -9: I2C2 -10: SPI0 -11: SPI1 -12: SPI2 -13: SPDIF -14: AC97 -15: TS -16: I2S -17: UART4 -18: UART5 -19: UART6 -20: UART7 -21: KEYPAD -22: TIMER0 -23: TIMER1 -24: TIMER2 -25: TIMER3 -26: CAN -27: DMA -28: PIO -29: TOUCH_PANEL -30: AUDIO_CODEC -31: LRADC -32: SDMC0 -33: SDMC1 -34: SDMC2 -35: SDMC3 -36: MEMSTICK -37: NAND -38: USB0 -39: USB1 -40: USB2 -41: SCR -42: CSI0 -43: CSI1 -44: LCDCTRL0 -45: LCDCTRL1 -46: MP -47: DEFEBE0 -48: DEFEBE1 -49: PMU -50: SPI3 -51: TZASC -52: PATA -53: VE -54: SS -55: EMAC -56: SATA -57: GPS -58: HDMI -59: TVE -60: ACE -61: TVD -62: PS2_0 -63: PS2_1 -64: USB3 -65: USB4 -66: PLE_PFM -67: TIMER4 -68: TIMER5 -69: GPU_GP -70: GPU_GPMMU -71: GPU_PP0 -72: GPU_PPMMU0 -73: GPU_PMU -74: GPU_RSV0 -75: GPU_RSV1 -76: GPU_RSV2 -77: GPU_RSV3 -78: GPU_RSV4 -79: GPU_RSV5 -80: GPU_RSV6 -82: SYNC_TIMER0 -83: SYNC_TIMER1 - -Example: - -intc: interrupt-controller { - compatible = "allwinner,sunxi-ic"; - reg = <0x01c20400 0x400>; - interrupt-controller; - #interrupt-cells = <2>; -}; diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 98e3b87bdf1b..54169650f55e 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o obj-$(CONFIG_METAG) += irq-metag-ext.o obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o -obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o +obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o obj-$(CONFIG_ARM_GIC) += irq-gic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c new file mode 100644 index 000000000000..b66d4ae06898 --- /dev/null +++ b/drivers/irqchip/irq-sun4i.c @@ -0,0 +1,149 @@ +/* + * Allwinner A1X SoCs IRQ chip driver. + * + * Copyright (C) 2012 Maxime Ripard + * + * Maxime Ripard + * + * Based on code from + * Allwinner Technology Co., Ltd. + * Benn Huang + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "irqchip.h" + +#define SUN4I_IRQ_VECTOR_REG 0x00 +#define SUN4I_IRQ_PROTECTION_REG 0x08 +#define SUN4I_IRQ_NMI_CTRL_REG 0x0c +#define SUN4I_IRQ_PENDING_REG(x) (0x10 + 0x4 * x) +#define SUN4I_IRQ_FIQ_PENDING_REG(x) (0x20 + 0x4 * x) +#define SUN4I_IRQ_ENABLE_REG(x) (0x40 + 0x4 * x) +#define SUN4I_IRQ_MASK_REG(x) (0x50 + 0x4 * x) + +static void __iomem *sun4i_irq_base; +static struct irq_domain *sun4i_irq_domain; + +static asmlinkage void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs); + +void sun4i_irq_ack(struct irq_data *irqd) +{ + unsigned int irq = irqd_to_hwirq(irqd); + unsigned int irq_off = irq % 32; + int reg = irq / 32; + u32 val; + + val = readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg)); + writel(val | (1 << irq_off), + sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg)); +} + +static void sun4i_irq_mask(struct irq_data *irqd) +{ + unsigned int irq = irqd_to_hwirq(irqd); + unsigned int irq_off = irq % 32; + int reg = irq / 32; + u32 val; + + val = readl(sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg)); + writel(val & ~(1 << irq_off), + sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg)); +} + +static void sun4i_irq_unmask(struct irq_data *irqd) +{ + unsigned int irq = irqd_to_hwirq(irqd); + unsigned int irq_off = irq % 32; + int reg = irq / 32; + u32 val; + + val = readl(sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg)); + writel(val | (1 << irq_off), + sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg)); +} + +static struct irq_chip sun4i_irq_chip = { + .name = "sun4i_irq", + .irq_ack = sun4i_irq_ack, + .irq_mask = sun4i_irq_mask, + .irq_unmask = sun4i_irq_unmask, +}; + +static int sun4i_irq_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(virq, &sun4i_irq_chip, + handle_level_irq); + set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); + + return 0; +} + +static struct irq_domain_ops sun4i_irq_ops = { + .map = sun4i_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static int __init sun4i_of_init(struct device_node *node, + struct device_node *parent) +{ + sun4i_irq_base = of_iomap(node, 0); + if (!sun4i_irq_base) + panic("%s: unable to map IC registers\n", + node->full_name); + + /* Disable all interrupts */ + writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(0)); + writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(1)); + writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(2)); + + /* Mask all the interrupts */ + writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(0)); + writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(1)); + writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(2)); + + /* Clear all the pending interrupts */ + writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0)); + writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(1)); + writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(2)); + + /* Enable protection mode */ + writel(0x01, sun4i_irq_base + SUN4I_IRQ_PROTECTION_REG); + + /* Configure the external interrupt source type */ + writel(0x00, sun4i_irq_base + SUN4I_IRQ_NMI_CTRL_REG); + + sun4i_irq_domain = irq_domain_add_linear(node, 3 * 32, + &sun4i_irq_ops, NULL); + if (!sun4i_irq_domain) + panic("%s: unable to create IRQ domain\n", node->full_name); + + set_handle_irq(sun4i_handle_irq); + + return 0; +} +IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-ic", sun4i_of_init); + +static asmlinkage void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) +{ + u32 irq, hwirq; + + hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; + while (hwirq != 0) { + irq = irq_find_mapping(sun4i_irq_domain, hwirq); + handle_IRQ(irq, regs); + hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; + } +} diff --git a/drivers/irqchip/irq-sunxi.c b/drivers/irqchip/irq-sunxi.c deleted file mode 100644 index 0fc49c577033..000000000000 --- a/drivers/irqchip/irq-sunxi.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Allwinner A1X SoCs IRQ chip driver. - * - * Copyright (C) 2012 Maxime Ripard - * - * Maxime Ripard - * - * Based on code from - * Allwinner Technology Co., Ltd. - * Benn Huang - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "irqchip.h" - -#define SUNXI_IRQ_VECTOR_REG 0x00 -#define SUNXI_IRQ_PROTECTION_REG 0x08 -#define SUNXI_IRQ_NMI_CTRL_REG 0x0c -#define SUNXI_IRQ_PENDING_REG(x) (0x10 + 0x4 * x) -#define SUNXI_IRQ_FIQ_PENDING_REG(x) (0x20 + 0x4 * x) -#define SUNXI_IRQ_ENABLE_REG(x) (0x40 + 0x4 * x) -#define SUNXI_IRQ_MASK_REG(x) (0x50 + 0x4 * x) - -static void __iomem *sunxi_irq_base; -static struct irq_domain *sunxi_irq_domain; - -static asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs); - -void sunxi_irq_ack(struct irq_data *irqd) -{ - unsigned int irq = irqd_to_hwirq(irqd); - unsigned int irq_off = irq % 32; - int reg = irq / 32; - u32 val; - - val = readl(sunxi_irq_base + SUNXI_IRQ_PENDING_REG(reg)); - writel(val | (1 << irq_off), - sunxi_irq_base + SUNXI_IRQ_PENDING_REG(reg)); -} - -static void sunxi_irq_mask(struct irq_data *irqd) -{ - unsigned int irq = irqd_to_hwirq(irqd); - unsigned int irq_off = irq % 32; - int reg = irq / 32; - u32 val; - - val = readl(sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); - writel(val & ~(1 << irq_off), - sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); -} - -static void sunxi_irq_unmask(struct irq_data *irqd) -{ - unsigned int irq = irqd_to_hwirq(irqd); - unsigned int irq_off = irq % 32; - int reg = irq / 32; - u32 val; - - val = readl(sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); - writel(val | (1 << irq_off), - sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); -} - -static struct irq_chip sunxi_irq_chip = { - .name = "sunxi_irq", - .irq_ack = sunxi_irq_ack, - .irq_mask = sunxi_irq_mask, - .irq_unmask = sunxi_irq_unmask, -}; - -static int sunxi_irq_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) -{ - irq_set_chip_and_handler(virq, &sunxi_irq_chip, - handle_level_irq); - set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); - - return 0; -} - -static struct irq_domain_ops sunxi_irq_ops = { - .map = sunxi_irq_map, - .xlate = irq_domain_xlate_onecell, -}; - -static int __init sunxi_of_init(struct device_node *node, - struct device_node *parent) -{ - sunxi_irq_base = of_iomap(node, 0); - if (!sunxi_irq_base) - panic("%s: unable to map IC registers\n", - node->full_name); - - /* Disable all interrupts */ - writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(0)); - writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(1)); - writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(2)); - - /* Mask all the interrupts */ - writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(0)); - writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(1)); - writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(2)); - - /* Clear all the pending interrupts */ - writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(0)); - writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(1)); - writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(2)); - - /* Enable protection mode */ - writel(0x01, sunxi_irq_base + SUNXI_IRQ_PROTECTION_REG); - - /* Configure the external interrupt source type */ - writel(0x00, sunxi_irq_base + SUNXI_IRQ_NMI_CTRL_REG); - - sunxi_irq_domain = irq_domain_add_linear(node, 3 * 32, - &sunxi_irq_ops, NULL); - if (!sunxi_irq_domain) - panic("%s: unable to create IRQ domain\n", node->full_name); - - set_handle_irq(sunxi_handle_irq); - - return 0; -} -IRQCHIP_DECLARE(allwinner_sunxi_ic, "allwinner,sunxi-ic", sunxi_of_init); - -static asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs) -{ - u32 irq, hwirq; - - hwirq = readl(sunxi_irq_base + SUNXI_IRQ_VECTOR_REG) >> 2; - while (hwirq != 0) { - irq = irq_find_mapping(sunxi_irq_domain, hwirq); - handle_IRQ(irq, regs); - hwirq = readl(sunxi_irq_base + SUNXI_IRQ_VECTOR_REG) >> 2; - } -} -- cgit v1.2.3