diff options
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 214 |
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) | |||
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 | ||
@@ -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) | 421 | static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) |
424 | |||
425 | static int | ||
426 | cmos_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 | 440 | static 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 | ||
505 | static const struct rtc_class_ops cmos_rtc_ops = { | 497 | static 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 | ||
526 | static ssize_t | 519 | static ssize_t |
527 | 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, | ||
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 | ||
554 | static ssize_t | 548 | static ssize_t |
555 | 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, | ||
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 | ||
977 | static u32 rtc_handler(void *context) | 974 | static 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 | ||
1102 | static void cmos_pnp_shutdown(struct device *pdev) | 1094 | static 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 | ||
1167 | static bool pnp_driver_registered; | ||
1168 | #endif | ||
1169 | static bool platform_driver_registered; | ||
1170 | |||
1177 | static int __init cmos_init(void) | 1171 | static 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); | |||
1199 | static void __exit cmos_exit(void) | 1199 | static 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 | } |
1206 | module_exit(cmos_exit); | 1208 | module_exit(cmos_exit); |
1207 | 1209 | ||