arm64: kernel: remove ARM64_CPU_SUSPEND config option
ARM64_CPU_SUSPEND config option was introduced to make code providing context save/restore selectable only on platforms requiring power management capabilities. Currently ARM64_CPU_SUSPEND depends on the PM_SLEEP config option which in turn is set by the SUSPEND config option. The introduction of CPU_IDLE for arm64 requires that code configured by ARM64_CPU_SUSPEND (context save/restore) should be compiled in in order to enable the CPU idle driver to rely on CPU operations carrying out context save/restore. The ARM64_CPUIDLE config option (ARM64 generic idle driver) is therefore forced to select ARM64_CPU_SUSPEND, even if there may be (ie PM_SLEEP) failed dependencies, which is not a clean way of handling the kernel configuration option. For these reasons, this patch removes the ARM64_CPU_SUSPEND config option and makes the context save/restore dependent on CPU_PM, which is selected whenever either SUSPEND or CPU_IDLE are configured, cleaning up dependencies in the process. This way, code previously configured through ARM64_CPU_SUSPEND is compiled in whenever a power management subsystem requires it to be present in the kernel (SUSPEND || CPU_IDLE), which is the behaviour expected on ARM64 kernels. The cpu_suspend and cpu_init_idle CPU operations are added only if CPU_IDLE is selected, since they are CPU_IDLE specific methods and should be grouped and defined accordingly. PSCI CPU operations are updated to reflect the introduced changes. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Will Deacon <will.deacon@arm.com> Cc: Krzysztof Kozlowski <k.kozlowski@samsung.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
committed by
Catalin Marinas
parent
c623b33b4e
commit
af3cfdbf56
@@ -642,9 +642,6 @@ source "kernel/power/Kconfig"
|
|||||||
config ARCH_SUSPEND_POSSIBLE
|
config ARCH_SUSPEND_POSSIBLE
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config ARM64_CPU_SUSPEND
|
|
||||||
def_bool PM_SLEEP
|
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "CPU Power Management"
|
menu "CPU Power Management"
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ struct device_node;
|
|||||||
* enable-method property.
|
* enable-method property.
|
||||||
* @cpu_init: Reads any data necessary for a specific enable-method from the
|
* @cpu_init: Reads any data necessary for a specific enable-method from the
|
||||||
* devicetree, for a given cpu node and proposed logical id.
|
* devicetree, for a given cpu node and proposed logical id.
|
||||||
* @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
|
|
||||||
* devicetree, for a given cpu node and proposed logical id.
|
|
||||||
* @cpu_prepare: Early one-time preparation step for a cpu. If there is a
|
* @cpu_prepare: Early one-time preparation step for a cpu. If there is a
|
||||||
* mechanism for doing so, tests whether it is possible to boot
|
* mechanism for doing so, tests whether it is possible to boot
|
||||||
* the given CPU.
|
* the given CPU.
|
||||||
@@ -42,6 +40,8 @@ struct device_node;
|
|||||||
* @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the
|
* @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the
|
||||||
* cpu being killed.
|
* cpu being killed.
|
||||||
* @cpu_kill: Ensures a cpu has left the kernel. Called from another cpu.
|
* @cpu_kill: Ensures a cpu has left the kernel. Called from another cpu.
|
||||||
|
* @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
|
||||||
|
* devicetree, for a given cpu node and proposed logical id.
|
||||||
* @cpu_suspend: Suspends a cpu and saves the required context. May fail owing
|
* @cpu_suspend: Suspends a cpu and saves the required context. May fail owing
|
||||||
* to wrong parameters or error conditions. Called from the
|
* to wrong parameters or error conditions. Called from the
|
||||||
* CPU being suspended. Must be called with IRQs disabled.
|
* CPU being suspended. Must be called with IRQs disabled.
|
||||||
@@ -49,7 +49,6 @@ struct device_node;
|
|||||||
struct cpu_operations {
|
struct cpu_operations {
|
||||||
const char *name;
|
const char *name;
|
||||||
int (*cpu_init)(struct device_node *, unsigned int);
|
int (*cpu_init)(struct device_node *, unsigned int);
|
||||||
int (*cpu_init_idle)(struct device_node *, unsigned int);
|
|
||||||
int (*cpu_prepare)(unsigned int);
|
int (*cpu_prepare)(unsigned int);
|
||||||
int (*cpu_boot)(unsigned int);
|
int (*cpu_boot)(unsigned int);
|
||||||
void (*cpu_postboot)(void);
|
void (*cpu_postboot)(void);
|
||||||
@@ -58,7 +57,8 @@ struct cpu_operations {
|
|||||||
void (*cpu_die)(unsigned int cpu);
|
void (*cpu_die)(unsigned int cpu);
|
||||||
int (*cpu_kill)(unsigned int cpu);
|
int (*cpu_kill)(unsigned int cpu);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ARM64_CPU_SUSPEND
|
#ifdef CONFIG_CPU_IDLE
|
||||||
|
int (*cpu_init_idle)(struct device_node *, unsigned int);
|
||||||
int (*cpu_suspend)(unsigned long);
|
int (*cpu_suspend)(unsigned long);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,11 +3,17 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_CPU_IDLE
|
#ifdef CONFIG_CPU_IDLE
|
||||||
extern int cpu_init_idle(unsigned int cpu);
|
extern int cpu_init_idle(unsigned int cpu);
|
||||||
|
extern int cpu_suspend(unsigned long arg);
|
||||||
#else
|
#else
|
||||||
static inline int cpu_init_idle(unsigned int cpu)
|
static inline int cpu_init_idle(unsigned int cpu)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int cpu_suspend(unsigned long arg)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,6 +23,4 @@ struct sleep_save_sp {
|
|||||||
|
|
||||||
extern int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
|
extern int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
|
||||||
extern void cpu_resume(void);
|
extern void cpu_resume(void);
|
||||||
extern int cpu_suspend(unsigned long);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o
|
|||||||
arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
|
arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
|
||||||
arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
|
arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
|
||||||
arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
|
||||||
arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
|
arm64-obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
|
||||||
arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||||
arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||||
arm64-obj-$(CONFIG_KGDB) += kgdb.o
|
arm64-obj-$(CONFIG_KGDB) += kgdb.o
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ int main(void)
|
|||||||
DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr));
|
DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr));
|
||||||
DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));
|
DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ARM64_CPU_SUSPEND
|
#ifdef CONFIG_CPU_PM
|
||||||
DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx));
|
DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx));
|
||||||
DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp));
|
DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp));
|
||||||
DEFINE(MPIDR_HASH_MASK, offsetof(struct mpidr_hash, mask));
|
DEFINE(MPIDR_HASH_MASK, offsetof(struct mpidr_hash, mask));
|
||||||
|
|||||||
@@ -29,3 +29,23 @@ int cpu_init_idle(unsigned int cpu)
|
|||||||
of_node_put(cpu_node);
|
of_node_put(cpu_node);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpu_suspend() - function to enter a low-power idle state
|
||||||
|
* @arg: argument to pass to CPU suspend operations
|
||||||
|
*
|
||||||
|
* Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU
|
||||||
|
* operations back-end error code otherwise.
|
||||||
|
*/
|
||||||
|
int cpu_suspend(unsigned long arg)
|
||||||
|
{
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If cpu_ops have not been registered or suspend
|
||||||
|
* has not been initialized, cpu_suspend call fails early.
|
||||||
|
*/
|
||||||
|
if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
return cpu_ops[cpu]->cpu_suspend(arg);
|
||||||
|
}
|
||||||
|
|||||||
@@ -894,7 +894,7 @@ static struct notifier_block hw_breakpoint_reset_nb = {
|
|||||||
.notifier_call = hw_breakpoint_reset_notify,
|
.notifier_call = hw_breakpoint_reset_notify,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_ARM64_CPU_SUSPEND
|
#ifdef CONFIG_CPU_PM
|
||||||
extern void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *));
|
extern void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *));
|
||||||
#else
|
#else
|
||||||
static inline void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
|
static inline void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
|
||||||
|
|||||||
@@ -540,8 +540,6 @@ const struct cpu_operations cpu_psci_ops = {
|
|||||||
.name = "psci",
|
.name = "psci",
|
||||||
#ifdef CONFIG_CPU_IDLE
|
#ifdef CONFIG_CPU_IDLE
|
||||||
.cpu_init_idle = cpu_psci_cpu_init_idle,
|
.cpu_init_idle = cpu_psci_cpu_init_idle,
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_ARM64_CPU_SUSPEND
|
|
||||||
.cpu_suspend = cpu_psci_cpu_suspend,
|
.cpu_suspend = cpu_psci_cpu_suspend,
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/cpu_ops.h>
|
|
||||||
#include <asm/debug-monitors.h>
|
#include <asm/debug-monitors.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/memory.h>
|
#include <asm/memory.h>
|
||||||
@@ -51,26 +50,6 @@ void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
|
|||||||
hw_breakpoint_restore = hw_bp_restore;
|
hw_breakpoint_restore = hw_bp_restore;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* cpu_suspend() - function to enter a low-power state
|
|
||||||
* @arg: argument to pass to CPU suspend operations
|
|
||||||
*
|
|
||||||
* Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU
|
|
||||||
* operations back-end error code otherwise.
|
|
||||||
*/
|
|
||||||
int cpu_suspend(unsigned long arg)
|
|
||||||
{
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If cpu_ops have not been registered or suspend
|
|
||||||
* has not been initialized, cpu_suspend call fails early.
|
|
||||||
*/
|
|
||||||
if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
return cpu_ops[cpu]->cpu_suspend(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __cpu_suspend
|
* __cpu_suspend
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ ENTRY(cpu_do_idle)
|
|||||||
ret
|
ret
|
||||||
ENDPROC(cpu_do_idle)
|
ENDPROC(cpu_do_idle)
|
||||||
|
|
||||||
#ifdef CONFIG_ARM64_CPU_SUSPEND
|
#ifdef CONFIG_CPU_PM
|
||||||
/**
|
/**
|
||||||
* cpu_do_suspend - save CPU registers context
|
* cpu_do_suspend - save CPU registers context
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
config ARM64_CPUIDLE
|
config ARM64_CPUIDLE
|
||||||
bool "Generic ARM64 CPU idle Driver"
|
bool "Generic ARM64 CPU idle Driver"
|
||||||
select ARM64_CPU_SUSPEND
|
|
||||||
select DT_IDLE_STATES
|
select DT_IDLE_STATES
|
||||||
help
|
help
|
||||||
Select this to enable generic cpuidle driver for ARM64.
|
Select this to enable generic cpuidle driver for ARM64.
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <asm/cpuidle.h>
|
#include <asm/cpuidle.h>
|
||||||
#include <asm/suspend.h>
|
|
||||||
|
|
||||||
#include "dt_idle_states.h"
|
#include "dt_idle_states.h"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user