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:
parent
a5e8801202
commit
c7708816c9
|
@ -155,7 +155,7 @@
|
||||||
#define SYS_IMP_APL_UPMSR_EL1 sys_reg(3, 7, 15, 6, 4)
|
#define SYS_IMP_APL_UPMSR_EL1 sys_reg(3, 7, 15, 6, 4)
|
||||||
#define UPMSR_IACT BIT(0)
|
#define UPMSR_IACT BIT(0)
|
||||||
|
|
||||||
#define AIC_NR_FIQ 4
|
#define AIC_NR_FIQ 6
|
||||||
#define AIC_NR_SWIPI 32
|
#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);
|
aic_irqc->nr_hw + AIC_TMR_EL02_VIRT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) ==
|
if (read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & PMCR0_IACT) {
|
||||||
(FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) {
|
int irq;
|
||||||
/*
|
if (cpumask_test_cpu(smp_processor_id(),
|
||||||
* Not supported yet, let's figure out how to handle this when
|
&aic_irqc->fiq_aff[AIC_CPU_PMU_P]->aff))
|
||||||
* we implement these proprietary performance counters. For now,
|
irq = AIC_CPU_PMU_P;
|
||||||
* just mask it and move on.
|
else
|
||||||
*/
|
irq = AIC_CPU_PMU_E;
|
||||||
pr_err_ratelimited("PMC FIQ fired. Masking.\n");
|
generic_handle_domain_irq(aic_irqc->hw_domain,
|
||||||
sysreg_clear_set_s(SYS_IMP_APL_PMCR0_EL1, PMCR0_IMODE | PMCR0_IACT,
|
aic_irqc->nr_hw + irq);
|
||||||
FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_IMP_APL_UPMCR0_EL1)) == UPMCR0_IMODE_FIQ &&
|
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);
|
handle_fasteoi_irq, NULL, NULL);
|
||||||
irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
|
irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
|
||||||
} else {
|
} else {
|
||||||
|
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);
|
irq_set_percpu_devid(irq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
irq_domain_set_info(id, irq, hw, &fiq_chip, id->host_data,
|
irq_domain_set_info(id, irq, hw, &fiq_chip, id->host_data,
|
||||||
handle_percpu_devid_irq, NULL, NULL);
|
handle_percpu_devid_irq, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue