From edd96900cfd5f993b448dcdcb0e13090701554ae Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sun, 28 Oct 2012 10:05:40 +0100 Subject: [PATCH 01/20] irqchip: add to the directories part of the IRQ subsystem in MAINTAINERS Now that the drivers/irqchip/ directory is getting more code, it needs a maintainer. The obvious maintainer for it is Thomas Gleixner, who is maintaining the overall IRQ subsystem. So we add drivers/irqchip/ in the list of directories that are part of the IRQ subsystem. Signed-off-by: Thomas Petazzoni Reviewed-by: Rob Herring --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 915564eda145..b4dea6cee2a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4209,6 +4209,7 @@ M: Thomas Gleixner S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core F: kernel/irq/ +F: drivers/irqchip/ IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY) M: Benjamin Herrenschmidt From f6e916b82022cba67bdd0ec7df84e2bce2ef3f73 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 20 Nov 2012 23:00:52 +0100 Subject: [PATCH 02/20] irqchip: add basic infrastructure With the recent creation of the drivers/irqchip/ directory, it is desirable to move irq controller drivers here. At the moment, the only driver here is irq-bcm2835, the driver for the irq controller found in the ARM BCM2835 SoC, present in Rasberry Pi systems. This irq controller driver was exporting its initialization function and its irq handling function through a header file in . When proposing to also move another irq controller driver in drivers/irqchip, Rob Herring raised the very valid point that moving things to drivers/irqchip was good in order to remove more stuff from arch/arm, but if it means adding gazillions of headers files in include/linux/irqchip/, it would not be very nice. So, upon the suggestion of Rob Herring and Arnd Bergmann, this commit introduces a small infrastructure that defines a central irqchip_init() function in drivers/irqchip/irqchip.c, which is meant to be called as the ->init_irq() callback of ARM platforms. This function calls of_irq_init() with an array of match strings and init functions generated from a special linker section. Note that the irq controller driver initialization function is responsible for setting the global handle_arch_irq() variable, so that ARM platforms no longer have to define the ->handle_irq field in their DT_MACHINE structure. A global header, is also added to expose the single irqchip_init() function to the reset of the kernel. A further commit moves the BCM2835 irq controller driver to this new small infrastructure, therefore removing the include/linux/irqchip/ directory. Signed-off-by: Thomas Petazzoni Reviewed-by: Stephen Warren Reviewed-by: Rob Herring Acked-by: Arnd Bergmann [rob.herring: reword commit message to reflect use of linker sections.] Signed-off-by: Rob Herring --- drivers/irqchip/Kconfig | 4 ++++ drivers/irqchip/Makefile | 2 ++ drivers/irqchip/irqchip.c | 30 ++++++++++++++++++++++++++++++ drivers/irqchip/irqchip.h | 29 +++++++++++++++++++++++++++++ include/asm-generic/vmlinux.lds.h | 12 +++++++++++- include/linux/irqchip.h | 16 ++++++++++++++++ 6 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 drivers/irqchip/irqchip.c create mode 100644 drivers/irqchip/irqchip.h create mode 100644 include/linux/irqchip.h diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 62ca575701d3..93dfd8fa66c7 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -1,3 +1,7 @@ +config IRQCHIP + def_bool y + depends on OF_IRQ + config VERSATILE_FPGA_IRQ bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index bf4609a5bd9d..29b78c9449c8 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -1,3 +1,5 @@ +obj-$(CONFIG_IRQCHIP) += irqchip.o + obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c new file mode 100644 index 000000000000..f496afce29de --- /dev/null +++ b/drivers/irqchip/irqchip.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2012 Thomas Petazzoni + * + * Thomas Petazzoni + * + * 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 "irqchip.h" + +/* + * This special of_device_id is the sentinel at the end of the + * of_device_id[] array of all irqchips. It is automatically placed at + * the end of the array by the linker, thanks to being part of a + * special section. + */ +static const struct of_device_id +irqchip_of_match_end __used __section(__irqchip_of_end); + +extern struct of_device_id __irqchip_begin[]; + +void __init irqchip_init(void) +{ + of_irq_init(__irqchip_begin); +} diff --git a/drivers/irqchip/irqchip.h b/drivers/irqchip/irqchip.h new file mode 100644 index 000000000000..e445ba2d6add --- /dev/null +++ b/drivers/irqchip/irqchip.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 Thomas Petazzoni + * + * Thomas Petazzoni + * + * 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. + */ + +#ifndef _IRQCHIP_H +#define _IRQCHIP_H + +/* + * This macro must be used by the different irqchip drivers to declare + * the association between their DT compatible string and their + * initialization function. + * + * @name: name that must be unique accross all IRQCHIP_DECLARE of the + * same file. + * @compstr: compatible string of the irqchip driver + * @fn: initialization function + */ +#define IRQCHIP_DECLARE(name,compstr,fn) \ + static const struct of_device_id irqchip_of_match_##name \ + __used __section(__irqchip_of_table) \ + = { .compatible = compstr, .data = fn } + +#endif diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index d1ea7ce0b4cb..c80c599897b9 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -149,6 +149,15 @@ #define TRACE_SYSCALLS() #endif +#ifdef CONFIG_IRQCHIP +#define IRQCHIP_OF_MATCH_TABLE() \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__irqchip_begin) = .; \ + *(__irqchip_of_table) \ + *(__irqchip_of_end) +#else +#define IRQCHIP_OF_MATCH_TABLE() +#endif #define KERNEL_DTB() \ STRUCT_ALIGN(); \ @@ -493,7 +502,8 @@ DEV_DISCARD(init.rodata) \ CPU_DISCARD(init.rodata) \ MEM_DISCARD(init.rodata) \ - KERNEL_DTB() + KERNEL_DTB() \ + IRQCHIP_OF_MATCH_TABLE() #define INIT_TEXT \ *(.init.text) \ diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h new file mode 100644 index 000000000000..e0006f1d35a0 --- /dev/null +++ b/include/linux/irqchip.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012 Thomas Petazzoni + * + * Thomas Petazzoni + * + * 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. + */ + +#ifndef _LINUX_IRQCHIP_H +#define _LINUX_IRQCHIP_H + +void irqchip_init(void); + +#endif From 73171d15873e9246c82aeda5c7fd8ec11cb97be9 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 20 Nov 2012 23:00:53 +0100 Subject: [PATCH 03/20] arm: add set_handle_irq() to register the parent IRQ controller handler function In order to allow irqchip drivers to register their IRQ handling function as the parent IRQ controller handler function, we provide a convenience function. This will avoid poking directly into the global handle_arch_irq variable. Suggested by Arnd Bergmann. Signed-off-by: Thomas Petazzoni [Rob Herring: remove warning. 1st one to initialize wins.] Signed-off-by: Rob Herring Acked-by: Olof Johansson --- arch/arm/include/asm/mach/irq.h | 1 + arch/arm/kernel/irq.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h index 15cb035309f7..18c883023339 100644 --- a/arch/arm/include/asm/mach/irq.h +++ b/arch/arm/include/asm/mach/irq.h @@ -22,6 +22,7 @@ extern int show_fiq_list(struct seq_file *, int); #ifdef CONFIG_MULTI_IRQ_HANDLER extern void (*handle_arch_irq)(struct pt_regs *); +extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); #endif /* diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 896165096d6a..8e4ef4c83a74 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -117,6 +117,16 @@ void __init init_IRQ(void) machine_desc->init_irq(); } +#ifdef CONFIG_MULTI_IRQ_HANDLER +void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) +{ + if (handle_arch_irq) + return; + + handle_arch_irq = handle_irq; +} +#endif + #ifdef CONFIG_SPARSE_IRQ int __init arch_probe_nr_irqs(void) { From 902ef5d77aeaff43bce8d3ce55c442a12eb71819 Mon Sep 17 00:00:00 2001 From: Srinidhi Kasagar Date: Fri, 2 Nov 2012 18:14:34 +0530 Subject: [PATCH 04/20] ARM: mach-ux500: use SGI0 to wake up the other core The commit 7d28e3eaa1a8e951251b942e7220f97114bd73b9 ("ARM: ux500: wake secondary cpu via resched") makes use of schedule IPI to wake up the secondary core which seems incorrect. Rather use SGI0. Signed-off-by: srinidhi kasagar Signed-off-by: Rob Herring Acked-by: Olof Johansson --- arch/arm/mach-ux500/platsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 3db7782f3afb..79531f1dffbc 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -91,7 +91,7 @@ static int __cpuinit ux500_boot_secondary(unsigned int cpu, struct task_struct * */ write_pen_release(cpu_logical_map(cpu)); - smp_send_reschedule(cpu); + gic_raise_softirq(cpumask_of(cpu), 0); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { From 428fef8ad855c03b9f61c226c63df61bb43dc3e1 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 1 Nov 2012 06:23:14 -0500 Subject: [PATCH 05/20] ARM: GIC: remove assembly ifdefs from gic.h With multi irq handler and all GIC users converted to it, we don't need asm/hardware/gic.h to be included in assembly. Clean-up ifdefs and unnecessary includes. Signed-off-by: Rob Herring Acked-by: Olof Johansson --- arch/arm/include/asm/hardware/gic.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 4b1ce6cd477f..fc596989241b 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -10,8 +10,6 @@ #ifndef __ASM_ARM_HARDWARE_GIC_H #define __ASM_ARM_HARDWARE_GIC_H -#include - #define GIC_CPU_CTRL 0x00 #define GIC_CPU_PRIMASK 0x04 #define GIC_CPU_BINPOINT 0x08 @@ -32,8 +30,6 @@ #define GIC_DIST_CONFIG 0xc00 #define GIC_DIST_SOFTINT 0xf00 -#ifndef __ASSEMBLY__ -#include struct device_node; extern struct irq_chip gic_arch_extn; @@ -53,5 +49,3 @@ static inline void gic_init(unsigned int nr, int start, } #endif - -#endif From b1cffebf1029c87e1f1984d48463ee21093a6bc7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 26 Nov 2012 15:05:48 -0600 Subject: [PATCH 06/20] ARM: GIC: remove direct use of gic_raise_softirq In preparation of moving gic code to drivers/irqchip, remove the direct platform dependencies on gic_raise_softirq. Move the setup of smp_cross_call into the gic code and use arch_send_wakeup_ipi_mask function to trigger wake-up IPIs. Signed-off-by: Rob Herring Cc: Russell King Cc: Kukjin Kim Cc: Sascha Hauer Cc: David Brown Cc: Daniel Walker Cc: Bryan Huntsman Acked-by: Tony Lindgren Acked-by: Santosh Shilimkar Cc: Paul Mundt Cc: Magnus Damm Acked-by: Viresh Kumar Cc: Shiraz Hashim Acked-by: Stephen Warren Cc: Srinidhi Kasagar Cc: Linus Walleij Acked-by: Olof Johansson --- arch/arm/common/gic.c | 45 +++++++++++++++-------------- arch/arm/include/asm/hardware/gic.h | 1 - arch/arm/kernel/smp.c | 3 +- arch/arm/mach-exynos/platsmp.c | 4 +-- arch/arm/mach-highbank/platsmp.c | 4 +-- arch/arm/mach-imx/platsmp.c | 2 -- arch/arm/mach-msm/platsmp.c | 4 +-- arch/arm/mach-omap2/omap-smp.c | 4 +-- arch/arm/mach-realview/platsmp.c | 3 -- arch/arm/mach-shmobile/platsmp.c | 2 -- arch/arm/mach-shmobile/smp-emev2.c | 2 +- arch/arm/mach-socfpga/platsmp.c | 2 -- arch/arm/mach-spear13xx/platsmp.c | 2 -- arch/arm/mach-tegra/platsmp.c | 2 -- arch/arm/mach-ux500/platsmp.c | 4 +-- arch/arm/mach-vexpress/ct-ca9x4.c | 2 -- arch/arm/mach-vexpress/platsmp.c | 2 -- arch/arm/plat-versatile/platsmp.c | 2 +- 18 files changed, 33 insertions(+), 57 deletions(-) diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 36ae03a3f5d1..788658cca960 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -617,6 +617,27 @@ static void __init gic_pm_init(struct gic_chip_data *gic) } #endif +#ifdef CONFIG_SMP +void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) +{ + int cpu; + unsigned long map = 0; + + /* Convert our logical CPU mask into a physical one. */ + for_each_cpu(cpu, mask) + map |= 1 << cpu_logical_map(cpu); + + /* + * Ensure that stores to Normal memory are visible to the + * other CPUs before issuing the IPI. + */ + dsb(); + + /* this always happens on GIC0 */ + writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); +} +#endif + static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { @@ -743,6 +764,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, if (WARN_ON(!gic->domain)) return; +#ifdef CONFIG_SMP + set_smp_cross_call(gic_raise_softirq); +#endif gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); gic_cpu_init(gic); @@ -756,27 +780,6 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr) gic_cpu_init(&gic_data[gic_nr]); } -#ifdef CONFIG_SMP -void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) -{ - int cpu; - unsigned long map = 0; - - /* Convert our logical CPU mask into a physical one. */ - for_each_cpu(cpu, mask) - map |= gic_cpu_map[cpu]; - - /* - * Ensure that stores to Normal memory are visible to the - * other CPUs before issuing the IPI. - */ - dsb(); - - /* this always happens on GIC0 */ - writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); -} -#endif - #ifdef CONFIG_OF static int gic_cnt __initdata = 0; diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index fc596989241b..cfd3a7eb453e 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -40,7 +40,6 @@ int gic_of_init(struct device_node *node, struct device_node *parent); void gic_secondary_init(unsigned int); void gic_handle_irq(struct pt_regs *regs); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); -void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); static inline void gic_init(unsigned int nr, int start, void __iomem *dist , void __iomem *cpu) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 84f4cbf652e5..3fc96db2a4b6 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -416,7 +416,8 @@ static void (*smp_cross_call)(const struct cpumask *, unsigned int); void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) { - smp_cross_call = fn; + if (!smp_cross_call) + smp_cross_call = fn; } void arch_send_call_function_ipi_mask(const struct cpumask *mask) diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index c5c840e947b8..5898f826b070 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -149,7 +149,7 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct __raw_writel(virt_to_phys(exynos4_secondary_startup), cpu_boot_reg(phys_cpu)); - gic_raise_softirq(cpumask_of(cpu), 0); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); if (pen_release == -1) break; @@ -190,8 +190,6 @@ static void __init exynos_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c index 4ecc864ac8b9..e8d3c5f0171f 100644 --- a/arch/arm/mach-highbank/platsmp.c +++ b/arch/arm/mach-highbank/platsmp.c @@ -33,7 +33,7 @@ static void __cpuinit highbank_secondary_init(unsigned int cpu) static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle) { highbank_set_cpu_jump(cpu, secondary_startup); - gic_raise_softirq(cpumask_of(cpu), 0); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); return 0; } @@ -56,8 +56,6 @@ static void __init highbank_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init highbank_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 3777b805b76b..8e720574fe9f 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -71,8 +71,6 @@ static void __init imx_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } void imx_smp_prepare(void) diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index 7ed69b69c87c..e27e57b12274 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@ -115,7 +115,7 @@ static int __cpuinit msm_boot_secondary(unsigned int cpu, struct task_struct *id * the boot monitor to read the system wide flags register, * and branch to the address found there. */ - gic_raise_softirq(cpumask_of(cpu), 0); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { @@ -153,8 +153,6 @@ static void __init msm_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init msm_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index cd42d921940d..668172a5f9ea 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -157,7 +157,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * booted = true; } - gic_raise_softirq(cpumask_of(cpu), 0); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); /* * Now the secondary core is starting up let it run its @@ -231,8 +231,6 @@ static void __init omap4_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index 300f7064465d..98e3052b7933 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -59,8 +58,6 @@ static void __init realview_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init realview_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index ed8d2351915e..d393c527ae8f 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -26,6 +26,4 @@ void __init shmobile_smp_init_cpus(unsigned int ncores) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index f67456286280..6262d6776f5d 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -100,7 +100,7 @@ static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct * /* Tell ROM loader about our vector (in headsmp.S) */ emev2_set_boot_vector(__pa(shmobile_secondary_vector)); - gic_raise_softirq(cpumask_of(cpu), 0); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); return 0; } diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c index 68dd1b69512a..98a22200104f 100644 --- a/arch/arm/mach-socfpga/platsmp.c +++ b/arch/arm/mach-socfpga/platsmp.c @@ -83,8 +83,6 @@ static void __init socfpga_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c index 2eaa3fa7b432..27e3f69c6274 100644 --- a/arch/arm/mach-spear13xx/platsmp.c +++ b/arch/arm/mach-spear13xx/platsmp.c @@ -104,8 +104,6 @@ static void __init spear13xx_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 1b926df99c4b..d8e6754e77a9 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -159,8 +159,6 @@ static void __init tegra_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 79531f1dffbc..fa07d4de6d85 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -91,7 +91,7 @@ static int __cpuinit ux500_boot_secondary(unsigned int cpu, struct task_struct * */ write_pen_release(cpu_logical_map(cpu)); - gic_raise_softirq(cpumask_of(cpu), 0); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { @@ -155,8 +155,6 @@ static void __init ux500_smp_init_cpus(void) for (i = 0; i < ncores; i++) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init ux500_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 60838ddb8564..0ad050f5c652 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -182,8 +182,6 @@ static void __init ct_ca9x4_init_cpu_map(void) for (i = 0; i < ncores; ++i) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init ct_ca9x4_smp_enable(unsigned int max_cpus) diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index c5d70de9bb4e..3bc0e38d70f7 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c @@ -128,8 +128,6 @@ static void __init vexpress_dt_smp_init_cpus(void) for (i = 0; i < ncores; ++i) set_cpu_possible(i, true); - - set_smp_cross_call(gic_raise_softirq); } static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c index 04ca4937d8ca..2336024d1b76 100644 --- a/arch/arm/plat-versatile/platsmp.c +++ b/arch/arm/plat-versatile/platsmp.c @@ -79,7 +79,7 @@ int __cpuinit versatile_boot_secondary(unsigned int cpu, struct task_struct *idl * the boot monitor to read the system wide flags register, * and branch to the address found there. */ - gic_raise_softirq(cpumask_of(cpu), 0); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { From cfed7d6014589f51a092463f9c4aca3683fffdb8 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sat, 3 Nov 2012 12:59:51 -0500 Subject: [PATCH 07/20] ARM: GIC: set handle_arch_irq in GIC initialization Set handle_arch_irq to gic_handle_irq. Only the first GIC initialized can setup the handler. Signed-off-by: Rob Herring Acked-by: Olof Johansson --- arch/arm/common/gic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 788658cca960..4b4ccf31e083 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -767,6 +767,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, #ifdef CONFIG_SMP set_smp_cross_call(gic_raise_softirq); #endif + + set_handle_irq(gic_handle_irq); + gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); gic_cpu_init(gic); From 1d5cc604f42ff1acdec0407247b2f720135ba0c2 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 20 Nov 2012 19:52:32 -0600 Subject: [PATCH 08/20] ARM: remove mach .handle_irq for GIC users Now that the GIC initialization sets up the handle_arch_irq pointer, we can remove it for all machines and make it static. Signed-off-by: Rob Herring Cc: Russell King Cc: Anton Vorontsov Cc: Kyungmin Park Cc: Sascha Hauer Cc: David Brown Cc: Daniel Walker Cc: Bryan Huntsman Acked-by: Tony Lindgren Cc: Paul Mundt Cc: Magnus Damm Cc: Dinh Nguyen Cc: Shiraz Hashim Acked-by: Stephen Warren Cc: Srinidhi Kasagar Cc: Linus Walleij Acked-by: Viresh Kumar Acked-by: Kukjin Kim Acked-by: Shawn Guo Acked-by: Olof Johansson Acked-by: Arnd Bergmann --- arch/arm/common/gic.c | 2 +- arch/arm/include/asm/hardware/gic.h | 1 - arch/arm/kernel/smp_twd.c | 1 - arch/arm/mach-bcm/board_bcm.c | 1 - arch/arm/mach-cns3xxx/cns3420vb.c | 2 -- arch/arm/mach-exynos/mach-armlex4210.c | 2 -- arch/arm/mach-exynos/mach-exynos4-dt.c | 2 -- arch/arm/mach-exynos/mach-exynos5-dt.c | 2 -- arch/arm/mach-exynos/mach-nuri.c | 2 -- arch/arm/mach-exynos/mach-origen.c | 2 -- arch/arm/mach-exynos/mach-smdk4x12.c | 3 --- arch/arm/mach-exynos/mach-smdkv310.c | 3 --- arch/arm/mach-exynos/mach-universal_c210.c | 2 -- arch/arm/mach-exynos/mct.c | 1 - arch/arm/mach-highbank/highbank.c | 1 - arch/arm/mach-imx/common.h | 1 - arch/arm/mach-imx/mach-imx6q.c | 1 - arch/arm/mach-msm/board-dt-8660.c | 1 - arch/arm/mach-msm/board-dt-8960.c | 1 - arch/arm/mach-msm/timer.c | 1 - arch/arm/mach-omap2/board-4430sdp.c | 1 - arch/arm/mach-omap2/board-generic.c | 3 --- arch/arm/mach-omap2/board-omap4panda.c | 1 - arch/arm/mach-realview/core.c | 1 - arch/arm/mach-realview/realview_eb.c | 1 - arch/arm/mach-realview/realview_pb1176.c | 1 - arch/arm/mach-realview/realview_pb11mp.c | 1 - arch/arm/mach-realview/realview_pba8.c | 1 - arch/arm/mach-realview/realview_pbx.c | 1 - arch/arm/mach-shmobile/board-ag5evm.c | 1 - arch/arm/mach-shmobile/board-kota2.c | 1 - arch/arm/mach-shmobile/board-kzm9d.c | 2 -- arch/arm/mach-shmobile/board-kzm9g.c | 1 - arch/arm/mach-shmobile/board-marzen.c | 2 -- arch/arm/mach-shmobile/platsmp.c | 1 - arch/arm/mach-shmobile/setup-emev2.c | 1 - arch/arm/mach-socfpga/socfpga.c | 1 - arch/arm/mach-spear13xx/spear1310.c | 1 - arch/arm/mach-spear13xx/spear1340.c | 1 - arch/arm/mach-tegra/board-dt-tegra20.c | 3 --- arch/arm/mach-tegra/board-dt-tegra30.c | 2 -- arch/arm/mach-ux500/board-mop500.c | 5 ----- arch/arm/mach-ux500/cpu-db8500.c | 2 -- arch/arm/mach-vexpress/platsmp.c | 1 - arch/arm/mach-vexpress/v2m.c | 2 -- arch/arm/mach-zynq/common.c | 1 - 46 files changed, 1 insertion(+), 70 deletions(-) diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 4b4ccf31e083..90eebfeae039 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -276,7 +276,7 @@ static int gic_set_wake(struct irq_data *d, unsigned int on) #define gic_set_wake NULL #endif -asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) +static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) { u32 irqstat, irqnr; struct gic_chip_data *gic = &gic_data[0]; diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index cfd3a7eb453e..2a16e0305bd1 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -38,7 +38,6 @@ void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, u32 offset, struct device_node *); int gic_of_init(struct device_node *node, struct device_node *parent); void gic_secondary_init(unsigned int); -void gic_handle_irq(struct pt_regs *regs); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); static inline void gic_init(unsigned int nr, int start, diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 49f335d301ba..dc9bb0146665 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -24,7 +24,6 @@ #include #include -#include /* set up by the platform code */ static void __iomem *twd_base; diff --git a/arch/arm/mach-bcm/board_bcm.c b/arch/arm/mach-bcm/board_bcm.c index 3a62f1b1cabc..6ad83d7f9517 100644 --- a/arch/arm/mach-bcm/board_bcm.c +++ b/arch/arm/mach-bcm/board_bcm.c @@ -53,5 +53,4 @@ DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor") .timer = &timer, .init_machine = board_init, .dt_compat = bcm11351_dt_compat, - .handle_irq = gic_handle_irq, MACHINE_END diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c index ae305397003c..26f36d7efecd 100644 --- a/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/arch/arm/mach-cns3xxx/cns3420vb.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -251,7 +250,6 @@ MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board") .map_io = cns3420_map_io, .init_irq = cns3xxx_init_irq, .timer = &cns3xxx_timer, - .handle_irq = gic_handle_irq, .init_machine = cns3420_init, .restart = cns3xxx_restart, MACHINE_END diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c index b938f9fc1dd1..a11a36fc7bf5 100644 --- a/arch/arm/mach-exynos/mach-armlex4210.c +++ b/arch/arm/mach-exynos/mach-armlex4210.c @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -201,7 +200,6 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210") .smp = smp_ops(exynos_smp_ops), .init_irq = exynos4_init_irq, .map_io = armlex4210_map_io, - .handle_irq = gic_handle_irq, .init_machine = armlex4210_machine_init, .init_late = exynos_init_late, .timer = &exynos4_timer, diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c index 92757ff817ae..34c45b6c8b2c 100644 --- a/arch/arm/mach-exynos/mach-exynos4-dt.c +++ b/arch/arm/mach-exynos/mach-exynos4-dt.c @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -107,7 +106,6 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)") .smp = smp_ops(exynos_smp_ops), .init_irq = exynos4_init_irq, .map_io = exynos4_dt_map_io, - .handle_irq = gic_handle_irq, .init_machine = exynos4_dt_machine_init, .init_late = exynos_init_late, .timer = &exynos4_timer, diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index e99d3d8f2bcf..3a3bee463c46 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -179,7 +178,6 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)") .init_irq = exynos5_init_irq, .smp = smp_ops(exynos_smp_ops), .map_io = exynos5_dt_map_io, - .handle_irq = gic_handle_irq, .init_machine = exynos5_dt_machine_init, .init_late = exynos_init_late, .timer = &exynos4_timer, diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index 27d4ed8b116e..55f8183e1d6f 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -39,7 +39,6 @@ #include #include -#include #include #include @@ -1379,7 +1378,6 @@ MACHINE_START(NURI, "NURI") .smp = smp_ops(exynos_smp_ops), .init_irq = exynos4_init_irq, .map_io = nuri_map_io, - .handle_irq = gic_handle_irq, .init_machine = nuri_machine_init, .init_late = exynos_init_late, .timer = &exynos4_timer, diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index 5e34b9c16196..45cda369923e 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -29,7 +29,6 @@ #include #include -#include #include #include