]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drivers/rtc/rtc-ds1302.c: handle write protection
authorSergey Yanovich <ynvich@gmail.com>
Wed, 19 Jun 2013 00:08:06 +0000 (10:08 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 19 Jun 2013 07:27:32 +0000 (17:27 +1000)
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>
drivers/rtc/rtc-ds1302.c

index 7533b723082ddfd214d08c330f2848e16ce14015..07e8d79b4a09015e56c58aa363a3ab1b0d3d9626 100644 (file)
 #define        RTC_CMD_READ    0x81            /* Read command */
 #define        RTC_CMD_WRITE   0x80            /* Write command */
 
+#define        RTC_CMD_WRITE_ENABLE    0x00            /* Write enable */
+#define        RTC_CMD_WRITE_DISABLE   0x80            /* Write disable */
+
 #define RTC_ADDR_RAM0  0x20            /* Address of RAM0 */
 #define RTC_ADDR_TCR   0x08            /* Address of trickle charge register */
+#define        RTC_ADDR_CTRL   0x07            /* Address of control register */
 #define        RTC_ADDR_YEAR   0x06            /* Address of year register */
 #define        RTC_ADDR_DAY    0x05            /* Address of day of week register */
 #define        RTC_ADDR_MON    0x04            /* Address of month register */
@@ -161,6 +165,7 @@ static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
 
 static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
+       ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_ENABLE);
        /* Stop RTC */
        ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
 
@@ -175,6 +180,8 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
        /* Start RTC */
        ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
 
+       ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_DISABLE);
+
        return 0;
 }