From 0b1b4d8571e26046bef016c1cf31720c3b7fa8c0 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 14 Nov 2007 16:59:57 -0800 Subject: [PATCH] --- yaml --- r: 73711 b: refs/heads/master c: 9626f1f117be21b6e4b7a1cb49814fc065dd3d2d h: refs/heads/master i: 73709: 69336228e526a849b8ee479e337630ba56b7fb5c 73707: 7c419e92d1fe4c920f991883581ea6b70e505d20 73703: 52775f32ec5cdf2db6ad38160f8a091d41ad4702 73695: 816f3dfaf83b2e42c1878c001cbb2e13071f2419 v: v3 --- [refs] | 2 +- trunk/drivers/char/rtc.c | 36 +++++++++++++++++++++++++------ trunk/include/linux/mc146818rtc.h | 3 +++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 5fb988e97d93..a54bd14abefb 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4c06be10c790008aa2b2d19df2872ff39990b7bd +refs/heads/master: 9626f1f117be21b6e4b7a1cb49814fc065dd3d2d diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index a162e1b3d5d3..0c66b802736a 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/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 @@ static int __init rtc_init(void) } 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/trunk/include/linux/mc146818rtc.h b/trunk/include/linux/mc146818rtc.h index 580b3f4956ee..2f4e957af656 100644 --- a/trunk/include/linux/mc146818rtc.h +++ b/trunk/include/linux/mc146818rtc.h @@ -109,8 +109,11 @@ struct cmos_rtc_board_info { #ifndef ARCH_RTC_LOCATION /* Override by ? */ #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 */