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>
This commit is contained in:
Родитель
c4681547bc
Коммит
8848f0665b
|
@ -49,4 +49,9 @@ extern int arm_cpuidle_suspend(int index);
|
|||
|
||||
extern int arm_cpuidle_init(int cpu);
|
||||
|
||||
struct arm_cpuidle_irq_context { };
|
||||
|
||||
#define arm_cpuidle_save_irq_context(c) (void)c
|
||||
#define arm_cpuidle_restore_irq_context(c) (void)c
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,4 +18,39 @@ static inline int arm_cpuidle_suspend(int index)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||
#include <asm/arch_gicv3.h>
|
||||
|
||||
struct arm_cpuidle_irq_context {
|
||||
unsigned long pmr;
|
||||
unsigned long daif_bits;
|
||||
};
|
||||
|
||||
#define arm_cpuidle_save_irq_context(__c) \
|
||||
do { \
|
||||
struct arm_cpuidle_irq_context *c = __c; \
|
||||
if (system_uses_irq_prio_masking()) { \
|
||||
c->daif_bits = read_sysreg(daif); \
|
||||
write_sysreg(c->daif_bits | PSR_I_BIT | PSR_F_BIT, \
|
||||
daif); \
|
||||
c->pmr = gic_read_pmr(); \
|
||||
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define arm_cpuidle_restore_irq_context(__c) \
|
||||
do { \
|
||||
struct arm_cpuidle_irq_context *c = __c; \
|
||||
if (system_uses_irq_prio_masking()) { \
|
||||
gic_write_pmr(c->pmr); \
|
||||
write_sysreg(c->daif_bits, daif); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
struct arm_cpuidle_irq_context { };
|
||||
|
||||
#define arm_cpuidle_save_irq_context(c) (void)c
|
||||
#define arm_cpuidle_restore_irq_context(c) (void)c
|
||||
#endif
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче