diff options
| -rw-r--r-- | drivers/acpi/processor_idle.c | 1 | ||||
| -rw-r--r-- | drivers/idle/intel_idle.c | 61 |
2 files changed, 46 insertions, 16 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f4428e82b352..07a8bb6506f7 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -1013,7 +1013,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
| 1013 | strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); | 1013 | strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); |
| 1014 | state->exit_latency = cx->latency; | 1014 | state->exit_latency = cx->latency; |
| 1015 | state->target_residency = cx->latency * latency_factor; | 1015 | state->target_residency = cx->latency * latency_factor; |
| 1016 | state->power_usage = cx->power; | ||
| 1017 | 1016 | ||
| 1018 | state->flags = 0; | 1017 | state->flags = 0; |
| 1019 | switch (cx->type) { | 1018 | switch (cx->type) { |
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 */ |
