aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/idle
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2012-07-05 09:23:25 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-07-05 16:37:47 -0400
commit25ac77613aa8fca131599705e3d7da2a0eaa06a0 (patch)
tree441f714bf32592797d1cf4c6c375e47e324ffded /drivers/idle
parent6e797a078824b30afbfae6cc4b1c2b21c51761ef (diff)
ACPI: intel_idle : break dependency between modules
When the system is booted with some cpus offline, the idle driver is not initialized. When a cpu is set online, the acpi code call the intel idle init function. Unfortunately this code introduce a dependency between intel_idle and acpi. This patch is intended to remove this dependency by using the notifier of intel_idle. This patch has the benefit of encapsulating the intel_idle driver and remove some exported functions. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Acked-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/idle')
-rw-r--r--drivers/idle/intel_idle.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index d0f59c3f87ef..fe95d5464a02 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -96,6 +96,7 @@ static const struct idle_cpu *icpu;
96static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; 96static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
97static int intel_idle(struct cpuidle_device *dev, 97static int intel_idle(struct cpuidle_device *dev,
98 struct cpuidle_driver *drv, int index); 98 struct cpuidle_driver *drv, int index);
99static int intel_idle_cpu_init(int cpu);
99 100
100static struct cpuidle_state *cpuidle_state_table; 101static struct cpuidle_state *cpuidle_state_table;
101 102
@@ -302,22 +303,35 @@ static void __setup_broadcast_timer(void *arg)
302 clockevents_notify(reason, &cpu); 303 clockevents_notify(reason, &cpu);
303} 304}
304 305
305static int setup_broadcast_cpuhp_notify(struct notifier_block *n, 306static int cpu_hotplug_notify(struct notifier_block *n,
306 unsigned long action, void *hcpu) 307 unsigned long action, void *hcpu)
307{ 308{
308 int hotcpu = (unsigned long)hcpu; 309 int hotcpu = (unsigned long)hcpu;
310 struct cpuidle_device *dev;
309 311
310 switch (action & 0xf) { 312 switch (action & 0xf) {
311 case CPU_ONLINE: 313 case CPU_ONLINE:
312 smp_call_function_single(hotcpu, __setup_broadcast_timer, 314
313 (void *)true, 1); 315 if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
316 smp_call_function_single(hotcpu, __setup_broadcast_timer,
317 (void *)true, 1);
318
319 /*
320 * Some systems can hotplug a cpu at runtime after
321 * the kernel has booted, we have to initialize the
322 * driver in this case
323 */
324 dev = per_cpu_ptr(intel_idle_cpuidle_devices, hotcpu);
325 if (!dev->registered)
326 intel_idle_cpu_init(hotcpu);
327
314 break; 328 break;
315 } 329 }
316 return NOTIFY_OK; 330 return NOTIFY_OK;
317} 331}
318 332
319static struct notifier_block setup_broadcast_notifier = { 333static struct notifier_block cpu_hotplug_notifier = {
320 .notifier_call = setup_broadcast_cpuhp_notify, 334 .notifier_call = cpu_hotplug_notify,
321}; 335};
322 336
323static void auto_demotion_disable(void *dummy) 337static void auto_demotion_disable(void *dummy)
@@ -405,10 +419,10 @@ static int intel_idle_probe(void)
405 419
406 if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ 420 if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
407 lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; 421 lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
408 else { 422 else
409 on_each_cpu(__setup_broadcast_timer, (void *)true, 1); 423 on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
410 register_cpu_notifier(&setup_broadcast_notifier); 424
411 } 425 register_cpu_notifier(&cpu_hotplug_notifier);
412 426
413 pr_debug(PREFIX "v" INTEL_IDLE_VERSION 427 pr_debug(PREFIX "v" INTEL_IDLE_VERSION
414 " model 0x%X\n", boot_cpu_data.x86_model); 428 " model 0x%X\n", boot_cpu_data.x86_model);
@@ -494,7 +508,7 @@ static int intel_idle_cpuidle_driver_init(void)
494 * allocate, initialize, register cpuidle_devices 508 * allocate, initialize, register cpuidle_devices
495 * @cpu: cpu/core to initialize 509 * @cpu: cpu/core to initialize
496 */ 510 */
497int intel_idle_cpu_init(int cpu) 511static int intel_idle_cpu_init(int cpu)
498{ 512{
499 int cstate; 513 int cstate;
500 struct cpuidle_device *dev; 514 struct cpuidle_device *dev;
@@ -539,7 +553,6 @@ int intel_idle_cpu_init(int cpu)
539 553
540 return 0; 554 return 0;
541} 555}
542EXPORT_SYMBOL_GPL(intel_idle_cpu_init);
543 556
544static int __init intel_idle_init(void) 557static int __init intel_idle_init(void)
545{ 558{
@@ -581,10 +594,10 @@ static void __exit intel_idle_exit(void)
581 intel_idle_cpuidle_devices_uninit(); 594 intel_idle_cpuidle_devices_uninit();
582 cpuidle_unregister_driver(&intel_idle_driver); 595 cpuidle_unregister_driver(&intel_idle_driver);
583 596
584 if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) { 597
598 if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
585 on_each_cpu(__setup_broadcast_timer, (void *)false, 1); 599 on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
586 unregister_cpu_notifier(&setup_broadcast_notifier); 600 unregister_cpu_notifier(&cpu_hotplug_notifier);
587 }
588 601
589 return; 602 return;
590} 603}