]> nv-tegra.nvidia Code Review - linux-3.10.git/blobdiff - drivers/char/rtc.c
rtc: fall back to requesting only the ports we actually use
[linux-3.10.git] / drivers / char / rtc.c
index a162e1b3d5d3a1dc1a327bd965b4ce9449f727b8..0c66b802736a10540bca3ed9d7ef34f5b0208b4a 100644 (file)
@@ -918,12 +918,29 @@ static const struct file_operations rtc_proc_fops = {
 };
 #endif
 
+static resource_size_t rtc_size;
+
+static struct resource * __init rtc_request_region(resource_size_t size)
+{
+       struct resource *r;
+
+       if (RTC_IOMAPPED)
+               r = request_region(RTC_PORT(0), size, "rtc");
+       else
+               r = request_mem_region(RTC_PORT(0), size, "rtc");
+
+       if (r)
+               rtc_size = size;
+
+       return r;
+}
+
 static void rtc_release_region(void)
 {
        if (RTC_IOMAPPED)
-               release_region(RTC_PORT(0), RTC_IO_EXTENT);
+               release_region(RTC_PORT(0), rtc_size);
        else
-               release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
+               release_mem_region(RTC_PORT(0), rtc_size);
 }
 
 static int __init rtc_init(void)
@@ -976,10 +993,17 @@ found:
        }
 no_irq:
 #else
-       if (RTC_IOMAPPED)
-               r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
-       else
-               r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
+       r = rtc_request_region(RTC_IO_EXTENT);
+
+       /*
+        * If we've already requested a smaller range (for example, because
+        * PNPBIOS or ACPI told us how the device is configured), the request
+        * above might fail because it's too big.
+        *
+        * If so, request just the range we actually use.
+        */
+       if (!r)
+               r = rtc_request_region(RTC_IO_EXTENT_USED);
        if (!r) {
 #ifdef RTC_IRQ
                rtc_has_irq = 0;