diff options
author | Alexander Shiyan <shc_work@mail.ru> | 2014-04-03 14:50:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-03 16:21:21 -0700 |
commit | 12de362108d5ec24cce1bbe520570dc8fdccca9c (patch) | |
tree | 04de7d96005b26d239f376e587f8d3526d8e34c7 | |
parent | fb1bd9a22da3d0f2436ffa95fdc0382b89659288 (diff) | |
download | op-kernel-dev-12de362108d5ec24cce1bbe520570dc8fdccca9c.zip op-kernel-dev-12de362108d5ec24cce1bbe520570dc8fdccca9c.tar.gz |
rtc: mc13xxx: change RTC validation scheme
Datasheet says: "When the VSRTC voltage drops to the range of 0.9 - 0.8V,
the RTCPORB reset signal is generated and the contents of the RTC will
be reset. <skip>. To inform the processor that the contents of the RTC
are no longer valid due to the reset, a timer reset interrupt function
is implemented with the RTCRSTI bit." This patch makes the RTC valid by
default until RTCRST interrupt occurs.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Sascha Hauer <kernel@pengutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/rtc/rtc-mc13xxx.c | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 0d60dd5..7b39852 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -64,12 +64,10 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) unsigned long s1970; int ret; - mc13xxx_lock(priv->mc13xxx); + if (!priv->valid) + return -ENODATA; - if (!priv->valid) { - ret = -ENODATA; - goto out; - } + mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); if (unlikely(ret)) @@ -154,11 +152,14 @@ static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) goto out; } - ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); - if (unlikely(ret)) - goto out; + if (!priv->valid) { + ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); + if (unlikely(ret)) + goto out; + + ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); + } - ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); out: priv->valid = !ret; @@ -295,7 +296,7 @@ static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) struct mc13xxx_rtc *priv = dev; struct mc13xxx *mc13xxx = priv->mc13xxx; - dev_dbg(&priv->rtc->dev, "RTCRST\n"); + dev_warn(&priv->rtc->dev, "Contents of the RTC are no longer valid\n"); priv->valid = 0; mc13xxx_irq_mask(mc13xxx, irq); @@ -308,7 +309,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) int ret; struct mc13xxx_rtc *priv; struct mc13xxx *mc13xxx; - int rtcrst_pending; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -316,6 +316,7 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) mc13xxx = dev_get_drvdata(pdev->dev.parent); priv->mc13xxx = mc13xxx; + priv->valid = 1; platform_set_drvdata(pdev, priv); @@ -326,18 +327,13 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) mc13xxx_lock(mc13xxx); + mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_RTCRST); + ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST, mc13xxx_rtc_reset_handler, DRIVER_NAME, priv); if (ret) goto err_reset_irq_request; - ret = mc13xxx_irq_status(mc13xxx, MC13XXX_IRQ_RTCRST, - NULL, &rtcrst_pending); - if (ret) - goto err_reset_irq_status; - - priv->valid = !rtcrst_pending; - ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_1HZ, mc13xxx_rtc_update_handler, DRIVER_NAME, priv); if (ret) |