LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/2] rtc/ab8500: set uie_unsupported flag
@ 2014-12-08 12:03 Xunlei Pang
  2014-12-08 12:03 ` [PATCH 2/2] rtc: Refine rtc_timer_do_work() to consider other set alarm failures Xunlei Pang
  0 siblings, 1 reply; 2+ messages in thread
From: Xunlei Pang @ 2014-12-08 12:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: rtc-linux, Alessandro Zummo, John Stultz, Arnd Bergmann, Xunlei Pang

Currently, ab8500 doesn't set uie_unsupported of rtc_device, while
it doesn't support UIE, see ab8500_rtc_set_alarm().

Thus, when going through rtc_update_irq_enable()->rtc_timer_enqueue(),
there's a chance it has an alarm timer1 queued before which is going to
fired, so this update timer2 will be queued because it isn't the leftmost
one, which means rtc_timer_enqueue() will return 0.

This will result in two problems:
1) UIE EMUL will not be used.
2) When the alarm timer1 is fired, in rtc_timer_do_work() timer2 will
   fail to set the alarm time, so this rtc will disfunctional due to
   timer2 with the earliest expires in the timerqueue.

So, rtc drivers must set this flag if they don't support UIE.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
---
 drivers/rtc/rtc-ab8500.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index 727e2f5..866e0ef 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -504,6 +504,8 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	rtc->uie_unsupported = 1;
+
 	return 0;
 }
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH 2/2] rtc: Refine rtc_timer_do_work() to consider other set alarm failures
  2014-12-08 12:03 [PATCH 1/2] rtc/ab8500: set uie_unsupported flag Xunlei Pang
@ 2014-12-08 12:03 ` Xunlei Pang
  0 siblings, 0 replies; 2+ messages in thread
From: Xunlei Pang @ 2014-12-08 12:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: rtc-linux, Alessandro Zummo, John Stultz, Arnd Bergmann, Xunlei Pang

rtc_timer_do_work() only judges -ETIME failure of__rtc_set_alarm(),
but doesn't handle other failures like -EIO, -EBUSY, etc.

If there is a failure other than -ETIME, the next rtc_timer will stay
in the timerqueue. Then later rtc_timers will be enqueued directly because
they have a later expires time, so the alarm irq will never be programmed.

When such failures happen, this patch will retry __rtc_set_alarm(), if
still can't program the alarm time, it will remove current rtc_timer from
timerqueue and fetch next one, thus preventing it from affecting other
rtc timers.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
---
 drivers/rtc/interface.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index af19213..77a1529 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -898,11 +898,24 @@ again:
 	if (next) {
 		struct rtc_wkalrm alarm;
 		int err;
+		int retry = 3;
+
 		alarm.time = rtc_ktime_to_tm(next->expires);
 		alarm.enabled = 1;
+reprogram:
 		err = __rtc_set_alarm(rtc, &alarm);
 		if (err == -ETIME)
 			goto again;
+		else if (err) {
+			if (retry-- > 0)
+				goto reprogram;
+
+			timer = container_of(next, struct rtc_timer, node);
+			timerqueue_del(&rtc->timerqueue, &timer->node);
+			timer->enabled = 0;
+			dev_err(&rtc->dev, "__rtc_set_alarm: err=%d\n", err);
+			goto again;
+		}
 	} else
 		rtc_alarm_disable(rtc);
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-12-08 12:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-08 12:03 [PATCH 1/2] rtc/ab8500: set uie_unsupported flag Xunlei Pang
2014-12-08 12:03 ` [PATCH 2/2] rtc: Refine rtc_timer_do_work() to consider other set alarm failures Xunlei Pang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).