Commit b66b8b9a4a79087dde1b358a016e5c8739ccf186

Authored by Andi Kleen
Committed by Greg Kroah-Hartman
1 parent 3bd391f056

intel-idle: convert to x86_cpu_id auto probing

With this it should be automatically loaded on suitable systems by
udev.

The old switch () is replaced with a table based approach, this
also cleans up the code.

Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Thomas Renninger <trenn@suse.de>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 1 changed file with 66 additions and 50 deletions Side-by-side Diff

drivers/idle/intel_idle.c
... ... @@ -62,6 +62,7 @@
62 62 #include <linux/notifier.h>
63 63 #include <linux/cpu.h>
64 64 #include <linux/module.h>
  65 +#include <asm/cpu_device_id.h>
65 66 #include <asm/mwait.h>
66 67 #include <asm/msr.h>
67 68  
... ... @@ -81,6 +82,17 @@
81 82 /* Reliable LAPIC Timer States, bit 1 for C1 etc. */
82 83 static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */
83 84  
  85 +struct idle_cpu {
  86 + struct cpuidle_state *state_table;
  87 +
  88 + /*
  89 + * Hardware C-state auto-demotion may not always be optimal.
  90 + * Indicate which enable bits to clear here.
  91 + */
  92 + unsigned long auto_demotion_disable_flags;
  93 +};
  94 +
  95 +static const struct idle_cpu *icpu;
84 96 static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
85 97 static int intel_idle(struct cpuidle_device *dev,
86 98 struct cpuidle_driver *drv, int index);
... ... @@ -88,12 +100,6 @@
88 100 static struct cpuidle_state *cpuidle_state_table;
89 101  
90 102 /*
91   - * Hardware C-state auto-demotion may not always be optimal.
92   - * Indicate which enable bits to clear here.
93   - */
94   -static unsigned long long auto_demotion_disable_flags;
95   -
96   -/*
97 103 * Set this flag for states where the HW flushes the TLB for us
98 104 * and so we don't need cross-calls to keep it consistent.
99 105 * If this flag is set, SW flushes the TLB, so even if the
100 106  
101 107  
102 108  
103 109  
104 110  
... ... @@ -319,28 +325,73 @@
319 325 unsigned long long msr_bits;
320 326  
321 327 rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
322   - msr_bits &= ~auto_demotion_disable_flags;
  328 + msr_bits &= ~(icpu->auto_demotion_disable_flags);
323 329 wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
324 330 }
325 331  
  332 +static const struct idle_cpu idle_cpu_nehalem = {
  333 + .state_table = nehalem_cstates,
  334 +};
  335 +
  336 +static const struct idle_cpu idle_cpu_westmere = {
  337 + .state_table = nehalem_cstates,
  338 + .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
  339 +};
  340 +
  341 +static const struct idle_cpu idle_cpu_atom = {
  342 + .state_table = atom_cstates,
  343 +};
  344 +
  345 +static const struct idle_cpu idle_cpu_lincroft = {
  346 + .state_table = atom_cstates,
  347 + .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE,
  348 +};
  349 +
  350 +static const struct idle_cpu idle_cpu_snb = {
  351 + .state_table = snb_cstates,
  352 +};
  353 +
  354 +#define ICPU(model, cpu) \
  355 + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
  356 +
  357 +static const struct x86_cpu_id intel_idle_ids[] = {
  358 + ICPU(0x1a, idle_cpu_nehalem),
  359 + ICPU(0x1e, idle_cpu_nehalem),
  360 + ICPU(0x1f, idle_cpu_nehalem),
  361 + ICPU(0x25, idle_cpu_westmere),
  362 + ICPU(0x2c, idle_cpu_westmere),
  363 + ICPU(0x2f, idle_cpu_westmere),
  364 + ICPU(0x1c, idle_cpu_atom),
  365 + ICPU(0x26, idle_cpu_lincroft),
  366 + ICPU(0x2f, idle_cpu_westmere),
  367 + ICPU(0x2a, idle_cpu_snb),
  368 + ICPU(0x2d, idle_cpu_snb),
  369 + {}
  370 +};
  371 +MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
  372 +
326 373 /*
327 374 * intel_idle_probe()
328 375 */
329 376 static int intel_idle_probe(void)
330 377 {
331 378 unsigned int eax, ebx, ecx;
  379 + const struct x86_cpu_id *id;
332 380  
333 381 if (max_cstate == 0) {
334 382 pr_debug(PREFIX "disabled\n");
335 383 return -EPERM;
336 384 }
337 385  
338   - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
  386 + id = x86_match_cpu(intel_idle_ids);
  387 + if (!id) {
  388 + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
  389 + boot_cpu_data.x86 == 6)
  390 + pr_debug(PREFIX "does not run on family %d model %d\n",
  391 + boot_cpu_data.x86, boot_cpu_data.x86_model);
339 392 return -ENODEV;
  393 + }
340 394  
341   - if (!boot_cpu_has(X86_FEATURE_MWAIT))
342   - return -ENODEV;
343   -
344 395 if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
345 396 return -ENODEV;
346 397  
347 398  
... ... @@ -353,44 +404,9 @@
353 404  
354 405 pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
355 406  
  407 + icpu = (const struct idle_cpu *)id->driver_data;
  408 + cpuidle_state_table = icpu->state_table;
356 409  
357   - if (boot_cpu_data.x86 != 6) /* family 6 */
358   - return -ENODEV;
359   -
360   - switch (boot_cpu_data.x86_model) {
361   -
362   - case 0x1A: /* Core i7, Xeon 5500 series */
363   - case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */
364   - case 0x1F: /* Core i7 and i5 Processor - Nehalem */
365   - case 0x2E: /* Nehalem-EX Xeon */
366   - case 0x2F: /* Westmere-EX Xeon */
367   - case 0x25: /* Westmere */
368   - case 0x2C: /* Westmere */
369   - cpuidle_state_table = nehalem_cstates;
370   - auto_demotion_disable_flags =
371   - (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE);
372   - break;
373   -
374   - case 0x1C: /* 28 - Atom Processor */
375   - cpuidle_state_table = atom_cstates;
376   - break;
377   -
378   - case 0x26: /* 38 - Lincroft Atom Processor */
379   - cpuidle_state_table = atom_cstates;
380   - auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE;
381   - break;
382   -
383   - case 0x2A: /* SNB */
384   - case 0x2D: /* SNB Xeon */
385   - cpuidle_state_table = snb_cstates;
386   - break;
387   -
388   - default:
389   - pr_debug(PREFIX "does not run on family %d model %d\n",
390   - boot_cpu_data.x86, boot_cpu_data.x86_model);
391   - return -ENODEV;
392   - }
393   -
394 410 if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
395 411 lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
396 412 else {
... ... @@ -470,7 +486,7 @@
470 486 drv->state_count += 1;
471 487 }
472 488  
473   - if (auto_demotion_disable_flags)
  489 + if (icpu->auto_demotion_disable_flags)
474 490 on_each_cpu(auto_demotion_disable, NULL, 1);
475 491  
476 492 return 0;
... ... @@ -522,7 +538,7 @@
522 538 return -EIO;
523 539 }
524 540  
525   - if (auto_demotion_disable_flags)
  541 + if (icpu->auto_demotion_disable_flags)
526 542 smp_call_function_single(cpu, auto_demotion_disable, NULL, 1);
527 543  
528 544 return 0;