aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpuidle/cpuidle-powernv.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
index 30d42298a69f..59372077ec7c 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -159,9 +159,7 @@ static int powernv_add_idle_states(void)
159 struct device_node *power_mgt; 159 struct device_node *power_mgt;
160 int nr_idle_states = 1; /* Snooze */ 160 int nr_idle_states = 1; /* Snooze */
161 int dt_idle_states; 161 int dt_idle_states;
162 const __be32 *idle_state_flags; 162 u32 *latency_ns, *residency_ns, *flags;
163 u32 len_flags, flags;
164 u32 *latency_ns, *residency_ns;
165 int i, rc; 163 int i, rc;
166 164
167 /* Currently we have snooze statically defined */ 165 /* Currently we have snooze statically defined */
@@ -172,14 +170,19 @@ static int powernv_add_idle_states(void)
172 goto out; 170 goto out;
173 } 171 }
174 172
175 idle_state_flags = of_get_property(power_mgt, 173 /* Read values of any property to determine the num of idle states */
176 "ibm,cpu-idle-state-flags", &len_flags); 174 dt_idle_states = of_property_count_u32_elems(power_mgt, "ibm,cpu-idle-state-flags");
177 if (!idle_state_flags) { 175 if (dt_idle_states < 0) {
178 pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-flags in DT\n"); 176 pr_warn("cpuidle-powernv: no idle states found in the DT\n");
179 goto out; 177 goto out;
180 } 178 }
181 179
182 dt_idle_states = len_flags / sizeof(u32); 180 flags = kzalloc(sizeof(*flags) * dt_idle_states, GFP_KERNEL);
181 if (of_property_read_u32_array(power_mgt,
182 "ibm,cpu-idle-state-flags", flags, dt_idle_states)) {
183 pr_warn("cpuidle-powernv : missing ibm,cpu-idle-state-flags in DT\n");
184 goto out_free_flags;
185 }
183 186
184 latency_ns = kzalloc(sizeof(*latency_ns) * dt_idle_states, GFP_KERNEL); 187 latency_ns = kzalloc(sizeof(*latency_ns) * dt_idle_states, GFP_KERNEL);
185 rc = of_property_read_u32_array(power_mgt, 188 rc = of_property_read_u32_array(power_mgt,
@@ -195,21 +198,19 @@ static int powernv_add_idle_states(void)
195 198
196 for (i = 0; i < dt_idle_states; i++) { 199 for (i = 0; i < dt_idle_states; i++) {
197 200
198 flags = be32_to_cpu(idle_state_flags[i]);
199
200 /* 201 /*
201 * Cpuidle accepts exit_latency and target_residency in us. 202 * Cpuidle accepts exit_latency and target_residency in us.
202 * Use default target_residency values if f/w does not expose it. 203 * Use default target_residency values if f/w does not expose it.
203 */ 204 */
204 if (flags & OPAL_PM_NAP_ENABLED) { 205 if (flags[i] & OPAL_PM_NAP_ENABLED) {
205 /* Add NAP state */ 206 /* Add NAP state */
206 strcpy(powernv_states[nr_idle_states].name, "Nap"); 207 strcpy(powernv_states[nr_idle_states].name, "Nap");
207 strcpy(powernv_states[nr_idle_states].desc, "Nap"); 208 strcpy(powernv_states[nr_idle_states].desc, "Nap");
208 powernv_states[nr_idle_states].flags = 0; 209 powernv_states[nr_idle_states].flags = 0;
209 powernv_states[nr_idle_states].target_residency = 100; 210 powernv_states[nr_idle_states].target_residency = 100;
210 powernv_states[nr_idle_states].enter = &nap_loop; 211 powernv_states[nr_idle_states].enter = &nap_loop;
211 } else if (flags & OPAL_PM_SLEEP_ENABLED || 212 } else if (flags[i] & OPAL_PM_SLEEP_ENABLED ||
212 flags & OPAL_PM_SLEEP_ENABLED_ER1) { 213 flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) {
213 /* Add FASTSLEEP state */ 214 /* Add FASTSLEEP state */
214 strcpy(powernv_states[nr_idle_states].name, "FastSleep"); 215 strcpy(powernv_states[nr_idle_states].name, "FastSleep");
215 strcpy(powernv_states[nr_idle_states].desc, "FastSleep"); 216 strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
@@ -232,6 +233,8 @@ static int powernv_add_idle_states(void)
232 kfree(residency_ns); 233 kfree(residency_ns);
233out_free_latency: 234out_free_latency:
234 kfree(latency_ns); 235 kfree(latency_ns);
236out_free_flags:
237 kfree(flags);
235out: 238out:
236 return nr_idle_states; 239 return nr_idle_states;
237} 240}