diff options
author | Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> | 2015-07-16 04:04:23 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-07-28 11:24:14 -0400 |
commit | 227942809b52f23cda414858b635c0285f11de00 (patch) | |
tree | 9ead4484e5679057df62d859a748f50a2716b437 /drivers/cpufreq/powernv-cpufreq.c | |
parent | 3dd3ebe5bb3837aeac28a23f8f22b97cb84abab6 (diff) |
cpufreq: powernv: Restore cpu frequency to policy->cur on unthrottling
If frequency is throttled due to OCC reset then cpus will be in Psafe
frequency, so restore the frequency on all cpus to policy->cur when
OCCs are active again. And if frequency is throttled due to Pmax
capping then restore the frequency of all the cpus in the chip on
unthrottling.
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/powernv-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/powernv-cpufreq.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 90b42938837e..546e056e416d 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c | |||
@@ -48,6 +48,7 @@ static struct chip { | |||
48 | bool throttled; | 48 | bool throttled; |
49 | cpumask_t mask; | 49 | cpumask_t mask; |
50 | struct work_struct throttle; | 50 | struct work_struct throttle; |
51 | bool restore; | ||
51 | } *chips; | 52 | } *chips; |
52 | 53 | ||
53 | static int nr_chips; | 54 | static int nr_chips; |
@@ -415,9 +416,29 @@ static struct notifier_block powernv_cpufreq_reboot_nb = { | |||
415 | void powernv_cpufreq_work_fn(struct work_struct *work) | 416 | void powernv_cpufreq_work_fn(struct work_struct *work) |
416 | { | 417 | { |
417 | struct chip *chip = container_of(work, struct chip, throttle); | 418 | struct chip *chip = container_of(work, struct chip, throttle); |
419 | unsigned int cpu; | ||
420 | cpumask_var_t mask; | ||
418 | 421 | ||
419 | smp_call_function_any(&chip->mask, | 422 | smp_call_function_any(&chip->mask, |
420 | powernv_cpufreq_throttle_check, NULL, 0); | 423 | powernv_cpufreq_throttle_check, NULL, 0); |
424 | |||
425 | if (!chip->restore) | ||
426 | return; | ||
427 | |||
428 | chip->restore = false; | ||
429 | cpumask_copy(mask, &chip->mask); | ||
430 | for_each_cpu_and(cpu, mask, cpu_online_mask) { | ||
431 | int index, tcpu; | ||
432 | struct cpufreq_policy policy; | ||
433 | |||
434 | cpufreq_get_policy(&policy, cpu); | ||
435 | cpufreq_frequency_table_target(&policy, policy.freq_table, | ||
436 | policy.cur, | ||
437 | CPUFREQ_RELATION_C, &index); | ||
438 | powernv_cpufreq_target_index(&policy, index); | ||
439 | for_each_cpu(tcpu, policy.cpus) | ||
440 | cpumask_clear_cpu(tcpu, mask); | ||
441 | } | ||
421 | } | 442 | } |
422 | 443 | ||
423 | static char throttle_reason[][30] = { | 444 | static char throttle_reason[][30] = { |
@@ -469,8 +490,10 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb, | |||
469 | throttled = false; | 490 | throttled = false; |
470 | pr_info("OCC: Active\n"); | 491 | pr_info("OCC: Active\n"); |
471 | 492 | ||
472 | for (i = 0; i < nr_chips; i++) | 493 | for (i = 0; i < nr_chips; i++) { |
494 | chips[i].restore = true; | ||
473 | schedule_work(&chips[i].throttle); | 495 | schedule_work(&chips[i].throttle); |
496 | } | ||
474 | 497 | ||
475 | return 0; | 498 | return 0; |
476 | } | 499 | } |
@@ -487,8 +510,11 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb, | |||
487 | return 0; | 510 | return 0; |
488 | 511 | ||
489 | for (i = 0; i < nr_chips; i++) | 512 | for (i = 0; i < nr_chips; i++) |
490 | if (chips[i].id == omsg.chip) | 513 | if (chips[i].id == omsg.chip) { |
514 | if (!omsg.throttle_status) | ||
515 | chips[i].restore = true; | ||
491 | schedule_work(&chips[i].throttle); | 516 | schedule_work(&chips[i].throttle); |
517 | } | ||
492 | } | 518 | } |
493 | return 0; | 519 | return 0; |
494 | } | 520 | } |
@@ -542,6 +568,7 @@ static int init_chip_info(void) | |||
542 | chips[i].throttled = false; | 568 | chips[i].throttled = false; |
543 | cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); | 569 | cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); |
544 | INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); | 570 | INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); |
571 | chips[i].restore = false; | ||
545 | } | 572 | } |
546 | 573 | ||
547 | return 0; | 574 | return 0; |