aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c73
1 files changed, 34 insertions, 39 deletions
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index c670314053af..1bbc10a54c59 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -29,6 +29,7 @@
29#include <linux/reboot.h> 29#include <linux/reboot.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/cpu.h> 31#include <linux/cpu.h>
32#include <trace/events/power.h>
32 33
33#include <asm/cputhreads.h> 34#include <asm/cputhreads.h>
34#include <asm/firmware.h> 35#include <asm/firmware.h>
@@ -45,12 +46,22 @@ static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
45static bool rebooting, throttled, occ_reset; 46static bool rebooting, throttled, occ_reset;
46static unsigned int *core_to_chip_map; 47static unsigned int *core_to_chip_map;
47 48
49static const char * const throttle_reason[] = {
50 "No throttling",
51 "Power Cap",
52 "Processor Over Temperature",
53 "Power Supply Failure",
54 "Over Current",
55 "OCC Reset"
56};
57
48static struct chip { 58static struct chip {
49 unsigned int id; 59 unsigned int id;
50 bool throttled; 60 bool throttled;
61 bool restore;
62 u8 throttle_reason;
51 cpumask_t mask; 63 cpumask_t mask;
52 struct work_struct throttle; 64 struct work_struct throttle;
53 bool restore;
54} *chips; 65} *chips;
55 66
56static int nr_chips; 67static int nr_chips;
@@ -331,17 +342,17 @@ static void powernv_cpufreq_throttle_check(void *data)
331 goto next; 342 goto next;
332 chips[i].throttled = true; 343 chips[i].throttled = true;
333 if (pmsr_pmax < powernv_pstate_info.nominal) 344 if (pmsr_pmax < powernv_pstate_info.nominal)
334 pr_crit("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n", 345 pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",
335 cpu, chips[i].id, pmsr_pmax, 346 cpu, chips[i].id, pmsr_pmax,
336 powernv_pstate_info.nominal); 347 powernv_pstate_info.nominal);
337 else 348 trace_powernv_throttle(chips[i].id,
338 pr_info("CPU %d on Chip %u has Pmax reduced below turbo frequency (%d < %d)\n", 349 throttle_reason[chips[i].throttle_reason],
339 cpu, chips[i].id, pmsr_pmax, 350 pmsr_pmax);
340 powernv_pstate_info.max);
341 } else if (chips[i].throttled) { 351 } else if (chips[i].throttled) {
342 chips[i].throttled = false; 352 chips[i].throttled = false;
343 pr_info("CPU %d on Chip %u has Pmax restored to %d\n", cpu, 353 trace_powernv_throttle(chips[i].id,
344 chips[i].id, pmsr_pmax); 354 throttle_reason[chips[i].throttle_reason],
355 pmsr_pmax);
345 } 356 }
346 357
347 /* Check if Psafe_mode_active is set in PMSR. */ 358 /* Check if Psafe_mode_active is set in PMSR. */
@@ -359,7 +370,7 @@ next:
359 370
360 if (throttled) { 371 if (throttled) {
361 pr_info("PMSR = %16lx\n", pmsr); 372 pr_info("PMSR = %16lx\n", pmsr);
362 pr_crit("CPU Frequency could be throttled\n"); 373 pr_warn("CPU Frequency could be throttled\n");
363 } 374 }
364} 375}
365 376
@@ -452,15 +463,6 @@ out:
452 put_online_cpus(); 463 put_online_cpus();
453} 464}
454 465
455static char throttle_reason[][30] = {
456 "No throttling",
457 "Power Cap",
458 "Processor Over Temperature",
459 "Power Supply Failure",
460 "Over Current",
461 "OCC Reset"
462 };
463
464static int powernv_cpufreq_occ_msg(struct notifier_block *nb, 466static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
465 unsigned long msg_type, void *_msg) 467 unsigned long msg_type, void *_msg)
466{ 468{
@@ -486,7 +488,7 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
486 */ 488 */
487 if (!throttled) { 489 if (!throttled) {
488 throttled = true; 490 throttled = true;
489 pr_crit("CPU frequency is throttled for duration\n"); 491 pr_warn("CPU frequency is throttled for duration\n");
490 } 492 }
491 493
492 break; 494 break;
@@ -510,23 +512,18 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
510 return 0; 512 return 0;
511 } 513 }
512 514
513 if (omsg.throttle_status && 515 for (i = 0; i < nr_chips; i++)
516 if (chips[i].id == omsg.chip)
517 break;
518
519 if (omsg.throttle_status >= 0 &&
514 omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) 520 omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS)
515 pr_info("OCC: Chip %u Pmax reduced due to %s\n", 521 chips[i].throttle_reason = omsg.throttle_status;
516 (unsigned int)omsg.chip,
517 throttle_reason[omsg.throttle_status]);
518 else if (!omsg.throttle_status)
519 pr_info("OCC: Chip %u %s\n", (unsigned int)omsg.chip,
520 throttle_reason[omsg.throttle_status]);
521 else
522 return 0;
523 522
524 for (i = 0; i < nr_chips; i++) 523 if (!omsg.throttle_status)
525 if (chips[i].id == omsg.chip) { 524 chips[i].restore = true;
526 if (!omsg.throttle_status) 525
527 chips[i].restore = true; 526 schedule_work(&chips[i].throttle);
528 schedule_work(&chips[i].throttle);
529 }
530 } 527 }
531 return 0; 528 return 0;
532} 529}
@@ -581,16 +578,14 @@ static int init_chip_info(void)
581 cpumask_andnot(&cpu_mask, &cpu_mask, cpu_sibling_mask(cpu)); 578 cpumask_andnot(&cpu_mask, &cpu_mask, cpu_sibling_mask(cpu));
582 } 579 }
583 580
584 chips = kmalloc_array(nr_chips, sizeof(struct chip), GFP_KERNEL); 581 chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL);
585 if (!chips) 582 if (!chips)
586 goto free_chip_map; 583 goto free_chip_map;
587 584
588 for (i = 0; i < nr_chips; i++) { 585 for (i = 0; i < nr_chips; i++) {
589 chips[i].id = chip[i]; 586 chips[i].id = chip[i];
590 chips[i].throttled = false;
591 cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); 587 cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
592 INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); 588 INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
593 chips[i].restore = false;
594 } 589 }
595 590
596 return 0; 591 return 0;