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.c214
1 files changed, 108 insertions, 106 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 23e10b6263d6..7e6ce626b7f1 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
@@ -420,49 +418,43 @@ static int cmos_irq_set_state(struct device *dev, int enabled)
420 return 0; 418 return 0;
421} 419}
422 420
423#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) 421static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
424
425static int
426cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
427{ 422{
428 struct cmos_rtc *cmos = dev_get_drvdata(dev); 423 struct cmos_rtc *cmos = dev_get_drvdata(dev);
429 unsigned long flags; 424 unsigned long flags;
430 425
431 switch (cmd) { 426 if (!is_valid_irq(cmos->irq))
432 case RTC_AIE_OFF: 427 return -EINVAL;
433 case RTC_AIE_ON:
434 case RTC_UIE_OFF:
435 case RTC_UIE_ON:
436 if (!is_valid_irq(cmos->irq))
437 return -EINVAL;
438 break;
439 /* PIE ON/OFF is handled by cmos_irq_set_state() */
440 default:
441 return -ENOIOCTLCMD;
442 }
443 428
444 spin_lock_irqsave(&rtc_lock, flags); 429 spin_lock_irqsave(&rtc_lock, flags);
445 switch (cmd) { 430
446 case RTC_AIE_OFF: /* alarm off */ 431 if (enabled)
447 cmos_irq_disable(cmos, RTC_AIE);
448 break;
449 case RTC_AIE_ON: /* alarm on */
450 cmos_irq_enable(cmos, RTC_AIE); 432 cmos_irq_enable(cmos, RTC_AIE);
451 break; 433 else
452 case RTC_UIE_OFF: /* update off */ 434 cmos_irq_disable(cmos, RTC_AIE);
453 cmos_irq_disable(cmos, RTC_UIE); 435
454 break;
455 case RTC_UIE_ON: /* update on */
456 cmos_irq_enable(cmos, RTC_UIE);
457 break;
458 }
459 spin_unlock_irqrestore(&rtc_lock, flags); 436 spin_unlock_irqrestore(&rtc_lock, flags);
460 return 0; 437 return 0;
461} 438}
462 439
463#else 440static int cmos_update_irq_enable(struct device *dev, unsigned int enabled)
464#define cmos_rtc_ioctl NULL 441{
465#endif 442 struct cmos_rtc *cmos = dev_get_drvdata(dev);
443 unsigned long flags;
444
445 if (!is_valid_irq(cmos->irq))
446 return -EINVAL;
447
448 spin_lock_irqsave(&rtc_lock, flags);
449
450 if (enabled)
451 cmos_irq_enable(cmos, RTC_UIE);
452 else
453 cmos_irq_disable(cmos, RTC_UIE);
454
455 spin_unlock_irqrestore(&rtc_lock, flags);
456 return 0;
457}
466 458
467#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) 459#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
468 460
@@ -484,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
484 "update_IRQ\t: %s\n" 476 "update_IRQ\t: %s\n"
485 "HPET_emulated\t: %s\n" 477 "HPET_emulated\t: %s\n"
486 // "square_wave\t: %s\n" 478 // "square_wave\t: %s\n"
487 // "BCD\t\t: %s\n" 479 "BCD\t\t: %s\n"
488 "DST_enable\t: %s\n" 480 "DST_enable\t: %s\n"
489 "periodic_freq\t: %d\n" 481 "periodic_freq\t: %d\n"
490 "batt_status\t: %s\n", 482 "batt_status\t: %s\n",
@@ -492,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
492 (rtc_control & RTC_UIE) ? "yes" : "no", 484 (rtc_control & RTC_UIE) ? "yes" : "no",
493 is_hpet_enabled() ? "yes" : "no", 485 is_hpet_enabled() ? "yes" : "no",
494 // (rtc_control & RTC_SQWE) ? "yes" : "no", 486 // (rtc_control & RTC_SQWE) ? "yes" : "no",
495 // (rtc_control & RTC_DM_BINARY) ? "no" : "yes", 487 (rtc_control & RTC_DM_BINARY) ? "no" : "yes",
496 (rtc_control & RTC_DST_EN) ? "yes" : "no", 488 (rtc_control & RTC_DST_EN) ? "yes" : "no",
497 cmos->rtc->irq_freq, 489 cmos->rtc->irq_freq,
498 (valid & RTC_VRT) ? "okay" : "dead"); 490 (valid & RTC_VRT) ? "okay" : "dead");
@@ -503,14 +495,15 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
503#endif 495#endif
504 496
505static const struct rtc_class_ops cmos_rtc_ops = { 497static const struct rtc_class_ops cmos_rtc_ops = {
506 .ioctl = cmos_rtc_ioctl, 498 .read_time = cmos_read_time,
507 .read_time = cmos_read_time, 499 .set_time = cmos_set_time,
508 .set_time = cmos_set_time, 500 .read_alarm = cmos_read_alarm,
509 .read_alarm = cmos_read_alarm, 501 .set_alarm = cmos_set_alarm,
510 .set_alarm = cmos_set_alarm, 502 .proc = cmos_procfs,
511 .proc = cmos_procfs, 503 .irq_set_freq = cmos_irq_set_freq,
512 .irq_set_freq = cmos_irq_set_freq, 504 .irq_set_state = cmos_irq_set_state,
513 .irq_set_state = cmos_irq_set_state, 505 .alarm_irq_enable = cmos_alarm_irq_enable,
506 .update_irq_enable = cmos_update_irq_enable,
514}; 507};
515 508
516/*----------------------------------------------------------------*/ 509/*----------------------------------------------------------------*/
@@ -524,7 +517,8 @@ static const struct rtc_class_ops cmos_rtc_ops = {
524#define NVRAM_OFFSET (RTC_REG_D + 1) 517#define NVRAM_OFFSET (RTC_REG_D + 1)
525 518
526static ssize_t 519static ssize_t
527cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, 520cmos_nvram_read(struct file *filp, struct kobject *kobj,
521 struct bin_attribute *attr,
528 char *buf, loff_t off, size_t count) 522 char *buf, loff_t off, size_t count)
529{ 523{
530 int retval; 524 int retval;
@@ -552,7 +546,8 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr,
552} 546}
553 547
554static ssize_t 548static ssize_t
555cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, 549cmos_nvram_write(struct file *filp, struct kobject *kobj,
550 struct bin_attribute *attr,
556 char *buf, loff_t off, size_t count) 551 char *buf, loff_t off, size_t count)
557{ 552{
558 struct cmos_rtc *cmos; 553 struct cmos_rtc *cmos;
@@ -691,7 +686,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
691 */ 686 */
692#if defined(CONFIG_ATARI) 687#if defined(CONFIG_ATARI)
693 address_space = 64; 688 address_space = 64;
694#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__sparc__) 689#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \
690 || defined(__sparc__) || defined(__mips__) \
691 || defined(__powerpc__)
695 address_space = 128; 692 address_space = 128;
696#else 693#else
697#warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. 694#warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
@@ -723,6 +720,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
723 } 720 }
724 } 721 }
725 722
723 cmos_rtc.dev = dev;
724 dev_set_drvdata(dev, &cmos_rtc);
725
726 cmos_rtc.rtc = rtc_device_register(driver_name, dev, 726 cmos_rtc.rtc = rtc_device_register(driver_name, dev,
727 &cmos_rtc_ops, THIS_MODULE); 727 &cmos_rtc_ops, THIS_MODULE);
728 if (IS_ERR(cmos_rtc.rtc)) { 728 if (IS_ERR(cmos_rtc.rtc)) {
@@ -730,8 +730,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
730 goto cleanup0; 730 goto cleanup0;
731 } 731 }
732 732
733 cmos_rtc.dev = dev;
734 dev_set_drvdata(dev, &cmos_rtc);
735 rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); 733 rename_region(ports, dev_name(&cmos_rtc.rtc->dev));
736 734
737 spin_lock_irq(&rtc_lock); 735 spin_lock_irq(&rtc_lock);
@@ -753,12 +751,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
753 751
754 spin_unlock_irq(&rtc_lock); 752 spin_unlock_irq(&rtc_lock);
755 753
756 /* FIXME teach the alarm code how to handle binary mode; 754 /* FIXME:
757 * <asm-generic/rtc.h> doesn't know 12-hour mode either. 755 * <asm-generic/rtc.h> doesn't know 12-hour mode either.
758 */ 756 */
759 if (is_valid_irq(rtc_irq) && 757 if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
760 (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { 758 dev_warn(dev, "only 24-hr supported\n");
761 dev_dbg(dev, "only 24-hr BCD mode supported\n");
762 retval = -ENXIO; 759 retval = -ENXIO;
763 goto cleanup1; 760 goto cleanup1;
764 } 761 }
@@ -871,8 +868,9 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
871 mask = RTC_IRQMASK; 868 mask = RTC_IRQMASK;
872 tmp &= ~mask; 869 tmp &= ~mask;
873 CMOS_WRITE(tmp, RTC_CONTROL); 870 CMOS_WRITE(tmp, RTC_CONTROL);
874 hpet_mask_rtc_irq_bit(mask);
875 871
872 /* shut down hpet emulation - we don't need it for alarm */
873 hpet_mask_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE);
876 cmos_checkintr(cmos, tmp); 874 cmos_checkintr(cmos, tmp);
877 } 875 }
878 spin_unlock_irq(&rtc_lock); 876 spin_unlock_irq(&rtc_lock);
@@ -973,7 +971,6 @@ static inline int cmos_poweroff(struct device *dev)
973 971
974#include <linux/acpi.h> 972#include <linux/acpi.h>
975 973
976#ifdef CONFIG_PM
977static u32 rtc_handler(void *context) 974static u32 rtc_handler(void *context)
978{ 975{
979 acpi_clear_event(ACPI_EVENT_RTC); 976 acpi_clear_event(ACPI_EVENT_RTC);
@@ -1002,11 +999,6 @@ static void rtc_wake_off(struct device *dev)
1002{ 999{
1003 acpi_disable_event(ACPI_EVENT_RTC, 0); 1000 acpi_disable_event(ACPI_EVENT_RTC, 0);
1004} 1001}
1005#else
1006#define rtc_wake_setup() do{}while(0)
1007#define rtc_wake_on NULL
1008#define rtc_wake_off NULL
1009#endif
1010 1002
1011/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find 1003/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
1012 * its device node and pass extra config data. This helps its driver use 1004 * its device node and pass extra config data. This helps its driver use
@@ -1099,9 +1091,9 @@ static int cmos_pnp_resume(struct pnp_dev *pnp)
1099#define cmos_pnp_resume NULL 1091#define cmos_pnp_resume NULL
1100#endif 1092#endif
1101 1093
1102static void cmos_pnp_shutdown(struct device *pdev) 1094static void cmos_pnp_shutdown(struct pnp_dev *pnp)
1103{ 1095{
1104 if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(pdev)) 1096 if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pnp->dev))
1105 return; 1097 return;
1106 1098
1107 cmos_do_shutdown(); 1099 cmos_do_shutdown();
@@ -1120,15 +1112,12 @@ static struct pnp_driver cmos_pnp_driver = {
1120 .id_table = rtc_ids, 1112 .id_table = rtc_ids,
1121 .probe = cmos_pnp_probe, 1113 .probe = cmos_pnp_probe,
1122 .remove = __exit_p(cmos_pnp_remove), 1114 .remove = __exit_p(cmos_pnp_remove),
1115 .shutdown = cmos_pnp_shutdown,
1123 1116
1124 /* flag ensures resume() gets called, and stops syslog spam */ 1117 /* flag ensures resume() gets called, and stops syslog spam */
1125 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, 1118 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
1126 .suspend = cmos_pnp_suspend, 1119 .suspend = cmos_pnp_suspend,
1127 .resume = cmos_pnp_resume, 1120 .resume = cmos_pnp_resume,
1128 .driver = {
1129 .name = (char *)driver_name,
1130 .shutdown = cmos_pnp_shutdown,
1131 }
1132}; 1121};
1133 1122
1134#endif /* CONFIG_PNP */ 1123#endif /* CONFIG_PNP */
@@ -1174,23 +1163,34 @@ static struct platform_driver cmos_platform_driver = {
1174 } 1163 }
1175}; 1164};
1176 1165
1166#ifdef CONFIG_PNP
1167static bool pnp_driver_registered;
1168#endif
1169static bool platform_driver_registered;
1170
1177static int __init cmos_init(void) 1171static int __init cmos_init(void)
1178{ 1172{
1179 int retval = 0; 1173 int retval = 0;
1180 1174
1181#ifdef CONFIG_PNP 1175#ifdef CONFIG_PNP
1182 pnp_register_driver(&cmos_pnp_driver); 1176 retval = pnp_register_driver(&cmos_pnp_driver);
1177 if (retval == 0)
1178 pnp_driver_registered = true;
1183#endif 1179#endif
1184 1180
1185 if (!cmos_rtc.dev) 1181 if (!cmos_rtc.dev) {
1186 retval = platform_driver_probe(&cmos_platform_driver, 1182 retval = platform_driver_probe(&cmos_platform_driver,
1187 cmos_platform_probe); 1183 cmos_platform_probe);
1184 if (retval == 0)
1185 platform_driver_registered = true;
1186 }
1188 1187
1189 if (retval == 0) 1188 if (retval == 0)
1190 return 0; 1189 return 0;
1191 1190
1192#ifdef CONFIG_PNP 1191#ifdef CONFIG_PNP
1193 pnp_unregister_driver(&cmos_pnp_driver); 1192 if (pnp_driver_registered)
1193 pnp_unregister_driver(&cmos_pnp_driver);
1194#endif 1194#endif
1195 return retval; 1195 return retval;
1196} 1196}
@@ -1199,9 +1199,11 @@ module_init(cmos_init);
1199static void __exit cmos_exit(void) 1199static void __exit cmos_exit(void)
1200{ 1200{
1201#ifdef CONFIG_PNP 1201#ifdef CONFIG_PNP
1202 pnp_unregister_driver(&cmos_pnp_driver); 1202 if (pnp_driver_registered)
1203 pnp_unregister_driver(&cmos_pnp_driver);
1203#endif 1204#endif
1204 platform_driver_unregister(&cmos_platform_driver); 1205 if (platform_driver_registered)
1206 platform_driver_unregister(&cmos_platform_driver);
1205} 1207}
1206module_exit(cmos_exit); 1208module_exit(cmos_exit);
1207 1209