aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/idle/intel_idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/idle/intel_idle.c')
-rw-r--r--drivers/idle/intel_idle.c96
1 files changed, 49 insertions, 47 deletions
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 5d2f8e13cf0..20bce51c2e8 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -197,7 +197,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
197 .enter = &intel_idle }, 197 .enter = &intel_idle },
198}; 198};
199 199
200static int get_driver_data(int cstate) 200static long get_driver_data(int cstate)
201{ 201{
202 int driver_data; 202 int driver_data;
203 switch (cstate) { 203 switch (cstate) {
@@ -232,6 +232,7 @@ static int get_driver_data(int cstate)
232 * @drv: cpuidle driver 232 * @drv: cpuidle driver
233 * @index: index of cpuidle state 233 * @index: index of cpuidle state
234 * 234 *
235 * Must be called under local_irq_disable().
235 */ 236 */
236static int intel_idle(struct cpuidle_device *dev, 237static int intel_idle(struct cpuidle_device *dev,
237 struct cpuidle_driver *drv, int index) 238 struct cpuidle_driver *drv, int index)
@@ -247,8 +248,6 @@ static int intel_idle(struct cpuidle_device *dev,
247 248
248 cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1; 249 cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
249 250
250 local_irq_disable();
251
252 /* 251 /*
253 * leave_mm() to avoid costly and often unnecessary wakeups 252 * leave_mm() to avoid costly and often unnecessary wakeups
254 * for flushing the user TLB's associated with the active mm. 253 * for flushing the user TLB's associated with the active mm.
@@ -348,7 +347,8 @@ static int intel_idle_probe(void)
348 cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); 347 cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates);
349 348
350 if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || 349 if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
351 !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) 350 !(ecx & CPUID5_ECX_INTERRUPT_BREAK) ||
351 !mwait_substates)
352 return -ENODEV; 352 return -ENODEV;
353 353
354 pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); 354 pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
@@ -394,7 +394,7 @@ static int intel_idle_probe(void)
394 if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ 394 if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
395 lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; 395 lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
396 else { 396 else {
397 smp_call_function(__setup_broadcast_timer, (void *)true, 1); 397 on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
398 register_cpu_notifier(&setup_broadcast_notifier); 398 register_cpu_notifier(&setup_broadcast_notifier);
399 } 399 }
400 400
@@ -471,71 +471,67 @@ static int intel_idle_cpuidle_driver_init(void)
471 } 471 }
472 472
473 if (auto_demotion_disable_flags) 473 if (auto_demotion_disable_flags)
474 smp_call_function(auto_demotion_disable, NULL, 1); 474 on_each_cpu(auto_demotion_disable, NULL, 1);
475 475
476 return 0; 476 return 0;
477} 477}
478 478
479 479
480/* 480/*
481 * intel_idle_cpuidle_devices_init() 481 * intel_idle_cpu_init()
482 * allocate, initialize, register cpuidle_devices 482 * allocate, initialize, register cpuidle_devices
483 * @cpu: cpu/core to initialize
483 */ 484 */
484static int intel_idle_cpuidle_devices_init(void) 485int intel_idle_cpu_init(int cpu)
485{ 486{
486 int i, cstate; 487 int cstate;
487 struct cpuidle_device *dev; 488 struct cpuidle_device *dev;
488 489
489 intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); 490 dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu);
490 if (intel_idle_cpuidle_devices == NULL)
491 return -ENOMEM;
492
493 for_each_online_cpu(i) {
494 dev = per_cpu_ptr(intel_idle_cpuidle_devices, i);
495 491
496 dev->state_count = 1; 492 dev->state_count = 1;
497 493
498 for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { 494 for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) {
499 int num_substates; 495 int num_substates;
500 496
501 if (cstate > max_cstate) { 497 if (cstate > max_cstate) {
502 printk(PREFIX "max_cstate %d reached\n", 498 printk(PREFIX "max_cstate %d reached\n",
503 max_cstate); 499 max_cstate);
504 break; 500 break;
505 } 501 }
506 502
507 /* does the state exist in CPUID.MWAIT? */ 503 /* does the state exist in CPUID.MWAIT? */
508 num_substates = (mwait_substates >> ((cstate) * 4)) 504 num_substates = (mwait_substates >> ((cstate) * 4))
509 & MWAIT_SUBSTATE_MASK; 505 & MWAIT_SUBSTATE_MASK;
510 if (num_substates == 0) 506 if (num_substates == 0)
511 continue; 507 continue;
512 /* is the state not enabled? */ 508 /* is the state not enabled? */
513 if (cpuidle_state_table[cstate].enter == NULL) { 509 if (cpuidle_state_table[cstate].enter == NULL)
514 continue; 510 continue;
515 }
516 511
517 dev->states_usage[dev->state_count].driver_data = 512 dev->states_usage[dev->state_count].driver_data =
518 (void *)get_driver_data(cstate); 513 (void *)get_driver_data(cstate);
519 514
520 dev->state_count += 1; 515 dev->state_count += 1;
521 } 516 }
517 dev->cpu = cpu;
522 518
523 dev->cpu = i; 519 if (cpuidle_register_device(dev)) {
524 if (cpuidle_register_device(dev)) { 520 pr_debug(PREFIX "cpuidle_register_device %d failed!\n", cpu);
525 pr_debug(PREFIX "cpuidle_register_device %d failed!\n", 521 intel_idle_cpuidle_devices_uninit();
526 i); 522 return -EIO;
527 intel_idle_cpuidle_devices_uninit();
528 return -EIO;
529 }
530 } 523 }
531 524
525 if (auto_demotion_disable_flags)
526 smp_call_function_single(cpu, auto_demotion_disable, NULL, 1);
527
532 return 0; 528 return 0;
533} 529}
534 530
535 531
536static int __init intel_idle_init(void) 532static int __init intel_idle_init(void)
537{ 533{
538 int retval; 534 int retval, i;
539 535
540 /* Do not load intel_idle at all for now if idle= is passed */ 536 /* Do not load intel_idle at all for now if idle= is passed */
541 if (boot_option_idle_override != IDLE_NO_OVERRIDE) 537 if (boot_option_idle_override != IDLE_NO_OVERRIDE)
@@ -553,10 +549,16 @@ static int __init intel_idle_init(void)
553 return retval; 549 return retval;
554 } 550 }
555 551
556 retval = intel_idle_cpuidle_devices_init(); 552 intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
557 if (retval) { 553 if (intel_idle_cpuidle_devices == NULL)
558 cpuidle_unregister_driver(&intel_idle_driver); 554 return -ENOMEM;
559 return retval; 555
556 for_each_online_cpu(i) {
557 retval = intel_idle_cpu_init(i);
558 if (retval) {
559 cpuidle_unregister_driver(&intel_idle_driver);
560 return retval;
561 }
560 } 562 }
561 563
562 return 0; 564 return 0;
@@ -568,7 +570,7 @@ static void __exit intel_idle_exit(void)
568 cpuidle_unregister_driver(&intel_idle_driver); 570 cpuidle_unregister_driver(&intel_idle_driver);
569 571
570 if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) { 572 if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) {
571 smp_call_function(__setup_broadcast_timer, (void *)false, 1); 573 on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
572 unregister_cpu_notifier(&setup_broadcast_notifier); 574 unregister_cpu_notifier(&setup_broadcast_notifier);
573 } 575 }
574 576