Skip to content

Commit c770881

Browse files
author
Marc Zyngier
committed
irqchip/apple-aic: Wire PMU interrupts
Add the necessary code to configure and P and E-core PMU interrupts with their respective affinities. When such an interrupt fires, map it onto the right pseudo-interrupt. Reviewed-by: Hector Martin <marcan@marcan.st> Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent a5e8801 commit c770881

1 file changed

Lines changed: 22 additions & 12 deletions

File tree

drivers/irqchip/irq-apple-aic.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@
155155
#define SYS_IMP_APL_UPMSR_EL1 sys_reg(3, 7, 15, 6, 4)
156156
#define UPMSR_IACT BIT(0)
157157

158-
#define AIC_NR_FIQ 4
158+
#define AIC_NR_FIQ 6
159159
#define AIC_NR_SWIPI 32
160160

161161
/*
@@ -415,16 +415,15 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
415415
aic_irqc->nr_hw + AIC_TMR_EL02_VIRT);
416416
}
417417

418-
if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) ==
419-
(FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) {
420-
/*
421-
* Not supported yet, let's figure out how to handle this when
422-
* we implement these proprietary performance counters. For now,
423-
* just mask it and move on.
424-
*/
425-
pr_err_ratelimited("PMC FIQ fired. Masking.\n");
426-
sysreg_clear_set_s(SYS_IMP_APL_PMCR0_EL1, PMCR0_IMODE | PMCR0_IACT,
427-
FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF));
418+
if (read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & PMCR0_IACT) {
419+
int irq;
420+
if (cpumask_test_cpu(smp_processor_id(),
421+
&aic_irqc->fiq_aff[AIC_CPU_PMU_P]->aff))
422+
irq = AIC_CPU_PMU_P;
423+
else
424+
irq = AIC_CPU_PMU_E;
425+
generic_handle_domain_irq(aic_irqc->hw_domain,
426+
aic_irqc->nr_hw + irq);
428427
}
429428

430429
if (FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_IMP_APL_UPMCR0_EL1)) == UPMCR0_IMODE_FIQ &&
@@ -464,7 +463,18 @@ static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
464463
handle_fasteoi_irq, NULL, NULL);
465464
irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
466465
} else {
467-
irq_set_percpu_devid(irq);
466+
int fiq = hw - ic->nr_hw;
467+
468+
switch (fiq) {
469+
case AIC_CPU_PMU_P:
470+
case AIC_CPU_PMU_E:
471+
irq_set_percpu_devid_partition(irq, &ic->fiq_aff[fiq]->aff);
472+
break;
473+
default:
474+
irq_set_percpu_devid(irq);
475+
break;
476+
}
477+
468478
irq_domain_set_info(id, irq, hw, &fiq_chip, id->host_data,
469479
handle_percpu_devid_irq, NULL, NULL);
470480
}

0 commit comments

Comments
 (0)