ACPI wakeup hooks for rtc-cmos
authorDavid Brownell <david-b@pacbell.net>
Tue, 8 May 2007 07:34:02 +0000 (00:34 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 8 May 2007 18:15:18 +0000 (11:15 -0700)
Remove /proc/acpi/alarm file when the rtc-cmos "wakealarm" file is available.
Instead, provide hooks that rtc-cmos will use.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/acpi/glue.c
drivers/acpi/sleep/proc.c

index 4334c208841a3f06586ba3693b10d8437fff5b12..83768e9cf29651f6fb41beeb514706af76623fa2 100644 (file)
@@ -245,6 +245,35 @@ arch_initcall(init_acpi_device_notify);
 
 #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
 
+#ifdef CONFIG_PM
+static u32 rtc_handler(void *context)
+{
+       acpi_clear_event(ACPI_EVENT_RTC);
+       acpi_disable_event(ACPI_EVENT_RTC, 0);
+       return ACPI_INTERRUPT_HANDLED;
+}
+
+static inline void rtc_wake_setup(void)
+{
+       acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
+}
+
+static void rtc_wake_on(struct device *dev)
+{
+       acpi_clear_event(ACPI_EVENT_RTC);
+       acpi_enable_event(ACPI_EVENT_RTC, 0);
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+       acpi_disable_event(ACPI_EVENT_RTC, 0);
+}
+#else
+#define rtc_wake_setup()       do{}while(0)
+#define rtc_wake_on            NULL
+#define rtc_wake_off           NULL
+#endif
+
 /* Every ACPI platform has a mc146818 compatible "cmos rtc".  Here we find
  * its device node and pass extra config data.  This helps its driver use
  * capabilities that the now-obsolete mc146818 didn't have, and informs it
@@ -283,11 +312,17 @@ static int __init acpi_rtc_init(void)
        struct device *dev = get_rtc_dev();
 
        if (dev) {
+               rtc_wake_setup();
+               rtc_info.wake_on = rtc_wake_on;
+               rtc_info.wake_off = rtc_wake_off;
+
                rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
                rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
                rtc_info.rtc_century = acpi_gbl_FADT.century;
 
-               /* NOTE:  acpi_gbl_FADT->rtcs4 is NOT currently useful */
+               /* NOTE:  S4_RTC_WAKE is NOT currently useful to Linux */
+               if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
+                       printk("ACPI: RTC can wake from S4\n");
 
                dev->platform_data = &rtc_info;
 
index dcde9ddd105ae358a35c041e839cdace01a12baa..5a76e5be61d5da1a1445feececba0f0a09f51bde 100644 (file)
@@ -70,6 +70,14 @@ acpi_system_write_sleep(struct file *file,
 }
 #endif                         /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
 
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
+#else
+#define        HAVE_ACPI_LEGACY_ALARM
+#endif
+
+#ifdef HAVE_ACPI_LEGACY_ALARM
+
 static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 {
        u32 sec, min, hr;
@@ -341,6 +349,8 @@ acpi_system_write_alarm(struct file *file,
       end:
        return_VALUE(result ? result : count);
 }
+#endif /* HAVE_ACPI_LEGACY_ALARM */
+
 
 extern struct list_head acpi_wakeup_device_list;
 extern spinlock_t acpi_device_lock;
@@ -464,6 +474,7 @@ static const struct file_operations acpi_system_sleep_fops = {
 };
 #endif                         /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
 
+#ifdef HAVE_ACPI_LEGACY_ALARM
 static const struct file_operations acpi_system_alarm_fops = {
        .open = acpi_system_alarm_open_fs,
        .read = seq_read,
@@ -479,8 +490,9 @@ static u32 rtc_handler(void *context)
 
        return ACPI_INTERRUPT_HANDLED;
 }
+#endif /* HAVE_ACPI_LEGACY_ALARM */
 
-static int acpi_sleep_proc_init(void)
+static int __init acpi_sleep_proc_init(void)
 {
        struct proc_dir_entry *entry = NULL;
 
@@ -496,6 +508,7 @@ static int acpi_sleep_proc_init(void)
                entry->proc_fops = &acpi_system_sleep_fops;
 #endif
 
+#ifdef HAVE_ACPI_LEGACY_ALARM
        /* 'alarm' [R/W] */
        entry =
            create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR,
@@ -503,6 +516,9 @@ static int acpi_sleep_proc_init(void)
        if (entry)
                entry->proc_fops = &acpi_system_alarm_fops;
 
+       acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
+#endif /* HAVE_ACPI_LEGACY_ALARM */
+
        /* 'wakeup device' [R/W] */
        entry =
            create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
@@ -510,7 +526,6 @@ static int acpi_sleep_proc_init(void)
        if (entry)
                entry->proc_fops = &acpi_system_wakeup_device_fops;
 
-       acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
        return 0;
 }