Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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