aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/powernv/setup.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index d2de7d5d7574..39d1971d77db 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -409,37 +409,39 @@ static int __init pnv_init_idle_states(void)
409{ 409{
410 struct device_node *power_mgt; 410 struct device_node *power_mgt;
411 int dt_idle_states; 411 int dt_idle_states;
412 const __be32 *idle_state_flags; 412 u32 *flags;
413 u32 len_flags, flags;
414 int i; 413 int i;
415 414
416 supported_cpuidle_states = 0; 415 supported_cpuidle_states = 0;
417 416
418 if (cpuidle_disable != IDLE_NO_OVERRIDE) 417 if (cpuidle_disable != IDLE_NO_OVERRIDE)
419 return 0; 418 goto out;
420 419
421 if (!firmware_has_feature(FW_FEATURE_OPALv3)) 420 if (!firmware_has_feature(FW_FEATURE_OPALv3))
422 return 0; 421 goto out;
423 422
424 power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); 423 power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
425 if (!power_mgt) { 424 if (!power_mgt) {
426 pr_warn("opal: PowerMgmt Node not found\n"); 425 pr_warn("opal: PowerMgmt Node not found\n");
427 return 0; 426 goto out;
427 }
428 dt_idle_states = of_property_count_u32_elems(power_mgt,
429 "ibm,cpu-idle-state-flags");
430 if (dt_idle_states < 0) {
431 pr_warn("cpuidle-powernv: no idle states found in the DT\n");
432 goto out;
428 } 433 }
429 434
430 idle_state_flags = of_get_property(power_mgt, 435 flags = kzalloc(sizeof(*flags) * dt_idle_states, GFP_KERNEL);
431 "ibm,cpu-idle-state-flags", &len_flags); 436 if (of_property_read_u32_array(power_mgt,
432 if (!idle_state_flags) { 437 "ibm,cpu-idle-state-flags", flags, dt_idle_states)) {
433 pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n"); 438 pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-flags in DT\n");
434 return 0; 439 goto out_free;
435 } 440 }
436 441
437 dt_idle_states = len_flags / sizeof(u32); 442 for (i = 0; i < dt_idle_states; i++)
443 supported_cpuidle_states |= flags[i];
438 444
439 for (i = 0; i < dt_idle_states; i++) {
440 flags = be32_to_cpu(idle_state_flags[i]);
441 supported_cpuidle_states |= flags;
442 }
443 if (!(supported_cpuidle_states & OPAL_PM_SLEEP_ENABLED_ER1)) { 445 if (!(supported_cpuidle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
444 patch_instruction( 446 patch_instruction(
445 (unsigned int *)pnv_fastsleep_workaround_at_entry, 447 (unsigned int *)pnv_fastsleep_workaround_at_entry,
@@ -449,6 +451,9 @@ static int __init pnv_init_idle_states(void)
449 PPC_INST_NOP); 451 PPC_INST_NOP);
450 } 452 }
451 pnv_alloc_idle_core_states(); 453 pnv_alloc_idle_core_states();
454out_free:
455 kfree(flags);
456out:
452 return 0; 457 return 0;
453} 458}
454 459