aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2014-04-14 09:54:02 -0400
committerJason Cooper <jason@lakedaemon.net>2014-05-08 10:42:00 -0400
commitd7df84b3cecad4c768e4065d1d61b2f8fd02b7fa (patch)
tree64b55219237723b95291719c0fbe9a3f42efe9cf
parentef37d337e1d37bd84ccaa5811a8d1f00f8b3677c (diff)
irqchip: irq-armada-370-xp: Use cpu notifier to initialize secondary CPUs
Some irqchip initialization must be done on secondary CPUs. On mvebu platforms, this is currently achieved by having the arch/arm/mach-mvebu/platsmp.c code directly call into a function exported by the irqchip driver, which isn't really nice. This commit changes this by using the same solution as the one used in the GIC driver: the irqchip driver registers a CPU notifier, which is used to do the secondary CPU IRQ initialization. This way, the irqchip driver is completely autonomous, and the function no longer needs to be exposed from the irqchip driver to the SoC code. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Link: https://lkml.kernel.org/r/1397483648-26611-6-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.h1
-rw-r--r--arch/arm/mach-mvebu/platsmp.c6
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c18
3 files changed, 17 insertions, 8 deletions
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index cd57c78af271..c3465f5b1250 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -20,7 +20,6 @@
20 20
21#define ARMADA_XP_MAX_CPUS 4 21#define ARMADA_XP_MAX_CPUS 4
22 22
23void armada_xp_mpic_smp_cpu_init(void);
24void armada_xp_secondary_startup(void); 23void armada_xp_secondary_startup(void);
25extern struct smp_operations armada_xp_smp_ops; 24extern struct smp_operations armada_xp_smp_ops;
26#endif 25#endif
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index 6f06f6ddb51e..e43727f391f7 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -70,11 +70,6 @@ static void __init set_secondary_cpus_clock(void)
70 } 70 }
71} 71}
72 72
73static void armada_xp_secondary_init(unsigned int cpu)
74{
75 armada_xp_mpic_smp_cpu_init();
76}
77
78static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle) 73static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
79{ 74{
80 pr_info("Booting CPU %d\n", cpu); 75 pr_info("Booting CPU %d\n", cpu);
@@ -122,7 +117,6 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
122struct smp_operations armada_xp_smp_ops __initdata = { 117struct smp_operations armada_xp_smp_ops __initdata = {
123 .smp_init_cpus = armada_xp_smp_init_cpus, 118 .smp_init_cpus = armada_xp_smp_init_cpus,
124 .smp_prepare_cpus = armada_xp_smp_prepare_cpus, 119 .smp_prepare_cpus = armada_xp_smp_prepare_cpus,
125 .smp_secondary_init = armada_xp_secondary_init,
126 .smp_boot_secondary = armada_xp_boot_secondary, 120 .smp_boot_secondary = armada_xp_boot_secondary,
127#ifdef CONFIG_HOTPLUG_CPU 121#ifdef CONFIG_HOTPLUG_CPU
128 .cpu_die = armada_xp_cpu_die, 122 .cpu_die = armada_xp_cpu_die,
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 727566216e24..71f77848bc23 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -19,6 +19,7 @@
19#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/irqchip/chained_irq.h> 21#include <linux/irqchip/chained_irq.h>
22#include <linux/cpu.h>
22#include <linux/io.h> 23#include <linux/io.h>
23#include <linux/of_address.h> 24#include <linux/of_address.h>
24#include <linux/of_irq.h> 25#include <linux/of_irq.h>
@@ -336,7 +337,7 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask,
336 ARMADA_370_XP_SW_TRIG_INT_OFFS); 337 ARMADA_370_XP_SW_TRIG_INT_OFFS);
337} 338}
338 339
339void armada_xp_mpic_smp_cpu_init(void) 340static void armada_xp_mpic_smp_cpu_init(void)
340{ 341{
341 /* Clear pending IPIs */ 342 /* Clear pending IPIs */
342 writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); 343 writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
@@ -348,6 +349,20 @@ void armada_xp_mpic_smp_cpu_init(void)
348 /* Unmask IPI interrupt */ 349 /* Unmask IPI interrupt */
349 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 350 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
350} 351}
352
353static int armada_xp_mpic_secondary_init(struct notifier_block *nfb,
354 unsigned long action, void *hcpu)
355{
356 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
357 armada_xp_mpic_smp_cpu_init();
358 return NOTIFY_OK;
359}
360
361static struct notifier_block armada_370_xp_mpic_cpu_notifier = {
362 .notifier_call = armada_xp_mpic_secondary_init,
363 .priority = 100,
364};
365
351#endif /* CONFIG_SMP */ 366#endif /* CONFIG_SMP */
352 367
353static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { 368static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
@@ -514,6 +529,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
514 set_handle_irq(armada_370_xp_handle_irq); 529 set_handle_irq(armada_370_xp_handle_irq);
515#ifdef CONFIG_SMP 530#ifdef CONFIG_SMP
516 set_smp_cross_call(armada_mpic_send_doorbell); 531 set_smp_cross_call(armada_mpic_send_doorbell);
532 register_cpu_notifier(&armada_370_xp_mpic_cpu_notifier);
517#endif 533#endif
518 } else { 534 } else {
519 irq_set_chained_handler(parent_irq, 535 irq_set_chained_handler(parent_irq,