aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/acpi/cstate.c70
1 files changed, 37 insertions, 33 deletions
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index c2502eb9aa83..cf5ec586f220 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -66,35 +66,15 @@ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
66 66
67#define NATIVE_CSTATE_BEYOND_HALT (2) 67#define NATIVE_CSTATE_BEYOND_HALT (2)
68 68
69int acpi_processor_ffh_cstate_probe(unsigned int cpu, 69static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
70 struct acpi_processor_cx *cx, struct acpi_power_register *reg)
71{ 70{
72 struct cstate_entry *percpu_entry; 71 struct acpi_processor_cx *cx = _cx;
73 struct cpuinfo_x86 *c = &cpu_data(cpu); 72 long retval;
74
75 cpumask_t saved_mask;
76 int retval;
77 unsigned int eax, ebx, ecx, edx; 73 unsigned int eax, ebx, ecx, edx;
78 unsigned int edx_part; 74 unsigned int edx_part;
79 unsigned int cstate_type; /* C-state type and not ACPI C-state type */ 75 unsigned int cstate_type; /* C-state type and not ACPI C-state type */
80 unsigned int num_cstate_subtype; 76 unsigned int num_cstate_subtype;
81 77
82 if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF )
83 return -1;
84
85 if (reg->bit_offset != NATIVE_CSTATE_BEYOND_HALT)
86 return -1;
87
88 percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
89 percpu_entry->states[cx->index].eax = 0;
90 percpu_entry->states[cx->index].ecx = 0;
91
92 /* Make sure we are running on right CPU */
93 saved_mask = current->cpus_allowed;
94 retval = set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
95 if (retval)
96 return -1;
97
98 cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); 78 cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
99 79
100 /* Check whether this particular cx_type (in CST) is supported or not */ 80 /* Check whether this particular cx_type (in CST) is supported or not */
@@ -114,21 +94,45 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
114 retval = -1; 94 retval = -1;
115 goto out; 95 goto out;
116 } 96 }
117 percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
118
119 /* Use the hint in CST */
120 percpu_entry->states[cx->index].eax = cx->address;
121 97
122 if (!mwait_supported[cstate_type]) { 98 if (!mwait_supported[cstate_type]) {
123 mwait_supported[cstate_type] = 1; 99 mwait_supported[cstate_type] = 1;
124 printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d " 100 printk(KERN_DEBUG
125 "state\n", cx->type); 101 "Monitor-Mwait will be used to enter C-%d "
102 "state\n", cx->type);
126 } 103 }
127 snprintf(cx->desc, ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x", 104 snprintf(cx->desc,
128 cx->address); 105 ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x",
129 106 cx->address);
130out: 107out:
131 set_cpus_allowed_ptr(current, &saved_mask); 108 return retval;
109}
110
111int acpi_processor_ffh_cstate_probe(unsigned int cpu,
112 struct acpi_processor_cx *cx, struct acpi_power_register *reg)
113{
114 struct cstate_entry *percpu_entry;
115 struct cpuinfo_x86 *c = &cpu_data(cpu);
116 long retval;
117
118 if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF)
119 return -1;
120
121 if (reg->bit_offset != NATIVE_CSTATE_BEYOND_HALT)
122 return -1;
123
124 percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
125 percpu_entry->states[cx->index].eax = 0;
126 percpu_entry->states[cx->index].ecx = 0;
127
128 /* Make sure we are running on right CPU */
129
130 retval = work_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx);
131 if (retval == 0) {
132 /* Use the hint in CST */
133 percpu_entry->states[cx->index].eax = cx->address;
134 percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
135 }
132 return retval; 136 return retval;
133} 137}
134EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); 138EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);