2005-04-17 02:20:36 +04:00
/*
* wakeup . c - support wakeup devices
* Copyright ( C ) 2004 Li Shaohua < shaohua . li @ intel . com >
*/
# include <linux/init.h>
# include <linux/acpi.h>
# include <acpi/acpi_drivers.h>
# include <linux/kernel.h>
# include <linux/types.h>
2009-03-13 21:08:26 +03:00
# include "internal.h"
2005-04-17 02:20:36 +04:00
# include "sleep.h"
2009-04-07 06:24:29 +04:00
/*
* We didn ' t lock acpi_device_lock in the file , because it invokes oops in
* suspend / resume and isn ' t really required as this is called in S - state . At
* that time , there is no device hotplug
* */
2005-04-17 02:20:36 +04:00
# define _COMPONENT ACPI_SYSTEM_COMPONENT
2005-08-05 08:44:28 +04:00
ACPI_MODULE_NAME ( " wakeup_devices " )
2005-04-17 02:20:36 +04:00
/**
2010-07-07 06:09:38 +04:00
* acpi_enable_wakeup_devices - Enable wake - up device GPEs .
2010-02-18 01:41:07 +03:00
* @ sleep_state : ACPI system sleep state .
*
2010-07-07 06:09:38 +04:00
* Enable wakeup device power of devices with the state . enable flag set and set
* the wakeup enable mask bits in the GPE registers that correspond to wakeup
* devices .
2005-04-17 02:20:36 +04:00
*/
2010-07-07 06:09:38 +04:00
void acpi_enable_wakeup_devices ( u8 sleep_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
struct list_head * node , * next ;
2005-04-17 02:20:36 +04:00
list_for_each_safe ( node , next , & acpi_wakeup_device_list ) {
2007-09-26 19:47:30 +04:00
struct acpi_device * dev =
container_of ( node , struct acpi_device , wakeup_list ) ;
2008-07-07 05:34:48 +04:00
2010-06-25 03:18:39 +04:00
if ( ! dev - > wakeup . flags . valid
| | ! ( dev - > wakeup . state . enabled | | dev - > wakeup . prepare_count )
2010-02-18 01:41:07 +03:00
| | sleep_state > ( u32 ) dev - > wakeup . sleep_state )
2005-04-17 02:20:36 +04:00
continue ;
2010-02-18 01:41:07 +03:00
2010-07-07 06:09:38 +04:00
if ( dev - > wakeup . state . enabled )
acpi_enable_wakeup_device_power ( dev , sleep_state ) ;
2010-02-18 01:41:07 +03:00
/* The wake-up power should have been enabled already. */
2010-06-25 03:18:39 +04:00
acpi_gpe_wakeup ( dev - > wakeup . gpe_device , dev - > wakeup . gpe_number ,
ACPI_GPE_ENABLE ) ;
2005-04-17 02:20:36 +04:00
}
}
/**
2010-07-07 06:09:38 +04:00
* acpi_disable_wakeup_devices - Disable devices ' wakeup capability .
2010-02-18 01:41:07 +03:00
* @ sleep_state : ACPI system sleep state .
2005-04-17 02:20:36 +04:00
*/
2010-07-07 06:09:38 +04:00
void acpi_disable_wakeup_devices ( u8 sleep_state )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
struct list_head * node , * next ;
2005-04-17 02:20:36 +04:00
list_for_each_safe ( node , next , & acpi_wakeup_device_list ) {
2007-09-26 19:47:30 +04:00
struct acpi_device * dev =
container_of ( node , struct acpi_device , wakeup_list ) ;
2005-04-17 02:20:36 +04:00
2010-06-25 03:18:39 +04:00
if ( ! dev - > wakeup . flags . valid
| | ! ( dev - > wakeup . state . enabled | | dev - > wakeup . prepare_count )
2010-02-18 01:41:07 +03:00
| | ( sleep_state > ( u32 ) dev - > wakeup . sleep_state ) )
2005-04-17 02:20:36 +04:00
continue ;
2010-06-25 03:18:39 +04:00
acpi_gpe_wakeup ( dev - > wakeup . gpe_device , dev - > wakeup . gpe_number ,
ACPI_GPE_DISABLE ) ;
if ( dev - > wakeup . state . enabled )
acpi_disable_wakeup_device_power ( dev ) ;
2005-04-17 02:20:36 +04:00
}
}
2009-03-25 01:50:19 +03:00
int __init acpi_wakeup_device_init ( void )
2005-04-17 02:20:36 +04:00
{
2005-08-05 08:44:28 +04:00
struct list_head * node , * next ;
2005-04-17 02:20:36 +04:00
2009-04-07 06:24:29 +04:00
mutex_lock ( & acpi_device_lock ) ;
2005-04-17 02:20:36 +04:00
list_for_each_safe ( node , next , & acpi_wakeup_device_list ) {
2005-08-05 08:44:28 +04:00
struct acpi_device * dev = container_of ( node ,
struct acpi_device ,
wakeup_list ) ;
2010-06-17 19:40:57 +04:00
if ( dev - > wakeup . flags . always_enabled )
dev - > wakeup . state . enabled = 1 ;
2005-04-17 02:20:36 +04:00
}
2009-04-07 06:24:29 +04:00
mutex_unlock ( & acpi_device_lock ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}