diff options
Diffstat (limited to 'drivers/acpi/glue.c')
-rw-r--r-- | drivers/acpi/glue.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 4334c208841a..41427a41f620 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -245,6 +245,35 @@ arch_initcall(init_acpi_device_notify); | |||
245 | 245 | ||
246 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) | 246 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) |
247 | 247 | ||
248 | #ifdef CONFIG_PM | ||
249 | static u32 rtc_handler(void *context) | ||
250 | { | ||
251 | acpi_clear_event(ACPI_EVENT_RTC); | ||
252 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
253 | return ACPI_INTERRUPT_HANDLED; | ||
254 | } | ||
255 | |||
256 | static inline void rtc_wake_setup(void) | ||
257 | { | ||
258 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | ||
259 | } | ||
260 | |||
261 | static void rtc_wake_on(struct device *dev) | ||
262 | { | ||
263 | acpi_clear_event(ACPI_EVENT_RTC); | ||
264 | acpi_enable_event(ACPI_EVENT_RTC, 0); | ||
265 | } | ||
266 | |||
267 | static void rtc_wake_off(struct device *dev) | ||
268 | { | ||
269 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
270 | } | ||
271 | #else | ||
272 | #define rtc_wake_setup() do{}while(0) | ||
273 | #define rtc_wake_on NULL | ||
274 | #define rtc_wake_off NULL | ||
275 | #endif | ||
276 | |||
248 | /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find | 277 | /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find |
249 | * its device node and pass extra config data. This helps its driver use | 278 | * its device node and pass extra config data. This helps its driver use |
250 | * capabilities that the now-obsolete mc146818 didn't have, and informs it | 279 | * capabilities that the now-obsolete mc146818 didn't have, and informs it |
@@ -283,11 +312,24 @@ static int __init acpi_rtc_init(void) | |||
283 | struct device *dev = get_rtc_dev(); | 312 | struct device *dev = get_rtc_dev(); |
284 | 313 | ||
285 | if (dev) { | 314 | if (dev) { |
315 | rtc_wake_setup(); | ||
316 | rtc_info.wake_on = rtc_wake_on; | ||
317 | rtc_info.wake_off = rtc_wake_off; | ||
318 | |||
319 | /* workaround bug in some ACPI tables */ | ||
320 | if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { | ||
321 | DBG("bogus FADT month_alarm\n"); | ||
322 | acpi_gbl_FADT.month_alarm = 0; | ||
323 | } | ||
324 | |||
286 | rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; | 325 | rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; |
287 | rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; | 326 | rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; |
288 | rtc_info.rtc_century = acpi_gbl_FADT.century; | 327 | rtc_info.rtc_century = acpi_gbl_FADT.century; |
289 | 328 | ||
290 | /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */ | 329 | /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ |
330 | if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) | ||
331 | printk(PREFIX "RTC can wake from S4\n"); | ||
332 | |||
291 | 333 | ||
292 | dev->platform_data = &rtc_info; | 334 | dev->platform_data = &rtc_info; |
293 | 335 | ||
@@ -296,7 +338,7 @@ static int __init acpi_rtc_init(void) | |||
296 | 338 | ||
297 | put_device(dev); | 339 | put_device(dev); |
298 | } else | 340 | } else |
299 | pr_debug("ACPI: RTC unavailable?\n"); | 341 | DBG("RTC unavailable?\n"); |
300 | return 0; | 342 | return 0; |
301 | } | 343 | } |
302 | /* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ | 344 | /* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ |