drivers/rtc/rtc-cmos.c: fix accidentally enabling rtc channel
authorDerek Basehore <dbasehore@chromium.org>
Wed, 12 Jun 2013 21:04:45 +0000 (14:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Jun 2013 23:29:45 +0000 (16:29 -0700)
During resume, we call hpet_rtc_timer_init after masking an irq bit in
hpet.  This will cause the call to hpet_disable_rtc_channel to be undone
if RTC_AIE is the only bit not masked.

Allowing the cmos interrupt handler to run before resuming caused some
issues where the timer for the alarm was not removed.  This would cause
other, later timers to not be cleared, so utilities such as hwclock
would time out when waiting for the update interrupt.

[akpm@linux-foundation.org: coding-style tweak]
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/rtc/rtc-cmos.c

index cc5bea9c4b1c3778ff817b973b52f29c4bee64bf..f1cb706445c739d7eee047a06482e63f0444de83 100644 (file)
@@ -854,6 +854,9 @@ static int cmos_resume(struct device *dev)
                }
 
                spin_lock_irq(&rtc_lock);
+               if (device_may_wakeup(dev))
+                       hpet_rtc_timer_init();
+
                do {
                        CMOS_WRITE(tmp, RTC_CONTROL);
                        hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK);
@@ -869,7 +872,6 @@ static int cmos_resume(struct device *dev)
                        rtc_update_irq(cmos->rtc, 1, mask);
                        tmp &= ~RTC_AIE;
                        hpet_mask_rtc_irq_bit(RTC_AIE);
-                       hpet_rtc_timer_init();
                } while (mask & RTC_AIE);
                spin_unlock_irq(&rtc_lock);
        }