Commit d7df84b3 authored by Thomas Petazzoni's avatar Thomas Petazzoni Committed by Jason Cooper

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: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1397483648-26611-6-git-send-email-thomas.petazzoni@free-electrons.comSigned-off-by: default avatarJason Cooper <jason@lakedaemon.net>
parent ef37d337
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#define ARMADA_XP_MAX_CPUS 4 #define ARMADA_XP_MAX_CPUS 4
void armada_xp_mpic_smp_cpu_init(void);
void armada_xp_secondary_startup(void); void armada_xp_secondary_startup(void);
extern struct smp_operations armada_xp_smp_ops; extern struct smp_operations armada_xp_smp_ops;
#endif #endif
......
...@@ -70,11 +70,6 @@ static void __init set_secondary_cpus_clock(void) ...@@ -70,11 +70,6 @@ static void __init set_secondary_cpus_clock(void)
} }
} }
static void armada_xp_secondary_init(unsigned int cpu)
{
armada_xp_mpic_smp_cpu_init();
}
static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle) static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
{ {
pr_info("Booting CPU %d\n", cpu); pr_info("Booting CPU %d\n", cpu);
...@@ -122,7 +117,6 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) ...@@ -122,7 +117,6 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
struct smp_operations armada_xp_smp_ops __initdata = { struct smp_operations armada_xp_smp_ops __initdata = {
.smp_init_cpus = armada_xp_smp_init_cpus, .smp_init_cpus = armada_xp_smp_init_cpus,
.smp_prepare_cpus = armada_xp_smp_prepare_cpus, .smp_prepare_cpus = armada_xp_smp_prepare_cpus,
.smp_secondary_init = armada_xp_secondary_init,
.smp_boot_secondary = armada_xp_boot_secondary, .smp_boot_secondary = armada_xp_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
.cpu_die = armada_xp_cpu_die, .cpu_die = armada_xp_cpu_die,
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqchip/chained_irq.h> #include <linux/irqchip/chained_irq.h>
#include <linux/cpu.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
...@@ -336,7 +337,7 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask, ...@@ -336,7 +337,7 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask,
ARMADA_370_XP_SW_TRIG_INT_OFFS); ARMADA_370_XP_SW_TRIG_INT_OFFS);
} }
void armada_xp_mpic_smp_cpu_init(void) static void armada_xp_mpic_smp_cpu_init(void)
{ {
/* Clear pending IPIs */ /* Clear pending IPIs */
writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); 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,6 +349,20 @@ void armada_xp_mpic_smp_cpu_init(void)
/* Unmask IPI interrupt */ /* Unmask IPI interrupt */
writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
} }
static int armada_xp_mpic_secondary_init(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
armada_xp_mpic_smp_cpu_init();
return NOTIFY_OK;
}
static struct notifier_block armada_370_xp_mpic_cpu_notifier = {
.notifier_call = armada_xp_mpic_secondary_init,
.priority = 100,
};
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { static 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,6 +529,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
set_handle_irq(armada_370_xp_handle_irq); set_handle_irq(armada_370_xp_handle_irq);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
set_smp_cross_call(armada_mpic_send_doorbell); set_smp_cross_call(armada_mpic_send_doorbell);
register_cpu_notifier(&armada_370_xp_mpic_cpu_notifier);
#endif #endif
} else { } else {
irq_set_chained_handler(parent_irq, irq_set_chained_handler(parent_irq,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment