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>
This commit is contained in:
Marc Zyngier 2021-11-01 19:59:20 +00:00
parent a5e8801202
commit c7708816c9
1 changed files with 22 additions and 12 deletions

View File

@ -155,7 +155,7 @@
#define SYS_IMP_APL_UPMSR_EL1 sys_reg(3, 7, 15, 6, 4)
#define UPMSR_IACT BIT(0)
#define AIC_NR_FIQ 4
#define AIC_NR_FIQ 6
#define AIC_NR_SWIPI 32
/*
@ -415,16 +415,15 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
aic_irqc->nr_hw + AIC_TMR_EL02_VIRT);
}
if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) ==
(FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) {
/*
* Not supported yet, let's figure out how to handle this when
* we implement these proprietary performance counters. For now,
* just mask it and move on.
*/
pr_err_ratelimited("PMC FIQ fired. Masking.\n");
sysreg_clear_set_s(SYS_IMP_APL_PMCR0_EL1, PMCR0_IMODE | PMCR0_IACT,
FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF));
if (read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & PMCR0_IACT) {
int irq;
if (cpumask_test_cpu(smp_processor_id(),
&aic_irqc->fiq_aff[AIC_CPU_PMU_P]->aff))
irq = AIC_CPU_PMU_P;
else
irq = AIC_CPU_PMU_E;
generic_handle_domain_irq(aic_irqc->hw_domain,
aic_irqc->nr_hw + irq);
}
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,
handle_fasteoi_irq, NULL, NULL);
irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
} else {
irq_set_percpu_devid(irq);
int fiq = hw - ic->nr_hw;
switch (fiq) {
case AIC_CPU_PMU_P:
case AIC_CPU_PMU_E:
irq_set_percpu_devid_partition(irq, &ic->fiq_aff[fiq]->aff);
break;
default:
irq_set_percpu_devid(irq);
break;
}
irq_domain_set_info(id, irq, hw, &fiq_chip, id->host_data,
handle_percpu_devid_irq, NULL, NULL);
}