Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Nikolaus Voss and committed by
Linus Torvalds
bcffb10f eb86c306

+27 -19
+27 -19
drivers/rtc/rtc-m41t93.c
··· 48 48 static int m41t93_set_time(struct device *dev, struct rtc_time *tm) 49 49 { 50 50 struct spi_device *spi = to_spi_device(dev); 51 + int tmp; 51 52 u8 buf[9] = {0x80}; /* write cmd + 8 data bytes */ 52 53 u8 * const data = &buf[1]; /* ptr to first data byte */ 53 54 ··· 61 60 if (tm->tm_year < 100) { 62 61 dev_warn(&spi->dev, "unsupported date (before 2000-01-01).\n"); 63 62 return -EINVAL; 63 + } 64 + 65 + tmp = spi_w8r8(spi, M41T93_REG_FLAGS); 66 + if (tmp < 0) 67 + return tmp; 68 + 69 + if (tmp & M41T93_FLAG_OF) { 70 + dev_warn(&spi->dev, "OF bit is set, resetting.\n"); 71 + m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF); 72 + 73 + tmp = spi_w8r8(spi, M41T93_REG_FLAGS); 74 + if (tmp < 0) { 75 + return tmp; 76 + } else if (tmp & M41T93_FLAG_OF) { 77 + /* OF cannot be immediately reset: oscillator has to be 78 + * restarted. */ 79 + u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST; 80 + 81 + dev_warn(&spi->dev, 82 + "OF bit is still set, kickstarting clock.\n"); 83 + m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); 84 + reset_osc &= ~M41T93_FLAG_ST; 85 + m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); 86 + } 64 87 } 65 88 66 89 data[M41T93_REG_SSEC] = 0; ··· 114 89 1. halt bit (HT) is set: the clock is running but update of readout 115 90 registers has been disabled due to power failure. This is normal 116 91 case after poweron. Time is valid after resetting HT bit. 117 - 2. oscillator fail bit (OF) is set. Oscillator has be stopped and 118 - time is invalid: 119 - a) OF can be immeditely reset. 120 - b) OF cannot be immediately reset: oscillator has to be restarted. 92 + 2. oscillator fail bit (OF) is set: time is invalid. 121 93 */ 122 94 tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT); 123 95 if (tmp < 0) ··· 132 110 133 111 if (tmp & M41T93_FLAG_OF) { 134 112 ret = -EINVAL; 135 - dev_warn(&spi->dev, "OF bit is set, resetting.\n"); 136 - m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF); 137 - 138 - tmp = spi_w8r8(spi, M41T93_REG_FLAGS); 139 - if (tmp < 0) 140 - return tmp; 141 - else if (tmp & M41T93_FLAG_OF) { 142 - u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST; 143 - 144 - dev_warn(&spi->dev, 145 - "OF bit is still set, kickstarting clock.\n"); 146 - m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); 147 - reset_osc &= ~M41T93_FLAG_ST; 148 - m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); 149 - } 113 + dev_warn(&spi->dev, "OF bit is set, write time to restart.\n"); 150 114 } 151 115 152 116 if (tmp & M41T93_FLAG_BL)