diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/glue.c | 37 | ||||
-rw-r--r-- | drivers/acpi/sleep/proc.c | 19 |
2 files changed, 53 insertions, 3 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 4334c208841a..83768e9cf296 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,17 @@ 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 | |||
286 | rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; | 319 | rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; |
287 | rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; | 320 | rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; |
288 | rtc_info.rtc_century = acpi_gbl_FADT.century; | 321 | rtc_info.rtc_century = acpi_gbl_FADT.century; |
289 | 322 | ||
290 | /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */ | 323 | /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ |
324 | if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) | ||
325 | printk("ACPI: RTC can wake from S4\n"); | ||
291 | 326 | ||
292 | dev->platform_data = &rtc_info; | 327 | dev->platform_data = &rtc_info; |
293 | 328 | ||
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index dcde9ddd105a..5a76e5be61d5 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -70,6 +70,14 @@ acpi_system_write_sleep(struct file *file, | |||
70 | } | 70 | } |
71 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ | 71 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ |
72 | 72 | ||
73 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) | ||
74 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ | ||
75 | #else | ||
76 | #define HAVE_ACPI_LEGACY_ALARM | ||
77 | #endif | ||
78 | |||
79 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
80 | |||
73 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | 81 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) |
74 | { | 82 | { |
75 | u32 sec, min, hr; | 83 | u32 sec, min, hr; |
@@ -341,6 +349,8 @@ acpi_system_write_alarm(struct file *file, | |||
341 | end: | 349 | end: |
342 | return_VALUE(result ? result : count); | 350 | return_VALUE(result ? result : count); |
343 | } | 351 | } |
352 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
353 | |||
344 | 354 | ||
345 | extern struct list_head acpi_wakeup_device_list; | 355 | extern struct list_head acpi_wakeup_device_list; |
346 | extern spinlock_t acpi_device_lock; | 356 | extern spinlock_t acpi_device_lock; |
@@ -464,6 +474,7 @@ static const struct file_operations acpi_system_sleep_fops = { | |||
464 | }; | 474 | }; |
465 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ | 475 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ |
466 | 476 | ||
477 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
467 | static const struct file_operations acpi_system_alarm_fops = { | 478 | static const struct file_operations acpi_system_alarm_fops = { |
468 | .open = acpi_system_alarm_open_fs, | 479 | .open = acpi_system_alarm_open_fs, |
469 | .read = seq_read, | 480 | .read = seq_read, |
@@ -479,8 +490,9 @@ static u32 rtc_handler(void *context) | |||
479 | 490 | ||
480 | return ACPI_INTERRUPT_HANDLED; | 491 | return ACPI_INTERRUPT_HANDLED; |
481 | } | 492 | } |
493 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
482 | 494 | ||
483 | static int acpi_sleep_proc_init(void) | 495 | static int __init acpi_sleep_proc_init(void) |
484 | { | 496 | { |
485 | struct proc_dir_entry *entry = NULL; | 497 | struct proc_dir_entry *entry = NULL; |
486 | 498 | ||
@@ -496,6 +508,7 @@ static int acpi_sleep_proc_init(void) | |||
496 | entry->proc_fops = &acpi_system_sleep_fops; | 508 | entry->proc_fops = &acpi_system_sleep_fops; |
497 | #endif | 509 | #endif |
498 | 510 | ||
511 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
499 | /* 'alarm' [R/W] */ | 512 | /* 'alarm' [R/W] */ |
500 | entry = | 513 | entry = |
501 | create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR, | 514 | create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR, |
@@ -503,6 +516,9 @@ static int acpi_sleep_proc_init(void) | |||
503 | if (entry) | 516 | if (entry) |
504 | entry->proc_fops = &acpi_system_alarm_fops; | 517 | entry->proc_fops = &acpi_system_alarm_fops; |
505 | 518 | ||
519 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | ||
520 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
521 | |||
506 | /* 'wakeup device' [R/W] */ | 522 | /* 'wakeup device' [R/W] */ |
507 | entry = | 523 | entry = |
508 | create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR, | 524 | create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR, |
@@ -510,7 +526,6 @@ static int acpi_sleep_proc_init(void) | |||
510 | if (entry) | 526 | if (entry) |
511 | entry->proc_fops = &acpi_system_wakeup_device_fops; | 527 | entry->proc_fops = &acpi_system_wakeup_device_fops; |
512 | 528 | ||
513 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | ||
514 | return 0; | 529 | return 0; |
515 | } | 530 | } |
516 | 531 | ||