// SPDX-License-Identifier: GPL-2.0
/*
 * wakeup.c - support wakeup devices
 * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com>
 */

#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/kernel.h>
#include <linux/types.h>

#include "internal.h"
#include "sleep.h"

struct acpi_wakeup_handler {
	struct list_head list_node;
	bool (*wakeup)(void *context);
	void *context;
};

static LIST_HEAD(acpi_wakeup_handler_head);
static DEFINE_MUTEX(acpi_wakeup_handler_mutex);

/*
 * 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
 **/
#define _COMPONENT		ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("wakeup_devices")

/**
 * acpi_enable_wakeup_devices - Enable wake-up device GPEs.
 * @sleep_state: ACPI system sleep state.
 *
 * 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.
 */
void acpi_enable_wakeup_devices(u8 sleep_state)
{
	struct list_head *node, *next;

	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
		struct acpi_device *dev =
			container_of(node, struct acpi_device, wakeup_list);

		if (!dev->wakeup.flags.valid
		    || sleep_state > (u32) dev->wakeup.sleep_state
		    || !(device_may_wakeup(&dev->dev)
		        || dev->wakeup.prepare_count))
			continue;

		if (device_may_wakeup(&dev->dev))
			acpi_enable_wakeup_device_power(dev, sleep_state);

		/* The wake-up power should have been enabled already. */
		acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
				ACPI_GPE_ENABLE);
	}
}

/**
 * acpi_disable_wakeup_devices - Disable devices' wakeup capability.
 * @sleep_state: ACPI system sleep state.
 */
void acpi_disable_wakeup_devices(u8 sleep_state)
{
	struct list_head *node, *next;

	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
		struct acpi_device *dev =
			container_of(node, struct acpi_device, wakeup_list);

		if (!dev->wakeup.flags.valid
		    || sleep_state > (u32) dev->wakeup.sleep_state
		    || !(device_may_wakeup(&dev->dev)
		        || dev->wakeup.prepare_count))
			continue;

		acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
				ACPI_GPE_DISABLE);

		if (device_may_wakeup(&dev->dev))
			acpi_disable_wakeup_device_power(dev);
	}
}

int __init acpi_wakeup_device_init(void)
{
	struct list_head *node, *next;

	mutex_lock(&acpi_device_lock);
	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
		struct acpi_device *dev = container_of(node,
						       struct acpi_device,
						       wakeup_list);
		if (device_can_wakeup(&dev->dev)) {
			/* Button GPEs are supposed to be always enabled. */
			acpi_enable_gpe(dev->wakeup.gpe_device,
					dev->wakeup.gpe_number);
			device_set_wakeup_enable(&dev->dev, true);
		}
	}
	mutex_unlock(&acpi_device_lock);
	return 0;
}

/**
 * acpi_register_wakeup_handler - Register wakeup handler
 * @wake_irq: The IRQ through which the device may receive wakeups
 * @wakeup:   Wakeup-handler to call when the SCI has triggered a wakeup
 * @context:  Context to pass to the handler when calling it
 *
 * Drivers which may share an IRQ with the SCI can use this to register
 * a handler which returns true when the device they are managing wants
 * to trigger a wakeup.
 */
int acpi_register_wakeup_handler(int wake_irq, bool (*wakeup)(void *context),
				 void *context)
{
	struct acpi_wakeup_handler *handler;

	/*
	 * If the device is not sharing its IRQ with the SCI, there is no
	 * need to register the handler.
	 */
	if (!acpi_sci_irq_valid() || wake_irq != acpi_sci_irq)
		return 0;

	handler = kmalloc(sizeof(*handler), GFP_KERNEL);
	if (!handler)
		return -ENOMEM;

	handler->wakeup = wakeup;
	handler->context = context;

	mutex_lock(&acpi_wakeup_handler_mutex);
	list_add(&handler->list_node, &acpi_wakeup_handler_head);
	mutex_unlock(&acpi_wakeup_handler_mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(acpi_register_wakeup_handler);

/**
 * acpi_unregister_wakeup_handler - Unregister wakeup handler
 * @wakeup:   Wakeup-handler passed to acpi_register_wakeup_handler()
 * @context:  Context passed to acpi_register_wakeup_handler()
 */
void acpi_unregister_wakeup_handler(bool (*wakeup)(void *context),
				    void *context)
{
	struct acpi_wakeup_handler *handler;

	mutex_lock(&acpi_wakeup_handler_mutex);
	list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) {
		if (handler->wakeup == wakeup && handler->context == context) {
			list_del(&handler->list_node);
			kfree(handler);
			break;
		}
	}
	mutex_unlock(&acpi_wakeup_handler_mutex);
}
EXPORT_SYMBOL_GPL(acpi_unregister_wakeup_handler);

bool acpi_check_wakeup_handlers(void)
{
	struct acpi_wakeup_handler *handler;

	/* No need to lock, nothing else is running when we're called. */
	list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) {
		if (handler->wakeup(handler->context))
			return true;
	}

	return false;
}
