diff options
Diffstat (limited to 'drivers/idle')
-rw-r--r-- | drivers/idle/intel_idle.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index cb3ccf3ed221..41665d2f9f93 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -74,7 +74,7 @@ static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1; | |||
74 | static unsigned int mwait_substates; | 74 | static unsigned int mwait_substates; |
75 | 75 | ||
76 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ | 76 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ |
77 | static unsigned int lapic_timer_reliable_states; | 77 | static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ |
78 | 78 | ||
79 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; | 79 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; |
80 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); | 80 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); |
@@ -94,7 +94,6 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
94 | .driver_data = (void *) 0x00, | 94 | .driver_data = (void *) 0x00, |
95 | .flags = CPUIDLE_FLAG_TIME_VALID, | 95 | .flags = CPUIDLE_FLAG_TIME_VALID, |
96 | .exit_latency = 3, | 96 | .exit_latency = 3, |
97 | .power_usage = 1000, | ||
98 | .target_residency = 6, | 97 | .target_residency = 6, |
99 | .enter = &intel_idle }, | 98 | .enter = &intel_idle }, |
100 | { /* MWAIT C2 */ | 99 | { /* MWAIT C2 */ |
@@ -103,7 +102,6 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
103 | .driver_data = (void *) 0x10, | 102 | .driver_data = (void *) 0x10, |
104 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | 103 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
105 | .exit_latency = 20, | 104 | .exit_latency = 20, |
106 | .power_usage = 500, | ||
107 | .target_residency = 80, | 105 | .target_residency = 80, |
108 | .enter = &intel_idle }, | 106 | .enter = &intel_idle }, |
109 | { /* MWAIT C3 */ | 107 | { /* MWAIT C3 */ |
@@ -112,11 +110,46 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
112 | .driver_data = (void *) 0x20, | 110 | .driver_data = (void *) 0x20, |
113 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | 111 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
114 | .exit_latency = 200, | 112 | .exit_latency = 200, |
115 | .power_usage = 350, | ||
116 | .target_residency = 800, | 113 | .target_residency = 800, |
117 | .enter = &intel_idle }, | 114 | .enter = &intel_idle }, |
118 | }; | 115 | }; |
119 | 116 | ||
117 | static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = { | ||
118 | { /* MWAIT C0 */ }, | ||
119 | { /* MWAIT C1 */ | ||
120 | .name = "SNB-C1", | ||
121 | .desc = "MWAIT 0x00", | ||
122 | .driver_data = (void *) 0x00, | ||
123 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
124 | .exit_latency = 1, | ||
125 | .target_residency = 4, | ||
126 | .enter = &intel_idle }, | ||
127 | { /* MWAIT C2 */ | ||
128 | .name = "SNB-C3", | ||
129 | .desc = "MWAIT 0x10", | ||
130 | .driver_data = (void *) 0x10, | ||
131 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
132 | .exit_latency = 80, | ||
133 | .target_residency = 160, | ||
134 | .enter = &intel_idle }, | ||
135 | { /* MWAIT C3 */ | ||
136 | .name = "SNB-C6", | ||
137 | .desc = "MWAIT 0x20", | ||
138 | .driver_data = (void *) 0x20, | ||
139 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
140 | .exit_latency = 104, | ||
141 | .target_residency = 208, | ||
142 | .enter = &intel_idle }, | ||
143 | { /* MWAIT C4 */ | ||
144 | .name = "SNB-C7", | ||
145 | .desc = "MWAIT 0x30", | ||
146 | .driver_data = (void *) 0x30, | ||
147 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
148 | .exit_latency = 109, | ||
149 | .target_residency = 300, | ||
150 | .enter = &intel_idle }, | ||
151 | }; | ||
152 | |||
120 | static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | 153 | static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { |
121 | { /* MWAIT C0 */ }, | 154 | { /* MWAIT C0 */ }, |
122 | { /* MWAIT C1 */ | 155 | { /* MWAIT C1 */ |
@@ -125,7 +158,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
125 | .driver_data = (void *) 0x00, | 158 | .driver_data = (void *) 0x00, |
126 | .flags = CPUIDLE_FLAG_TIME_VALID, | 159 | .flags = CPUIDLE_FLAG_TIME_VALID, |
127 | .exit_latency = 1, | 160 | .exit_latency = 1, |
128 | .power_usage = 1000, | ||
129 | .target_residency = 4, | 161 | .target_residency = 4, |
130 | .enter = &intel_idle }, | 162 | .enter = &intel_idle }, |
131 | { /* MWAIT C2 */ | 163 | { /* MWAIT C2 */ |
@@ -134,7 +166,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
134 | .driver_data = (void *) 0x10, | 166 | .driver_data = (void *) 0x10, |
135 | .flags = CPUIDLE_FLAG_TIME_VALID, | 167 | .flags = CPUIDLE_FLAG_TIME_VALID, |
136 | .exit_latency = 20, | 168 | .exit_latency = 20, |
137 | .power_usage = 500, | ||
138 | .target_residency = 80, | 169 | .target_residency = 80, |
139 | .enter = &intel_idle }, | 170 | .enter = &intel_idle }, |
140 | { /* MWAIT C3 */ }, | 171 | { /* MWAIT C3 */ }, |
@@ -144,7 +175,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
144 | .driver_data = (void *) 0x30, | 175 | .driver_data = (void *) 0x30, |
145 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | 176 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
146 | .exit_latency = 100, | 177 | .exit_latency = 100, |
147 | .power_usage = 250, | ||
148 | .target_residency = 400, | 178 | .target_residency = 400, |
149 | .enter = &intel_idle }, | 179 | .enter = &intel_idle }, |
150 | { /* MWAIT C5 */ }, | 180 | { /* MWAIT C5 */ }, |
@@ -154,7 +184,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
154 | .driver_data = (void *) 0x52, | 184 | .driver_data = (void *) 0x52, |
155 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | 185 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
156 | .exit_latency = 140, | 186 | .exit_latency = 140, |
157 | .power_usage = 150, | ||
158 | .target_residency = 560, | 187 | .target_residency = 560, |
159 | .enter = &intel_idle }, | 188 | .enter = &intel_idle }, |
160 | }; | 189 | }; |
@@ -179,13 +208,10 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) | |||
179 | local_irq_disable(); | 208 | local_irq_disable(); |
180 | 209 | ||
181 | /* | 210 | /* |
182 | * If the state flag indicates that the TLB will be flushed or if this | 211 | * leave_mm() to avoid costly and often unnecessary wakeups |
183 | * is the deepest c-state supported, do a voluntary leave mm to avoid | 212 | * for flushing the user TLB's associated with the active mm. |
184 | * costly and mostly unnecessary wakeups for flushing the user TLB's | ||
185 | * associated with the active mm. | ||
186 | */ | 213 | */ |
187 | if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED || | 214 | if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED) |
188 | (&dev->states[dev->state_count - 1] == state)) | ||
189 | leave_mm(cpu); | 215 | leave_mm(cpu); |
190 | 216 | ||
191 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 217 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) |
@@ -269,9 +295,14 @@ static int intel_idle_probe(void) | |||
269 | 295 | ||
270 | case 0x1C: /* 28 - Atom Processor */ | 296 | case 0x1C: /* 28 - Atom Processor */ |
271 | case 0x26: /* 38 - Lincroft Atom Processor */ | 297 | case 0x26: /* 38 - Lincroft Atom Processor */ |
272 | lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ | 298 | lapic_timer_reliable_states = (1 << 1); /* C1 */ |
273 | cpuidle_state_table = atom_cstates; | 299 | cpuidle_state_table = atom_cstates; |
274 | break; | 300 | break; |
301 | |||
302 | case 0x2A: /* SNB */ | ||
303 | case 0x2D: /* SNB Xeon */ | ||
304 | cpuidle_state_table = snb_cstates; | ||
305 | break; | ||
275 | #ifdef FUTURE_USE | 306 | #ifdef FUTURE_USE |
276 | case 0x17: /* 23 - Core 2 Duo */ | 307 | case 0x17: /* 23 - Core 2 Duo */ |
277 | lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ | 308 | lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ |