diff options
author | Mike Rapoport <mike@compulab.co.il> | 2007-09-11 18:23:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-09-11 20:21:20 -0400 |
commit | f3d79b20df961880697c8442e1f7bc7969ce50a4 (patch) | |
tree | 0fbaa4aaf098ce0a6f9048a508a8a53c3ff6ed8f /drivers/rtc/rtc-v3020.c | |
parent | 693c10e6c1087e8f0ba0e2fd1a67adcff230a484 (diff) |
RTC v3020 fixes
Fix off-by-one in month calculations
Add delay for bus accesses to satisfy Tw > 500ns
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
Acked-by: Raphael Assenat <raph@8d.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-v3020.c')
-rw-r--r-- | drivers/rtc/rtc-v3020.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index 3b58d3d5d38a..a6b572978dc0 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
28 | #include <linux/rtc-v3020.h> | 28 | #include <linux/rtc-v3020.h> |
29 | #include <linux/delay.h> | ||
29 | 30 | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | 32 | ||
@@ -47,6 +48,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address, | |||
47 | for (i = 0; i < 4; i++) { | 48 | for (i = 0; i < 4; i++) { |
48 | writel((tmp & 1) << chip->leftshift, chip->ioaddress); | 49 | writel((tmp & 1) << chip->leftshift, chip->ioaddress); |
49 | tmp >>= 1; | 50 | tmp >>= 1; |
51 | udelay(1); | ||
50 | } | 52 | } |
51 | 53 | ||
52 | /* Commands dont have data */ | 54 | /* Commands dont have data */ |
@@ -54,6 +56,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address, | |||
54 | for (i = 0; i < 8; i++) { | 56 | for (i = 0; i < 8; i++) { |
55 | writel((data & 1) << chip->leftshift, chip->ioaddress); | 57 | writel((data & 1) << chip->leftshift, chip->ioaddress); |
56 | data >>= 1; | 58 | data >>= 1; |
59 | udelay(1); | ||
57 | } | 60 | } |
58 | } | 61 | } |
59 | } | 62 | } |
@@ -66,12 +69,14 @@ static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address) | |||
66 | for (i = 0; i < 4; i++) { | 69 | for (i = 0; i < 4; i++) { |
67 | writel((address & 1) << chip->leftshift, chip->ioaddress); | 70 | writel((address & 1) << chip->leftshift, chip->ioaddress); |
68 | address >>= 1; | 71 | address >>= 1; |
72 | udelay(1); | ||
69 | } | 73 | } |
70 | 74 | ||
71 | for (i = 0; i < 8; i++) { | 75 | for (i = 0; i < 8; i++) { |
72 | data >>= 1; | 76 | data >>= 1; |
73 | if (readl(chip->ioaddress) & (1 << chip->leftshift)) | 77 | if (readl(chip->ioaddress) & (1 << chip->leftshift)) |
74 | data |= 0x80; | 78 | data |= 0x80; |
79 | udelay(1); | ||
75 | } | 80 | } |
76 | 81 | ||
77 | return data; | 82 | return data; |
@@ -95,7 +100,7 @@ static int v3020_read_time(struct device *dev, struct rtc_time *dt) | |||
95 | tmp = v3020_get_reg(chip, V3020_MONTH_DAY); | 100 | tmp = v3020_get_reg(chip, V3020_MONTH_DAY); |
96 | dt->tm_mday = BCD2BIN(tmp); | 101 | dt->tm_mday = BCD2BIN(tmp); |
97 | tmp = v3020_get_reg(chip, V3020_MONTH); | 102 | tmp = v3020_get_reg(chip, V3020_MONTH); |
98 | dt->tm_mon = BCD2BIN(tmp); | 103 | dt->tm_mon = BCD2BIN(tmp) - 1; |
99 | tmp = v3020_get_reg(chip, V3020_WEEK_DAY); | 104 | tmp = v3020_get_reg(chip, V3020_WEEK_DAY); |
100 | dt->tm_wday = BCD2BIN(tmp); | 105 | dt->tm_wday = BCD2BIN(tmp); |
101 | tmp = v3020_get_reg(chip, V3020_YEAR); | 106 | tmp = v3020_get_reg(chip, V3020_YEAR); |
@@ -135,7 +140,7 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt) | |||
135 | v3020_set_reg(chip, V3020_MINUTES, BIN2BCD(dt->tm_min)); | 140 | v3020_set_reg(chip, V3020_MINUTES, BIN2BCD(dt->tm_min)); |
136 | v3020_set_reg(chip, V3020_HOURS, BIN2BCD(dt->tm_hour)); | 141 | v3020_set_reg(chip, V3020_HOURS, BIN2BCD(dt->tm_hour)); |
137 | v3020_set_reg(chip, V3020_MONTH_DAY, BIN2BCD(dt->tm_mday)); | 142 | v3020_set_reg(chip, V3020_MONTH_DAY, BIN2BCD(dt->tm_mday)); |
138 | v3020_set_reg(chip, V3020_MONTH, BIN2BCD(dt->tm_mon)); | 143 | v3020_set_reg(chip, V3020_MONTH, BIN2BCD(dt->tm_mon + 1)); |
139 | v3020_set_reg(chip, V3020_WEEK_DAY, BIN2BCD(dt->tm_wday)); | 144 | v3020_set_reg(chip, V3020_WEEK_DAY, BIN2BCD(dt->tm_wday)); |
140 | v3020_set_reg(chip, V3020_YEAR, BIN2BCD(dt->tm_year % 100)); | 145 | v3020_set_reg(chip, V3020_YEAR, BIN2BCD(dt->tm_year % 100)); |
141 | 146 | ||