aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r--drivers/acpi/processor_idle.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 71066066d626..0a395fca843b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -38,6 +38,7 @@
38#include <linux/dmi.h> 38#include <linux/dmi.h>
39#include <linux/moduleparam.h> 39#include <linux/moduleparam.h>
40#include <linux/sched.h> /* need_resched() */ 40#include <linux/sched.h> /* need_resched() */
41#include <linux/latency.h>
41 42
42#include <asm/io.h> 43#include <asm/io.h>
43#include <asm/uaccess.h> 44#include <asm/uaccess.h>
@@ -453,7 +454,8 @@ static void acpi_processor_idle(void)
453 */ 454 */
454 if (cx->promotion.state && 455 if (cx->promotion.state &&
455 ((cx->promotion.state - pr->power.states) <= max_cstate)) { 456 ((cx->promotion.state - pr->power.states) <= max_cstate)) {
456 if (sleep_ticks > cx->promotion.threshold.ticks) { 457 if (sleep_ticks > cx->promotion.threshold.ticks &&
458 cx->promotion.state->latency <= system_latency_constraint()) {
457 cx->promotion.count++; 459 cx->promotion.count++;
458 cx->demotion.count = 0; 460 cx->demotion.count = 0;
459 if (cx->promotion.count >= 461 if (cx->promotion.count >=
@@ -494,8 +496,10 @@ static void acpi_processor_idle(void)
494 end: 496 end:
495 /* 497 /*
496 * Demote if current state exceeds max_cstate 498 * Demote if current state exceeds max_cstate
499 * or if the latency of the current state is unacceptable
497 */ 500 */
498 if ((pr->power.state - pr->power.states) > max_cstate) { 501 if ((pr->power.state - pr->power.states) > max_cstate ||
502 pr->power.state->latency > system_latency_constraint()) {
499 if (cx->demotion.state) 503 if (cx->demotion.state)
500 next_state = cx->demotion.state; 504 next_state = cx->demotion.state;
501 } 505 }
@@ -1009,9 +1013,11 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
1009 1013
1010 seq_printf(seq, "active state: C%zd\n" 1014 seq_printf(seq, "active state: C%zd\n"
1011 "max_cstate: C%d\n" 1015 "max_cstate: C%d\n"
1012 "bus master activity: %08x\n", 1016 "bus master activity: %08x\n"
1017 "maximum allowed latency: %d usec\n",
1013 pr->power.state ? pr->power.state - pr->power.states : 0, 1018 pr->power.state ? pr->power.state - pr->power.states : 0,
1014 max_cstate, (unsigned)pr->power.bm_activity); 1019 max_cstate, (unsigned)pr->power.bm_activity,
1020 system_latency_constraint());
1015 1021
1016 seq_puts(seq, "states:\n"); 1022 seq_puts(seq, "states:\n");
1017 1023
@@ -1077,6 +1083,28 @@ static const struct file_operations acpi_processor_power_fops = {
1077 .release = single_release, 1083 .release = single_release,
1078}; 1084};
1079 1085
1086static void smp_callback(void *v)
1087{
1088 /* we already woke the CPU up, nothing more to do */
1089}
1090
1091/*
1092 * This function gets called when a part of the kernel has a new latency
1093 * requirement. This means we need to get all processors out of their C-state,
1094 * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
1095 * wakes them all right up.
1096 */
1097static int acpi_processor_latency_notify(struct notifier_block *b,
1098 unsigned long l, void *v)
1099{
1100 smp_call_function(smp_callback, NULL, 0, 1);
1101 return NOTIFY_OK;
1102}
1103
1104static struct notifier_block acpi_processor_latency_notifier = {
1105 .notifier_call = acpi_processor_latency_notify,
1106};
1107
1080int acpi_processor_power_init(struct acpi_processor *pr, 1108int acpi_processor_power_init(struct acpi_processor *pr,
1081 struct acpi_device *device) 1109 struct acpi_device *device)
1082{ 1110{
@@ -1093,6 +1121,7 @@ int acpi_processor_power_init(struct acpi_processor *pr,
1093 "ACPI: processor limited to max C-state %d\n", 1121 "ACPI: processor limited to max C-state %d\n",
1094 max_cstate); 1122 max_cstate);
1095 first_run++; 1123 first_run++;
1124 register_latency_notifier(&acpi_processor_latency_notifier);
1096 } 1125 }
1097 1126
1098 if (!pr) 1127 if (!pr)
@@ -1164,6 +1193,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
1164 * copies of pm_idle before proceeding. 1193 * copies of pm_idle before proceeding.
1165 */ 1194 */
1166 cpu_idle_wait(); 1195 cpu_idle_wait();
1196 unregister_latency_notifier(&acpi_processor_latency_notifier);
1167 } 1197 }
1168 1198
1169 return 0; 1199 return 0;