aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-m41t93.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-29 21:05:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-29 21:05:31 -0400
commit7d36014b972a3833b883a7ef41e6bd3b0d187850 (patch)
tree5c828b0de1cd357288135cc04461d31386b89c26 /drivers/rtc/rtc-m41t93.c
parent442a9ffabb21f175027e93e72ea05159818271a6 (diff)
parentecb41a77411358d385e3fde5b4e98a5f3d9cfdd5 (diff)
Merge branch 'akpm' (Andrew's patch-bomb)
Merge patches through Andrew Morton: "180 patches - err 181 - listed below: - most of MM. I held back the (large) "memcg: add hugetlb extension" series because a bunfight has recently broken out. - leds. After this, Bryan Wu will be handling drivers/leds/ - backlight - lib/ - rtc" * emailed from Andrew Morton <akpm@linux-foundation.org>: (181 patches) drivers/rtc/rtc-s3c.c: fix compiler warning drivers/rtc/rtc-tegra.c: clean up probe/remove routines drivers/rtc/rtc-pl031.c: remove RTC timer interrupt handling drivers/rtc/rtc-lpc32xx.c: add device tree support drivers/rtc/rtc-m41t93.c: don't let get_time() reset M41T93_FLAG_OF rtc: ds1307: add trickle charger support rtc: ds1307: remove superfluous initialization rtc: rename CONFIG_RTC_MXC to CONFIG_RTC_DRV_MXC drivers/rtc/Kconfig: place RTC_DRV_IMXDI and RTC_MXC under "on-CPU RTC drivers" drivers/rtc/rtc-pcf8563.c: add RTC_VL_READ/RTC_VL_CLR ioctl feature rtc: add ioctl to get/clear battery low voltage status drivers/rtc/rtc-ep93xx.c: convert to use module_platform_driver() rtc/spear: add Device Tree probing capability lib/vsprintf.c: "%#o",0 becomes '0' instead of '00' radix-tree: fix preload vector size spinlock_debug: print kallsyms name for lock vsprintf: fix %ps on non symbols when using kallsyms lib/bitmap.c: fix documentation for scnprintf() functions lib/string_helpers.c: make arrays static lib/test-kstrtox.c: mark const init data with __initconst instead of __initdata ...
Diffstat (limited to 'drivers/rtc/rtc-m41t93.c')
-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)