diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/powernv/setup.c | 35 |
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(); |
454 | out_free: | ||
455 | kfree(flags); | ||
456 | out: | ||
452 | return 0; | 457 | return 0; |
453 | } | 458 | } |
454 | 459 | ||