diff options
author | Arnaud Patard <apatard@mandriva.com> | 2010-04-29 05:58:44 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-05-21 16:31:19 -0400 |
commit | 3804a89bfb84fb8849c72e3bbafddaee539b3430 (patch) | |
tree | 4784730807dd2746363d95949fca45c8fc4971c0 /drivers/rtc/rtc-cmos.c | |
parent | 893556e602d6d5d86ed401ff72bf63d8cfa4a9d0 (diff) |
RTC: rtc-cmos: Fix binary mode support
As a follow-up to the thread about RTC support for some Loongson 2E/2F
boards, this patch tries to address the "REVISIT"/"FIXME" comments about
rtc binary mode handling and allow rtc to work with rtc in binary mode.
I've also raised the message about 24-h mode not supported to warning
otherwise, one may end up with no rtc without any message in the kernel
log.
Signed-off-by: Arnaud Patard <apatard@mandriva.com>
To: linux-mips@linux-mips.org
To: rtc-linux@googlegroups.com
Cc: david-b@pacbell.net
Cc: a.zummo@towertech.it
Cc: akpm@linux-foundation.org
Patchwork: http://patchwork.linux-mips.org/patch/1158/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index ece4dbddc0ea..96e8e70fbf1e 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -238,31 +238,32 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
238 | rtc_control = CMOS_READ(RTC_CONTROL); | 238 | rtc_control = CMOS_READ(RTC_CONTROL); |
239 | spin_unlock_irq(&rtc_lock); | 239 | spin_unlock_irq(&rtc_lock); |
240 | 240 | ||
241 | /* REVISIT this assumes PC style usage: always BCD */ | 241 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
242 | 242 | if (((unsigned)t->time.tm_sec) < 0x60) | |
243 | if (((unsigned)t->time.tm_sec) < 0x60) | 243 | t->time.tm_sec = bcd2bin(t->time.tm_sec); |
244 | t->time.tm_sec = bcd2bin(t->time.tm_sec); | ||
245 | else | ||
246 | t->time.tm_sec = -1; | ||
247 | if (((unsigned)t->time.tm_min) < 0x60) | ||
248 | t->time.tm_min = bcd2bin(t->time.tm_min); | ||
249 | else | ||
250 | t->time.tm_min = -1; | ||
251 | if (((unsigned)t->time.tm_hour) < 0x24) | ||
252 | t->time.tm_hour = bcd2bin(t->time.tm_hour); | ||
253 | else | ||
254 | t->time.tm_hour = -1; | ||
255 | |||
256 | if (cmos->day_alrm) { | ||
257 | if (((unsigned)t->time.tm_mday) <= 0x31) | ||
258 | t->time.tm_mday = bcd2bin(t->time.tm_mday); | ||
259 | else | 244 | else |
260 | t->time.tm_mday = -1; | 245 | t->time.tm_sec = -1; |
261 | if (cmos->mon_alrm) { | 246 | if (((unsigned)t->time.tm_min) < 0x60) |
262 | if (((unsigned)t->time.tm_mon) <= 0x12) | 247 | t->time.tm_min = bcd2bin(t->time.tm_min); |
263 | t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1; | 248 | else |
249 | t->time.tm_min = -1; | ||
250 | if (((unsigned)t->time.tm_hour) < 0x24) | ||
251 | t->time.tm_hour = bcd2bin(t->time.tm_hour); | ||
252 | else | ||
253 | t->time.tm_hour = -1; | ||
254 | |||
255 | if (cmos->day_alrm) { | ||
256 | if (((unsigned)t->time.tm_mday) <= 0x31) | ||
257 | t->time.tm_mday = bcd2bin(t->time.tm_mday); | ||
264 | else | 258 | else |
265 | t->time.tm_mon = -1; | 259 | t->time.tm_mday = -1; |
260 | |||
261 | if (cmos->mon_alrm) { | ||
262 | if (((unsigned)t->time.tm_mon) <= 0x12) | ||
263 | t->time.tm_mon = bcd2bin(t->time.tm_mon)-1; | ||
264 | else | ||
265 | t->time.tm_mon = -1; | ||
266 | } | ||
266 | } | 267 | } |
267 | } | 268 | } |
268 | t->time.tm_year = -1; | 269 | t->time.tm_year = -1; |
@@ -322,29 +323,26 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) | |||
322 | static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 323 | static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
323 | { | 324 | { |
324 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 325 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
325 | unsigned char mon, mday, hrs, min, sec; | 326 | unsigned char mon, mday, hrs, min, sec, rtc_control; |
326 | 327 | ||
327 | if (!is_valid_irq(cmos->irq)) | 328 | if (!is_valid_irq(cmos->irq)) |
328 | return -EIO; | 329 | return -EIO; |
329 | 330 | ||
330 | /* REVISIT this assumes PC style usage: always BCD */ | ||
331 | |||
332 | /* Writing 0xff means "don't care" or "match all". */ | ||
333 | |||
334 | mon = t->time.tm_mon + 1; | 331 | mon = t->time.tm_mon + 1; |
335 | mon = (mon <= 12) ? bin2bcd(mon) : 0xff; | ||
336 | |||
337 | mday = t->time.tm_mday; | 332 | mday = t->time.tm_mday; |
338 | mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; | ||
339 | |||
340 | hrs = t->time.tm_hour; | 333 | hrs = t->time.tm_hour; |
341 | hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; | ||
342 | |||
343 | min = t->time.tm_min; | 334 | min = t->time.tm_min; |
344 | min = (min < 60) ? bin2bcd(min) : 0xff; | ||
345 | |||
346 | sec = t->time.tm_sec; | 335 | sec = t->time.tm_sec; |
347 | sec = (sec < 60) ? bin2bcd(sec) : 0xff; | 336 | |
337 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
338 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
339 | /* Writing 0xff means "don't care" or "match all". */ | ||
340 | mon = (mon <= 12) ? bin2bcd(mon) : 0xff; | ||
341 | mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; | ||
342 | hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; | ||
343 | min = (min < 60) ? bin2bcd(min) : 0xff; | ||
344 | sec = (sec < 60) ? bin2bcd(sec) : 0xff; | ||
345 | } | ||
348 | 346 | ||
349 | spin_lock_irq(&rtc_lock); | 347 | spin_lock_irq(&rtc_lock); |
350 | 348 | ||
@@ -478,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) | |||
478 | "update_IRQ\t: %s\n" | 476 | "update_IRQ\t: %s\n" |
479 | "HPET_emulated\t: %s\n" | 477 | "HPET_emulated\t: %s\n" |
480 | // "square_wave\t: %s\n" | 478 | // "square_wave\t: %s\n" |
481 | // "BCD\t\t: %s\n" | 479 | "BCD\t\t: %s\n" |
482 | "DST_enable\t: %s\n" | 480 | "DST_enable\t: %s\n" |
483 | "periodic_freq\t: %d\n" | 481 | "periodic_freq\t: %d\n" |
484 | "batt_status\t: %s\n", | 482 | "batt_status\t: %s\n", |
@@ -486,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) | |||
486 | (rtc_control & RTC_UIE) ? "yes" : "no", | 484 | (rtc_control & RTC_UIE) ? "yes" : "no", |
487 | is_hpet_enabled() ? "yes" : "no", | 485 | is_hpet_enabled() ? "yes" : "no", |
488 | // (rtc_control & RTC_SQWE) ? "yes" : "no", | 486 | // (rtc_control & RTC_SQWE) ? "yes" : "no", |
489 | // (rtc_control & RTC_DM_BINARY) ? "no" : "yes", | 487 | (rtc_control & RTC_DM_BINARY) ? "no" : "yes", |
490 | (rtc_control & RTC_DST_EN) ? "yes" : "no", | 488 | (rtc_control & RTC_DST_EN) ? "yes" : "no", |
491 | cmos->rtc->irq_freq, | 489 | cmos->rtc->irq_freq, |
492 | (valid & RTC_VRT) ? "okay" : "dead"); | 490 | (valid & RTC_VRT) ? "okay" : "dead"); |
@@ -751,12 +749,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
751 | 749 | ||
752 | spin_unlock_irq(&rtc_lock); | 750 | spin_unlock_irq(&rtc_lock); |
753 | 751 | ||
754 | /* FIXME teach the alarm code how to handle binary mode; | 752 | /* FIXME: |
755 | * <asm-generic/rtc.h> doesn't know 12-hour mode either. | 753 | * <asm-generic/rtc.h> doesn't know 12-hour mode either. |
756 | */ | 754 | */ |
757 | if (is_valid_irq(rtc_irq) && | 755 | if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) { |
758 | (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { | 756 | dev_warn(dev, "only 24-hr supported\n"); |
759 | dev_dbg(dev, "only 24-hr BCD mode supported\n"); | ||
760 | retval = -ENXIO; | 757 | retval = -ENXIO; |
761 | goto cleanup1; | 758 | goto cleanup1; |
762 | } | 759 | } |