: ACPI: duplicate ACPI sleep "wakeup" attribute in sysfs
Subsystems (2)
PATCH 4/6 : ACPI: duplicate ACPI sleep "wakeup" attribute in sysfs
From: Zhang Rui <[email protected]>
Add "sleep_state" and "wakeup" attributes for devices that can wakeup a sleep system.
They are located under sysfs device tree, i.e. /sys/device/acpi_system/.../xxx/.
"sleep_state" indicates the lowest power system sleeping state that can be entered while still providing wake functionality. #echo 1 or 0 >/sys/devices/acpi_system/.../xxx/wakeup can be used to enable/disable the device's ability to wake a sleeping system.
--- drivers/acpi/scan.c | 12 +++++ drivers/acpi/sleep/proc.c | 90 ++++++++++++++++++++++++++++++++++++++++++-- include/acpi/acpi_drivers.h | 6 ++ 3 files changed, 105 insertions(+), 3 deletions(-)
drivers/acpi/sleep/proc.c +87 -3
@@ -296,6 +296,93 @@ static int alarm_add_sysfs(void)return sysfs_create_file (&power_subsys.kset.kobj, &alarm_attr.attr); } +/* +* "sleep_state" and "wakeup" attributes are created when device is registered +*/ +extern struct list_head acpi_wakeup_device_list; +extern spinlock_t acpi_device_lock; + +static ssize_t +acpi_sleep_state_show (struct device *dev,struct device_attribute *attr,char * buf){ +struct acpi_device *acpi_dev =to_acpi_device (dev); + +return sprintf (buf,"%2d\n" , (u32 ) acpi_dev->wakeup.sleep_state); +} +static DEVICE_ATTR(sleep_state, 0444, acpi_sleep_state_show, NULL); + +static ssize_t +acpi_wakeup_show (struct device *dev,struct device_attribute *attr,char * buf){ +struct acpi_device *acpi_dev =to_acpi_device (dev); + +return sprintf (buf,"%2d\n" , (u32 ) acpi_dev->wakeup.state.enabled); +} + +static ssize_t +acpi_wakeup_store (struct device *dev,struct device_attribute *attr,const char * buf,size_t count){ +struct acpi_device *acpi_dev =to_acpi_device (dev); +struct acpi_device *other_dev; +struct list_head *node, *next; +char *endp; +int state; + +if (!acpi_dev) +return -EINVAL ; + + state =simple_strtol (buf, &endp,0 ); +if (*endp =='\0' ) +return -EINVAL ; + +if (state !=0 && state !=1 ) +return -EINVAL ; + acpi_dev->wakeup.state.enabled = state; + +spin_lock (&acpi_device_lock); +list_for_each_safe (node, next, &acpi_wakeup_device_list) { + other_dev = container_of(node, struct acpi_device, wakeup_list); +if ((other_dev != acpi_dev) && + (other_dev->wakeup.gpe_number == acpi_dev->wakeup.gpe_number) && + (other_dev->wakeup.gpe_device == acpi_dev->wakeup.gpe_device)) { +printk (KERN_WARNING "ACPI: '%s' and '%s' have the same GPE, " +"can't disable/enable one seperately\n" , + other_dev->pnp.bus_id, acpi_dev->pnp.bus_id); + other_dev->wakeup.state.enabled = acpi_dev->wakeup.state.enabled; + } + } +spin_unlock (&acpi_device_lock); +return count; +} + +#define DEVICE_ATTR_RO (_name, _mode, _show) \ +struct device_attribute dev_attr_##_name##_ro = __ATTR(_name, _mode, _show, NULL) + +static DEVICE_ATTR(wakeup, 0644, acpi_wakeup_show, acpi_wakeup_store); +static DEVICE_ATTR_RO(wakeup, 0444, acpi_wakeup_show); + +int acpi_add_wakeup_sysfs (struct acpi_device *dev) { +int result; + + result =device_create_file (&dev->dev, &dev_attr_sleep_state); +if (result) + goto end; +if (dev->wakeup.flags.run_wake) + result =device_create_file (&dev->dev, &dev_attr_wakeup_ro); +else + result =device_create_file (&dev->dev, &dev_attr_wakeup); + end: +return result; +} +EXPORT_SYMBOL (acpi_add_wakeup_sysfs); + +void acpi_remove_wakeup_sysfs (struct acpi_device *dev) { + +if (dev->wakeup.flags.run_wake) +device_remove_file (&dev->dev, &dev_attr_wakeup_ro); +else +device_remove_file (&dev->dev, &dev_attr_wakeup); +device_remove_file (&dev->dev, &dev_attr_sleep_state); +} +EXPORT_SYMBOL (acpi_remove_wakeup_sysfs); +/* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */
@@ -598,9 +685,6 @@ acpi_system_write_alarm(struct file *filreturn_VALUE (result ? result : count); } -extern struct list_head acpi_wakeup_device_list; -extern spinlock_t acpi_device_lock; -static int acpi_system_wakeup_device_seq_show (struct seq_file *seq,void *offset) {
drivers/acpi/scan.c +12 -0
@@ -155,6 +155,15 @@ static int acpi_device_setup_files(struc goto end; } +/* +* add "wakeup" and "sleep_state" attributes for ACPI devices +*/ +if (dev->wakeup.flags.valid) { + result =acpi_add_wakeup_sysfs (dev); +if (result) + goto end; + } +/* * If device has _EJ0, 'eject' file is created that is used to trigger * hot-removal function from userland.
@@ -179,6 +188,9 @@ static void acpi_device_remove_files(strif (ACPI_SUCCESS (status))device_remove_file (&dev->dev, &dev_attr_eject); +if (dev->wakeup.flags.valid) +acpi_remove_wakeup_sysfs (dev); +if (dev->flags.hardware_id)device_remove_file (&dev->dev, &dev_attr_hid);if (dev->handle)
include/acpi/acpi_drivers.h +6 -0
@@ -45,6 +45,12 @@#define ACPI_VIDEO_HID "video"#define ACPI_BAY_HID "bay" + +/* -------------------------------------------------------------------------- +Wakeup +-------------------------------------------------------------------------- */ +int acpi_add_wakeup_sysfs (struct acpi_device *dev); +void acpi_remove_wakeup_sysfs (struct acpi_device *dev);/* -------------------------------------------------------------------------- PCI -------------------------------------------------------------------------- */
Hi!
Quoted 21 lines
From: Zhang Rui <[email protected]>
Add "
sleep_state" and "wakeup" attributes for devices that can wakeup a sleep system.
They are located under sysfs device tree, i.e./sys/device/acpi_system/.../xxx/.
"sleep_state" indicates the lowest power system sleeping state that can be entered while still providing wake functionality. #echo 1 or 0 >/sys/devices/acpi_system/.../xxx/wakeup can be used to enable/disable the device's ability to wake a sleeping system.Signed-off-by Zhang Rui <[email protected]>--- drivers/acpi/scan.c | 12 +++++ drivers/acpi/sleep/proc.c | 90 ++++++++++++++++++++++++++++++++++++++++++-- include/acpi/acpi_drivers.h | 6 ++ 3 files changed, 105 insertions(+), 3 deletions(-)Index:
linux-2.6.20-rc2-mm1/drivers/acpi/sleep/proc.c
===================================================================drivers/acpi/sleep/proc.c +0
-0@@ -296,6 +296,93 @@ static int alarm_add_sysfs(void)return sysfs_create_file (&power_subsys.kset.kobj, &alarm_attr.attr); }
drivers/acpi/sleep/proc.c static int alarm_add_sysfs(void) · line 307
Quoted 10 lines
drivers/acpi/sleep/proc.c +9
-0+/* +* "sleep_state" and "wakeup" attributes are created when device is registered +*/ +extern struct list_head acpi_wakeup_device_list; +extern spinlock_t acpi_device_lock; + +static ssize_t +acpi_sleep_state_show (struct device *dev,struct device_attribute *attr,char * buf){ +struct acpi_device *acpi_dev =to_acpi_device (dev);
CodingStyle.
drivers/acpi/sleep/proc.c static int alarm_add_sysfs(void) · line 309
Quoted 1 line
drivers/acpi/sleep/proc.c +1
-0+return sprintf (buf,"%2d\n" , (u32 ) acpi_dev->wakeup.sleep_state);
This exports ACPI Sx states as integers; but those make no sense on non-acpi systems. Exporting /sys/power/state -like things might be berrer?
Pavel
Signature · 1 line
Thanks for all the (sleeping) penguins.