aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-cmos.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
-rw-r--r--drivers/rtc/rtc-cmos.c88
1 files changed, 43 insertions, 45 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index ece4dbddc0ea..11b8ea29d2b7 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");
@@ -721,6 +719,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
721 } 719 }
722 } 720 }
723 721
722 cmos_rtc.dev = dev;
723 dev_set_drvdata(dev, &cmos_rtc);
724
724 cmos_rtc.rtc = rtc_device_register(driver_name, dev, 725 cmos_rtc.rtc = rtc_device_register(driver_name, dev,
725 &cmos_rtc_ops, THIS_MODULE); 726 &cmos_rtc_ops, THIS_MODULE);
726 if (IS_ERR(cmos_rtc.rtc)) { 727 if (IS_ERR(cmos_rtc.rtc)) {
@@ -728,8 +729,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
728 goto cleanup0; 729 goto cleanup0;
729 } 730 }
730 731
731 cmos_rtc.dev = dev;
732 dev_set_drvdata(dev, &cmos_rtc);
733 rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); 732 rename_region(ports, dev_name(&cmos_rtc.rtc->dev));
734 733
735 spin_lock_irq(&rtc_lock); 734 spin_lock_irq(&rtc_lock);
@@ -751,12 +750,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
751 750
752 spin_unlock_irq(&rtc_lock); 751 spin_unlock_irq(&rtc_lock);
753 752
754 /* FIXME teach the alarm code how to handle binary mode; 753 /* FIXME:
755 * <asm-generic/rtc.h> doesn't know 12-hour mode either. 754 * <asm-generic/rtc.h> doesn't know 12-hour mode either.
756 */ 755 */
757 if (is_valid_irq(rtc_irq) && 756 if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
758 (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { 757 dev_warn(dev, "only 24-hr supported\n");
759 dev_dbg(dev, "only 24-hr BCD mode supported\n");
760 retval = -ENXIO; 758 retval = -ENXIO;
761 goto cleanup1; 759 goto cleanup1;
762 } 760 }