aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-cmos.c
diff options
context:
space:
mode:
authorArnaud Patard <apatard@mandriva.com>2010-04-29 05:58:44 -0400
committerRalf Baechle <ralf@linux-mips.org>2010-05-21 16:31:19 -0400
commit3804a89bfb84fb8849c72e3bbafddaee539b3430 (patch)
tree4784730807dd2746363d95949fca45c8fc4971c0 /drivers/rtc/rtc-cmos.c
parent893556e602d6d5d86ed401ff72bf63d8cfa4a9d0 (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.c83
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)
322static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) 323static 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 }