Skip to content

Commit 8848f06

Browse files
Marc Zyngierwilldeacon
authored andcommitted
arm64: Add cpuidle context save/restore helpers
As we need to start doing some additional work on all idle paths, let's introduce a set of macros that will perform the work related to the GICv3 pseudo-NMI idle entry exit. Stubs are introduced to 32bit ARM for compatibility. As these helpers are currently unused, there is no functional change. Tested-by: Valentin Schneider <valentin.schneider@arm.com> Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20210615111227.2454465-2-maz@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
1 parent c468154 commit 8848f06

2 files changed

Lines changed: 40 additions & 0 deletions

File tree

arch/arm/include/asm/cpuidle.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,9 @@ extern int arm_cpuidle_suspend(int index);
4949

5050
extern int arm_cpuidle_init(int cpu);
5151

52+
struct arm_cpuidle_irq_context { };
53+
54+
#define arm_cpuidle_save_irq_context(c) (void)c
55+
#define arm_cpuidle_restore_irq_context(c) (void)c
56+
5257
#endif

arch/arm64/include/asm/cpuidle.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,39 @@ static inline int arm_cpuidle_suspend(int index)
1818
return -EOPNOTSUPP;
1919
}
2020
#endif
21+
22+
#ifdef CONFIG_ARM64_PSEUDO_NMI
23+
#include <asm/arch_gicv3.h>
24+
25+
struct arm_cpuidle_irq_context {
26+
unsigned long pmr;
27+
unsigned long daif_bits;
28+
};
29+
30+
#define arm_cpuidle_save_irq_context(__c) \
31+
do { \
32+
struct arm_cpuidle_irq_context *c = __c; \
33+
if (system_uses_irq_prio_masking()) { \
34+
c->daif_bits = read_sysreg(daif); \
35+
write_sysreg(c->daif_bits | PSR_I_BIT | PSR_F_BIT, \
36+
daif); \
37+
c->pmr = gic_read_pmr(); \
38+
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET); \
39+
} \
40+
} while (0)
41+
42+
#define arm_cpuidle_restore_irq_context(__c) \
43+
do { \
44+
struct arm_cpuidle_irq_context *c = __c; \
45+
if (system_uses_irq_prio_masking()) { \
46+
gic_write_pmr(c->pmr); \
47+
write_sysreg(c->daif_bits, daif); \
48+
} \
49+
} while (0)
50+
#else
51+
struct arm_cpuidle_irq_context { };
52+
53+
#define arm_cpuidle_save_irq_context(c) (void)c
54+
#define arm_cpuidle_restore_irq_context(c) (void)c
55+
#endif
2156
#endif

0 commit comments

Comments
 (0)