diff options
author | Ben Dooks <ben-linux@fluff.org> | 2006-08-27 04:23:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-08-27 14:01:28 -0400 |
commit | 9a654518e1b774b8e8f74a819fd12a931e7672c9 (patch) | |
tree | 54ba738524292b9f54404ba97029727b05e7a04f /drivers/rtc/rtc-s3c.c | |
parent | 66a377c5041e1e399633153c8b500d457281e7c1 (diff) |
[PATCH] drivers/rtc: fix rtc-s3c.c
In the cleanups of drivers/rtc/s3c-rtc.c, the base address for the
registers got broken. This patch fixes that by ensuring the readb/writeb
are all prefixed with the base returned from ioremap()ing the registers.
Also fix check for valid year range, which was the wrong way around.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/rtc/rtc-s3c.c')
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 121 |
1 files changed, 67 insertions, 54 deletions
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index d6d1bff52b8e..aacbfea98678 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -69,12 +69,12 @@ static void s3c_rtc_setaie(int to) | |||
69 | 69 | ||
70 | pr_debug("%s: aie=%d\n", __FUNCTION__, to); | 70 | pr_debug("%s: aie=%d\n", __FUNCTION__, to); |
71 | 71 | ||
72 | tmp = readb(S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 72 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; |
73 | 73 | ||
74 | if (to) | 74 | if (to) |
75 | tmp |= S3C2410_RTCALM_ALMEN; | 75 | tmp |= S3C2410_RTCALM_ALMEN; |
76 | 76 | ||
77 | writeb(tmp, S3C2410_RTCALM); | 77 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); |
78 | } | 78 | } |
79 | 79 | ||
80 | static void s3c_rtc_setpie(int to) | 80 | static void s3c_rtc_setpie(int to) |
@@ -84,12 +84,12 @@ static void s3c_rtc_setpie(int to) | |||
84 | pr_debug("%s: pie=%d\n", __FUNCTION__, to); | 84 | pr_debug("%s: pie=%d\n", __FUNCTION__, to); |
85 | 85 | ||
86 | spin_lock_irq(&s3c_rtc_pie_lock); | 86 | spin_lock_irq(&s3c_rtc_pie_lock); |
87 | tmp = readb(S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; | 87 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; |
88 | 88 | ||
89 | if (to) | 89 | if (to) |
90 | tmp |= S3C2410_TICNT_ENABLE; | 90 | tmp |= S3C2410_TICNT_ENABLE; |
91 | 91 | ||
92 | writeb(tmp, S3C2410_TICNT); | 92 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
93 | spin_unlock_irq(&s3c_rtc_pie_lock); | 93 | spin_unlock_irq(&s3c_rtc_pie_lock); |
94 | } | 94 | } |
95 | 95 | ||
@@ -98,13 +98,13 @@ static void s3c_rtc_setfreq(int freq) | |||
98 | unsigned int tmp; | 98 | unsigned int tmp; |
99 | 99 | ||
100 | spin_lock_irq(&s3c_rtc_pie_lock); | 100 | spin_lock_irq(&s3c_rtc_pie_lock); |
101 | tmp = readb(S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | 101 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; |
102 | 102 | ||
103 | s3c_rtc_freq = freq; | 103 | s3c_rtc_freq = freq; |
104 | 104 | ||
105 | tmp |= (128 / freq)-1; | 105 | tmp |= (128 / freq)-1; |
106 | 106 | ||
107 | writeb(tmp, S3C2410_TICNT); | 107 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
108 | spin_unlock_irq(&s3c_rtc_pie_lock); | 108 | spin_unlock_irq(&s3c_rtc_pie_lock); |
109 | } | 109 | } |
110 | 110 | ||
@@ -113,14 +113,15 @@ static void s3c_rtc_setfreq(int freq) | |||
113 | static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | 113 | static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) |
114 | { | 114 | { |
115 | unsigned int have_retried = 0; | 115 | unsigned int have_retried = 0; |
116 | void __iomem *base = s3c_rtc_base; | ||
116 | 117 | ||
117 | retry_get_time: | 118 | retry_get_time: |
118 | rtc_tm->tm_min = readb(S3C2410_RTCMIN); | 119 | rtc_tm->tm_min = readb(base + S3C2410_RTCMIN); |
119 | rtc_tm->tm_hour = readb(S3C2410_RTCHOUR); | 120 | rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR); |
120 | rtc_tm->tm_mday = readb(S3C2410_RTCDATE); | 121 | rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE); |
121 | rtc_tm->tm_mon = readb(S3C2410_RTCMON); | 122 | rtc_tm->tm_mon = readb(base + S3C2410_RTCMON); |
122 | rtc_tm->tm_year = readb(S3C2410_RTCYEAR); | 123 | rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); |
123 | rtc_tm->tm_sec = readb(S3C2410_RTCSEC); | 124 | rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); |
124 | 125 | ||
125 | /* the only way to work out wether the system was mid-update | 126 | /* the only way to work out wether the system was mid-update |
126 | * when we read it is to check the second counter, and if it | 127 | * when we read it is to check the second counter, and if it |
@@ -151,17 +152,25 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
151 | 152 | ||
152 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | 153 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) |
153 | { | 154 | { |
155 | void __iomem *base = s3c_rtc_base; | ||
156 | |||
154 | /* the rtc gets round the y2k problem by just not supporting it */ | 157 | /* the rtc gets round the y2k problem by just not supporting it */ |
155 | 158 | ||
156 | if (tm->tm_year < 100) | 159 | if (tm->tm_year > 100) { |
160 | dev_err(dev, "rtc only supports 100 years\n"); | ||
157 | return -EINVAL; | 161 | return -EINVAL; |
162 | } | ||
163 | |||
164 | pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n", | ||
165 | tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
166 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
158 | 167 | ||
159 | writeb(BIN2BCD(tm->tm_sec), S3C2410_RTCSEC); | 168 | writeb(BIN2BCD(tm->tm_sec), base + S3C2410_RTCSEC); |
160 | writeb(BIN2BCD(tm->tm_min), S3C2410_RTCMIN); | 169 | writeb(BIN2BCD(tm->tm_min), base + S3C2410_RTCMIN); |
161 | writeb(BIN2BCD(tm->tm_hour), S3C2410_RTCHOUR); | 170 | writeb(BIN2BCD(tm->tm_hour), base + S3C2410_RTCHOUR); |
162 | writeb(BIN2BCD(tm->tm_mday), S3C2410_RTCDATE); | 171 | writeb(BIN2BCD(tm->tm_mday), base + S3C2410_RTCDATE); |
163 | writeb(BIN2BCD(tm->tm_mon + 1), S3C2410_RTCMON); | 172 | writeb(BIN2BCD(tm->tm_mon + 1), base + S3C2410_RTCMON); |
164 | writeb(BIN2BCD(tm->tm_year - 100), S3C2410_RTCYEAR); | 173 | writeb(BIN2BCD(tm->tm_year - 100), base + S3C2410_RTCYEAR); |
165 | 174 | ||
166 | return 0; | 175 | return 0; |
167 | } | 176 | } |
@@ -169,16 +178,17 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
169 | static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | 178 | static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) |
170 | { | 179 | { |
171 | struct rtc_time *alm_tm = &alrm->time; | 180 | struct rtc_time *alm_tm = &alrm->time; |
181 | void __iomem *base = s3c_rtc_base; | ||
172 | unsigned int alm_en; | 182 | unsigned int alm_en; |
173 | 183 | ||
174 | alm_tm->tm_sec = readb(S3C2410_ALMSEC); | 184 | alm_tm->tm_sec = readb(base + S3C2410_ALMSEC); |
175 | alm_tm->tm_min = readb(S3C2410_ALMMIN); | 185 | alm_tm->tm_min = readb(base + S3C2410_ALMMIN); |
176 | alm_tm->tm_hour = readb(S3C2410_ALMHOUR); | 186 | alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR); |
177 | alm_tm->tm_mon = readb(S3C2410_ALMMON); | 187 | alm_tm->tm_mon = readb(base + S3C2410_ALMMON); |
178 | alm_tm->tm_mday = readb(S3C2410_ALMDATE); | 188 | alm_tm->tm_mday = readb(base + S3C2410_ALMDATE); |
179 | alm_tm->tm_year = readb(S3C2410_ALMYEAR); | 189 | alm_tm->tm_year = readb(base + S3C2410_ALMYEAR); |
180 | 190 | ||
181 | alm_en = readb(S3C2410_RTCALM); | 191 | alm_en = readb(base + S3C2410_RTCALM); |
182 | 192 | ||
183 | pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", | 193 | pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", |
184 | alm_en, | 194 | alm_en, |
@@ -226,6 +236,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
226 | static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | 236 | static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) |
227 | { | 237 | { |
228 | struct rtc_time *tm = &alrm->time; | 238 | struct rtc_time *tm = &alrm->time; |
239 | void __iomem *base = s3c_rtc_base; | ||
229 | unsigned int alrm_en; | 240 | unsigned int alrm_en; |
230 | 241 | ||
231 | pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", | 242 | pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", |
@@ -234,32 +245,32 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
234 | tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec); | 245 | tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec); |
235 | 246 | ||
236 | 247 | ||
237 | alrm_en = readb(S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; | 248 | alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; |
238 | writeb(0x00, S3C2410_RTCALM); | 249 | writeb(0x00, base + S3C2410_RTCALM); |
239 | 250 | ||
240 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { | 251 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { |
241 | alrm_en |= S3C2410_RTCALM_SECEN; | 252 | alrm_en |= S3C2410_RTCALM_SECEN; |
242 | writeb(BIN2BCD(tm->tm_sec), S3C2410_ALMSEC); | 253 | writeb(BIN2BCD(tm->tm_sec), base + S3C2410_ALMSEC); |
243 | } | 254 | } |
244 | 255 | ||
245 | if (tm->tm_min < 60 && tm->tm_min >= 0) { | 256 | if (tm->tm_min < 60 && tm->tm_min >= 0) { |
246 | alrm_en |= S3C2410_RTCALM_MINEN; | 257 | alrm_en |= S3C2410_RTCALM_MINEN; |
247 | writeb(BIN2BCD(tm->tm_min), S3C2410_ALMMIN); | 258 | writeb(BIN2BCD(tm->tm_min), base + S3C2410_ALMMIN); |
248 | } | 259 | } |
249 | 260 | ||
250 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { | 261 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { |
251 | alrm_en |= S3C2410_RTCALM_HOUREN; | 262 | alrm_en |= S3C2410_RTCALM_HOUREN; |
252 | writeb(BIN2BCD(tm->tm_hour), S3C2410_ALMHOUR); | 263 | writeb(BIN2BCD(tm->tm_hour), base + S3C2410_ALMHOUR); |
253 | } | 264 | } |
254 | 265 | ||
255 | pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); | 266 | pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); |
256 | 267 | ||
257 | writeb(alrm_en, S3C2410_RTCALM); | 268 | writeb(alrm_en, base + S3C2410_RTCALM); |
258 | 269 | ||
259 | if (0) { | 270 | if (0) { |
260 | alrm_en = readb(S3C2410_RTCALM); | 271 | alrm_en = readb(base + S3C2410_RTCALM); |
261 | alrm_en &= ~S3C2410_RTCALM_ALMEN; | 272 | alrm_en &= ~S3C2410_RTCALM_ALMEN; |
262 | writeb(alrm_en, S3C2410_RTCALM); | 273 | writeb(alrm_en, base + S3C2410_RTCALM); |
263 | disable_irq_wake(s3c_rtc_alarmno); | 274 | disable_irq_wake(s3c_rtc_alarmno); |
264 | } | 275 | } |
265 | 276 | ||
@@ -319,8 +330,8 @@ static int s3c_rtc_ioctl(struct device *dev, | |||
319 | 330 | ||
320 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | 331 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) |
321 | { | 332 | { |
322 | unsigned int rtcalm = readb(S3C2410_RTCALM); | 333 | unsigned int rtcalm = readb(s3c_rtc_base + S3C2410_RTCALM); |
323 | unsigned int ticnt = readb (S3C2410_TICNT); | 334 | unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); |
324 | 335 | ||
325 | seq_printf(seq, "alarm_IRQ\t: %s\n", | 336 | seq_printf(seq, "alarm_IRQ\t: %s\n", |
326 | (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" ); | 337 | (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" ); |
@@ -387,39 +398,40 @@ static struct rtc_class_ops s3c_rtcops = { | |||
387 | 398 | ||
388 | static void s3c_rtc_enable(struct platform_device *pdev, int en) | 399 | static void s3c_rtc_enable(struct platform_device *pdev, int en) |
389 | { | 400 | { |
401 | void __iomem *base = s3c_rtc_base; | ||
390 | unsigned int tmp; | 402 | unsigned int tmp; |
391 | 403 | ||
392 | if (s3c_rtc_base == NULL) | 404 | if (s3c_rtc_base == NULL) |
393 | return; | 405 | return; |
394 | 406 | ||
395 | if (!en) { | 407 | if (!en) { |
396 | tmp = readb(S3C2410_RTCCON); | 408 | tmp = readb(base + S3C2410_RTCCON); |
397 | writeb(tmp & ~S3C2410_RTCCON_RTCEN, S3C2410_RTCCON); | 409 | writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON); |
398 | 410 | ||
399 | tmp = readb(S3C2410_TICNT); | 411 | tmp = readb(base + S3C2410_TICNT); |
400 | writeb(tmp & ~S3C2410_TICNT_ENABLE, S3C2410_TICNT); | 412 | writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT); |
401 | } else { | 413 | } else { |
402 | /* re-enable the device, and check it is ok */ | 414 | /* re-enable the device, and check it is ok */ |
403 | 415 | ||
404 | if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){ | 416 | if ((readb(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){ |
405 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); | 417 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); |
406 | 418 | ||
407 | tmp = readb(S3C2410_RTCCON); | 419 | tmp = readb(base + S3C2410_RTCCON); |
408 | writeb(tmp | S3C2410_RTCCON_RTCEN , S3C2410_RTCCON); | 420 | writeb(tmp|S3C2410_RTCCON_RTCEN, base+S3C2410_RTCCON); |
409 | } | 421 | } |
410 | 422 | ||
411 | if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){ | 423 | if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){ |
412 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); | 424 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); |
413 | 425 | ||
414 | tmp = readb(S3C2410_RTCCON); | 426 | tmp = readb(base + S3C2410_RTCCON); |
415 | writeb(tmp& ~S3C2410_RTCCON_CNTSEL , S3C2410_RTCCON); | 427 | writeb(tmp& ~S3C2410_RTCCON_CNTSEL, base+S3C2410_RTCCON); |
416 | } | 428 | } |
417 | 429 | ||
418 | if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){ | 430 | if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){ |
419 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); | 431 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); |
420 | 432 | ||
421 | tmp = readb(S3C2410_RTCCON); | 433 | tmp = readb(base + S3C2410_RTCCON); |
422 | writeb(tmp & ~S3C2410_RTCCON_CLKRST, S3C2410_RTCCON); | 434 | writeb(tmp & ~S3C2410_RTCCON_CLKRST, base+S3C2410_RTCCON); |
423 | } | 435 | } |
424 | } | 436 | } |
425 | } | 437 | } |
@@ -475,8 +487,8 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
475 | } | 487 | } |
476 | 488 | ||
477 | s3c_rtc_mem = request_mem_region(res->start, | 489 | s3c_rtc_mem = request_mem_region(res->start, |
478 | res->end-res->start+1, | 490 | res->end-res->start+1, |
479 | pdev->name); | 491 | pdev->name); |
480 | 492 | ||
481 | if (s3c_rtc_mem == NULL) { | 493 | if (s3c_rtc_mem == NULL) { |
482 | dev_err(&pdev->dev, "failed to reserve memory region\n"); | 494 | dev_err(&pdev->dev, "failed to reserve memory region\n"); |
@@ -495,7 +507,8 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
495 | 507 | ||
496 | s3c_rtc_enable(pdev, 1); | 508 | s3c_rtc_enable(pdev, 1); |
497 | 509 | ||
498 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(S3C2410_RTCCON)); | 510 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", |
511 | readb(s3c_rtc_base + S3C2410_RTCCON)); | ||
499 | 512 | ||
500 | s3c_rtc_setfreq(s3c_rtc_freq); | 513 | s3c_rtc_setfreq(s3c_rtc_freq); |
501 | 514 | ||
@@ -543,7 +556,7 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
543 | 556 | ||
544 | /* save TICNT for anyone using periodic interrupts */ | 557 | /* save TICNT for anyone using periodic interrupts */ |
545 | 558 | ||
546 | ticnt_save = readb(S3C2410_TICNT); | 559 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); |
547 | 560 | ||
548 | /* calculate time delta for suspend */ | 561 | /* calculate time delta for suspend */ |
549 | 562 | ||
@@ -567,7 +580,7 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
567 | rtc_tm_to_time(&tm, &time.tv_sec); | 580 | rtc_tm_to_time(&tm, &time.tv_sec); |
568 | restore_time_delta(&s3c_rtc_delta, &time); | 581 | restore_time_delta(&s3c_rtc_delta, &time); |
569 | 582 | ||
570 | writeb(ticnt_save, S3C2410_TICNT); | 583 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
571 | return 0; | 584 | return 0; |
572 | } | 585 | } |
573 | #else | 586 | #else |