(cc's added) On Thu, 18 Sep 2008 10:42:46 -0700 David Brownell <david-b@xxxxxxxxxxx> wrote: > From: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx> > > A bugzilla entry (http://bugzilla.kernel.org/show_bug.cgi?id=11580) > reports that some PNPACPI tables don't list RTC devices; they are > instead glommed into a generic "system resources" entry. > > Address that on x86 (while ignoring ia64, the other user of ACPI) by > having ACPI glue check for that case, and if necessary then setting > up a platform device and having rtc_cmos use it. > > Signed-off-by: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx> > Reported-by: Rik Theys <rik.theys@xxxxxxxxxxxxxxxx> > --- > Seems like a candidate for 2.6.27-final and for backporting. > There's a Fedora kernel report for this too. Workaround is > simple (see the bug report) but less functional. > > arch/x86/kernel/rtc.c | 13 ++++++++++++- > drivers/acpi/glue.c | 16 +++++++++++++++- > drivers/pnp/core.c | 8 ++++++++ > drivers/rtc/rtc-cmos.c | 4 ++-- > include/asm-x86/mc146818rtc.h | 5 +++++ > include/linux/pnp.h | 1 + > 6 files changed, 43 insertions(+), 4 deletions(-) > > --- a/arch/x86/kernel/rtc.c > +++ b/arch/x86/kernel/rtc.c > @@ -220,11 +220,22 @@ static struct platform_device rtc_device > .num_resources = ARRAY_SIZE(rtc_resources), > }; > > +#ifdef CONFIG_PNP > +/* PNPACPI tables sometimes omit the RTC, or are ignored */ > +struct device *__init add_nonpnp_rtc_cmos(void) > +{ > + if (!rtc_device.dev.bus) > + platform_device_register(&rtc_device); > + return &rtc_device.dev; > +} > +#endif > + > static __init int add_rtc_cmos(void) > { > #ifdef CONFIG_PNP > + /* in case of pnpacpi=off */ > if (!pnp_platform_devices) > - platform_device_register(&rtc_device); > + add_nonpnp_rtc_cmos(); > #else > platform_device_register(&rtc_device); > #endif /* CONFIG_PNP */ > --- a/drivers/acpi/glue.c > +++ b/drivers/acpi/glue.c > @@ -338,7 +338,21 @@ static int __init pnp_match(struct devic > > static struct device *__init get_rtc_dev(void) > { > - return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match); > + struct device *rtc; > + > + /* return RTC from PNPACPI tables */ > + rtc = bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match); > + > +#ifdef ARCH_PNP_RTC_WORKAROUND > + /* cope with buggy PNPACPI tables (like the HP DL3x0 servers > + * which have no RTC device listed), and with pnpacpi=off > + */ > + if (!rtc) { > + pnp_rtc_missing = true; > + rtc = add_nonpnp_rtc_cmos(); > + } > +#endif > + return rtc; > } > > static int __init acpi_rtc_init(void) > --- a/drivers/pnp/core.c > +++ b/drivers/pnp/core.c > @@ -25,10 +25,18 @@ DEFINE_SPINLOCK(pnp_lock); > * ACPI or PNPBIOS should tell us about all platform devices, so we can > * skip some blind probes. ISAPNP typically enumerates only plug-in ISA > * devices, not built-in things like COM ports. > + * > + * Sometimes ACPI tables omit devices like RTCs, which can be critical. > + * To avoid legacy poke-the-hardware-and-guess drivers (unfriendly to > + * the driver model), something else creates a (platform) device node; > + * and drivers must know to kick-in their non-PNP (non-PC) bus glue. > */ > int pnp_platform_devices; > EXPORT_SYMBOL(pnp_platform_devices); > > +bool pnp_rtc_missing; > +EXPORT_SYMBOL(pnp_rtc_missing); > + > void *pnp_alloc(long size) > { > void *result; > --- a/drivers/rtc/rtc-cmos.c > +++ b/drivers/rtc/rtc-cmos.c > @@ -1137,7 +1137,7 @@ static struct platform_driver cmos_platf > static int __init cmos_init(void) > { > #ifdef CONFIG_PNP > - if (pnp_platform_devices) > + if (pnp_platform_devices && !pnp_rtc_missing) > return pnp_register_driver(&cmos_pnp_driver); > else > return platform_driver_probe(&cmos_platform_driver, > @@ -1152,7 +1152,7 @@ module_init(cmos_init); > static void __exit cmos_exit(void) > { > #ifdef CONFIG_PNP > - if (pnp_platform_devices) > + if (pnp_platform_devices && !pnp_rtc_missing) > pnp_unregister_driver(&cmos_pnp_driver); > else > platform_driver_unregister(&cmos_platform_driver); > --- a/include/asm-x86/mc146818rtc.h > +++ b/include/asm-x86/mc146818rtc.h > @@ -101,4 +101,9 @@ extern unsigned long mach_get_cmos_time( > > #define RTC_IRQ 8 > > +#ifdef CONFIG_PNP > +#define ARCH_PNP_RTC_WORKAROUND > +extern struct device *add_nonpnp_rtc_cmos(void); > +#endif > + > #endif /* _ASM_MC146818RTC_H */ > --- a/include/linux/pnp.h > +++ b/include/linux/pnp.h > @@ -420,6 +420,7 @@ int pnp_device_attach(struct pnp_dev *pn > void pnp_device_detach(struct pnp_dev *pnp_dev); > extern struct list_head pnp_global; > extern int pnp_platform_devices; > +extern bool pnp_rtc_missing; > > /* multidevice card support */ > struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html