diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2010-05-10 14:32:46 +0100 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-05-10 14:32:46 +0100 |
commit | 0ae28a35bcb7984838acbf28bfba9c030f8b74f0 (patch) | |
tree | 4f449d929b5df9e126e839f388ff0fd2b52028a0 /kernel/time/tick-oneshot.c | |
parent | 6f1f3d0ab5c3eeea9f04486481c25e9afdfa26c5 (diff) | |
parent | b57f95a38233a2e73b679bea4a5453a1cc2a1cc9 (diff) | |
download | kernel_samsung_smdk4412-0ae28a35bcb7984838acbf28bfba9c030f8b74f0.zip kernel_samsung_smdk4412-0ae28a35bcb7984838acbf28bfba9c030f8b74f0.tar.gz kernel_samsung_smdk4412-0ae28a35bcb7984838acbf28bfba9c030f8b74f0.tar.bz2 |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/mtd/mtdcore.c
Pull in the bdi fixes and ARM platform changes that other outstanding
patches depend on.
Diffstat (limited to 'kernel/time/tick-oneshot.c')
-rw-r--r-- | kernel/time/tick-oneshot.c | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c index 0a8a213..aada0e5 100644 --- a/kernel/time/tick-oneshot.c +++ b/kernel/time/tick-oneshot.c @@ -22,6 +22,29 @@ #include "tick-internal.h" +/* Limit min_delta to a jiffie */ +#define MIN_DELTA_LIMIT (NSEC_PER_SEC / HZ) + +static int tick_increase_min_delta(struct clock_event_device *dev) +{ + /* Nothing to do if we already reached the limit */ + if (dev->min_delta_ns >= MIN_DELTA_LIMIT) + return -ETIME; + + if (dev->min_delta_ns < 5000) + dev->min_delta_ns = 5000; + else + dev->min_delta_ns += dev->min_delta_ns >> 1; + + if (dev->min_delta_ns > MIN_DELTA_LIMIT) + dev->min_delta_ns = MIN_DELTA_LIMIT; + + printk(KERN_WARNING "CE: %s increased min_delta_ns to %llu nsec\n", + dev->name ? dev->name : "?", + (unsigned long long) dev->min_delta_ns); + return 0; +} + /** * tick_program_event internal worker function */ @@ -37,23 +60,28 @@ int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires, if (!ret || !force) return ret; + dev->retries++; /* - * We tried 2 times to program the device with the given - * min_delta_ns. If that's not working then we double it + * We tried 3 times to program the device with the given + * min_delta_ns. If that's not working then we increase it * and emit a warning. */ if (++i > 2) { /* Increase the min. delta and try again */ - if (!dev->min_delta_ns) - dev->min_delta_ns = 5000; - else - dev->min_delta_ns += dev->min_delta_ns >> 1; - - printk(KERN_WARNING - "CE: %s increasing min_delta_ns to %llu nsec\n", - dev->name ? dev->name : "?", - (unsigned long long) dev->min_delta_ns << 1); - + if (tick_increase_min_delta(dev)) { + /* + * Get out of the loop if min_delta_ns + * hit the limit already. That's + * better than staying here forever. + * + * We clear next_event so we have a + * chance that the box survives. + */ + printk(KERN_WARNING + "CE: Reprogramming failure. Giving up\n"); + dev->next_event.tv64 = KTIME_MAX; + return -ETIME; + } i = 0; } |