aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorNikolaus Voss <n.voss@weinmann.de>2012-05-29 18:07:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-29 19:22:33 -0400
commitbcffb10f287c89ca6e4f89ef748301a9e22384d0 (patch)
treeec0394305953a3e28e32b7045ffabc12784c2987 /drivers/rtc
parenteb86c3064b3c53837fdfea17df1483d825919894 (diff)
drivers/rtc/rtc-m41t93.c: don't let get_time() reset M41T93_FLAG_OF
If the rtc reports the time might be invalid due to oscillator failure, M41T93_FLAG_OF flag must not be reset by get_time() as the read operation doesn't make the time valid. Without this patch, only the first get_time() reported an invalid time, the second get_time() reported a valid time althought the reported time is probably wrong due to oscillator failure. Instead of resetting in get_time(), with this patch M41T93_FLAG_OF is reset in set_time() when a valid time is to be written. Signed-off-by: Nikolaus Voss <n.voss@weinmann.de> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-m41t93.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c
index 10f1c29436ec..efab3d48cb15 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)
48static int m41t93_set_time(struct device *dev, struct rtc_time *tm) 48static int m41t93_set_time(struct device *dev, struct rtc_time *tm)
49{ 49{
50 struct spi_device *spi = to_spi_device(dev); 50 struct spi_device *spi = to_spi_device(dev);
51 int tmp;
51 u8 buf[9] = {0x80}; /* write cmd + 8 data bytes */ 52 u8 buf[9] = {0x80}; /* write cmd + 8 data bytes */
52 u8 * const data = &buf[1]; /* ptr to first data byte */ 53 u8 * const data = &buf[1]; /* ptr to first data byte */
53 54
@@ -62,6 +63,30 @@ static int m41t93_set_time(struct device *dev, struct rtc_time *tm)
62 return -EINVAL; 63 return -EINVAL;
63 } 64 }
64 65
66 tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
67 if (tmp < 0)
68 return tmp;
69
70 if (tmp & M41T93_FLAG_OF) {
71 dev_warn(&spi->dev, "OF bit is set, resetting.\n");
72 m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF);
73
74 tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
75 if (tmp < 0) {
76 return tmp;
77 } else if (tmp & M41T93_FLAG_OF) {
78 /* OF cannot be immediately reset: oscillator has to be
79 * restarted. */
80 u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST;
81
82 dev_warn(&spi->dev,
83 "OF bit is still set, kickstarting clock.\n");
84 m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
85 reset_osc &= ~M41T93_FLAG_ST;
86 m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
87 }
88 }
89
65 data[M41T93_REG_SSEC] = 0; 90 data[M41T93_REG_SSEC] = 0;
66 data[M41T93_REG_ST_SEC] = bin2bcd(tm->tm_sec); 91 data[M41T93_REG_ST_SEC] = bin2bcd(tm->tm_sec);
67 data[M41T93_REG_MIN] = bin2bcd(tm->tm_min); 92 data[M41T93_REG_MIN] = bin2bcd(tm->tm_min);
@@ -89,10 +114,7 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm)
89 1. halt bit (HT) is set: the clock is running but update of readout 114 1. halt bit (HT) is set: the clock is running but update of readout
90 registers has been disabled due to power failure. This is normal 115 registers has been disabled due to power failure. This is normal
91 case after poweron. Time is valid after resetting HT bit. 116 case after poweron. Time is valid after resetting HT bit.
92 2. oscillator fail bit (OF) is set. Oscillator has be stopped and 117 2. oscillator fail bit (OF) is set: time is invalid.
93 time is invalid:
94 a) OF can be immeditely reset.
95 b) OF cannot be immediately reset: oscillator has to be restarted.
96 */ 118 */
97 tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT); 119 tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT);
98 if (tmp < 0) 120 if (tmp < 0)
@@ -110,21 +132,7 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm)
110 132
111 if (tmp & M41T93_FLAG_OF) { 133 if (tmp & M41T93_FLAG_OF) {
112 ret = -EINVAL; 134 ret = -EINVAL;
113 dev_warn(&spi->dev, "OF bit is set, resetting.\n"); 135 dev_warn(&spi->dev, "OF bit is set, write time to restart.\n");
114 m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF);
115
116 tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
117 if (tmp < 0)
118 return tmp;
119 else if (tmp & M41T93_FLAG_OF) {
120 u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST;
121
122 dev_warn(&spi->dev,
123 "OF bit is still set, kickstarting clock.\n");
124 m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
125 reset_osc &= ~M41T93_FLAG_ST;
126 m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
127 }
128 } 136 }
129 137
130 if (tmp & M41T93_FLAG_BL) 138 if (tmp & M41T93_FLAG_BL)