Skip to content

Commit 59fc20b

Browse files
Konrad DybcioKAGA-KOKO
authored andcommitted
irqchip/apple-aic: Only access system registers on SoCs which provide them
Starting from the A11 (T8015) SoC, Apple introuced system registers for fast IPI and UNCORE PMC control. These sysregs do not exist on earlier A7-A10 SoCs and trying to access them results in an instant crash. Restrict sysreg access within the AIC driver to configurations where use_fast_ipi is true to allow AIC to function properly on A7-A10 SoCs. Co-developed-by: Nick Chan <[email protected]> Signed-off-by: Konrad Dybcio <[email protected]> Signed-off-by: Nick Chan <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Sven Peter <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent a845342 commit 59fc20b

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

drivers/irqchip/irq-apple-aic.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ enum fiq_hwirq {
234234
AIC_NR_FIQ
235235
};
236236

237+
/* True if UNCORE/UNCORE2 and Sn_... IPI registers are present and used (A11+) */
237238
static DEFINE_STATIC_KEY_TRUE(use_fast_ipi);
238239
/* True if SYS_IMP_APL_IPI_RR_LOCAL_EL1 exists for local fast IPIs (M1+) */
239240
static DEFINE_STATIC_KEY_TRUE(use_local_fast_ipi);
@@ -550,14 +551,9 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
550551
* we check for everything here, even things we don't support yet.
551552
*/
552553

553-
if (read_sysreg_s(SYS_IMP_APL_IPI_SR_EL1) & IPI_SR_PENDING) {
554-
if (static_branch_likely(&use_fast_ipi)) {
555-
aic_handle_ipi(regs);
556-
} else {
557-
pr_err_ratelimited("Fast IPI fired. Acking.\n");
558-
write_sysreg_s(IPI_SR_PENDING, SYS_IMP_APL_IPI_SR_EL1);
559-
}
560-
}
554+
if (static_branch_likely(&use_fast_ipi) &&
555+
(read_sysreg_s(SYS_IMP_APL_IPI_SR_EL1) & IPI_SR_PENDING))
556+
aic_handle_ipi(regs);
561557

562558
if (TIMER_FIRING(read_sysreg(cntp_ctl_el0)))
563559
generic_handle_domain_irq(aic_irqc->hw_domain,
@@ -592,8 +588,9 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
592588
AIC_FIQ_HWIRQ(irq));
593589
}
594590

595-
if (FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_IMP_APL_UPMCR0_EL1)) == UPMCR0_IMODE_FIQ &&
596-
(read_sysreg_s(SYS_IMP_APL_UPMSR_EL1) & UPMSR_IACT)) {
591+
if (static_branch_likely(&use_fast_ipi) &&
592+
(FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_IMP_APL_UPMCR0_EL1)) == UPMCR0_IMODE_FIQ) &&
593+
(read_sysreg_s(SYS_IMP_APL_UPMSR_EL1) & UPMSR_IACT)) {
597594
/* Same story with uncore PMCs */
598595
pr_err_ratelimited("Uncore PMC FIQ fired. Masking.\n");
599596
sysreg_clear_set_s(SYS_IMP_APL_UPMCR0_EL1, UPMCR0_IMODE,
@@ -829,7 +826,8 @@ static int aic_init_cpu(unsigned int cpu)
829826
/* Mask all hard-wired per-CPU IRQ/FIQ sources */
830827

831828
/* Pending Fast IPI FIQs */
832-
write_sysreg_s(IPI_SR_PENDING, SYS_IMP_APL_IPI_SR_EL1);
829+
if (static_branch_likely(&use_fast_ipi))
830+
write_sysreg_s(IPI_SR_PENDING, SYS_IMP_APL_IPI_SR_EL1);
833831

834832
/* Timer FIQs */
835833
sysreg_clear_set(cntp_ctl_el0, 0, ARCH_TIMER_CTRL_IT_MASK);
@@ -850,8 +848,10 @@ static int aic_init_cpu(unsigned int cpu)
850848
FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF));
851849

852850
/* Uncore PMC FIQ */
853-
sysreg_clear_set_s(SYS_IMP_APL_UPMCR0_EL1, UPMCR0_IMODE,
854-
FIELD_PREP(UPMCR0_IMODE, UPMCR0_IMODE_OFF));
851+
if (static_branch_likely(&use_fast_ipi)) {
852+
sysreg_clear_set_s(SYS_IMP_APL_UPMCR0_EL1, UPMCR0_IMODE,
853+
FIELD_PREP(UPMCR0_IMODE, UPMCR0_IMODE_OFF));
854+
}
855855

856856
/* Commit all of the above */
857857
isb();

0 commit comments

Comments
 (0)