| Submitter | John Stultz |
|---|---|
| Date | March 6, 2012, 11:36 p.m. |
| Message ID | <1331076961.2191.165.camel@work-vm> |
| Download | mbox | patch |
| Permalink | /patch/145055/ |
| State | New |
| Headers | show |
Comments
On 07.03.2012 00:36, John Stultz wrote: > On Wed, 2012-02-29 at 22:41 +0100, Richard Weinberger wrote: >> Hi! >> >> hwclock calls the RTC_UIE_ON ioctl to wait for a timer tick. >> If RTC_UIE_ON was successful it opens /dev/rtcX and waits up to 5 seconds using select() >> for a tick. >> Some RTC drivers have no support for RTC_UIE_ON and ioctl just returns -EINVAL. >> Drivers indicated this by setting rtc_class_ops->update_irq_enable to NULL. >> In this case hwclock waits in a busy loop for the next timer tick. >> >> These two commits changed this behavior: >> 6610e08 (RTC: Rework RTC code to use timerqueue for events) >> 51ba60c (RTC: Cleanup rtc_class_ops->update_irq_enable()) >> >> rtc_class_ops->update_irq_enable was removed and rtc_update_irq_enable() >> is now using rtc_class_ops->set_alarm instead of rtc_class_ops->update_irq_enable. >> >> Some RTC devices (like mpc515x) don't support intervals smaller than one >> minute. >> rtc-mpc5121.c deals with this by rounding up to one minute. >> But now after commit 6610e08 RTC_UIE_ON will no longer return -EINVAL and >> the next tick comes somewhen within the next 60 seconds, because the driver rounded up... >> hwclock's select() is not happy about this and timeouts in most cases. > > Thanks for diagnosing and pointing out this issue! I hadn't been aware > of such hardware. > > Would something like the following be a better generic interface? > Basically allow the RTC drivers to flag that UIE is unsupported (much as > setting the update_irq_enable to null did prior). > > Let me know if this works for you, and I'll look to see what other > drivers might be affected here. > > thanks > -john > > Add generic infrastructure to handle rtc devices that don't support UIE > mode. > > Signed-off-by: John Stultz<john.stultz@linaro.org> Tested-by: Richard Weinberger <richard@nod.at> > diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c > index 9d3cacc..be6d4f4 100644 > --- a/drivers/rtc/rtc-mpc5121.c > +++ b/drivers/rtc/rtc-mpc5121.c > @@ -360,6 +360,8 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op) > &mpc5200_rtc_ops, THIS_MODULE); > } > > + rtc->rtc.uie_unsupported = 1; > + Please replace this line by: rtc->rtc->uie_unsupported = 1; Thanks, //richard
Patch
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index dc87eda..eb415bd 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -458,6 +458,11 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) if (rtc->uie_rtctimer.enabled == enabled) goto out; + if (rtc->uie_unsupported) { + err = -EINVAL; + goto out; + } + if (enabled) { struct rtc_time tm; ktime_t now, onesec; diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 9d3cacc..be6d4f4 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -360,6 +360,8 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op) &mpc5200_rtc_ops, THIS_MODULE); } + rtc->rtc.uie_unsupported = 1; + if (IS_ERR(rtc->rtc)) { err = PTR_ERR(rtc->rtc); goto out_free_irq; diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 93f4d03..fcabfb4 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -202,7 +202,8 @@ struct rtc_device struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */ int pie_enabled; struct work_struct irqwork; - + /* Some hardware can't support UIE mode */ + int uie_unsupported; #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL struct work_struct uie_task;