diff options
author | Jisheng Zhang <jszhang@marvell.com> | 2016-07-14 06:37:27 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2016-07-14 11:30:44 -0400 |
commit | f222a7695219217c7d8ad9f842242ed223e2a1a4 (patch) | |
tree | cb3a83cd2a5a7494ceff25d9941db75b4afb9abc | |
parent | 1a695a905c18548062509178b98bc91e67510864 (diff) |
ARM: 8585/1: cpuidle: fix !cpuidle_ops[cpu].init case during init
Let's assume cpuidle_ops exists but it doesn't implement the according
init callback, current arm_cpuidle_init() will return success to its
caller, but in fact it should return -EOPNOTSUPP.
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/kernel/cpuidle.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index a44b268e12e1..2129b297ec20 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c | |||
@@ -92,7 +92,8 @@ static const struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method) | |||
92 | * process. | 92 | * process. |
93 | * | 93 | * |
94 | * Return 0 on sucess, -ENOENT if no 'enable-method' is defined, -EOPNOTSUPP if | 94 | * Return 0 on sucess, -ENOENT if no 'enable-method' is defined, -EOPNOTSUPP if |
95 | * no cpuidle_ops is registered for the 'enable-method'. | 95 | * no cpuidle_ops is registered for the 'enable-method', or if no init callback |
96 | * is defined. | ||
96 | */ | 97 | */ |
97 | static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu) | 98 | static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu) |
98 | { | 99 | { |
@@ -110,6 +111,12 @@ static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu) | |||
110 | return -EOPNOTSUPP; | 111 | return -EOPNOTSUPP; |
111 | } | 112 | } |
112 | 113 | ||
114 | if (!ops->init) { | ||
115 | pr_warn("cpuidle_ops '%s': no init callback\n", | ||
116 | enable_method); | ||
117 | return -EOPNOTSUPP; | ||
118 | } | ||
119 | |||
113 | cpuidle_ops[cpu] = *ops; /* structure copy */ | 120 | cpuidle_ops[cpu] = *ops; /* structure copy */ |
114 | 121 | ||
115 | pr_notice("cpuidle: enable-method property '%s'" | 122 | pr_notice("cpuidle: enable-method property '%s'" |
@@ -129,7 +136,8 @@ static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu) | |||
129 | * Returns: | 136 | * Returns: |
130 | * 0 on success, | 137 | * 0 on success, |
131 | * -ENODEV if it fails to find the cpu node in the device tree, | 138 | * -ENODEV if it fails to find the cpu node in the device tree, |
132 | * -EOPNOTSUPP if it does not find a registered cpuidle_ops for this cpu, | 139 | * -EOPNOTSUPP if it does not find a registered and valid cpuidle_ops for |
140 | * this cpu, | ||
133 | * -ENOENT if it fails to find an 'enable-method' property, | 141 | * -ENOENT if it fails to find an 'enable-method' property, |
134 | * -ENXIO if the HW reports a failure or a misconfiguration, | 142 | * -ENXIO if the HW reports a failure or a misconfiguration, |
135 | * -ENOMEM if the HW report an memory allocation failure | 143 | * -ENOMEM if the HW report an memory allocation failure |
@@ -143,7 +151,7 @@ int __init arm_cpuidle_init(int cpu) | |||
143 | return -ENODEV; | 151 | return -ENODEV; |
144 | 152 | ||
145 | ret = arm_cpuidle_read_ops(cpu_node, cpu); | 153 | ret = arm_cpuidle_read_ops(cpu_node, cpu); |
146 | if (!ret && cpuidle_ops[cpu].init) | 154 | if (!ret) |
147 | ret = cpuidle_ops[cpu].init(cpu_node, cpu); | 155 | ret = cpuidle_ops[cpu].init(cpu_node, cpu); |
148 | 156 | ||
149 | of_node_put(cpu_node); | 157 | of_node_put(cpu_node); |