• Nils Carlson's avatar
    drivers/char/hpet.c: fix periodic-emulation for delayed interrupts · 273ef950
    Nils Carlson authored
    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: default avatarNils 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: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    273ef950
hpet.c 24.5 KB