aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Lo <josephl@nvidia.com>2019-01-31 21:16:39 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-02-01 06:58:58 -0500
commitdb10945cf49e9c04053b436abe334412003f9af9 (patch)
tree24797e28e65efb606e6e3f0aa374f6377d85db7b
parent8a56bdeb09007e33107e6fdf72909e74c2fe1b95 (diff)
cpuidle: dt: bail out if the idle-state DT node is not compatible
Currently, the DT of the idle states will be parsed first whether it's compatible or not. This could cause a warning message that comes from if the CPU doesn't support identical idle states. E.g. Tegra186 can run with 2 Cortex-A57 and 2 Denver cores with different idle states on different types of these cores. So fix it by checking the match node earlier, then it can make sure it only goes through the idle states that the CPU supported. Signed-off-by: Joseph Lo <josephl@nvidia.com> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpuidle/dt_idle_states.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
index 53342b7f1010..add9569636b5 100644
--- a/drivers/cpuidle/dt_idle_states.c
+++ b/drivers/cpuidle/dt_idle_states.c
@@ -22,16 +22,12 @@
22#include "dt_idle_states.h" 22#include "dt_idle_states.h"
23 23
24static int init_state_node(struct cpuidle_state *idle_state, 24static int init_state_node(struct cpuidle_state *idle_state,
25 const struct of_device_id *matches, 25 const struct of_device_id *match_id,
26 struct device_node *state_node) 26 struct device_node *state_node)
27{ 27{
28 int err; 28 int err;
29 const struct of_device_id *match_id;
30 const char *desc; 29 const char *desc;
31 30
32 match_id = of_match_node(matches, state_node);
33 if (!match_id)
34 return -ENODEV;
35 /* 31 /*
36 * CPUidle drivers are expected to initialize the const void *data 32 * CPUidle drivers are expected to initialize the const void *data
37 * pointer of the passed in struct of_device_id array to the idle 33 * pointer of the passed in struct of_device_id array to the idle
@@ -160,6 +156,7 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
160{ 156{
161 struct cpuidle_state *idle_state; 157 struct cpuidle_state *idle_state;
162 struct device_node *state_node, *cpu_node; 158 struct device_node *state_node, *cpu_node;
159 const struct of_device_id *match_id;
163 int i, err = 0; 160 int i, err = 0;
164 const cpumask_t *cpumask; 161 const cpumask_t *cpumask;
165 unsigned int state_idx = start_idx; 162 unsigned int state_idx = start_idx;
@@ -180,6 +177,12 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
180 if (!state_node) 177 if (!state_node)
181 break; 178 break;
182 179
180 match_id = of_match_node(matches, state_node);
181 if (!match_id) {
182 err = -ENODEV;
183 break;
184 }
185
183 if (!of_device_is_available(state_node)) { 186 if (!of_device_is_available(state_node)) {
184 of_node_put(state_node); 187 of_node_put(state_node);
185 continue; 188 continue;
@@ -198,7 +201,7 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
198 } 201 }
199 202
200 idle_state = &drv->states[state_idx++]; 203 idle_state = &drv->states[state_idx++];
201 err = init_state_node(idle_state, matches, state_node); 204 err = init_state_node(idle_state, match_id, state_node);
202 if (err) { 205 if (err) {
203 pr_err("Parsing idle state node %pOF failed with err %d\n", 206 pr_err("Parsing idle state node %pOF failed with err %d\n",
204 state_node, err); 207 state_node, err);