0001
0002
0003
0004
0005
0006
0007 #include <linux/init.h>
0008 #include <linux/acpi.h>
0009 #include <linux/kernel.h>
0010 #include <linux/types.h>
0011
0012 #include "internal.h"
0013 #include "sleep.h"
0014
0015 struct acpi_wakeup_handler {
0016 struct list_head list_node;
0017 bool (*wakeup)(void *context);
0018 void *context;
0019 };
0020
0021 static LIST_HEAD(acpi_wakeup_handler_head);
0022 static DEFINE_MUTEX(acpi_wakeup_handler_mutex);
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 void acpi_enable_wakeup_devices(u8 sleep_state)
0039 {
0040 struct acpi_device *dev, *tmp;
0041
0042 list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
0043 wakeup_list) {
0044 if (!dev->wakeup.flags.valid
0045 || sleep_state > (u32) dev->wakeup.sleep_state
0046 || !(device_may_wakeup(&dev->dev)
0047 || dev->wakeup.prepare_count))
0048 continue;
0049
0050 if (device_may_wakeup(&dev->dev))
0051 acpi_enable_wakeup_device_power(dev, sleep_state);
0052
0053
0054 acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
0055 ACPI_GPE_ENABLE);
0056 }
0057 }
0058
0059
0060
0061
0062
0063 void acpi_disable_wakeup_devices(u8 sleep_state)
0064 {
0065 struct acpi_device *dev, *tmp;
0066
0067 list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
0068 wakeup_list) {
0069 if (!dev->wakeup.flags.valid
0070 || sleep_state > (u32) dev->wakeup.sleep_state
0071 || !(device_may_wakeup(&dev->dev)
0072 || dev->wakeup.prepare_count))
0073 continue;
0074
0075 acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
0076 ACPI_GPE_DISABLE);
0077
0078 if (device_may_wakeup(&dev->dev))
0079 acpi_disable_wakeup_device_power(dev);
0080 }
0081 }
0082
0083 int __init acpi_wakeup_device_init(void)
0084 {
0085 struct acpi_device *dev, *tmp;
0086
0087 mutex_lock(&acpi_device_lock);
0088 list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
0089 wakeup_list) {
0090 if (device_can_wakeup(&dev->dev)) {
0091
0092 acpi_enable_gpe(dev->wakeup.gpe_device,
0093 dev->wakeup.gpe_number);
0094 device_set_wakeup_enable(&dev->dev, true);
0095 }
0096 }
0097 mutex_unlock(&acpi_device_lock);
0098 return 0;
0099 }
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 int acpi_register_wakeup_handler(int wake_irq, bool (*wakeup)(void *context),
0112 void *context)
0113 {
0114 struct acpi_wakeup_handler *handler;
0115
0116
0117
0118
0119
0120 if (!acpi_sci_irq_valid() || wake_irq != acpi_sci_irq)
0121 return 0;
0122
0123 handler = kmalloc(sizeof(*handler), GFP_KERNEL);
0124 if (!handler)
0125 return -ENOMEM;
0126
0127 handler->wakeup = wakeup;
0128 handler->context = context;
0129
0130 mutex_lock(&acpi_wakeup_handler_mutex);
0131 list_add(&handler->list_node, &acpi_wakeup_handler_head);
0132 mutex_unlock(&acpi_wakeup_handler_mutex);
0133
0134 return 0;
0135 }
0136 EXPORT_SYMBOL_GPL(acpi_register_wakeup_handler);
0137
0138
0139
0140
0141
0142
0143 void acpi_unregister_wakeup_handler(bool (*wakeup)(void *context),
0144 void *context)
0145 {
0146 struct acpi_wakeup_handler *handler;
0147
0148 mutex_lock(&acpi_wakeup_handler_mutex);
0149 list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) {
0150 if (handler->wakeup == wakeup && handler->context == context) {
0151 list_del(&handler->list_node);
0152 kfree(handler);
0153 break;
0154 }
0155 }
0156 mutex_unlock(&acpi_wakeup_handler_mutex);
0157 }
0158 EXPORT_SYMBOL_GPL(acpi_unregister_wakeup_handler);
0159
0160 bool acpi_check_wakeup_handlers(void)
0161 {
0162 struct acpi_wakeup_handler *handler;
0163
0164
0165 list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) {
0166 if (handler->wakeup(handler->context))
0167 return true;
0168 }
0169
0170 return false;
0171 }