]> err.no Git - linux-2.6/blobdiff - drivers/rtc/rtc-cmos.c
[Blackfin] arch: Add proper SW System Reset delay sequence
[linux-2.6] / drivers / rtc / rtc-cmos.c
index 6d0c35397b4932fc09d6b95b951858c9e555a8e4..29cf1457ca10f507104a5a54d9fedd88f0544a95 100644 (file)
@@ -120,7 +120,8 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
        t->time.tm_hour = CMOS_READ(RTC_HOURS_ALARM);
 
        if (cmos->day_alrm) {
-               t->time.tm_mday = CMOS_READ(cmos->day_alrm);
+               /* ignore upper bits on readback per ACPI spec */
+               t->time.tm_mday = CMOS_READ(cmos->day_alrm) & 0x3f;
                if (!t->time.tm_mday)
                        t->time.tm_mday = -1;
 
@@ -433,6 +434,19 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
        if (!ports)
                return -ENODEV;
 
+       /* Claim I/O ports ASAP, minimizing conflict with legacy driver.
+        *
+        * REVISIT non-x86 systems may instead use memory space resources
+        * (needing ioremap etc), not i/o space resources like this ...
+        */
+       ports = request_region(ports->start,
+                       ports->end + 1 - ports->start,
+                       driver_name);
+       if (!ports) {
+               dev_dbg(dev, "i/o registers already in use\n");
+               return -EBUSY;
+       }
+
        cmos_rtc.irq = rtc_irq;
        cmos_rtc.iomem = ports;
 
@@ -454,24 +468,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
 
        cmos_rtc.rtc = rtc_device_register(driver_name, dev,
                                &cmos_rtc_ops, THIS_MODULE);
-       if (IS_ERR(cmos_rtc.rtc))
-               return PTR_ERR(cmos_rtc.rtc);
+       if (IS_ERR(cmos_rtc.rtc)) {
+               retval = PTR_ERR(cmos_rtc.rtc);
+               goto cleanup0;
+       }
 
        cmos_rtc.dev = dev;
        dev_set_drvdata(dev, &cmos_rtc);
-
-       /* platform and pnp busses handle resources incompatibly.
-        *
-        * REVISIT for non-x86 systems we may need to handle io memory
-        * resources: ioremap them, and request_mem_region().
-        */
-       if (is_pnp()) {
-               retval = request_resource(&ioport_resource, ports);
-               if (retval < 0) {
-                       dev_dbg(dev, "i/o registers already in use\n");
-                       goto cleanup0;
-               }
-       }
        rename_region(ports, cmos_rtc.rtc->dev.bus_id);
 
        spin_lock_irq(&rtc_lock);
@@ -534,9 +537,10 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
        return 0;
 
 cleanup1:
-       rename_region(ports, NULL);
-cleanup0:
+       cmos_rtc.dev = NULL;
        rtc_device_unregister(cmos_rtc.rtc);
+cleanup0:
+       release_region(ports->start, ports->end + 1 - ports->start);
        return retval;
 }
 
@@ -555,19 +559,21 @@ static void cmos_do_shutdown(void)
 static void __exit cmos_do_remove(struct device *dev)
 {
        struct cmos_rtc *cmos = dev_get_drvdata(dev);
+       struct resource *ports;
 
        cmos_do_shutdown();
 
-       if (is_pnp())
-               release_resource(cmos->iomem);
-       rename_region(cmos->iomem, NULL);
-
        if (is_valid_irq(cmos->irq))
-               free_irq(cmos->irq, cmos_rtc.rtc);
+               free_irq(cmos->irq, cmos->rtc);
 
-       rtc_device_unregister(cmos_rtc.rtc);
+       rtc_device_unregister(cmos->rtc);
+       cmos->rtc = NULL;
 
-       cmos_rtc.dev = NULL;
+       ports = cmos->iomem;
+       release_region(ports->start, ports->end + 1 - ports->start);
+       cmos->iomem = NULL;
+
+       cmos->dev = NULL;
        dev_set_drvdata(dev, NULL);
 }
 
@@ -654,7 +660,8 @@ static int cmos_resume(struct device *dev)
 /*----------------------------------------------------------------*/
 
 /* The "CMOS" RTC normally lives on the platform_bus.  On ACPI systems,
- * the device node will always be created as a PNPACPI device.
+ * the device node will always be created as a PNPACPI device.  Plus
+ * pre-ACPI PCs probably list it in the PNPBIOS tables.
  */
 
 #ifdef CONFIG_PNP