149 lines
4.7 KiB
Diff
149 lines
4.7 KiB
Diff
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
|
|
Date: Tue, 14 Oct 2008 23:01:03 +0000 (-0600)
|
|
Subject: x86: register a platform RTC device if PNP doesn't describe it
|
|
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=758a7f7bb86b520aadc484f23da85e547b3bf3d8
|
|
|
|
x86: register a platform RTC device if PNP doesn't describe it
|
|
|
|
Most if not all x86 platforms have an RTC device, but sometimes the RTC
|
|
is not exposed as a PNP0b00/PNP0b01/PNP0b02 device in PNPBIOS or ACPI:
|
|
|
|
http://bugzilla.kernel.org/show_bug.cgi?id=11580
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=451188
|
|
|
|
It's best if we can discover the RTC via PNP because then we know
|
|
which flavor of device it is, where it lives, and which IRQ it uses.
|
|
|
|
But if we can't, we should register a platform device using the
|
|
compiled-in RTC_PORT/RTC_IRQ resource assumptions.
|
|
|
|
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
|
|
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
|
|
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
|
Reported-by: Rik Theys <rik.theys@esat.kuleuven.be>
|
|
Reported-by: shr_msn@yahoo.com.tw
|
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
---
|
|
|
|
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
|
|
index 05191bb..0a23b57 100644
|
|
--- a/arch/x86/kernel/rtc.c
|
|
+++ b/arch/x86/kernel/rtc.c
|
|
@@ -223,11 +223,25 @@ static struct platform_device rtc_device = {
|
|
static __init int add_rtc_cmos(void)
|
|
{
|
|
#ifdef CONFIG_PNP
|
|
- if (!pnp_platform_devices)
|
|
- platform_device_register(&rtc_device);
|
|
-#else
|
|
+ static const char *ids[] __initconst =
|
|
+ { "PNP0b00", "PNP0b01", "PNP0b02", };
|
|
+ struct pnp_dev *dev;
|
|
+ struct pnp_id *id;
|
|
+ int i;
|
|
+
|
|
+ pnp_for_each_dev(dev) {
|
|
+ for (id = dev->id; id; id = id->next) {
|
|
+ for (i = 0; i < ARRAY_SIZE(ids); i++) {
|
|
+ if (compare_pnp_id(id, ids[i]) != 0)
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
platform_device_register(&rtc_device);
|
|
-#endif /* CONFIG_PNP */
|
|
+ dev_info(&rtc_device.dev,
|
|
+ "registered platform RTC device (no PNP device found)\n");
|
|
return 0;
|
|
}
|
|
device_initcall(add_rtc_cmos);
|
|
|
|
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
|
|
Date: Tue, 14 Oct 2008 23:01:59 +0000 (-0600)
|
|
Subject: rtc-cmos: look for PNP RTC first, then for platform RTC
|
|
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=72f22b1eb6ca5e4676a632a04d40d46cb61d4562
|
|
|
|
rtc-cmos: look for PNP RTC first, then for platform RTC
|
|
|
|
We shouldn't rely on "pnp_platform_devices" to tell us whether there
|
|
is a PNP RTC device.
|
|
|
|
I introduced "pnp_platform_devices", but I think it was a mistake.
|
|
All it tells us is whether we found any PNPBIOS or PNPACPI devices.
|
|
Many machines have some PNP devices, but do not describe the RTC
|
|
via PNP. On those machines, we need to do the platform driver probe
|
|
to find the RTC.
|
|
|
|
We should just register the PNP driver and see whether it claims anything.
|
|
If we don't find a PNP RTC, fall back to the platform driver probe.
|
|
|
|
This (in conjunction with the arch/x86/kernel/rtc.c patch to add
|
|
a platform RTC device when PNP doesn't have one) should resolve
|
|
these issues:
|
|
|
|
http://bugzilla.kernel.org/show_bug.cgi?id=11580
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=451188
|
|
|
|
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
|
|
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
|
|
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
|
Reported-by: Rik Theys <rik.theys@esat.kuleuven.be>
|
|
Reported-by: shr_msn@yahoo.com.tw
|
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
---
|
|
|
|
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
|
|
index 6778f82..963ad0b 100644
|
|
--- a/drivers/rtc/rtc-cmos.c
|
|
+++ b/drivers/rtc/rtc-cmos.c
|
|
@@ -1120,29 +1120,32 @@ static struct platform_driver cmos_platform_driver = {
|
|
|
|
static int __init cmos_init(void)
|
|
{
|
|
+ int retval = 0;
|
|
+
|
|
#ifdef CONFIG_PNP
|
|
- if (pnp_platform_devices)
|
|
- return pnp_register_driver(&cmos_pnp_driver);
|
|
- else
|
|
- return platform_driver_probe(&cmos_platform_driver,
|
|
- cmos_platform_probe);
|
|
-#else
|
|
- return platform_driver_probe(&cmos_platform_driver,
|
|
- cmos_platform_probe);
|
|
-#endif /* CONFIG_PNP */
|
|
+ pnp_register_driver(&cmos_pnp_driver);
|
|
+#endif
|
|
+
|
|
+ if (!cmos_rtc.dev)
|
|
+ retval = platform_driver_probe(&cmos_platform_driver,
|
|
+ cmos_platform_probe);
|
|
+
|
|
+ if (retval == 0)
|
|
+ return 0;
|
|
+
|
|
+#ifdef CONFIG_PNP
|
|
+ pnp_unregister_driver(&cmos_pnp_driver);
|
|
+#endif
|
|
+ return retval;
|
|
}
|
|
module_init(cmos_init);
|
|
|
|
static void __exit cmos_exit(void)
|
|
{
|
|
#ifdef CONFIG_PNP
|
|
- if (pnp_platform_devices)
|
|
- pnp_unregister_driver(&cmos_pnp_driver);
|
|
- else
|
|
- platform_driver_unregister(&cmos_platform_driver);
|
|
-#else
|
|
+ pnp_unregister_driver(&cmos_pnp_driver);
|
|
+#endif
|
|
platform_driver_unregister(&cmos_platform_driver);
|
|
-#endif /* CONFIG_PNP */
|
|
}
|
|
module_exit(cmos_exit);
|
|
|