diff options
| -rw-r--r-- | drivers/acpi/processor_driver.c | 2 | ||||
| -rw-r--r-- | drivers/cpuidle/governors/menu.c | 2 | ||||
| -rw-r--r--[-rwxr-xr-x] | drivers/idle/intel_idle.c | 20 | ||||
| -rw-r--r-- | drivers/pci/quirks.c | 20 | ||||
| -rw-r--r-- | include/linux/cpuidle.h | 1 |
5 files changed, 38 insertions, 7 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 156021892389..347eb21b2353 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
| @@ -850,7 +850,7 @@ static int __init acpi_processor_init(void) | |||
| 850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", | 850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
| 851 | acpi_idle_driver.name); | 851 | acpi_idle_driver.name); |
| 852 | } else { | 852 | } else { |
| 853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s", | 853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n", |
| 854 | cpuidle_get_driver()->name); | 854 | cpuidle_get_driver()->name); |
| 855 | } | 855 | } |
| 856 | 856 | ||
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c2408bbe9c2e..f508690eb958 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
| @@ -80,7 +80,7 @@ | |||
| 80 | * Limiting Performance Impact | 80 | * Limiting Performance Impact |
| 81 | * --------------------------- | 81 | * --------------------------- |
| 82 | * C states, especially those with large exit latencies, can have a real | 82 | * C states, especially those with large exit latencies, can have a real |
| 83 | * noticable impact on workloads, which is not acceptable for most sysadmins, | 83 | * noticeable impact on workloads, which is not acceptable for most sysadmins, |
| 84 | * and in addition, less performance has a power price of its own. | 84 | * and in addition, less performance has a power price of its own. |
| 85 | * | 85 | * |
| 86 | * As a general rule of thumb, menu assumes that the following heuristic | 86 | * As a general rule of thumb, menu assumes that the following heuristic |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a10152bb1427..0906fc5b69b9 100755..100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
| @@ -83,7 +83,7 @@ static unsigned int mwait_substates; | |||
| 83 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ | 83 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ |
| 84 | static unsigned int lapic_timer_reliable_states; | 84 | static unsigned int lapic_timer_reliable_states; |
| 85 | 85 | ||
| 86 | static struct cpuidle_device *intel_idle_cpuidle_devices; | 86 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; |
| 87 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); | 87 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); |
| 88 | 88 | ||
| 89 | static struct cpuidle_state *cpuidle_state_table; | 89 | static struct cpuidle_state *cpuidle_state_table; |
| @@ -108,7 +108,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
| 108 | .name = "NHM-C3", | 108 | .name = "NHM-C3", |
| 109 | .desc = "MWAIT 0x10", | 109 | .desc = "MWAIT 0x10", |
| 110 | .driver_data = (void *) 0x10, | 110 | .driver_data = (void *) 0x10, |
| 111 | .flags = CPUIDLE_FLAG_TIME_VALID, | 111 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
| 112 | .exit_latency = 20, | 112 | .exit_latency = 20, |
| 113 | .power_usage = 500, | 113 | .power_usage = 500, |
| 114 | .target_residency = 80, | 114 | .target_residency = 80, |
| @@ -117,7 +117,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
| 117 | .name = "NHM-C6", | 117 | .name = "NHM-C6", |
| 118 | .desc = "MWAIT 0x20", | 118 | .desc = "MWAIT 0x20", |
| 119 | .driver_data = (void *) 0x20, | 119 | .driver_data = (void *) 0x20, |
| 120 | .flags = CPUIDLE_FLAG_TIME_VALID, | 120 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
| 121 | .exit_latency = 200, | 121 | .exit_latency = 200, |
| 122 | .power_usage = 350, | 122 | .power_usage = 350, |
| 123 | .target_residency = 800, | 123 | .target_residency = 800, |
| @@ -149,7 +149,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
| 149 | .name = "ATM-C4", | 149 | .name = "ATM-C4", |
| 150 | .desc = "MWAIT 0x30", | 150 | .desc = "MWAIT 0x30", |
| 151 | .driver_data = (void *) 0x30, | 151 | .driver_data = (void *) 0x30, |
| 152 | .flags = CPUIDLE_FLAG_TIME_VALID, | 152 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
| 153 | .exit_latency = 100, | 153 | .exit_latency = 100, |
| 154 | .power_usage = 250, | 154 | .power_usage = 250, |
| 155 | .target_residency = 400, | 155 | .target_residency = 400, |
| @@ -159,7 +159,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
| 159 | .name = "ATM-C6", | 159 | .name = "ATM-C6", |
| 160 | .desc = "MWAIT 0x40", | 160 | .desc = "MWAIT 0x40", |
| 161 | .driver_data = (void *) 0x40, | 161 | .driver_data = (void *) 0x40, |
| 162 | .flags = CPUIDLE_FLAG_TIME_VALID, | 162 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
| 163 | .exit_latency = 200, | 163 | .exit_latency = 200, |
| 164 | .power_usage = 150, | 164 | .power_usage = 150, |
| 165 | .target_residency = 800, | 165 | .target_residency = 800, |
| @@ -185,6 +185,16 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) | |||
| 185 | 185 | ||
| 186 | local_irq_disable(); | 186 | local_irq_disable(); |
| 187 | 187 | ||
| 188 | /* | ||
| 189 | * If the state flag indicates that the TLB will be flushed or if this | ||
| 190 | * is the deepest c-state supported, do a voluntary leave mm to avoid | ||
| 191 | * costly and mostly unnecessary wakeups for flushing the user TLB's | ||
| 192 | * associated with the active mm. | ||
| 193 | */ | ||
| 194 | if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED || | ||
| 195 | (&dev->states[dev->state_count - 1] == state)) | ||
| 196 | leave_mm(cpu); | ||
| 197 | |||
| 188 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 198 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) |
| 189 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | 199 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); |
| 190 | 200 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 89ed181cd90c..857ae01734a6 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -163,6 +163,26 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_d | |||
| 163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); | 163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); |
| 164 | 164 | ||
| 165 | /* | 165 | /* |
| 166 | * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear | ||
| 167 | * for some HT machines to use C4 w/o hanging. | ||
| 168 | */ | ||
| 169 | static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev) | ||
| 170 | { | ||
| 171 | u32 pmbase; | ||
| 172 | u16 pm1a; | ||
| 173 | |||
| 174 | pci_read_config_dword(dev, 0x40, &pmbase); | ||
| 175 | pmbase = pmbase & 0xff80; | ||
| 176 | pm1a = inw(pmbase); | ||
| 177 | |||
| 178 | if (pm1a & 0x10) { | ||
| 179 | dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n"); | ||
| 180 | outw(0x10, pmbase); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts); | ||
| 184 | |||
| 185 | /* | ||
| 166 | * Chipsets where PCI->PCI transfers vanish or hang | 186 | * Chipsets where PCI->PCI transfers vanish or hang |
| 167 | */ | 187 | */ |
| 168 | static void __devinit quirk_nopcipci(struct pci_dev *dev) | 188 | static void __devinit quirk_nopcipci(struct pci_dev *dev) |
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 36ca9721a0c2..1be416bbbb82 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
| @@ -53,6 +53,7 @@ struct cpuidle_state { | |||
| 53 | #define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */ | 53 | #define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */ |
| 54 | #define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */ | 54 | #define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */ |
| 55 | #define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ | 55 | #define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ |
| 56 | #define CPUIDLE_FLAG_TLB_FLUSHED (0x200) /* tlb will be flushed */ | ||
| 56 | 57 | ||
| 57 | #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) | 58 | #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) |
| 58 | 59 | ||
