|
@@ -29,6 +29,7 @@
|
|
|
#include <linux/reboot.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/cpu.h>
|
|
|
+#include <trace/events/power.h>
|
|
|
|
|
|
#include <asm/cputhreads.h>
|
|
|
#include <asm/firmware.h>
|
|
@@ -45,12 +46,22 @@ static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
|
|
|
static bool rebooting, throttled, occ_reset;
|
|
|
static unsigned int *core_to_chip_map;
|
|
|
|
|
|
+static const char * const throttle_reason[] = {
|
|
|
+ "No throttling",
|
|
|
+ "Power Cap",
|
|
|
+ "Processor Over Temperature",
|
|
|
+ "Power Supply Failure",
|
|
|
+ "Over Current",
|
|
|
+ "OCC Reset"
|
|
|
+};
|
|
|
+
|
|
|
static struct chip {
|
|
|
unsigned int id;
|
|
|
bool throttled;
|
|
|
+ bool restore;
|
|
|
+ u8 throttle_reason;
|
|
|
cpumask_t mask;
|
|
|
struct work_struct throttle;
|
|
|
- bool restore;
|
|
|
} *chips;
|
|
|
|
|
|
static int nr_chips;
|
|
@@ -331,17 +342,17 @@ static void powernv_cpufreq_throttle_check(void *data)
|
|
|
goto next;
|
|
|
chips[i].throttled = true;
|
|
|
if (pmsr_pmax < powernv_pstate_info.nominal)
|
|
|
- pr_crit("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",
|
|
|
- cpu, chips[i].id, pmsr_pmax,
|
|
|
- powernv_pstate_info.nominal);
|
|
|
- else
|
|
|
- pr_info("CPU %d on Chip %u has Pmax reduced below turbo frequency (%d < %d)\n",
|
|
|
- cpu, chips[i].id, pmsr_pmax,
|
|
|
- powernv_pstate_info.max);
|
|
|
+ pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n",
|
|
|
+ cpu, chips[i].id, pmsr_pmax,
|
|
|
+ powernv_pstate_info.nominal);
|
|
|
+ trace_powernv_throttle(chips[i].id,
|
|
|
+ throttle_reason[chips[i].throttle_reason],
|
|
|
+ pmsr_pmax);
|
|
|
} else if (chips[i].throttled) {
|
|
|
chips[i].throttled = false;
|
|
|
- pr_info("CPU %d on Chip %u has Pmax restored to %d\n", cpu,
|
|
|
- chips[i].id, pmsr_pmax);
|
|
|
+ trace_powernv_throttle(chips[i].id,
|
|
|
+ throttle_reason[chips[i].throttle_reason],
|
|
|
+ pmsr_pmax);
|
|
|
}
|
|
|
|
|
|
/* Check if Psafe_mode_active is set in PMSR. */
|
|
@@ -359,7 +370,7 @@ next:
|
|
|
|
|
|
if (throttled) {
|
|
|
pr_info("PMSR = %16lx\n", pmsr);
|
|
|
- pr_crit("CPU Frequency could be throttled\n");
|
|
|
+ pr_warn("CPU Frequency could be throttled\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -452,15 +463,6 @@ out:
|
|
|
put_online_cpus();
|
|
|
}
|
|
|
|
|
|
-static char throttle_reason[][30] = {
|
|
|
- "No throttling",
|
|
|
- "Power Cap",
|
|
|
- "Processor Over Temperature",
|
|
|
- "Power Supply Failure",
|
|
|
- "Over Current",
|
|
|
- "OCC Reset"
|
|
|
- };
|
|
|
-
|
|
|
static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
|
|
|
unsigned long msg_type, void *_msg)
|
|
|
{
|
|
@@ -486,7 +488,7 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
|
|
|
*/
|
|
|
if (!throttled) {
|
|
|
throttled = true;
|
|
|
- pr_crit("CPU frequency is throttled for duration\n");
|
|
|
+ pr_warn("CPU frequency is throttled for duration\n");
|
|
|
}
|
|
|
|
|
|
break;
|
|
@@ -510,23 +512,18 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (omsg.throttle_status &&
|
|
|
+ for (i = 0; i < nr_chips; i++)
|
|
|
+ if (chips[i].id == omsg.chip)
|
|
|
+ break;
|
|
|
+
|
|
|
+ if (omsg.throttle_status >= 0 &&
|
|
|
omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS)
|
|
|
- pr_info("OCC: Chip %u Pmax reduced due to %s\n",
|
|
|
- (unsigned int)omsg.chip,
|
|
|
- throttle_reason[omsg.throttle_status]);
|
|
|
- else if (!omsg.throttle_status)
|
|
|
- pr_info("OCC: Chip %u %s\n", (unsigned int)omsg.chip,
|
|
|
- throttle_reason[omsg.throttle_status]);
|
|
|
- else
|
|
|
- return 0;
|
|
|
+ chips[i].throttle_reason = omsg.throttle_status;
|
|
|
|
|
|
- for (i = 0; i < nr_chips; i++)
|
|
|
- if (chips[i].id == omsg.chip) {
|
|
|
- if (!omsg.throttle_status)
|
|
|
- chips[i].restore = true;
|
|
|
- schedule_work(&chips[i].throttle);
|
|
|
- }
|
|
|
+ if (!omsg.throttle_status)
|
|
|
+ chips[i].restore = true;
|
|
|
+
|
|
|
+ schedule_work(&chips[i].throttle);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -581,16 +578,14 @@ static int init_chip_info(void)
|
|
|
cpumask_andnot(&cpu_mask, &cpu_mask, cpu_sibling_mask(cpu));
|
|
|
}
|
|
|
|
|
|
- chips = kmalloc_array(nr_chips, sizeof(struct chip), GFP_KERNEL);
|
|
|
+ chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL);
|
|
|
if (!chips)
|
|
|
goto free_chip_map;
|
|
|
|
|
|
for (i = 0; i < nr_chips; i++) {
|
|
|
chips[i].id = chip[i];
|
|
|
- chips[i].throttled = false;
|
|
|
cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
|
|
|
INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
|
|
|
- chips[i].restore = false;
|
|
|
}
|
|
|
|
|
|
return 0;
|