diff options
| author | Sascha Bischoff <Sascha.Bischoff@arm.com> | 2026-09-07 16:49:50 +0000 |
|---|---|---|
| committer | Thomas Gleixner <tglx@kernel.org> | 2026-09-07 21:44:17 +0200 |
| commit | 1017911fcc03584b6854b1b8f0aafeb25f5a8d25 (patch) | |
| tree | 7fc26f8518f5c34172932257e377e8dad0f10cf3 | |
| parent | df2908090cda368b01ff43709f51890076c56157 (diff) | |
| download | linux-1017911fcc03584b6854b1b8f0aafeb25f5a8d25.tar.gz linux-1017911fcc03584b6854b1b8f0aafeb25f5a8d25.zip | |
irqchip/gic-v5: Preserve ICC_CR0_EL1 state
In addition to EN, ICC_CR0_EL1 contains other fields, such as LINK and
LINK_IDLE. The driver only needs to modify EN, and must preserve the
values of all other fields when enabling or disabling the CPU
interface.
Define the missing LINK and LINK_IDLE fields, and use read-modify-write
accesses to update EN without affecting the rest of ICC_CR0_EL1.
Fixes: 7ec80fb3f025 ("irqchip/gic-v5: Add GICv5 PPI support")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://patch.msgid.link/20260907164945.714545-1-sascha.bischoff@arm.com
Closes: https://lore.kernel.org/r/20260807121703.D4B7A1F00A3A@smtp.kernel.org
| -rw-r--r-- | arch/arm64/tools/sysreg | 4 | ||||
| -rw-r--r-- | drivers/irqchip/irq-gic-v5.c | 6 |
2 files changed, 7 insertions, 3 deletions
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 94bf065c8ac7..e2d37ee221b8 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3761,7 +3761,9 @@ Sysreg ICC_CR0_EL1 3 1 12 0 1 Res0 63:39 Field 38 PID Field 37:32 IPPT -Res0 31:1 +Res0 31:3 +Field 2 LINK_IDLE +Field 1 LINK Field 0 EN EndSysreg diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index ac2d423b1723..5f2551cf077d 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -974,7 +974,8 @@ static void gicv5_cpu_disable_interrupts(void) { u64 cr0; - cr0 = FIELD_PREP(ICC_CR0_EL1_EN, 0); + cr0 = read_sysreg_s(SYS_ICC_CR0_EL1); + cr0 &= ~ICC_CR0_EL1_EN_MASK; write_sysreg_s(cr0, SYS_ICC_CR0_EL1); isb(); } @@ -991,7 +992,8 @@ static void gicv5_cpu_enable_interrupts(void) pcr = FIELD_PREP(ICC_PCR_EL1_PRIORITY, GICV5_IRQ_PRI_MI); write_sysreg_s(pcr, SYS_ICC_PCR_EL1); - cr0 = FIELD_PREP(ICC_CR0_EL1_EN, 1); + cr0 = read_sysreg_s(SYS_ICC_CR0_EL1); + cr0 |= ICC_CR0_EL1_EN_MASK; write_sysreg_s(cr0, SYS_ICC_CR0_EL1); } |
