21 #include <linux/kernel.h>
23 #include <linux/module.h>
25 #include <linux/types.h>
30 #include <linux/slab.h>
35 #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad"
36 #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
37 #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
41 static unsigned long power_saving_mwait_eax;
43 static unsigned char tsc_detected_unstable;
44 static unsigned char tsc_marked_unstable;
45 static unsigned char lapic_detected_unstable;
46 static unsigned char lapic_marked_unstable;
48 static void power_saving_mwait_init(
void)
50 unsigned int eax,
ebx,
ecx, edx;
51 unsigned int highest_cstate = 0;
52 unsigned int highest_subcstate = 0;
74 (highest_subcstate - 1);
76 #if defined(CONFIG_X86)
85 tsc_detected_unstable = 1;
87 lapic_detected_unstable = 1;
91 tsc_detected_unstable = 1;
92 lapic_detected_unstable = 1;
97 static unsigned long cpu_weight[
NR_CPUS];
100 static void round_robin_cpu(
unsigned int tsk_index)
115 cpumask_andnot(tmp, cpu_online_mask, tmp);
117 if (cpumask_empty(tmp))
118 cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus);
119 if (cpumask_empty(tmp)) {
124 if (cpu_weight[cpu] < min_weight) {
125 min_weight = cpu_weight[
cpu];
130 if (tsk_in_cpu[tsk_index] != -1)
131 cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
132 tsk_in_cpu[tsk_index] = preferred_cpu;
133 cpumask_set_cpu(preferred_cpu, pad_busy_cpus);
134 cpu_weight[preferred_cpu]++;
140 static void exit_round_robin(
unsigned int tsk_index)
143 cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
144 tsk_in_cpu[tsk_index] = -1;
147 static unsigned int idle_pct = 5;
148 static unsigned int round_robin_time = 1;
149 static int power_saving_thread(
void *
data)
153 unsigned int tsk_index = (
unsigned long)data;
154 u64 last_jiffies = 0;
165 if (last_jiffies + round_robin_time *
HZ < jiffies) {
167 round_robin_cpu(tsk_index);
172 expire_time =
jiffies +
HZ * (100 - idle_pct) / 100;
174 while (!need_resched()) {
175 if (tsc_detected_unstable && !tsc_marked_unstable) {
178 tsc_marked_unstable = 1;
180 if (lapic_detected_unstable && !lapic_marked_unstable) {
185 CLOCK_EVT_NOTIFY_BROADCAST_ON,
187 lapic_marked_unstable = 1;
191 if (lapic_marked_unstable)
193 CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
199 __mwait(power_saving_mwait_eax, 1);
202 if (lapic_marked_unstable)
204 CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
207 if (jiffies > expire_time) {
226 exit_round_robin(tsk_index);
231 static unsigned int ps_tsk_num;
232 static int create_power_saving_task(
void)
236 ps_tsks[ps_tsk_num] =
kthread_run(power_saving_thread,
237 (
void *)(
unsigned long)ps_tsk_num,
238 "acpi_pad/%d", ps_tsk_num);
239 rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0;
243 ps_tsks[ps_tsk_num] =
NULL;
248 static void destroy_power_saving_task(
void)
250 if (ps_tsk_num > 0) {
253 ps_tsks[ps_tsk_num] =
NULL;
257 static void set_power_saving_task_num(
unsigned int num)
259 if (num > ps_tsk_num) {
260 while (ps_tsk_num < num) {
261 if (create_power_saving_task())
264 }
else if (num < ps_tsk_num) {
265 while (ps_tsk_num > num)
266 destroy_power_saving_task();
270 static void acpi_pad_idle_cpus(
unsigned int num_cpus)
275 set_power_saving_task_num(num_cpus);
280 static uint32_t acpi_pad_idle_cpus_num(
void)
291 if (num < 1 || num >= 100)
294 round_robin_time = num;
305 acpi_pad_rrtime_show,
306 acpi_pad_rrtime_store);
314 if (num < 1 || num >= 100)
328 acpi_pad_idlepct_show,
329 acpi_pad_idlepct_store);
338 acpi_pad_idle_cpus(num);
353 acpi_pad_idlecpus_show,
354 acpi_pad_idlecpus_store);
356 static int acpi_pad_add_sysfs(
struct acpi_device *
device)
377 static void acpi_pad_remove_sysfs(
struct acpi_device *device)
400 package = buffer.pointer;
404 package->
package.elements[0].integer.value == 1)
406 num = package->
package.elements[1].integer.value;
425 params[2].
buffer.length = 4;
426 params[2].
buffer.pointer = (
void *)&idle_cpus;
430 static void acpi_pad_handle_notify(
acpi_handle handle)
436 num_cpus = acpi_pad_pur(handle);
441 acpi_pad_idle_cpus(num_cpus);
442 idle_cpus = acpi_pad_idle_cpus_num();
443 acpi_pad_ost(handle, 0, idle_cpus);
450 struct acpi_device *device =
data;
454 acpi_pad_handle_notify(handle);
455 acpi_bus_generate_proc_event(device, event, 0);
457 dev_name(&device->dev), event, 0);
465 static int acpi_pad_add(
struct acpi_device *device)
472 if (acpi_pad_add_sysfs(device))
478 acpi_pad_remove_sysfs(device);
485 static int acpi_pad_remove(
struct acpi_device *device,
489 acpi_pad_idle_cpus(0);
494 acpi_pad_remove_sysfs(device);
504 static struct acpi_driver acpi_pad_driver = {
505 .name =
"processor_aggregator",
507 .ids = pad_device_ids,
510 .remove = acpi_pad_remove,
514 static int __init acpi_pad_init(
void)
516 power_saving_mwait_init();
517 if (power_saving_mwait_eax == 0)
523 static void __exit acpi_pad_exit(
void)