aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/configs/CM-BF548_defconfig
diff options
context:
space:
mode:
authorNils Carlson <nils.carlson@ericsson.com>2011-06-15 15:08:54 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-15 20:04:02 -0700
commit273ef9509b7903e50f36aaf9f1d5dc9087fca506 (patch)
tree4d1800cadbb85647b4db5cf5cb855dc43465536c /arch/blackfin/configs/CM-BF548_defconfig
parentDocumentation/feature-removal-schedule.txt: remove ns_cgroup from feature-removal-schedule.txt (diff)
downloadlinux-dev-273ef9509b7903e50f36aaf9f1d5dc9087fca506.tar.xz
linux-dev-273ef9509b7903e50f36aaf9f1d5dc9087fca506.zip
drivers/char/hpet.c: fix periodic-emulation for delayed interrupts
When interrupts are delayed due to interrupt masking or due to other interrupts being serviced the HPET periodic-emuation would fail. This happened because given an interval t and a time for the current interrupt m we would compute the next time as t + m. This works until we are delayed for > t, in which case we would be writing a new value which is in fact in the past. This can be solved by computing the next time instead as (k * t) + m where k is large enough to be in the future. The exact computation of k is described in a comment to the code. More detail: Assuming an interval of 5 between each expected interrupt we have a normal case of t0: interrupt, read t0 from comparator, set next interrupt t0 + 5 t5: interrupt, read t5 from comparator, set next interrupt t5 + 5 t10: interrupt, read t10 from comparator, set next interrupt t10 + 5 ... So, what happens when the interrupt is serviced too late? t0: interrupt, read t0 from comparator, set next interrupt t0 + 5 t11: delayed interrupt serviced, read t5 from comparator, set next interrupt t5 + 5, which is in the past! ... counter loops ... t10: Much much later, get the next interrupt. This can happen either because we have interrupts masked for too long (some stupid driver goes on a printk rampage) or just because we are pushing the limits of the interval (too small a period), or both most probably. My solution is to read the main counter as well and set the next interrupt to occur at the right interval, for example: t0: interrupt, read t0 from comparator, set next interrupt t0 + 5 t11: delayed interrupt serviced, read t5 from comparator, set next interrupt t15 as t10 has been missed. t15: back on track. Signed-off-by: Nils Carlson <nils.carlson@ericsson.com> Cc: John Stultz <john.stultz@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to '')
0 files changed, 0 insertions, 0 deletions