aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/rtc.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2007-11-14 19:59:57 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-14 21:45:41 -0500
commit9626f1f117be21b6e4b7a1cb49814fc065dd3d2d (patch)
tree259ba0c9362924d1a7e21a6befcc43e23f9fa9d5 /drivers/char/rtc.c
parent4c06be10c790008aa2b2d19df2872ff39990b7bd (diff)
rtc: fall back to requesting only the ports we actually use
Firmware like PNPBIOS or ACPI can report the address space consumed by the RTC. The actual space consumed may be less than the size (RTC_IO_EXTENT) assumed by the RTC driver. The PNP core doesn't request resources yet, but I'd like to make it do so. If/when it does, the RTC_IO_EXTENT request may fail, which prevents the RTC driver from loading. Since we only use the RTC index and data registers at RTC_PORT(0) and RTC_PORT(1), we can fall back to requesting just enough space for those. If the PNP core requests resources, this results in typical I/O port usage like this: 0070-0073 : 00:06 <-- PNP device 00:06 responds to 70-73 0070-0071 : rtc <-- RTC driver uses only 70-71 instead of the current: 0070-0077 : rtc <-- RTC_IO_EXTENT == 8 Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: David Brownell <david-b@pacbell.net> Cc: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/rtc.c')
-rw-r--r--drivers/char/rtc.c36
1 files changed, 30 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 = {
918}; 918};
919#endif 919#endif
920 920
921static resource_size_t rtc_size;
922
923static struct resource * __init rtc_request_region(resource_size_t size)
924{
925 struct resource *r;
926
927 if (RTC_IOMAPPED)
928 r = request_region(RTC_PORT(0), size, "rtc");
929 else
930 r = request_mem_region(RTC_PORT(0), size, "rtc");
931
932 if (r)
933 rtc_size = size;
934
935 return r;
936}
937
921static void rtc_release_region(void) 938static void rtc_release_region(void)
922{ 939{
923 if (RTC_IOMAPPED) 940 if (RTC_IOMAPPED)
924 release_region(RTC_PORT(0), RTC_IO_EXTENT); 941 release_region(RTC_PORT(0), rtc_size);
925 else 942 else
926 release_mem_region(RTC_PORT(0), RTC_IO_EXTENT); 943 release_mem_region(RTC_PORT(0), rtc_size);
927} 944}
928 945
929static int __init rtc_init(void) 946static int __init rtc_init(void)
@@ -976,10 +993,17 @@ found:
976 } 993 }
977no_irq: 994no_irq:
978#else 995#else
979 if (RTC_IOMAPPED) 996 r = rtc_request_region(RTC_IO_EXTENT);
980 r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); 997
981 else 998 /*
982 r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); 999 * If we've already requested a smaller range (for example, because
1000 * PNPBIOS or ACPI told us how the device is configured), the request
1001 * above might fail because it's too big.
1002 *
1003 * If so, request just the range we actually use.
1004 */
1005 if (!r)
1006 r = rtc_request_region(RTC_IO_EXTENT_USED);
983 if (!r) { 1007 if (!r) {
984#ifdef RTC_IRQ 1008#ifdef RTC_IRQ
985 rtc_has_irq = 0; 1009 rtc_has_irq = 0;