diff options
Diffstat (limited to 'drivers/rtc/interface.c')
-rw-r--r-- | drivers/rtc/interface.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 5b2717f5dafa..45bfc28ee3aa 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -30,6 +30,14 @@ static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) | |||
30 | else { | 30 | else { |
31 | memset(tm, 0, sizeof(struct rtc_time)); | 31 | memset(tm, 0, sizeof(struct rtc_time)); |
32 | err = rtc->ops->read_time(rtc->dev.parent, tm); | 32 | err = rtc->ops->read_time(rtc->dev.parent, tm); |
33 | if (err < 0) { | ||
34 | dev_err(&rtc->dev, "read_time: fail to read\n"); | ||
35 | return err; | ||
36 | } | ||
37 | |||
38 | err = rtc_valid_tm(tm); | ||
39 | if (err < 0) | ||
40 | dev_err(&rtc->dev, "read_time: rtc_time isn't valid\n"); | ||
33 | } | 41 | } |
34 | return err; | 42 | return err; |
35 | } | 43 | } |
@@ -891,11 +899,24 @@ again: | |||
891 | if (next) { | 899 | if (next) { |
892 | struct rtc_wkalrm alarm; | 900 | struct rtc_wkalrm alarm; |
893 | int err; | 901 | int err; |
902 | int retry = 3; | ||
903 | |||
894 | alarm.time = rtc_ktime_to_tm(next->expires); | 904 | alarm.time = rtc_ktime_to_tm(next->expires); |
895 | alarm.enabled = 1; | 905 | alarm.enabled = 1; |
906 | reprogram: | ||
896 | err = __rtc_set_alarm(rtc, &alarm); | 907 | err = __rtc_set_alarm(rtc, &alarm); |
897 | if (err == -ETIME) | 908 | if (err == -ETIME) |
898 | goto again; | 909 | goto again; |
910 | else if (err) { | ||
911 | if (retry-- > 0) | ||
912 | goto reprogram; | ||
913 | |||
914 | timer = container_of(next, struct rtc_timer, node); | ||
915 | timerqueue_del(&rtc->timerqueue, &timer->node); | ||
916 | timer->enabled = 0; | ||
917 | dev_err(&rtc->dev, "__rtc_set_alarm: err=%d\n", err); | ||
918 | goto again; | ||
919 | } | ||
899 | } else | 920 | } else |
900 | rtc_alarm_disable(rtc); | 921 | rtc_alarm_disable(rtc); |
901 | 922 | ||