aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.h2
-rw-r--r--arch/arm/mach-mvebu/platsmp.c8
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c24
-rw-r--r--drivers/irqchip/irq-orion.c4
4 files changed, 24 insertions, 14 deletions
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index 237c86b83390..c3465f5b1250 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -20,8 +20,6 @@
20 20
21#define ARMADA_XP_MAX_CPUS 4 21#define ARMADA_XP_MAX_CPUS 4
22 22
23void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq);
24void armada_xp_mpic_smp_cpu_init(void);
25void armada_xp_secondary_startup(void); 23void armada_xp_secondary_startup(void);
26extern struct smp_operations armada_xp_smp_ops; 24extern struct smp_operations armada_xp_smp_ops;
27#endif 25#endif
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index e01ae51bee56..32bf78e80c48 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 int ret, hw_cpu; 75 int ret, hw_cpu;
@@ -98,8 +93,6 @@ static void __init armada_xp_smp_init_cpus(void)
98 93
99 if (ncores == 0 || ncores > ARMADA_XP_MAX_CPUS) 94 if (ncores == 0 || ncores > ARMADA_XP_MAX_CPUS)
100 panic("Invalid number of CPUs in DT\n"); 95 panic("Invalid number of CPUs in DT\n");
101
102 set_smp_cross_call(armada_mpic_send_doorbell);
103} 96}
104 97
105static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) 98static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
@@ -132,7 +125,6 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
132struct smp_operations armada_xp_smp_ops __initdata = { 125struct smp_operations armada_xp_smp_ops __initdata = {
133 .smp_init_cpus = armada_xp_smp_init_cpus, 126 .smp_init_cpus = armada_xp_smp_init_cpus,
134 .smp_prepare_cpus = armada_xp_smp_prepare_cpus, 127 .smp_prepare_cpus = armada_xp_smp_prepare_cpus,
135 .smp_secondary_init = armada_xp_secondary_init,
136 .smp_boot_secondary = armada_xp_boot_secondary, 128 .smp_boot_secondary = armada_xp_boot_secondary,
137#ifdef CONFIG_HOTPLUG_CPU 129#ifdef CONFIG_HOTPLUG_CPU
138 .cpu_die = armada_xp_cpu_die, 130 .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 41be897df8d5..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>
@@ -315,7 +316,8 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
315} 316}
316 317
317#ifdef CONFIG_SMP 318#ifdef CONFIG_SMP
318void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq) 319static void armada_mpic_send_doorbell(const struct cpumask *mask,
320 unsigned int irq)
319{ 321{
320 int cpu; 322 int cpu;
321 unsigned long map = 0; 323 unsigned long map = 0;
@@ -335,7 +337,7 @@ void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq)
335 ARMADA_370_XP_SW_TRIG_INT_OFFS); 337 ARMADA_370_XP_SW_TRIG_INT_OFFS);
336} 338}
337 339
338void armada_xp_mpic_smp_cpu_init(void) 340static void armada_xp_mpic_smp_cpu_init(void)
339{ 341{
340 /* Clear pending IPIs */ 342 /* Clear pending IPIs */
341 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);
@@ -347,6 +349,20 @@ void armada_xp_mpic_smp_cpu_init(void)
347 /* Unmask IPI interrupt */ 349 /* Unmask IPI interrupt */
348 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);
349} 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
350#endif /* CONFIG_SMP */ 366#endif /* CONFIG_SMP */
351 367
352static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { 368static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
@@ -511,6 +527,10 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
511 if (parent_irq <= 0) { 527 if (parent_irq <= 0) {
512 irq_set_default_host(armada_370_xp_mpic_domain); 528 irq_set_default_host(armada_370_xp_mpic_domain);
513 set_handle_irq(armada_370_xp_handle_irq); 529 set_handle_irq(armada_370_xp_handle_irq);
530#ifdef CONFIG_SMP
531 set_smp_cross_call(armada_mpic_send_doorbell);
532 register_cpu_notifier(&armada_370_xp_mpic_cpu_notifier);
533#endif
514 } else { 534 } else {
515 irq_set_chained_handler(parent_irq, 535 irq_set_chained_handler(parent_irq,
516 armada_370_xp_mpic_handle_cascade_irq); 536 armada_370_xp_mpic_handle_cascade_irq);
diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c
index e25f246cd2fb..34d18b48bb78 100644
--- a/drivers/irqchip/irq-orion.c
+++ b/drivers/irqchip/irq-orion.c
@@ -42,7 +42,7 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs)
42 u32 stat = readl_relaxed(gc->reg_base + ORION_IRQ_CAUSE) & 42 u32 stat = readl_relaxed(gc->reg_base + ORION_IRQ_CAUSE) &
43 gc->mask_cache; 43 gc->mask_cache;
44 while (stat) { 44 while (stat) {
45 u32 hwirq = ffs(stat) - 1; 45 u32 hwirq = __fls(stat);
46 u32 irq = irq_find_mapping(orion_irq_domain, 46 u32 irq = irq_find_mapping(orion_irq_domain,
47 gc->irq_base + hwirq); 47 gc->irq_base + hwirq);
48 handle_IRQ(irq, regs); 48 handle_IRQ(irq, regs);
@@ -117,7 +117,7 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc)
117 gc->mask_cache; 117 gc->mask_cache;
118 118
119 while (stat) { 119 while (stat) {
120 u32 hwirq = ffs(stat) - 1; 120 u32 hwirq = __fls(stat);
121 121
122 generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq)); 122 generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq));
123 stat &= ~(1 << hwirq); 123 stat &= ~(1 << hwirq);