root/drivers/acpi/wakeup.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_disable_wakeup_devices
  3. acpi_wakeup_device_init
  4. acpi_register_wakeup_handler
  5. acpi_unregister_wakeup_handler
  6. acpi_check_wakeup_handlers

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * wakeup.c - support wakeup devices
   4  * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com>
   5  */
   6 
   7 #include <linux/init.h>
   8 #include <linux/acpi.h>
   9 #include <linux/kernel.h>
  10 #include <linux/types.h>
  11 
  12 #include "internal.h"
  13 #include "sleep.h"
  14 
  15 struct acpi_wakeup_handler {
  16         struct list_head list_node;
  17         bool (*wakeup)(void *context);
  18         void *context;
  19 };
  20 
  21 static LIST_HEAD(acpi_wakeup_handler_head);
  22 static DEFINE_MUTEX(acpi_wakeup_handler_mutex);
  23 
  24 /*
  25  * We didn't lock acpi_device_lock in the file, because it invokes oops in
  26  * suspend/resume and isn't really required as this is called in S-state. At
  27  * that time, there is no device hotplug
  28  **/
  29 #define _COMPONENT              ACPI_SYSTEM_COMPONENT
  30 ACPI_MODULE_NAME("wakeup_devices")
  31 
  32 /**
  33  * acpi_enable_wakeup_devices - Enable wake-up device GPEs.
  34  * @sleep_state: ACPI system sleep state.
  35  *
  36  * Enable wakeup device power of devices with the state.enable flag set and set
  37  * the wakeup enable mask bits in the GPE registers that correspond to wakeup
  38  * devices.
  39  */
  40 void acpi_enable_wakeup_devices(u8 sleep_state)
  41 {
  42         struct list_head *node, *next;
  43 
  44         list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  45                 struct acpi_device *dev =
  46                         container_of(node, struct acpi_device, wakeup_list);
  47 
  48                 if (!dev->wakeup.flags.valid
  49                     || sleep_state > (u32) dev->wakeup.sleep_state
  50                     || !(device_may_wakeup(&dev->dev)
  51                         || dev->wakeup.prepare_count))
  52                         continue;
  53 
  54                 if (device_may_wakeup(&dev->dev))
  55                         acpi_enable_wakeup_device_power(dev, sleep_state);
  56 
  57                 /* The wake-up power should have been enabled already. */
  58                 acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
  59                                 ACPI_GPE_ENABLE);
  60         }
  61 }
  62 
  63 /**
  64  * acpi_disable_wakeup_devices - Disable devices' wakeup capability.
  65  * @sleep_state: ACPI system sleep state.
  66  */
  67 void acpi_disable_wakeup_devices(u8 sleep_state)
  68 {
  69         struct list_head *node, *next;
  70 
  71         list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  72                 struct acpi_device *dev =
  73                         container_of(node, struct acpi_device, wakeup_list);
  74 
  75                 if (!dev->wakeup.flags.valid
  76                     || sleep_state > (u32) dev->wakeup.sleep_state
  77                     || !(device_may_wakeup(&dev->dev)
  78                         || dev->wakeup.prepare_count))
  79                         continue;
  80 
  81                 acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
  82                                 ACPI_GPE_DISABLE);
  83 
  84                 if (device_may_wakeup(&dev->dev))
  85                         acpi_disable_wakeup_device_power(dev);
  86         }
  87 }
  88 
  89 int __init acpi_wakeup_device_init(void)
  90 {
  91         struct list_head *node, *next;
  92 
  93         mutex_lock(&acpi_device_lock);
  94         list_for_each_safe(node, next, &acpi_wakeup_device_list) {
  95                 struct acpi_device *dev = container_of(node,
  96                                                        struct acpi_device,
  97                                                        wakeup_list);
  98                 if (device_can_wakeup(&dev->dev)) {
  99                         /* Button GPEs are supposed to be always enabled. */
 100                         acpi_enable_gpe(dev->wakeup.gpe_device,
 101                                         dev->wakeup.gpe_number);
 102                         device_set_wakeup_enable(&dev->dev, true);
 103                 }
 104         }
 105         mutex_unlock(&acpi_device_lock);
 106         return 0;
 107 }
 108 
 109 /**
 110  * acpi_register_wakeup_handler - Register wakeup handler
 111  * @wake_irq: The IRQ through which the device may receive wakeups
 112  * @wakeup:   Wakeup-handler to call when the SCI has triggered a wakeup
 113  * @context:  Context to pass to the handler when calling it
 114  *
 115  * Drivers which may share an IRQ with the SCI can use this to register
 116  * a handler which returns true when the device they are managing wants
 117  * to trigger a wakeup.
 118  */
 119 int acpi_register_wakeup_handler(int wake_irq, bool (*wakeup)(void *context),
 120                                  void *context)
 121 {
 122         struct acpi_wakeup_handler *handler;
 123 
 124         /*
 125          * If the device is not sharing its IRQ with the SCI, there is no
 126          * need to register the handler.
 127          */
 128         if (!acpi_sci_irq_valid() || wake_irq != acpi_sci_irq)
 129                 return 0;
 130 
 131         handler = kmalloc(sizeof(*handler), GFP_KERNEL);
 132         if (!handler)
 133                 return -ENOMEM;
 134 
 135         handler->wakeup = wakeup;
 136         handler->context = context;
 137 
 138         mutex_lock(&acpi_wakeup_handler_mutex);
 139         list_add(&handler->list_node, &acpi_wakeup_handler_head);
 140         mutex_unlock(&acpi_wakeup_handler_mutex);
 141 
 142         return 0;
 143 }
 144 EXPORT_SYMBOL_GPL(acpi_register_wakeup_handler);
 145 
 146 /**
 147  * acpi_unregister_wakeup_handler - Unregister wakeup handler
 148  * @wakeup:   Wakeup-handler passed to acpi_register_wakeup_handler()
 149  * @context:  Context passed to acpi_register_wakeup_handler()
 150  */
 151 void acpi_unregister_wakeup_handler(bool (*wakeup)(void *context),
 152                                     void *context)
 153 {
 154         struct acpi_wakeup_handler *handler;
 155 
 156         mutex_lock(&acpi_wakeup_handler_mutex);
 157         list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) {
 158                 if (handler->wakeup == wakeup && handler->context == context) {
 159                         list_del(&handler->list_node);
 160                         kfree(handler);
 161                         break;
 162                 }
 163         }
 164         mutex_unlock(&acpi_wakeup_handler_mutex);
 165 }
 166 EXPORT_SYMBOL_GPL(acpi_unregister_wakeup_handler);
 167 
 168 bool acpi_check_wakeup_handlers(void)
 169 {
 170         struct acpi_wakeup_handler *handler;
 171 
 172         /* No need to lock, nothing else is running when we're called. */
 173         list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) {
 174                 if (handler->wakeup(handler->context))
 175                         return true;
 176         }
 177 
 178         return false;
 179 }

/* [<][>][^][v][top][bottom][index][help] */