|
@@ -25,7 +25,9 @@
|
|
|
#include <asm/mach/arch.h>
|
|
|
#include <asm/exception.h>
|
|
|
#include <asm/smp_plat.h>
|
|
|
-#include <asm/hardware/cache-l2x0.h>
|
|
|
+#include <asm/mach/irq.h>
|
|
|
+
|
|
|
+#include "irqchip.h"
|
|
|
|
|
|
/* Interrupt Controller Registers Map */
|
|
|
#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48)
|
|
@@ -46,7 +48,9 @@
|
|
|
|
|
|
#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5)
|
|
|
|
|
|
-#define ACTIVE_DOORBELLS (8)
|
|
|
+#define IPI_DOORBELL_START (0)
|
|
|
+#define IPI_DOORBELL_END (8)
|
|
|
+#define IPI_DOORBELL_MASK 0xFF
|
|
|
|
|
|
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
|
|
|
|
|
@@ -190,7 +194,7 @@ void armada_xp_mpic_smp_cpu_init(void)
|
|
|
writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
|
|
|
|
|
|
/* Enable first 8 IPIs */
|
|
|
- writel((1 << ACTIVE_DOORBELLS) - 1, per_cpu_int_base +
|
|
|
+ writel(IPI_DOORBELL_MASK, per_cpu_int_base +
|
|
|
ARMADA_370_XP_IN_DRBEL_MSK_OFFS);
|
|
|
|
|
|
/* Unmask IPI interrupt */
|
|
@@ -203,46 +207,8 @@ static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
|
|
|
.xlate = irq_domain_xlate_onecell,
|
|
|
};
|
|
|
|
|
|
-static int __init armada_370_xp_mpic_of_init(struct device_node *node,
|
|
|
- struct device_node *parent)
|
|
|
-{
|
|
|
- u32 control;
|
|
|
-
|
|
|
- main_int_base = of_iomap(node, 0);
|
|
|
- per_cpu_int_base = of_iomap(node, 1);
|
|
|
-
|
|
|
- BUG_ON(!main_int_base);
|
|
|
- BUG_ON(!per_cpu_int_base);
|
|
|
-
|
|
|
- control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
|
|
|
-
|
|
|
- armada_370_xp_mpic_domain =
|
|
|
- irq_domain_add_linear(node, (control >> 2) & 0x3ff,
|
|
|
- &armada_370_xp_mpic_irq_ops, NULL);
|
|
|
-
|
|
|
- if (!armada_370_xp_mpic_domain)
|
|
|
- panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n");
|
|
|
-
|
|
|
- irq_set_default_host(armada_370_xp_mpic_domain);
|
|
|
-
|
|
|
-#ifdef CONFIG_SMP
|
|
|
- armada_xp_mpic_smp_cpu_init();
|
|
|
-
|
|
|
- /*
|
|
|
- * Set the default affinity from all CPUs to the boot cpu.
|
|
|
- * This is required since the MPIC doesn't limit several CPUs
|
|
|
- * from acknowledging the same interrupt.
|
|
|
- */
|
|
|
- cpumask_clear(irq_default_affinity);
|
|
|
- cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
|
|
|
-
|
|
|
-#endif
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-asmlinkage void __exception_irq_entry armada_370_xp_handle_irq(struct pt_regs
|
|
|
- *regs)
|
|
|
+static asmlinkage void __exception_irq_entry
|
|
|
+armada_370_xp_handle_irq(struct pt_regs *regs)
|
|
|
{
|
|
|
u32 irqstat, irqnr;
|
|
|
|
|
@@ -267,13 +233,14 @@ asmlinkage void __exception_irq_entry armada_370_xp_handle_irq(struct pt_regs
|
|
|
|
|
|
ipimask = readl_relaxed(per_cpu_int_base +
|
|
|
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
|
|
|
- & 0xFF;
|
|
|
+ & IPI_DOORBELL_MASK;
|
|
|
|
|
|
- writel(0x0, per_cpu_int_base +
|
|
|
+ writel(~IPI_DOORBELL_MASK, per_cpu_int_base +
|
|
|
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
|
|
|
|
|
|
/* Handle all pending doorbells */
|
|
|
- for (ipinr = 0; ipinr < ACTIVE_DOORBELLS; ipinr++) {
|
|
|
+ for (ipinr = IPI_DOORBELL_START;
|
|
|
+ ipinr < IPI_DOORBELL_END; ipinr++) {
|
|
|
if (ipimask & (0x1 << ipinr))
|
|
|
handle_IPI(ipinr, regs);
|
|
|
}
|
|
@@ -284,15 +251,44 @@ asmlinkage void __exception_irq_entry armada_370_xp_handle_irq(struct pt_regs
|
|
|
} while (1);
|
|
|
}
|
|
|
|
|
|
-static const struct of_device_id mpic_of_match[] __initconst = {
|
|
|
- {.compatible = "marvell,mpic", .data = armada_370_xp_mpic_of_init},
|
|
|
- {},
|
|
|
-};
|
|
|
-
|
|
|
-void __init armada_370_xp_init_irq(void)
|
|
|
+static int __init armada_370_xp_mpic_of_init(struct device_node *node,
|
|
|
+ struct device_node *parent)
|
|
|
{
|
|
|
- of_irq_init(mpic_of_match);
|
|
|
-#ifdef CONFIG_CACHE_L2X0
|
|
|
- l2x0_of_init(0, ~0UL);
|
|
|
+ u32 control;
|
|
|
+
|
|
|
+ main_int_base = of_iomap(node, 0);
|
|
|
+ per_cpu_int_base = of_iomap(node, 1);
|
|
|
+
|
|
|
+ BUG_ON(!main_int_base);
|
|
|
+ BUG_ON(!per_cpu_int_base);
|
|
|
+
|
|
|
+ control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
|
|
|
+
|
|
|
+ armada_370_xp_mpic_domain =
|
|
|
+ irq_domain_add_linear(node, (control >> 2) & 0x3ff,
|
|
|
+ &armada_370_xp_mpic_irq_ops, NULL);
|
|
|
+
|
|
|
+ if (!armada_370_xp_mpic_domain)
|
|
|
+ panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n");
|
|
|
+
|
|
|
+ irq_set_default_host(armada_370_xp_mpic_domain);
|
|
|
+
|
|
|
+#ifdef CONFIG_SMP
|
|
|
+ armada_xp_mpic_smp_cpu_init();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set the default affinity from all CPUs to the boot cpu.
|
|
|
+ * This is required since the MPIC doesn't limit several CPUs
|
|
|
+ * from acknowledging the same interrupt.
|
|
|
+ */
|
|
|
+ cpumask_clear(irq_default_affinity);
|
|
|
+ cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
|
|
|
+
|
|
|
#endif
|
|
|
+
|
|
|
+ set_handle_irq(armada_370_xp_handle_irq);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
+
|
|
|
+IRQCHIP_DECLARE(armada_370_xp_mpic, "marvell,mpic", armada_370_xp_mpic_of_init);
|