aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2007-02-16 04:28:04 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:13:59 -0500
commite9e2cdb412412326c4827fc78ba27f410d837e6e (patch)
treecd4ca03e6bdc3691619024492fb9414427b2f813 /drivers
parent79bf2bb335b85db25d27421c798595a2fa2a0e82 (diff)
[PATCH] clockevents: i386 drivers
Add clockevent drivers for i386: lapic (local) and PIT/HPET (global). Update the timer IRQ to call into the PIT/HPET driver's event handler and the lapic-timer IRQ to call into the lapic clockevent driver. The assignement of timer functionality is delegated to the core framework code and replaces the compile and runtime evalution in do_timer_interrupt_hook() Use the clockevents broadcast support and implement the lapic_broadcast function for ACPI. No changes to existing functionality. [ kdump fix from Vivek Goyal <vgoyal@in.ibm.com> ] [ fixes based on review feedback from Arjan van de Ven <arjan@infradead.org> ] Cleanups-from: Adrian Bunk <bunk@stusta.de> Build-fixes-from: Andrew Morton <akpm@osdl.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/processor_idle.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 4ea6d8b20d17..8206fc1ecc58 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -39,6 +39,7 @@
39#include <linux/moduleparam.h> 39#include <linux/moduleparam.h>
40#include <linux/sched.h> /* need_resched() */ 40#include <linux/sched.h> /* need_resched() */
41#include <linux/latency.h> 41#include <linux/latency.h>
42#include <linux/clockchips.h>
42 43
43/* 44/*
44 * Include the apic definitions for x86 to have the APIC timer related defines 45 * Include the apic definitions for x86 to have the APIC timer related defines
@@ -274,12 +275,40 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
274 275
275static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) 276static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
276{ 277{
278#ifdef CONFIG_GENERIC_CLOCKEVENTS
279 unsigned long reason;
280
281 reason = pr->power.timer_broadcast_on_state < INT_MAX ?
282 CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
283
284 clockevents_notify(reason, &pr->id);
285#else
277 cpumask_t mask = cpumask_of_cpu(pr->id); 286 cpumask_t mask = cpumask_of_cpu(pr->id);
278 287
279 if (pr->power.timer_broadcast_on_state < INT_MAX) 288 if (pr->power.timer_broadcast_on_state < INT_MAX)
280 on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1); 289 on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
281 else 290 else
282 on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1); 291 on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
292#endif
293}
294
295/* Power(C) State timer broadcast control */
296static void acpi_state_timer_broadcast(struct acpi_processor *pr,
297 struct acpi_processor_cx *cx,
298 int broadcast)
299{
300#ifdef CONFIG_GENERIC_CLOCKEVENTS
301
302 int state = cx - pr->power.states;
303
304 if (state >= pr->power.timer_broadcast_on_state) {
305 unsigned long reason;
306
307 reason = broadcast ? CLOCK_EVT_NOTIFY_BROADCAST_ENTER :
308 CLOCK_EVT_NOTIFY_BROADCAST_EXIT;
309 clockevents_notify(reason, &pr->id);
310 }
311#endif
283} 312}
284 313
285#else 314#else
@@ -287,6 +316,11 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
287static void acpi_timer_check_state(int state, struct acpi_processor *pr, 316static void acpi_timer_check_state(int state, struct acpi_processor *pr,
288 struct acpi_processor_cx *cstate) { } 317 struct acpi_processor_cx *cstate) { }
289static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { } 318static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { }
319static void acpi_state_timer_broadcast(struct acpi_processor *pr,
320 struct acpi_processor_cx *cx,
321 int broadcast)
322{
323}
290 324
291#endif 325#endif
292 326
@@ -434,6 +468,7 @@ static void acpi_processor_idle(void)
434 /* Get start time (ticks) */ 468 /* Get start time (ticks) */
435 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 469 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
436 /* Invoke C2 */ 470 /* Invoke C2 */
471 acpi_state_timer_broadcast(pr, cx, 1);
437 acpi_cstate_enter(cx); 472 acpi_cstate_enter(cx);
438 /* Get end time (ticks) */ 473 /* Get end time (ticks) */
439 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 474 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -448,6 +483,7 @@ static void acpi_processor_idle(void)
448 /* Compute time (ticks) that we were actually asleep */ 483 /* Compute time (ticks) that we were actually asleep */
449 sleep_ticks = 484 sleep_ticks =
450 ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; 485 ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
486 acpi_state_timer_broadcast(pr, cx, 0);
451 break; 487 break;
452 488
453 case ACPI_STATE_C3: 489 case ACPI_STATE_C3:
@@ -469,6 +505,7 @@ static void acpi_processor_idle(void)
469 /* Get start time (ticks) */ 505 /* Get start time (ticks) */
470 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 506 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
471 /* Invoke C3 */ 507 /* Invoke C3 */
508 acpi_state_timer_broadcast(pr, cx, 1);
472 acpi_cstate_enter(cx); 509 acpi_cstate_enter(cx);
473 /* Get end time (ticks) */ 510 /* Get end time (ticks) */
474 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 511 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -488,6 +525,7 @@ static void acpi_processor_idle(void)
488 /* Compute time (ticks) that we were actually asleep */ 525 /* Compute time (ticks) that we were actually asleep */
489 sleep_ticks = 526 sleep_ticks =
490 ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; 527 ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
528 acpi_state_timer_broadcast(pr, cx, 0);
491 break; 529 break;
492 530
493 default: 531 default: