aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2014-05-30 16:18:18 -0400
committerJason Cooper <jason@lakedaemon.net>2014-06-20 20:39:04 -0400
commitb73842b75646da3810d6e1e161f223a288c64bd8 (patch)
tree180670b2241d76a3815a2494918b6e6346eb2873
parent7171511eaec5bf23fb06078f59784a3a0626b38f (diff)
irqchip: armada-370-xp: Mask all interrupts during initialization.
Until now, the irq-armada-370-xp irqchip driver was not masking all interrupts at initialization. While in most cases this is not a problem because the bootloader has probably masked all interrupts, it becomes a problem when you use kexec: you're in kernel A, with many interrupts enabled, and then kexec into kernel B, without going through the bootloader. So during the boot process, if an interrupt occurs while the corresponding driver has not been loaded, you would get spurious interrupts. This commit fixes that by ensuring all interrupts are properly masked when the irqchip driver is initialized. Note that interrupt masking takes place at two level: at the global level (main_int_base) and at the per-CPU level (per_cpu_int_base). Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Link: https://lkml.kernel.org/r/1401481098-23326-6-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index c887e6eebc41..574aba0eba4e 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -334,6 +334,15 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask,
334 334
335static void armada_xp_mpic_smp_cpu_init(void) 335static void armada_xp_mpic_smp_cpu_init(void)
336{ 336{
337 u32 control;
338 int nr_irqs, i;
339
340 control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
341 nr_irqs = (control >> 2) & 0x3ff;
342
343 for (i = 0; i < nr_irqs; i++)
344 writel(i, per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS);
345
337 /* Clear pending IPIs */ 346 /* Clear pending IPIs */
338 writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); 347 writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
339 348
@@ -474,7 +483,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
474 struct device_node *parent) 483 struct device_node *parent)
475{ 484{
476 struct resource main_int_res, per_cpu_int_res; 485 struct resource main_int_res, per_cpu_int_res;
477 int parent_irq; 486 int parent_irq, nr_irqs, i;
478 u32 control; 487 u32 control;
479 488
480 BUG_ON(of_address_to_resource(node, 0, &main_int_res)); 489 BUG_ON(of_address_to_resource(node, 0, &main_int_res));
@@ -496,9 +505,13 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
496 BUG_ON(!per_cpu_int_base); 505 BUG_ON(!per_cpu_int_base);
497 506
498 control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); 507 control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
508 nr_irqs = (control >> 2) & 0x3ff;
509
510 for (i = 0; i < nr_irqs; i++)
511 writel(i, main_int_base + ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS);
499 512
500 armada_370_xp_mpic_domain = 513 armada_370_xp_mpic_domain =
501 irq_domain_add_linear(node, (control >> 2) & 0x3ff, 514 irq_domain_add_linear(node, nr_irqs,
502 &armada_370_xp_mpic_irq_ops, NULL); 515 &armada_370_xp_mpic_irq_ops, NULL);
503 516
504 BUG_ON(!armada_370_xp_mpic_domain); 517 BUG_ON(!armada_370_xp_mpic_domain);