aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/Kconfig3
-rw-r--r--arch/arm64/include/asm/cpu_ops.h8
-rw-r--r--arch/arm64/include/asm/cpuidle.h6
-rw-r--r--arch/arm64/include/asm/suspend.h2
-rw-r--r--arch/arm64/kernel/Makefile2
-rw-r--r--arch/arm64/kernel/asm-offsets.c2
-rw-r--r--arch/arm64/kernel/cpuidle.c20
-rw-r--r--arch/arm64/kernel/hw_breakpoint.c2
-rw-r--r--arch/arm64/kernel/psci.c2
-rw-r--r--arch/arm64/kernel/suspend.c21
-rw-r--r--arch/arm64/mm/proc.S2
-rw-r--r--drivers/cpuidle/Kconfig.arm641
-rw-r--r--drivers/cpuidle/cpuidle-arm64.c1
13 files changed, 34 insertions, 38 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 21a59bf37145..d3f7e4941231 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -642,9 +642,6 @@ source "kernel/power/Kconfig"
642config ARCH_SUSPEND_POSSIBLE 642config ARCH_SUSPEND_POSSIBLE
643 def_bool y 643 def_bool y
644 644
645config ARM64_CPU_SUSPEND
646 def_bool PM_SLEEP
647
648endmenu 645endmenu
649 646
650menu "CPU Power Management" 647menu "CPU Power Management"
diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
index 6f8e2ef9094a..da301ee7395c 100644
--- a/arch/arm64/include/asm/cpu_ops.h
+++ b/arch/arm64/include/asm/cpu_ops.h
@@ -28,8 +28,6 @@ struct device_node;
28 * enable-method property. 28 * enable-method property.
29 * @cpu_init: Reads any data necessary for a specific enable-method from the 29 * @cpu_init: Reads any data necessary for a specific enable-method from the
30 * devicetree, for a given cpu node and proposed logical id. 30 * devicetree, for a given cpu node and proposed logical id.
31 * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
32 * devicetree, for a given cpu node and proposed logical id.
33 * @cpu_prepare: Early one-time preparation step for a cpu. If there is a 31 * @cpu_prepare: Early one-time preparation step for a cpu. If there is a
34 * mechanism for doing so, tests whether it is possible to boot 32 * mechanism for doing so, tests whether it is possible to boot
35 * the given CPU. 33 * the given CPU.
@@ -42,6 +40,8 @@ struct device_node;
42 * @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the 40 * @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the
43 * cpu being killed. 41 * cpu being killed.
44 * @cpu_kill: Ensures a cpu has left the kernel. Called from another cpu. 42 * @cpu_kill: Ensures a cpu has left the kernel. Called from another cpu.
43 * @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
44 * devicetree, for a given cpu node and proposed logical id.
45 * @cpu_suspend: Suspends a cpu and saves the required context. May fail owing 45 * @cpu_suspend: Suspends a cpu and saves the required context. May fail owing
46 * to wrong parameters or error conditions. Called from the 46 * to wrong parameters or error conditions. Called from the
47 * CPU being suspended. Must be called with IRQs disabled. 47 * CPU being suspended. Must be called with IRQs disabled.
@@ -49,7 +49,6 @@ struct device_node;
49struct cpu_operations { 49struct cpu_operations {
50 const char *name; 50 const char *name;
51 int (*cpu_init)(struct device_node *, unsigned int); 51 int (*cpu_init)(struct device_node *, unsigned int);
52 int (*cpu_init_idle)(struct device_node *, unsigned int);
53 int (*cpu_prepare)(unsigned int); 52 int (*cpu_prepare)(unsigned int);
54 int (*cpu_boot)(unsigned int); 53 int (*cpu_boot)(unsigned int);
55 void (*cpu_postboot)(void); 54 void (*cpu_postboot)(void);
@@ -58,7 +57,8 @@ struct cpu_operations {
58 void (*cpu_die)(unsigned int cpu); 57 void (*cpu_die)(unsigned int cpu);
59 int (*cpu_kill)(unsigned int cpu); 58 int (*cpu_kill)(unsigned int cpu);
60#endif 59#endif
61#ifdef CONFIG_ARM64_CPU_SUSPEND 60#ifdef CONFIG_CPU_IDLE
61 int (*cpu_init_idle)(struct device_node *, unsigned int);
62 int (*cpu_suspend)(unsigned long); 62 int (*cpu_suspend)(unsigned long);
63#endif 63#endif
64}; 64};
diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h
index b52a9932e2b1..0710654631e7 100644
--- a/arch/arm64/include/asm/cpuidle.h
+++ b/arch/arm64/include/asm/cpuidle.h
@@ -3,11 +3,17 @@
3 3
4#ifdef CONFIG_CPU_IDLE 4#ifdef CONFIG_CPU_IDLE
5extern int cpu_init_idle(unsigned int cpu); 5extern int cpu_init_idle(unsigned int cpu);
6extern int cpu_suspend(unsigned long arg);
6#else 7#else
7static inline int cpu_init_idle(unsigned int cpu) 8static inline int cpu_init_idle(unsigned int cpu)
8{ 9{
9 return -EOPNOTSUPP; 10 return -EOPNOTSUPP;
10} 11}
12
13static inline int cpu_suspend(unsigned long arg)
14{
15 return -EOPNOTSUPP;
16}
11#endif 17#endif
12 18
13#endif 19#endif
diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index 456d67c1f0fa..003802f58963 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -23,6 +23,4 @@ struct sleep_save_sp {
23 23
24extern int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long)); 24extern int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
25extern void cpu_resume(void); 25extern void cpu_resume(void);
26extern int cpu_suspend(unsigned long);
27
28#endif 26#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 3b3b1cd3e7f0..bef04afd6031 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -27,7 +27,7 @@ arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o
27arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o 27arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
28arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o 28arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
29arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o 29arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
30arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o 30arm64-obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
31arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o 31arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
32arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o 32arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
33arm64-obj-$(CONFIG_KGDB) += kgdb.o 33arm64-obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 9a9fce090d58..a2ae19403abb 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -152,7 +152,7 @@ int main(void)
152 DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); 152 DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr));
153 DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); 153 DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));
154#endif 154#endif
155#ifdef CONFIG_ARM64_CPU_SUSPEND 155#ifdef CONFIG_CPU_PM
156 DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx)); 156 DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx));
157 DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp)); 157 DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp));
158 DEFINE(MPIDR_HASH_MASK, offsetof(struct mpidr_hash, mask)); 158 DEFINE(MPIDR_HASH_MASK, offsetof(struct mpidr_hash, mask));
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index 19d17f51db37..5c0896647fd1 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -29,3 +29,23 @@ int cpu_init_idle(unsigned int cpu)
29 of_node_put(cpu_node); 29 of_node_put(cpu_node);
30 return ret; 30 return ret;
31} 31}
32
33/**
34 * cpu_suspend() - function to enter a low-power idle state
35 * @arg: argument to pass to CPU suspend operations
36 *
37 * Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU
38 * operations back-end error code otherwise.
39 */
40int cpu_suspend(unsigned long arg)
41{
42 int cpu = smp_processor_id();
43
44 /*
45 * If cpu_ops have not been registered or suspend
46 * has not been initialized, cpu_suspend call fails early.
47 */
48 if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend)
49 return -EOPNOTSUPP;
50 return cpu_ops[cpu]->cpu_suspend(arg);
51}
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index df1cf15377b4..98bbe06e469c 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -894,7 +894,7 @@ static struct notifier_block hw_breakpoint_reset_nb = {
894 .notifier_call = hw_breakpoint_reset_notify, 894 .notifier_call = hw_breakpoint_reset_notify,
895}; 895};
896 896
897#ifdef CONFIG_ARM64_CPU_SUSPEND 897#ifdef CONFIG_CPU_PM
898extern void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *)); 898extern void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *));
899#else 899#else
900static inline void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *)) 900static inline void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index f1dbca7d5c96..3425f311c49e 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -540,8 +540,6 @@ const struct cpu_operations cpu_psci_ops = {
540 .name = "psci", 540 .name = "psci",
541#ifdef CONFIG_CPU_IDLE 541#ifdef CONFIG_CPU_IDLE
542 .cpu_init_idle = cpu_psci_cpu_init_idle, 542 .cpu_init_idle = cpu_psci_cpu_init_idle,
543#endif
544#ifdef CONFIG_ARM64_CPU_SUSPEND
545 .cpu_suspend = cpu_psci_cpu_suspend, 543 .cpu_suspend = cpu_psci_cpu_suspend,
546#endif 544#endif
547#ifdef CONFIG_SMP 545#ifdef CONFIG_SMP
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 2d6b6065fe7f..d7daf45ae7a2 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -1,7 +1,6 @@
1#include <linux/percpu.h> 1#include <linux/percpu.h>
2#include <linux/slab.h> 2#include <linux/slab.h>
3#include <asm/cacheflush.h> 3#include <asm/cacheflush.h>
4#include <asm/cpu_ops.h>
5#include <asm/debug-monitors.h> 4#include <asm/debug-monitors.h>
6#include <asm/pgtable.h> 5#include <asm/pgtable.h>
7#include <asm/memory.h> 6#include <asm/memory.h>
@@ -51,26 +50,6 @@ void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
51 hw_breakpoint_restore = hw_bp_restore; 50 hw_breakpoint_restore = hw_bp_restore;
52} 51}
53 52
54/**
55 * cpu_suspend() - function to enter a low-power state
56 * @arg: argument to pass to CPU suspend operations
57 *
58 * Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU
59 * operations back-end error code otherwise.
60 */
61int cpu_suspend(unsigned long arg)
62{
63 int cpu = smp_processor_id();
64
65 /*
66 * If cpu_ops have not been registered or suspend
67 * has not been initialized, cpu_suspend call fails early.
68 */
69 if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend)
70 return -EOPNOTSUPP;
71 return cpu_ops[cpu]->cpu_suspend(arg);
72}
73
74/* 53/*
75 * __cpu_suspend 54 * __cpu_suspend
76 * 55 *
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index b98fc8ce6a16..28eebfb6af76 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -102,7 +102,7 @@ ENTRY(cpu_do_idle)
102 ret 102 ret
103ENDPROC(cpu_do_idle) 103ENDPROC(cpu_do_idle)
104 104
105#ifdef CONFIG_ARM64_CPU_SUSPEND 105#ifdef CONFIG_CPU_PM
106/** 106/**
107 * cpu_do_suspend - save CPU registers context 107 * cpu_do_suspend - save CPU registers context
108 * 108 *
diff --git a/drivers/cpuidle/Kconfig.arm64 b/drivers/cpuidle/Kconfig.arm64
index d0a08ed1b2ee..6effb3656735 100644
--- a/drivers/cpuidle/Kconfig.arm64
+++ b/drivers/cpuidle/Kconfig.arm64
@@ -4,7 +4,6 @@
4 4
5config ARM64_CPUIDLE 5config ARM64_CPUIDLE
6 bool "Generic ARM64 CPU idle Driver" 6 bool "Generic ARM64 CPU idle Driver"
7 select ARM64_CPU_SUSPEND
8 select DT_IDLE_STATES 7 select DT_IDLE_STATES
9 help 8 help
10 Select this to enable generic cpuidle driver for ARM64. 9 Select this to enable generic cpuidle driver for ARM64.
diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm64.c
index 80704b931ba4..39a2c62716c3 100644
--- a/drivers/cpuidle/cpuidle-arm64.c
+++ b/drivers/cpuidle/cpuidle-arm64.c
@@ -19,7 +19,6 @@
19#include <linux/of.h> 19#include <linux/of.h>
20 20
21#include <asm/cpuidle.h> 21#include <asm/cpuidle.h>
22#include <asm/suspend.h>
23 22
24#include "dt_idle_states.h" 23#include "dt_idle_states.h"
25 24