aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-cmos.c
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2007-10-16 04:28:21 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:13 -0400
commit05440dfcfcabde6fcf7297dfa5a29f0355b78ffb (patch)
tree31cdb76cee66c890ab4e337e0d5c9cea31b992a7 /drivers/rtc/rtc-cmos.c
parent0e36a9a4a788e4e92407774df76c545910810d35 (diff)
rtc-cmos probe() cleanup
Some cleanups for the rtc-cmos probe logic: - Claim i/o ports with request_region() not request_resource(), for better coexistence betwen platform and pnp bus glues. - Claim those ports earlier, to help work around procfs bugs (it allows duplicate names, like /proc/driver/rtc). - Fix some glitches in cleanup code, notably a cut'n'paste-o where the i/o port region might not get released during cleanup after a probe fault. And some comment clarifications, including noting that this code must work with PNPBIOS not just PNPACPI.. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
-rw-r--r--drivers/rtc/rtc-cmos.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 6d0c35397b4..e3fe83a23cf 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -433,6 +433,19 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
433 if (!ports) 433 if (!ports)
434 return -ENODEV; 434 return -ENODEV;
435 435
436 /* Claim I/O ports ASAP, minimizing conflict with legacy driver.
437 *
438 * REVISIT non-x86 systems may instead use memory space resources
439 * (needing ioremap etc), not i/o space resources like this ...
440 */
441 ports = request_region(ports->start,
442 ports->end + 1 - ports->start,
443 driver_name);
444 if (!ports) {
445 dev_dbg(dev, "i/o registers already in use\n");
446 return -EBUSY;
447 }
448
436 cmos_rtc.irq = rtc_irq; 449 cmos_rtc.irq = rtc_irq;
437 cmos_rtc.iomem = ports; 450 cmos_rtc.iomem = ports;
438 451
@@ -454,24 +467,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
454 467
455 cmos_rtc.rtc = rtc_device_register(driver_name, dev, 468 cmos_rtc.rtc = rtc_device_register(driver_name, dev,
456 &cmos_rtc_ops, THIS_MODULE); 469 &cmos_rtc_ops, THIS_MODULE);
457 if (IS_ERR(cmos_rtc.rtc)) 470 if (IS_ERR(cmos_rtc.rtc)) {
458 return PTR_ERR(cmos_rtc.rtc); 471 retval = PTR_ERR(cmos_rtc.rtc);
472 goto cleanup0;
473 }
459 474
460 cmos_rtc.dev = dev; 475 cmos_rtc.dev = dev;
461 dev_set_drvdata(dev, &cmos_rtc); 476 dev_set_drvdata(dev, &cmos_rtc);
462
463 /* platform and pnp busses handle resources incompatibly.
464 *
465 * REVISIT for non-x86 systems we may need to handle io memory
466 * resources: ioremap them, and request_mem_region().
467 */
468 if (is_pnp()) {
469 retval = request_resource(&ioport_resource, ports);
470 if (retval < 0) {
471 dev_dbg(dev, "i/o registers already in use\n");
472 goto cleanup0;
473 }
474 }
475 rename_region(ports, cmos_rtc.rtc->dev.bus_id); 477 rename_region(ports, cmos_rtc.rtc->dev.bus_id);
476 478
477 spin_lock_irq(&rtc_lock); 479 spin_lock_irq(&rtc_lock);
@@ -534,9 +536,10 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
534 return 0; 536 return 0;
535 537
536cleanup1: 538cleanup1:
537 rename_region(ports, NULL); 539 cmos_rtc.dev = NULL;
538cleanup0:
539 rtc_device_unregister(cmos_rtc.rtc); 540 rtc_device_unregister(cmos_rtc.rtc);
541cleanup0:
542 release_region(ports->start, ports->end + 1 - ports->start);
540 return retval; 543 return retval;
541} 544}
542 545
@@ -555,19 +558,21 @@ static void cmos_do_shutdown(void)
555static void __exit cmos_do_remove(struct device *dev) 558static void __exit cmos_do_remove(struct device *dev)
556{ 559{
557 struct cmos_rtc *cmos = dev_get_drvdata(dev); 560 struct cmos_rtc *cmos = dev_get_drvdata(dev);
561 struct resource *ports;
558 562
559 cmos_do_shutdown(); 563 cmos_do_shutdown();
560 564
561 if (is_pnp())
562 release_resource(cmos->iomem);
563 rename_region(cmos->iomem, NULL);
564
565 if (is_valid_irq(cmos->irq)) 565 if (is_valid_irq(cmos->irq))
566 free_irq(cmos->irq, cmos_rtc.rtc); 566 free_irq(cmos->irq, cmos->rtc);
567 567
568 rtc_device_unregister(cmos_rtc.rtc); 568 rtc_device_unregister(cmos->rtc);
569 cmos->rtc = NULL;
569 570
570 cmos_rtc.dev = NULL; 571 ports = cmos->iomem;
572 release_region(ports->start, ports->end + 1 - ports->start);
573 cmos->iomem = NULL;
574
575 cmos->dev = NULL;
571 dev_set_drvdata(dev, NULL); 576 dev_set_drvdata(dev, NULL);
572} 577}
573 578
@@ -654,7 +659,8 @@ static int cmos_resume(struct device *dev)
654/*----------------------------------------------------------------*/ 659/*----------------------------------------------------------------*/
655 660
656/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems, 661/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems,
657 * the device node will always be created as a PNPACPI device. 662 * the device node will always be created as a PNPACPI device. Plus
663 * pre-ACPI PCs probably list it in the PNPBIOS tables.
658 */ 664 */
659 665
660#ifdef CONFIG_PNP 666#ifdef CONFIG_PNP