aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2015-03-03 05:43:16 -0500
committerJason Cooper <jason@lakedaemon.net>2015-03-08 00:21:57 -0500
commit28da06dfd9e4b04577c517f9c4b52aaa73e3d1c7 (patch)
tree2ee36377c66b305d989a8c1f3cfdc1295ab97199
parent2c299de527ca2f39d231a257c00d09c498bb8447 (diff)
irqchip: armada-370-xp: Enable the PMU interrupts
In order to let the Performance Monitoring Unit interrupts flowing in the MPIC, we need to unmask these interrupts in the Coherency Fabric Local Interrupt Mask Register. Since this register is a CPU-local register, unmasking this interrupt needs to be done on the boot CPU when the driver initializes, but also on the secondary CPU when they are brought up. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Link: https://lkml.kernel.org/r/1425379400-4346-4-git-send-email-maxime.ripard@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index ea57fba263cf..b36373c019ba 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -38,6 +38,8 @@
38/* Interrupt Controller Registers Map */ 38/* Interrupt Controller Registers Map */
39#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) 39#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48)
40#define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) 40#define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C)
41#define ARMADA_370_XP_INT_FABRIC_MASK_OFFS (0x54)
42#define ARMADA_370_XP_INT_CAUSE_PERF(cpu) (1 << cpu)
41 43
42#define ARMADA_370_XP_INT_CONTROL (0x00) 44#define ARMADA_370_XP_INT_CONTROL (0x00)
43#define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30) 45#define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30)
@@ -56,6 +58,7 @@
56#define ARMADA_370_XP_MAX_PER_CPU_IRQS (28) 58#define ARMADA_370_XP_MAX_PER_CPU_IRQS (28)
57 59
58#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5) 60#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5)
61#define ARMADA_370_XP_FABRIC_IRQ (3)
59 62
60#define IPI_DOORBELL_START (0) 63#define IPI_DOORBELL_START (0)
61#define IPI_DOORBELL_END (8) 64#define IPI_DOORBELL_END (8)
@@ -81,6 +84,7 @@ static inline bool is_percpu_irq(irq_hw_number_t irq)
81{ 84{
82 switch (irq) { 85 switch (irq) {
83 case ARMADA_370_XP_TIMER0_PER_CPU_IRQ: 86 case ARMADA_370_XP_TIMER0_PER_CPU_IRQ:
87 case ARMADA_370_XP_FABRIC_IRQ:
84 return true; 88 return true;
85 default: 89 default:
86 return false; 90 return false;
@@ -340,6 +344,15 @@ static void armada_xp_mpic_smp_cpu_init(void)
340 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 344 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
341} 345}
342 346
347static void armada_xp_mpic_perf_init(void)
348{
349 unsigned long cpuid = cpu_logical_map(smp_processor_id());
350
351 /* Enable Performance Counter Overflow interrupts */
352 writel(ARMADA_370_XP_INT_CAUSE_PERF(cpuid),
353 per_cpu_int_base + ARMADA_370_XP_INT_FABRIC_MASK_OFFS);
354}
355
343#ifdef CONFIG_SMP 356#ifdef CONFIG_SMP
344static void armada_mpic_send_doorbell(const struct cpumask *mask, 357static void armada_mpic_send_doorbell(const struct cpumask *mask,
345 unsigned int irq) 358 unsigned int irq)
@@ -365,8 +378,10 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask,
365static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, 378static int armada_xp_mpic_secondary_init(struct notifier_block *nfb,
366 unsigned long action, void *hcpu) 379 unsigned long action, void *hcpu)
367{ 380{
368 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) 381 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) {
382 armada_xp_mpic_perf_init();
369 armada_xp_mpic_smp_cpu_init(); 383 armada_xp_mpic_smp_cpu_init();
384 }
370 385
371 return NOTIFY_OK; 386 return NOTIFY_OK;
372} 387}
@@ -379,8 +394,10 @@ static struct notifier_block armada_370_xp_mpic_cpu_notifier = {
379static int mpic_cascaded_secondary_init(struct notifier_block *nfb, 394static int mpic_cascaded_secondary_init(struct notifier_block *nfb,
380 unsigned long action, void *hcpu) 395 unsigned long action, void *hcpu)
381{ 396{
382 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) 397 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) {
398 armada_xp_mpic_perf_init();
383 enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); 399 enable_percpu_irq(parent_irq, IRQ_TYPE_NONE);
400 }
384 401
385 return NOTIFY_OK; 402 return NOTIFY_OK;
386} 403}
@@ -389,7 +406,6 @@ static struct notifier_block mpic_cascaded_cpu_notifier = {
389 .notifier_call = mpic_cascaded_secondary_init, 406 .notifier_call = mpic_cascaded_secondary_init,
390 .priority = 100, 407 .priority = 100,
391}; 408};
392
393#endif /* CONFIG_SMP */ 409#endif /* CONFIG_SMP */
394 410
395static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { 411static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
@@ -599,6 +615,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
599 BUG_ON(!armada_370_xp_mpic_domain); 615 BUG_ON(!armada_370_xp_mpic_domain);
600 616
601 /* Setup for the boot CPU */ 617 /* Setup for the boot CPU */
618 armada_xp_mpic_perf_init();
602 armada_xp_mpic_smp_cpu_init(); 619 armada_xp_mpic_smp_cpu_init();
603 620
604 armada_370_xp_msi_init(node, main_int_res.start); 621 armada_370_xp_msi_init(node, main_int_res.start);