Commit dfc657b1330990213a3865aaef9d8af563ccad51

Authored by Sergey Yanovich
Committed by Linus Torvalds
1 parent 25d053cf10

drivers/rtc/rtc-ds1302.c: handle write protection

This chip has a control register and can prevent altering saved clock.
Without this patch we could have:

(arm)root@pac14:~# date
Tue May 21 03:08:27 MSK 2013
(arm)root@pac14:~# /etc/init.d/hwclock.sh show
Tue May 21 11:13:58 2013  -0.067322 seconds
(arm)root@pac14:~# /etc/init.d/hwclock.sh stop
[info] Saving the system clock.
[info] Hardware Clock updated to Tue May 21 03:09:01 MSK 2013.
(arm)root@pac14:~# /etc/init.d/hwclock.sh show
Tue May 21 11:14:15 2013  -0.624272 seconds

The patch enables write access to rtc before the driver tries to write
time and re-disables when time data is written.

Signed-off-by: Sergey Yanovich <ynvich@gmail.com>
Acked-by: Marc Zyngier <maz@misterjones.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Sachin Kamat <sachin.kamat@linaro.org>
Cc: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 7 additions and 0 deletions Side-by-side Diff

drivers/rtc/rtc-ds1302.c
... ... @@ -23,8 +23,12 @@
23 23 #define RTC_CMD_READ 0x81 /* Read command */
24 24 #define RTC_CMD_WRITE 0x80 /* Write command */
25 25  
  26 +#define RTC_CMD_WRITE_ENABLE 0x00 /* Write enable */
  27 +#define RTC_CMD_WRITE_DISABLE 0x80 /* Write disable */
  28 +
26 29 #define RTC_ADDR_RAM0 0x20 /* Address of RAM0 */
27 30 #define RTC_ADDR_TCR 0x08 /* Address of trickle charge register */
  31 +#define RTC_ADDR_CTRL 0x07 /* Address of control register */
28 32 #define RTC_ADDR_YEAR 0x06 /* Address of year register */
29 33 #define RTC_ADDR_DAY 0x05 /* Address of day of week register */
30 34 #define RTC_ADDR_MON 0x04 /* Address of month register */
... ... @@ -161,6 +165,7 @@
161 165  
162 166 static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
163 167 {
  168 + ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_ENABLE);
164 169 /* Stop RTC */
165 170 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
166 171  
... ... @@ -174,6 +179,8 @@
174 179  
175 180 /* Start RTC */
176 181 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
  182 +
  183 + ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_DISABLE);
177 184  
178 185 return 0;
179 186 }