linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drivers/rtc/rtc-m41t93.c: don't let get_time() reset error state
@ 2012-04-23 10:51 Nikolaus Voss
  2012-04-23 20:53 ` Andrew Morton
  0 siblings, 1 reply; 3+ messages in thread
From: Nikolaus Voss @ 2012-04-23 10:51 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, rtc-linux; +Cc: akpm, a.zummo, grant.likely

If the rtc reports the time might be invalid due to oscillator
failure, this flags must not be reset by get_time() as the read
operation doesn't make the time valid.

Instead, the flag is reset in set_time() when a valid time is
to be written.

Signed-off-by: Nikolaus Voss <n.voss@weinmann.de>
---
 drivers/rtc/rtc-m41t93.c |   46 +++++++++++++++++++++++++++-------------------
 1 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c
index ef71132..f19f45c 100644
--- a/drivers/rtc/rtc-m41t93.c
+++ b/drivers/rtc/rtc-m41t93.c
@@ -48,6 +48,7 @@ static inline int m41t93_set_reg(struct spi_device *spi, u8 addr, u8 data)
 static int m41t93_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct spi_device *spi = to_spi_device(dev);
+	int tmp;
 	u8 buf[9] = {0x80};        /* write cmd + 8 data bytes */
 	u8 * const data = &buf[1]; /* ptr to first data byte */
 
@@ -62,6 +63,30 @@ static int m41t93_set_time(struct device *dev, struct rtc_time *tm)
 		return -EINVAL;
 	}
 
+	tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
+	if (tmp < 0)
+		return tmp;
+
+	if (tmp & M41T93_FLAG_OF) {
+		dev_warn(&spi->dev, "OF bit is set, resetting.\n");
+		m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF);
+
+		tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
+		if (tmp < 0) {
+			return tmp;
+		} else if (tmp & M41T93_FLAG_OF) {
+			/* OF cannot be immediately reset: oscillator has to be
+			 * restarted. */
+			u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST;
+
+			dev_warn(&spi->dev,
+				 "OF bit is still set, kickstarting clock.\n");
+			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
+			reset_osc &= ~M41T93_FLAG_ST;
+			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
+		}
+	}
+
 	data[M41T93_REG_SSEC]		= 0;
 	data[M41T93_REG_ST_SEC]		= bin2bcd(tm->tm_sec);
 	data[M41T93_REG_MIN]		= bin2bcd(tm->tm_min);
@@ -89,10 +114,7 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm)
 	   1. halt bit (HT) is set: the clock is running but update of readout
 	      registers has been disabled due to power failure. This is normal
 	      case after poweron. Time is valid after resetting HT bit.
-	   2. oscillator fail bit (OF) is set. Oscillator has be stopped and
-	      time is invalid:
-	      a) OF can be immeditely reset.
-	      b) OF cannot be immediately reset: oscillator has to be restarted.
+	   2. oscillator fail bit (OF) is set: time is invalid.
 	*/
 	tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT);
 	if (tmp < 0)
@@ -110,21 +132,7 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm)
 
 	if (tmp & M41T93_FLAG_OF) {
 		ret = -EINVAL;
-		dev_warn(&spi->dev, "OF bit is set, resetting.\n");
-		m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF);
-
-		tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
-		if (tmp < 0)
-			return tmp;
-		else if (tmp & M41T93_FLAG_OF) {
-			u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST;
-
-			dev_warn(&spi->dev,
-				 "OF bit is still set, kickstarting clock.\n");
-			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
-			reset_osc &= ~M41T93_FLAG_ST;
-			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
-		}
+		dev_warn(&spi->dev, "OF bit is set, write time to restart.\n");
 	}
 
 	if (tmp & M41T93_FLAG_BL)
-- 
1.7.5.4


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

* Re: [PATCH] drivers/rtc/rtc-m41t93.c: don't let get_time() reset error state
  2012-04-23 10:51 [PATCH] drivers/rtc/rtc-m41t93.c: don't let get_time() reset error state Nikolaus Voss
@ 2012-04-23 20:53 ` Andrew Morton
  2012-04-24  4:51   ` Voss, Nikolaus
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2012-04-23 20:53 UTC (permalink / raw)
  To: Nikolaus Voss
  Cc: linux-arm-kernel, linux-kernel, rtc-linux, a.zummo, grant.likely

On Mon, 23 Apr 2012 12:51:23 +0200
Nikolaus Voss <n.voss@weinmann.de> wrote:

> If the rtc reports the time might be invalid due to oscillator
> failure, this flags must not be reset by get_time() as the read
> operation doesn't make the time valid.
> 
> Instead, the flag is reset in set_time() when a valid time is
> to be written.

This is rather vague - what is/are "these flags"?  From the patch I
think you're referring to (the maddeningly undocumented)
M41T93_FLAG_ST?  If so, I'd suggest something like

: If the rtc reports the time might be invalid due to oscillator failure,
: the M41T93_FLAG_ST flag must not be reset by get_time() as the read
: operation doesn't make the time valid.
: 
: Instead, the M41T93_FLAG_ST flag is reset in set_time() when a valid time
: is to be written.

Secondly, you provided no description of the user-visible effects of
the bug.  Hence I cannot work out which kernel version(s) this patch
should be merged into.


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

* RE: [PATCH] drivers/rtc/rtc-m41t93.c: don't let get_time() reset error state
  2012-04-23 20:53 ` Andrew Morton
@ 2012-04-24  4:51   ` Voss, Nikolaus
  0 siblings, 0 replies; 3+ messages in thread
From: Voss, Nikolaus @ 2012-04-24  4:51 UTC (permalink / raw)
  To: 'Andrew Morton'
  Cc: 'linux-arm-kernel@lists.infradead.org',
	'linux-kernel@vger.kernel.org',
	'rtc-linux@googlegroups.com',
	'a.zummo@towertech.it',
	'grant.likely@secretlab.ca'

Andrew Morton wrote on 2012-04-23:
> On Mon, 23 Apr 2012 12:51:23 +0200
> Nikolaus Voss <n.voss@weinmann.de> wrote:
> 
>> If the rtc reports the time might be invalid due to oscillator
>> failure, this flags must not be reset by get_time() as the read
>> operation doesn't make the time valid.
>> 
>> Instead, the flag is reset in set_time() when a valid time is
>> to be written.
> 
> This is rather vague - what is/are "these flags"?

Sorry, that's true. I speak of the M41T93_FLAG_OF
(Oscillator Fail) flag.

[...]
> Secondly, you provided no description of the user-visible effects of
> the bug.  Hence I cannot work out which kernel version(s) this patch
> should be merged into.

What the user sees is that the first get_time() read reports
an error (invalid time) and the second reports no error, so the
first read magically heals the rtc time.

The patch applies to all kernel versions with support for m41t93 rtc.

I'll repost the patch with a proper description.

Niko



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

end of thread, other threads:[~2012-04-24  5:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-23 10:51 [PATCH] drivers/rtc/rtc-m41t93.c: don't let get_time() reset error state Nikolaus Voss
2012-04-23 20:53 ` Andrew Morton
2012-04-24  4:51   ` Voss, Nikolaus

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).