rtc: Disable the alarm in the hardware (v2)
authorRabin Vincent <[email protected]>
Tue, 22 Nov 2011 10:03:14 +0000 (11:03 +0100)
committerJohn Stultz <[email protected]>
Fri, 27 Jan 2012 03:41:42 +0000 (19:41 -0800)
Currently, the RTC code does not disable the alarm in the hardware.

This means that after a sequence such as the one below (the files are in the
RTC sysfs), the box will boot up after 2 minutes even though we've
asked for the alarm to be turned off.

# echo $((`cat since_epoch`)+120) > wakealarm
# echo 0 > wakealarm
# poweroff

Fix this by disabling the alarm when there are no timers to run.

The original version of this patch was reverted. This version
disables the irq directly instead of setting a disabled timer
in the future.

Cc: [email protected]
Cc: John Stultz <[email protected]>
Signed-off-by: Rabin Vincent <[email protected]>
[Merged in the second revision from Rabin]
Signed-off-by: John Stultz <[email protected]>
drivers/rtc/interface.c

index 167e68a9ffdad5c7e37c691f2d7b99c865fe6d20..dc87eda6581434c9708173948878e906e46319f6 100644 (file)
@@ -776,6 +776,14 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
        return 0;
 }
 
+static void rtc_alarm_disable(struct rtc_device *rtc)
+{
+       if (!rtc->ops || !rtc->ops->alarm_irq_enable)
+               return;
+
+       rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
+}
+
 /**
  * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
  * @rtc rtc device
@@ -797,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
                struct rtc_wkalrm alarm;
                int err;
                next = timerqueue_getnext(&rtc->timerqueue);
-               if (!next)
+               if (!next) {
+                       rtc_alarm_disable(rtc);
                        return;
+               }
                alarm.time = rtc_ktime_to_tm(next->expires);
                alarm.enabled = 1;
                err = __rtc_set_alarm(rtc, &alarm);
@@ -860,7 +870,8 @@ again:
                err = __rtc_set_alarm(rtc, &alarm);
                if (err == -ETIME)
                        goto again;
-       }
+       } else
+               rtc_alarm_disable(rtc);
 
        mutex_unlock(&rtc->ops_lock);
 }