aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2008-10-14 15:50:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-14 19:08:21 -0400
commita474aaedac99ba86e28ef6c912a7647c482db6dd (patch)
tree0b5972b98ea601ea22845290f5351c40a0bb7771
parent8acd3a60bcca17c6d89c73cee3ad6057eb83ba1e (diff)
rtc-cmos: move wake setup from ACPI glue into RTC driver
Move rtc_wake_setup() from drivers/acpi/glue.c into the RTC driver in drivers/rtc/rtc-cmos.c. This removes the ordering constraint between the module_init(acpi_rtc_init) and the cmos_do_probe() code that depends on it. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Acked-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/acpi/glue.c112
-rw-r--r--drivers/rtc/rtc-cmos.c89
2 files changed, 89 insertions, 112 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 3c578ef78c48..24649ada08df 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -260,115 +260,3 @@ static int __init init_acpi_device_notify(void)
260} 260}
261 261
262arch_initcall(init_acpi_device_notify); 262arch_initcall(init_acpi_device_notify);
263
264
265#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
266
267#ifdef CONFIG_PM
268static u32 rtc_handler(void *context)
269{
270 acpi_clear_event(ACPI_EVENT_RTC);
271 acpi_disable_event(ACPI_EVENT_RTC, 0);
272 return ACPI_INTERRUPT_HANDLED;
273}
274
275static inline void rtc_wake_setup(void)
276{
277 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
278 /*
279 * After the RTC handler is installed, the Fixed_RTC event should
280 * be disabled. Only when the RTC alarm is set will it be enabled.
281 */
282 acpi_clear_event(ACPI_EVENT_RTC);
283 acpi_disable_event(ACPI_EVENT_RTC, 0);
284}
285
286static void rtc_wake_on(struct device *dev)
287{
288 acpi_clear_event(ACPI_EVENT_RTC);
289 acpi_enable_event(ACPI_EVENT_RTC, 0);
290}
291
292static void rtc_wake_off(struct device *dev)
293{
294 acpi_disable_event(ACPI_EVENT_RTC, 0);
295}
296#else
297#define rtc_wake_setup() do{}while(0)
298#define rtc_wake_on NULL
299#define rtc_wake_off NULL
300#endif
301
302/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
303 * its device node and pass extra config data. This helps its driver use
304 * capabilities that the now-obsolete mc146818 didn't have, and informs it
305 * that this board's RTC is wakeup-capable (per ACPI spec).
306 */
307#include <linux/mc146818rtc.h>
308
309static struct cmos_rtc_board_info rtc_info;
310
311
312/* PNP devices are registered in a subsys_initcall();
313 * ACPI specifies the PNP IDs to use.
314 */
315#include <linux/pnp.h>
316
317static int __init pnp_match(struct device *dev, void *data)
318{
319 static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", };
320 struct pnp_dev *pnp = to_pnp_dev(dev);
321 int i;
322
323 for (i = 0; i < ARRAY_SIZE(ids); i++) {
324 if (compare_pnp_id(pnp->id, ids[i]) != 0)
325 return 1;
326 }
327 return 0;
328}
329
330static struct device *__init get_rtc_dev(void)
331{
332 return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match);
333}
334
335static int __init acpi_rtc_init(void)
336{
337 struct device *dev = get_rtc_dev();
338
339 if (acpi_disabled)
340 return 0;
341
342 if (dev) {
343 rtc_wake_setup();
344 rtc_info.wake_on = rtc_wake_on;
345 rtc_info.wake_off = rtc_wake_off;
346
347 /* workaround bug in some ACPI tables */
348 if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
349 DBG("bogus FADT month_alarm\n");
350 acpi_gbl_FADT.month_alarm = 0;
351 }
352
353 rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
354 rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
355 rtc_info.rtc_century = acpi_gbl_FADT.century;
356
357 /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
358 if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
359 printk(PREFIX "RTC can wake from S4\n");
360
361
362 dev->platform_data = &rtc_info;
363
364 /* RTC always wakes from S1/S2/S3, and often S4/STD */
365 device_init_wakeup(dev, 1);
366
367 put_device(dev);
368 } else
369 DBG("RTC unavailable?\n");
370 return 0;
371}
372module_init(acpi_rtc_init);
373
374#endif
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index b23af0c2a869..6778f82bad24 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -913,6 +913,92 @@ static inline int cmos_poweroff(struct device *dev)
913 * predate even PNPBIOS should set up platform_bus devices. 913 * predate even PNPBIOS should set up platform_bus devices.
914 */ 914 */
915 915
916#ifdef CONFIG_ACPI
917
918#include <linux/acpi.h>
919
920#ifdef CONFIG_PM
921static u32 rtc_handler(void *context)
922{
923 acpi_clear_event(ACPI_EVENT_RTC);
924 acpi_disable_event(ACPI_EVENT_RTC, 0);
925 return ACPI_INTERRUPT_HANDLED;
926}
927
928static inline void rtc_wake_setup(void)
929{
930 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
931 /*
932 * After the RTC handler is installed, the Fixed_RTC event should
933 * be disabled. Only when the RTC alarm is set will it be enabled.
934 */
935 acpi_clear_event(ACPI_EVENT_RTC);
936 acpi_disable_event(ACPI_EVENT_RTC, 0);
937}
938
939static void rtc_wake_on(struct device *dev)
940{
941 acpi_clear_event(ACPI_EVENT_RTC);
942 acpi_enable_event(ACPI_EVENT_RTC, 0);
943}
944
945static void rtc_wake_off(struct device *dev)
946{
947 acpi_disable_event(ACPI_EVENT_RTC, 0);
948}
949#else
950#define rtc_wake_setup() do{}while(0)
951#define rtc_wake_on NULL
952#define rtc_wake_off NULL
953#endif
954
955/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
956 * its device node and pass extra config data. This helps its driver use
957 * capabilities that the now-obsolete mc146818 didn't have, and informs it
958 * that this board's RTC is wakeup-capable (per ACPI spec).
959 */
960static struct cmos_rtc_board_info acpi_rtc_info;
961
962static void __devinit
963cmos_wake_setup(struct device *dev)
964{
965 if (acpi_disabled)
966 return;
967
968 rtc_wake_setup();
969 acpi_rtc_info.wake_on = rtc_wake_on;
970 acpi_rtc_info.wake_off = rtc_wake_off;
971
972 /* workaround bug in some ACPI tables */
973 if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
974 dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
975 acpi_gbl_FADT.month_alarm);
976 acpi_gbl_FADT.month_alarm = 0;
977 }
978
979 acpi_rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
980 acpi_rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
981 acpi_rtc_info.rtc_century = acpi_gbl_FADT.century;
982
983 /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
984 if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
985 dev_info(dev, "RTC can wake from S4\n");
986
987 dev->platform_data = &acpi_rtc_info;
988
989 /* RTC always wakes from S1/S2/S3, and often S4/STD */
990 device_init_wakeup(dev, 1);
991}
992
993#else
994
995static void __devinit
996cmos_wake_setup(struct device *dev)
997{
998}
999
1000#endif
1001
916#ifdef CONFIG_PNP 1002#ifdef CONFIG_PNP
917 1003
918#include <linux/pnp.h> 1004#include <linux/pnp.h>
@@ -920,6 +1006,8 @@ static inline int cmos_poweroff(struct device *dev)
920static int __devinit 1006static int __devinit
921cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) 1007cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
922{ 1008{
1009 cmos_wake_setup(&pnp->dev);
1010
923 if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0)) 1011 if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
924 /* Some machines contain a PNP entry for the RTC, but 1012 /* Some machines contain a PNP entry for the RTC, but
925 * don't define the IRQ. It should always be safe to 1013 * don't define the IRQ. It should always be safe to
@@ -997,6 +1085,7 @@ static struct pnp_driver cmos_pnp_driver = {
997 1085
998static int __init cmos_platform_probe(struct platform_device *pdev) 1086static int __init cmos_platform_probe(struct platform_device *pdev)
999{ 1087{
1088 cmos_wake_setup(&pdev->dev);
1000 return cmos_do_probe(&pdev->dev, 1089 return cmos_do_probe(&pdev->dev,
1001 platform_get_resource(pdev, IORESOURCE_IO, 0), 1090 platform_get_resource(pdev, IORESOURCE_IO, 0),
1002 platform_get_irq(pdev, 0)); 1091 platform_get_irq(pdev, 0));