aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/idle/intel_idle.c
diff options
context:
space:
mode:
authorDavid Brown <davidb@codeaurora.org>2011-03-17 01:13:16 -0400
committerDavid Brown <davidb@codeaurora.org>2011-03-17 01:13:16 -0400
commit92c260f755c42337c550d8ac1f8ccd1b32bffb20 (patch)
tree6d04fefc1adeecabfb2b00c201e0db78fa2b5529 /drivers/idle/intel_idle.c
parent8e76a80960bf06c245160a484d5a363ca6b520bb (diff)
parent05e34754518b6a90d5c392790c032575fab12d66 (diff)
Merge remote branch 'rmk/for-linus' into for-linus
* rmk/for-linus: (1557 commits) ARM: 6806/1: irq: introduce entry and exit functions for chained handlers ARM: 6781/1: Thumb-2: Work around buggy Thumb-2 short branch relocations in gas ARM: 6747/1: P2V: Thumb2 support ARM: 6798/1: aout-core: zero thread debug registers in a.out core dump ARM: 6796/1: Footbridge: Fix I/O mappings for NOMMU mode ARM: 6784/1: errata: no automatic Store Buffer drain on Cortex-A9 ARM: 6772/1: errata: possible fault MMU translations following an ASID switch ARM: 6776/1: mach-ux500: activate fix for errata 753970 ARM: 6794/1: SPEAr: Append UL to device address macros. ARM: 6793/1: SPEAr: Remove unused *_SIZE macros from spear*.h files ARM: 6792/1: SPEAr: Replace SIZE macro's with SZ_4K macros ARM: 6791/1: SPEAr3xx: Declare device structures after shirq code ARM: 6790/1: SPEAr: Clock Framework: Rename usbd clock and align apb_clk entry ARM: 6789/1: SPEAr3xx: Rename sdio to sdhci ARM: 6788/1: SPEAr: Include mach/hardware.h instead of mach/spear.h ARM: 6787/1: SPEAr: Reorder #includes in .h & .c files. ARM: 6681/1: SPEAr: add debugfs support to clk API ARM: 6703/1: SPEAr: update clk API support ARM: 6679/1: SPEAr: make clk API functions more generic ARM: 6737/1: SPEAr: formalized timer support ... Conflicts: arch/arm/mach-msm/board-msm7x27.c arch/arm/mach-msm/board-msm7x30.c arch/arm/mach-msm/board-qsd8x50.c arch/arm/mach-msm/board-sapphire.c arch/arm/mach-msm/include/mach/memory.h
Diffstat (limited to 'drivers/idle/intel_idle.c')
-rw-r--r--drivers/idle/intel_idle.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 7acb32e7f817..4a5c4a44ffb1 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -62,6 +62,7 @@
62#include <linux/notifier.h> 62#include <linux/notifier.h>
63#include <linux/cpu.h> 63#include <linux/cpu.h>
64#include <asm/mwait.h> 64#include <asm/mwait.h>
65#include <asm/msr.h>
65 66
66#define INTEL_IDLE_VERSION "0.4" 67#define INTEL_IDLE_VERSION "0.4"
67#define PREFIX "intel_idle: " 68#define PREFIX "intel_idle: "
@@ -85,6 +86,12 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state);
85static struct cpuidle_state *cpuidle_state_table; 86static struct cpuidle_state *cpuidle_state_table;
86 87
87/* 88/*
89 * Hardware C-state auto-demotion may not always be optimal.
90 * Indicate which enable bits to clear here.
91 */
92static unsigned long long auto_demotion_disable_flags;
93
94/*
88 * Set this flag for states where the HW flushes the TLB for us 95 * Set this flag for states where the HW flushes the TLB for us
89 * and so we don't need cross-calls to keep it consistent. 96 * and so we don't need cross-calls to keep it consistent.
90 * If this flag is set, SW flushes the TLB, so even if the 97 * If this flag is set, SW flushes the TLB, so even if the
@@ -263,7 +270,7 @@ static void __setup_broadcast_timer(void *arg)
263 clockevents_notify(reason, &cpu); 270 clockevents_notify(reason, &cpu);
264} 271}
265 272
266static int __cpuinit setup_broadcast_cpuhp_notify(struct notifier_block *n, 273static int setup_broadcast_cpuhp_notify(struct notifier_block *n,
267 unsigned long action, void *hcpu) 274 unsigned long action, void *hcpu)
268{ 275{
269 int hotcpu = (unsigned long)hcpu; 276 int hotcpu = (unsigned long)hcpu;
@@ -273,18 +280,23 @@ static int __cpuinit setup_broadcast_cpuhp_notify(struct notifier_block *n,
273 smp_call_function_single(hotcpu, __setup_broadcast_timer, 280 smp_call_function_single(hotcpu, __setup_broadcast_timer,
274 (void *)true, 1); 281 (void *)true, 1);
275 break; 282 break;
276 case CPU_DOWN_PREPARE:
277 smp_call_function_single(hotcpu, __setup_broadcast_timer,
278 (void *)false, 1);
279 break;
280 } 283 }
281 return NOTIFY_OK; 284 return NOTIFY_OK;
282} 285}
283 286
284static struct notifier_block __cpuinitdata setup_broadcast_notifier = { 287static struct notifier_block setup_broadcast_notifier = {
285 .notifier_call = setup_broadcast_cpuhp_notify, 288 .notifier_call = setup_broadcast_cpuhp_notify,
286}; 289};
287 290
291static void auto_demotion_disable(void *dummy)
292{
293 unsigned long long msr_bits;
294
295 rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
296 msr_bits &= ~auto_demotion_disable_flags;
297 wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
298}
299
288/* 300/*
289 * intel_idle_probe() 301 * intel_idle_probe()
290 */ 302 */
@@ -328,11 +340,17 @@ static int intel_idle_probe(void)
328 case 0x25: /* Westmere */ 340 case 0x25: /* Westmere */
329 case 0x2C: /* Westmere */ 341 case 0x2C: /* Westmere */
330 cpuidle_state_table = nehalem_cstates; 342 cpuidle_state_table = nehalem_cstates;
343 auto_demotion_disable_flags =
344 (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE);
331 break; 345 break;
332 346
333 case 0x1C: /* 28 - Atom Processor */ 347 case 0x1C: /* 28 - Atom Processor */
348 cpuidle_state_table = atom_cstates;
349 break;
350
334 case 0x26: /* 38 - Lincroft Atom Processor */ 351 case 0x26: /* 38 - Lincroft Atom Processor */
335 cpuidle_state_table = atom_cstates; 352 cpuidle_state_table = atom_cstates;
353 auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE;
336 break; 354 break;
337 355
338 case 0x2A: /* SNB */ 356 case 0x2A: /* SNB */
@@ -440,6 +458,8 @@ static int intel_idle_cpuidle_devices_init(void)
440 return -EIO; 458 return -EIO;
441 } 459 }
442 } 460 }
461 if (auto_demotion_disable_flags)
462 smp_call_function(auto_demotion_disable, NULL, 1);
443 463
444 return 0; 464 return 0;
445} 465}