aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/rtc.c36
-rw-r--r--include/linux/mc146818rtc.h3
2 files changed, 33 insertions, 6 deletions
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index a162e1b3d5d3..0c66b802736a 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -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;
diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
index 580b3f4956ee..2f4e957af656 100644
--- a/include/linux/mc146818rtc.h
+++ b/include/linux/mc146818rtc.h
@@ -109,8 +109,11 @@ struct cmos_rtc_board_info {
#ifndef ARCH_RTC_LOCATION /* Override by <asm/mc146818rtc.h>? */
#define RTC_IO_EXTENT 0x8
+#define RTC_IO_EXTENT_USED 0x2
#define RTC_IOMAPPED 1 /* Default to I/O mapping. */
+#else
+#define RTC_IO_EXTENT_USED RTC_IO_EXTENT
#endif /* ARCH_RTC_LOCATION */
#endif /* _MC146818RTC_H */