aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/powernv-cpufreq.c
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2015-07-16 04:04:23 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-07-28 11:24:14 -0400
commit227942809b52f23cda414858b635c0285f11de00 (patch)
tree9ead4484e5679057df62d859a748f50a2716b437 /drivers/cpufreq/powernv-cpufreq.c
parent3dd3ebe5bb3837aeac28a23f8f22b97cb84abab6 (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.c31
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
53static int nr_chips; 54static int nr_chips;
@@ -415,9 +416,29 @@ static struct notifier_block powernv_cpufreq_reboot_nb = {
415void powernv_cpufreq_work_fn(struct work_struct *work) 416void 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
423static char throttle_reason[][30] = { 444static 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;