1 /* 2 * wakeup.c - support wakeup devices 3 * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com> 4 */ 5 6 #include <linux/init.h> 7 #include <linux/acpi.h> 8 #include <acpi/acpi_drivers.h> 9 #include <linux/kernel.h> 10 #include <linux/types.h> 11 12 #include "internal.h" 13 #include "sleep.h" 14 15 /* 16 * We didn't lock acpi_device_lock in the file, because it invokes oops in 17 * suspend/resume and isn't really required as this is called in S-state. At 18 * that time, there is no device hotplug 19 **/ 20 #define _COMPONENT ACPI_SYSTEM_COMPONENT 21 ACPI_MODULE_NAME("wakeup_devices") 22 23 /** 24 * acpi_enable_wakeup_device_prep - prepare wakeup devices 25 * @sleep_state: ACPI state 26 * Enable all wakup devices power if the devices' wakeup level 27 * is higher than requested sleep level 28 */ 29 30 void acpi_enable_wakeup_device_prep(u8 sleep_state) 31 { 32 struct list_head *node, *next; 33 34 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 35 struct acpi_device *dev = container_of(node, 36 struct acpi_device, 37 wakeup_list); 38 39 if (!dev->wakeup.flags.valid || 40 !dev->wakeup.state.enabled || 41 (sleep_state > (u32) dev->wakeup.sleep_state)) 42 continue; 43 44 acpi_enable_wakeup_device_power(dev, sleep_state); 45 } 46 } 47 48 /** 49 * acpi_enable_wakeup_device - enable wakeup devices 50 * @sleep_state: ACPI state 51 * Enable all wakup devices's GPE 52 */ 53 void acpi_enable_wakeup_device(u8 sleep_state) 54 { 55 struct list_head *node, *next; 56 57 /* 58 * Caution: this routine must be invoked when interrupt is disabled 59 * Refer ACPI2.0: P212 60 */ 61 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 62 struct acpi_device *dev = 63 container_of(node, struct acpi_device, wakeup_list); 64 65 if (!dev->wakeup.flags.valid) 66 continue; 67 68 /* If users want to disable run-wake GPE, 69 * we only disable it for wake and leave it for runtime 70 */ 71 if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) 72 || sleep_state > (u32) dev->wakeup.sleep_state) { 73 if (dev->wakeup.flags.run_wake) { 74 /* set_gpe_type will disable GPE, leave it like that */ 75 acpi_set_gpe_type(dev->wakeup.gpe_device, 76 dev->wakeup.gpe_number, 77 ACPI_GPE_TYPE_RUNTIME); 78 } 79 continue; 80 } 81 if (!dev->wakeup.flags.run_wake) 82 acpi_enable_gpe(dev->wakeup.gpe_device, 83 dev->wakeup.gpe_number); 84 } 85 } 86 87 /** 88 * acpi_disable_wakeup_device - disable devices' wakeup capability 89 * @sleep_state: ACPI state 90 * Disable all wakup devices's GPE and wakeup capability 91 */ 92 void acpi_disable_wakeup_device(u8 sleep_state) 93 { 94 struct list_head *node, *next; 95 96 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 97 struct acpi_device *dev = 98 container_of(node, struct acpi_device, wakeup_list); 99 100 if (!dev->wakeup.flags.valid) 101 continue; 102 103 if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) 104 || sleep_state > (u32) dev->wakeup.sleep_state) { 105 if (dev->wakeup.flags.run_wake) { 106 acpi_set_gpe_type(dev->wakeup.gpe_device, 107 dev->wakeup.gpe_number, 108 ACPI_GPE_TYPE_WAKE_RUN); 109 /* Re-enable it, since set_gpe_type will disable it */ 110 acpi_enable_gpe(dev->wakeup.gpe_device, 111 dev->wakeup.gpe_number); 112 } 113 continue; 114 } 115 116 acpi_disable_wakeup_device_power(dev); 117 /* Never disable run-wake GPE */ 118 if (!dev->wakeup.flags.run_wake) { 119 acpi_disable_gpe(dev->wakeup.gpe_device, 120 dev->wakeup.gpe_number); 121 acpi_clear_gpe(dev->wakeup.gpe_device, 122 dev->wakeup.gpe_number, ACPI_NOT_ISR); 123 } 124 } 125 } 126 127 int __init acpi_wakeup_device_init(void) 128 { 129 struct list_head *node, *next; 130 131 mutex_lock(&acpi_device_lock); 132 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 133 struct acpi_device *dev = container_of(node, 134 struct acpi_device, 135 wakeup_list); 136 /* In case user doesn't load button driver */ 137 if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled) 138 continue; 139 acpi_set_gpe_type(dev->wakeup.gpe_device, 140 dev->wakeup.gpe_number, 141 ACPI_GPE_TYPE_WAKE_RUN); 142 acpi_enable_gpe(dev->wakeup.gpe_device, 143 dev->wakeup.gpe_number); 144 dev->wakeup.state.enabled = 1; 145 } 146 mutex_unlock(&acpi_device_lock); 147 return 0; 148 } 149