X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=kernel%2Ftime%2Ftick-common.c;h=bfda3f7f0716a9ad4915dd2191390f8bbf59ddd8;hb=e6349a958b3577da6e5c5eacda85c07f9a364cb5;hp=c35d449be031ae84de018564a9296d0bb60dccf1;hpb=79bf2bb335b85db25d27421c798595a2fa2a0e82;p=linux-2.6-omap-h63xx.git diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index c35d449be03..bfda3f7f071 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -34,6 +34,14 @@ ktime_t tick_period; static int tick_do_timer_cpu = -1; DEFINE_SPINLOCK(tick_device_lock); +/* + * Debugging: see timer_list.c + */ +struct tick_device *tick_get_device(int cpu) +{ + return &per_cpu(tick_cpu_device, cpu); +} + /** * tick_is_oneshot_available - check for a oneshot capable event device */ @@ -69,6 +77,7 @@ static void tick_periodic(int cpu) void tick_handle_periodic(struct clock_event_device *dev) { int cpu = smp_processor_id(); + ktime_t next; tick_periodic(cpu); @@ -78,12 +87,12 @@ void tick_handle_periodic(struct clock_event_device *dev) * Setup the next period for devices, which do not have * periodic mode: */ + next = ktime_add(dev->next_event, tick_period); for (;;) { - ktime_t next = ktime_add(dev->next_event, tick_period); - if (!clockevents_program_event(dev, next, ktime_get())) return; tick_periodic(cpu); + next = ktime_add(next, tick_period); } } @@ -289,6 +298,29 @@ static void tick_shutdown(unsigned int *cpup) spin_unlock_irqrestore(&tick_device_lock, flags); } +static void tick_suspend(void) +{ + struct tick_device *td = &__get_cpu_var(tick_cpu_device); + unsigned long flags; + + spin_lock_irqsave(&tick_device_lock, flags); + clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN); + spin_unlock_irqrestore(&tick_device_lock, flags); +} + +static void tick_resume(void) +{ + struct tick_device *td = &__get_cpu_var(tick_cpu_device); + unsigned long flags; + + spin_lock_irqsave(&tick_device_lock, flags); + if (td->mode == TICKDEV_MODE_PERIODIC) + tick_setup_periodic(td->evtdev, 0); + else + tick_resume_oneshot(); + spin_unlock_irqrestore(&tick_device_lock, flags); +} + /* * Notification about clock event devices */ @@ -316,6 +348,16 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason, tick_shutdown(dev); break; + case CLOCK_EVT_NOTIFY_SUSPEND: + tick_suspend(); + tick_suspend_broadcast(); + break; + + case CLOCK_EVT_NOTIFY_RESUME: + if (!tick_resume_broadcast()) + tick_resume(); + break; + default: break; }