diff options
author | Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | 2005-04-15 15:07:10 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-07-12 00:14:36 -0400 |
commit | 02df8b9385c21fdba165bd380f60eca1d3b0578b (patch) | |
tree | 988ad0e0ca73a40993fb1458d5cd19f90f922b31 /arch | |
parent | 17e9c78a75ce9eacd61200f9e1f1924012e28846 (diff) |
[ACPI] enable C2 and C3 idle power states on SMP
http://bugzilla.kernel.org/show_bug.cgi?id=4401
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/acpi/Makefile | 4 | ||||
-rw-r--r-- | arch/i386/kernel/acpi/cstate.c | 103 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 2 |
3 files changed, 108 insertions, 1 deletions
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index ee75cb286cfe..5e291a20c03d 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile | |||
@@ -2,3 +2,7 @@ obj-$(CONFIG_ACPI_BOOT) := boot.o | |||
2 | obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o | 2 | obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o |
3 | obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o | 3 | obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o |
4 | 4 | ||
5 | ifneq ($(CONFIG_ACPI_PROCESSOR),) | ||
6 | obj-y += cstate.o | ||
7 | endif | ||
8 | |||
diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c new file mode 100644 index 000000000000..4c3036ba65df --- /dev/null +++ b/arch/i386/kernel/acpi/cstate.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * arch/i386/kernel/acpi/cstate.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Intel Corporation | ||
5 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
6 | * - Added _PDC for SMP C-states on Intel CPUs | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/acpi.h> | ||
13 | |||
14 | #include <acpi/processor.h> | ||
15 | #include <asm/acpi.h> | ||
16 | |||
17 | static void acpi_processor_power_init_intel_pdc(struct acpi_processor_power | ||
18 | *pow) | ||
19 | { | ||
20 | struct acpi_object_list *obj_list; | ||
21 | union acpi_object *obj; | ||
22 | u32 *buf; | ||
23 | |||
24 | /* allocate and initialize pdc. It will be used later. */ | ||
25 | obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); | ||
26 | if (!obj_list) { | ||
27 | printk(KERN_ERR "Memory allocation error\n"); | ||
28 | return; | ||
29 | } | ||
30 | |||
31 | obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); | ||
32 | if (!obj) { | ||
33 | printk(KERN_ERR "Memory allocation error\n"); | ||
34 | kfree(obj_list); | ||
35 | return; | ||
36 | } | ||
37 | |||
38 | buf = kmalloc(12, GFP_KERNEL); | ||
39 | if (!buf) { | ||
40 | printk(KERN_ERR "Memory allocation error\n"); | ||
41 | kfree(obj); | ||
42 | kfree(obj_list); | ||
43 | return; | ||
44 | } | ||
45 | |||
46 | buf[0] = ACPI_PDC_REVISION_ID; | ||
47 | buf[1] = 1; | ||
48 | buf[2] = ACPI_PDC_C_CAPABILITY_SMP; | ||
49 | |||
50 | obj->type = ACPI_TYPE_BUFFER; | ||
51 | obj->buffer.length = 12; | ||
52 | obj->buffer.pointer = (u8 *) buf; | ||
53 | obj_list->count = 1; | ||
54 | obj_list->pointer = obj; | ||
55 | pow->pdc = obj_list; | ||
56 | |||
57 | return; | ||
58 | } | ||
59 | |||
60 | /* Initialize _PDC data based on the CPU vendor */ | ||
61 | void acpi_processor_power_init_pdc(struct acpi_processor_power *pow, | ||
62 | unsigned int cpu) | ||
63 | { | ||
64 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
65 | |||
66 | pow->pdc = NULL; | ||
67 | if (c->x86_vendor == X86_VENDOR_INTEL) | ||
68 | acpi_processor_power_init_intel_pdc(pow); | ||
69 | |||
70 | return; | ||
71 | } | ||
72 | |||
73 | EXPORT_SYMBOL(acpi_processor_power_init_pdc); | ||
74 | |||
75 | /* | ||
76 | * Initialize bm_flags based on the CPU cache properties | ||
77 | * On SMP it depends on cache configuration | ||
78 | * - When cache is not shared among all CPUs, we flush cache | ||
79 | * before entering C3. | ||
80 | * - When cache is shared among all CPUs, we use bm_check | ||
81 | * mechanism as in UP case | ||
82 | * | ||
83 | * This routine is called only after all the CPUs are online | ||
84 | */ | ||
85 | void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, | ||
86 | unsigned int cpu) | ||
87 | { | ||
88 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
89 | |||
90 | flags->bm_check = 0; | ||
91 | if (num_online_cpus() == 1) | ||
92 | flags->bm_check = 1; | ||
93 | else if (c->x86_vendor == X86_VENDOR_INTEL) { | ||
94 | /* | ||
95 | * Today all CPUs that support C3 share cache. | ||
96 | * TBD: This needs to look at cache shared map, once | ||
97 | * multi-core detection patch makes to the base. | ||
98 | */ | ||
99 | flags->bm_check = 1; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | EXPORT_SYMBOL(acpi_processor_power_init_bm_check); | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 7dcbf70fc16f..327a55d4d1c6 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | |||
@@ -375,7 +375,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) | |||
375 | arg0.buffer.pointer = (u8 *) arg0_buf; | 375 | arg0.buffer.pointer = (u8 *) arg0_buf; |
376 | arg0_buf[0] = ACPI_PDC_REVISION_ID; | 376 | arg0_buf[0] = ACPI_PDC_REVISION_ID; |
377 | arg0_buf[1] = 1; | 377 | arg0_buf[1] = 1; |
378 | arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_MSR; | 378 | arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP_MSR; |
379 | 379 | ||
380 | p.pdc = &arg_list; | 380 | p.pdc = &arg_list; |
381 | 381 | ||