diff options
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
| -rw-r--r-- | drivers/rtc/rtc-cmos.c | 94 |
1 files changed, 47 insertions, 47 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index e9aa814ddd23..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) | |||
| 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"); |
| @@ -519,7 +517,8 @@ static const struct rtc_class_ops cmos_rtc_ops = { | |||
| 519 | #define NVRAM_OFFSET (RTC_REG_D + 1) | 517 | #define NVRAM_OFFSET (RTC_REG_D + 1) |
| 520 | 518 | ||
| 521 | static ssize_t | 519 | static ssize_t |
| 522 | cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | 520 | cmos_nvram_read(struct file *filp, struct kobject *kobj, |
| 521 | struct bin_attribute *attr, | ||
| 523 | char *buf, loff_t off, size_t count) | 522 | char *buf, loff_t off, size_t count) |
| 524 | { | 523 | { |
| 525 | int retval; | 524 | int retval; |
| @@ -547,7 +546,8 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
| 547 | } | 546 | } |
| 548 | 547 | ||
| 549 | static ssize_t | 548 | static ssize_t |
| 550 | cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | 549 | cmos_nvram_write(struct file *filp, struct kobject *kobj, |
| 550 | struct bin_attribute *attr, | ||
| 551 | char *buf, loff_t off, size_t count) | 551 | char *buf, loff_t off, size_t count) |
| 552 | { | 552 | { |
| 553 | struct cmos_rtc *cmos; | 553 | struct cmos_rtc *cmos; |
| @@ -719,6 +719,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 719 | } | 719 | } |
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | cmos_rtc.dev = dev; | ||
| 723 | dev_set_drvdata(dev, &cmos_rtc); | ||
| 724 | |||
| 722 | cmos_rtc.rtc = rtc_device_register(driver_name, dev, | 725 | cmos_rtc.rtc = rtc_device_register(driver_name, dev, |
| 723 | &cmos_rtc_ops, THIS_MODULE); | 726 | &cmos_rtc_ops, THIS_MODULE); |
| 724 | if (IS_ERR(cmos_rtc.rtc)) { | 727 | if (IS_ERR(cmos_rtc.rtc)) { |
| @@ -726,8 +729,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 726 | goto cleanup0; | 729 | goto cleanup0; |
| 727 | } | 730 | } |
| 728 | 731 | ||
| 729 | cmos_rtc.dev = dev; | ||
| 730 | dev_set_drvdata(dev, &cmos_rtc); | ||
| 731 | rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); | 732 | rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); |
| 732 | 733 | ||
| 733 | spin_lock_irq(&rtc_lock); | 734 | spin_lock_irq(&rtc_lock); |
| @@ -749,12 +750,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 749 | 750 | ||
| 750 | spin_unlock_irq(&rtc_lock); | 751 | spin_unlock_irq(&rtc_lock); |
| 751 | 752 | ||
| 752 | /* FIXME teach the alarm code how to handle binary mode; | 753 | /* FIXME: |
| 753 | * <asm-generic/rtc.h> doesn't know 12-hour mode either. | 754 | * <asm-generic/rtc.h> doesn't know 12-hour mode either. |
| 754 | */ | 755 | */ |
| 755 | if (is_valid_irq(rtc_irq) && | 756 | if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) { |
| 756 | (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { | 757 | dev_warn(dev, "only 24-hr supported\n"); |
| 757 | dev_dbg(dev, "only 24-hr BCD mode supported\n"); | ||
| 758 | retval = -ENXIO; | 758 | retval = -ENXIO; |
| 759 | goto cleanup1; | 759 | goto cleanup1; |
| 760 | } | 760 | } |
