// SPDX-License-Identifier: GPL-2.0
/*
 * Architecture-specific ACPI-based support for suspend-to-idle.
 *
 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
 * Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
 * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
 *
 * On platforms supporting the Low Power S0 Idle interface there is an ACPI
 * device object with the PNP0D80 compatible device ID (System Power Management
 * Controller) and a specific _DSM method under it.  That method, if present,
 * can be used to indicate to the platform that the OS is transitioning into a
 * low-power state in which certain types of activity are not desirable or that
 * it is leaving such a state, which allows the platform to adjust its operation
 * mode accordingly.
 */

#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/suspend.h>

#include "../sleep.h"

#ifdef CONFIG_SUSPEND

static bool sleep_no_lps0 __read_mostly;
module_param(sleep_no_lps0, bool, 0644);
MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface");

static const struct acpi_device_id lps0_device_ids[] = {
	{"PNP0D80", },
	{"", },
};

/* Microsoft platform agnostic UUID */
#define ACPI_LPS0_DSM_UUID_MICROSOFT      "11e00d56-ce64-47ce-837b-1f898f9aa461"

#define ACPI_LPS0_DSM_UUID	"c4eb40a0-6cd2-11e2-bcfd-0800200c9a66"

#define ACPI_LPS0_GET_DEVICE_CONSTRAINTS	1
#define ACPI_LPS0_SCREEN_OFF	3
#define ACPI_LPS0_SCREEN_ON	4
#define ACPI_LPS0_ENTRY		5
#define ACPI_LPS0_EXIT		6
#define ACPI_LPS0_MS_ENTRY      7
#define ACPI_LPS0_MS_EXIT       8

/* AMD */
#define ACPI_LPS0_DSM_UUID_AMD      "e3f32452-febc-43ce-9039-932122d37721"
#define ACPI_LPS0_ENTRY_AMD         2
#define ACPI_LPS0_EXIT_AMD          3
#define ACPI_LPS0_SCREEN_OFF_AMD    4
#define ACPI_LPS0_SCREEN_ON_AMD     5

static acpi_handle lps0_device_handle;
static guid_t lps0_dsm_guid;
static int lps0_dsm_func_mask;

static guid_t lps0_dsm_guid_microsoft;
static int lps0_dsm_func_mask_microsoft;
static int lps0_dsm_state;

/* Device constraint entry structure */
struct lpi_device_info {
	char *name;
	int enabled;
	union acpi_object *package;
};

/* Constraint package structure */
struct lpi_device_constraint {
	int uid;
	int min_dstate;
	int function_states;
};

struct lpi_constraints {
	acpi_handle handle;
	int min_dstate;
};

/* AMD Constraint package structure */
struct lpi_device_constraint_amd {
	char *name;
	int enabled;
	int function_states;
	int min_dstate;
};

static LIST_HEAD(lps0_s2idle_devops_head);

static struct lpi_constraints *lpi_constraints_table;
static int lpi_constraints_table_size;
static int rev_id;

#define for_each_lpi_constraint(entry)						\
	for (int i = 0;								\
	     entry = &lpi_constraints_table[i], i < lpi_constraints_table_size;	\
	     i++)

static void lpi_device_get_constraints_amd(void)
{
	union acpi_object *out_obj;
	int i, j, k;

	out_obj = acpi_evaluate_dsm_typed(lps0_device_handle, &lps0_dsm_guid,
					  rev_id, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
					  NULL, ACPI_TYPE_PACKAGE);

	acpi_handle_debug(lps0_device_handle, "_DSM function 1 eval %s\n",
			  out_obj ? "successful" : "failed");

	if (!out_obj)
		return;

	for (i = 0; i < out_obj->package.count; i++) {
		union acpi_object *package = &out_obj->package.elements[i];

		if (package->type == ACPI_TYPE_PACKAGE) {
			if (lpi_constraints_table) {
				acpi_handle_err(lps0_device_handle,
						"Duplicate constraints list\n");
				goto free_acpi_buffer;
			}

			lpi_constraints_table = kcalloc(package->package.count,
							sizeof(*lpi_constraints_table),
							GFP_KERNEL);

			if (!lpi_constraints_table)
				goto free_acpi_buffer;

			acpi_handle_debug(lps0_device_handle,
					  "LPI: constraints list begin:\n");

			for (j = 0; j < package->package.count; j++) {
				union acpi_object *info_obj = &package->package.elements[j];
				struct lpi_device_constraint_amd dev_info = {};
				struct lpi_constraints *list;
				acpi_status status;

				list = &lpi_constraints_table[lpi_constraints_table_size];

				for (k = 0; k < info_obj->package.count; k++) {
					union acpi_object *obj = &info_obj->package.elements[k];

					switch (k) {
					case 0:
						dev_info.enabled = obj->integer.value;
						break;
					case 1:
						dev_info.name = obj->string.pointer;
						break;
					case 2:
						dev_info.function_states = obj->integer.value;
						break;
					case 3:
						dev_info.min_dstate = obj->integer.value;
						break;
					}
				}

				acpi_handle_debug(lps0_device_handle,
						  "Name:%s, Enabled: %d, States: %d, MinDstate: %d\n",
						  dev_info.name,
						  dev_info.enabled,
						  dev_info.function_states,
						  dev_info.min_dstate);

				if (!dev_info.enabled || !dev_info.name ||
				    !dev_info.min_dstate)
					continue;

				status = acpi_get_handle(NULL, dev_info.name, &list->handle);
				if (ACPI_FAILURE(status))
					continue;

				list->min_dstate = dev_info.min_dstate;

				lpi_constraints_table_size++;
			}
		}
	}

	acpi_handle_debug(lps0_device_handle, "LPI: constraints list end\n");

free_acpi_buffer:
	ACPI_FREE(out_obj);
}

static void lpi_device_get_constraints(void)
{
	union acpi_object *out_obj;
	int i;

	out_obj = acpi_evaluate_dsm_typed(lps0_device_handle, &lps0_dsm_guid,
					  1, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
					  NULL, ACPI_TYPE_PACKAGE);

	acpi_handle_debug(lps0_device_handle, "_DSM function 1 eval %s\n",
			  out_obj ? "successful" : "failed");

	if (!out_obj)
		return;

	lpi_constraints_table = kcalloc(out_obj->package.count,
					sizeof(*lpi_constraints_table),
					GFP_KERNEL);
	if (!lpi_constraints_table)
		goto free_acpi_buffer;

	acpi_handle_debug(lps0_device_handle, "LPI: constraints list begin:\n");

	for (i = 0; i < out_obj->package.count; i++) {
		struct lpi_constraints *constraint;
		acpi_status status;
		union acpi_object *package = &out_obj->package.elements[i];
		struct lpi_device_info info = { };
		int package_count = 0, j;

		if (!package)
			continue;

		for (j = 0; j < package->package.count; j++) {
			union acpi_object *element =
					&(package->package.elements[j]);

			switch (element->type) {
			case ACPI_TYPE_INTEGER:
				info.enabled = element->integer.value;
				break;
			case ACPI_TYPE_STRING:
				info.name = element->string.pointer;
				break;
			case ACPI_TYPE_PACKAGE:
				package_count = element->package.count;
				info.package = element->package.elements;
				break;
			}
		}

		if (!info.enabled || !info.package || !info.name)
			continue;

		constraint = &lpi_constraints_table[lpi_constraints_table_size];

		status = acpi_get_handle(NULL, info.name, &constraint->handle);
		if (ACPI_FAILURE(status))
			continue;

		acpi_handle_debug(lps0_device_handle,
				  "index:%d Name:%s\n", i, info.name);

		constraint->min_dstate = -1;

		for (j = 0; j < package_count; j++) {
			union acpi_object *info_obj = &info.package[j];
			union acpi_object *cnstr_pkg;
			union acpi_object *obj;
			struct lpi_device_constraint dev_info;

			switch (info_obj->type) {
			case ACPI_TYPE_INTEGER:
				/* version */
				break;
			case ACPI_TYPE_PACKAGE:
				if (info_obj->package.count < 2)
					break;

				cnstr_pkg = info_obj->package.elements;
				obj = &cnstr_pkg[0];
				dev_info.uid = obj->integer.value;
				obj = &cnstr_pkg[1];
				dev_info.min_dstate = obj->integer.value;

				acpi_handle_debug(lps0_device_handle,
					"uid:%d min_dstate:%s\n",
					dev_info.uid,
					acpi_power_state_string(dev_info.min_dstate));

				constraint->min_dstate = dev_info.min_dstate;
				break;
			}
		}

		if (constraint->min_dstate < 0) {
			acpi_handle_debug(lps0_device_handle,
					  "Incomplete constraint defined\n");
			continue;
		}

		lpi_constraints_table_size++;
	}

	acpi_handle_debug(lps0_device_handle, "LPI: constraints list end\n");

free_acpi_buffer:
	ACPI_FREE(out_obj);
}

/**
 * acpi_get_lps0_constraint - Get the LPS0 constraint for a device.
 * @adev: Device to get the constraint for.
 *
 * The LPS0 constraint is the shallowest (minimum) power state in which the
 * device can be so as to allow the platform as a whole to achieve additional
 * energy conservation by utilizing a system-wide low-power state.
 *
 * Returns:
 *  - ACPI power state value of the constraint for @adev on success.
 *  - Otherwise, ACPI_STATE_UNKNOWN.
 */
int acpi_get_lps0_constraint(struct acpi_device *adev)
{
	struct lpi_constraints *entry;

	for_each_lpi_constraint(entry) {
		if (adev->handle == entry->handle)
			return entry->min_dstate;
	}

	return ACPI_STATE_UNKNOWN;
}

static void lpi_check_constraints(void)
{
	struct lpi_constraints *entry;

	for_each_lpi_constraint(entry) {
		struct acpi_device *adev = acpi_fetch_acpi_dev(entry->handle);

		if (!adev)
			continue;

		acpi_handle_debug(entry->handle,
			"LPI: required min power state:%s current power state:%s\n",
			acpi_power_state_string(entry->min_dstate),
			acpi_power_state_string(adev->power.state));

		if (!adev->flags.power_manageable) {
			acpi_handle_info(entry->handle, "LPI: Device not power manageable\n");
			entry->handle = NULL;
			continue;
		}

		if (adev->power.state < entry->min_dstate)
			acpi_handle_info(entry->handle,
				"LPI: Constraint not met; min power state:%s current power state:%s\n",
				acpi_power_state_string(entry->min_dstate),
				acpi_power_state_string(adev->power.state));
	}
}

static bool acpi_s2idle_vendor_amd(void)
{
	return boot_cpu_data.x86_vendor == X86_VENDOR_AMD;
}

static const char *acpi_sleep_dsm_state_to_str(unsigned int state)
{
	if (lps0_dsm_func_mask_microsoft || !acpi_s2idle_vendor_amd()) {
		switch (state) {
		case ACPI_LPS0_SCREEN_OFF:
			return "screen off";
		case ACPI_LPS0_SCREEN_ON:
			return "screen on";
		case ACPI_LPS0_ENTRY:
			return "lps0 entry";
		case ACPI_LPS0_EXIT:
			return "lps0 exit";
		case ACPI_LPS0_MS_ENTRY:
			return "lps0 ms entry";
		case ACPI_LPS0_MS_EXIT:
			return "lps0 ms exit";
		}
	} else {
		switch (state) {
		case ACPI_LPS0_SCREEN_ON_AMD:
			return "screen on";
		case ACPI_LPS0_SCREEN_OFF_AMD:
			return "screen off";
		case ACPI_LPS0_ENTRY_AMD:
			return "lps0 entry";
		case ACPI_LPS0_EXIT_AMD:
			return "lps0 exit";
		}
	}

	return "unknown";
}

static void acpi_sleep_run_lps0_dsm(unsigned int func, unsigned int func_mask, guid_t dsm_guid)
{
	union acpi_object *out_obj;

	if (!(func_mask & (1 << func)))
		return;

	out_obj = acpi_evaluate_dsm(lps0_device_handle, &dsm_guid,
					rev_id, func, NULL);
	ACPI_FREE(out_obj);

	lps0_dsm_state = func;
	if (pm_debug_messages_on) {
		acpi_handle_info(lps0_device_handle,
				"%s transitioned to state %s\n",
				 out_obj ? "Successfully" : "Failed to",
				 acpi_sleep_dsm_state_to_str(lps0_dsm_state));
	}
}


static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *dsm_guid)
{
	union acpi_object *obj;
	int ret = -EINVAL;

	guid_parse(uuid, dsm_guid);

	/* Check if the _DSM is present and as expected. */
	obj = acpi_evaluate_dsm_typed(handle, dsm_guid, rev, 0, NULL, ACPI_TYPE_BUFFER);
	if (!obj || obj->buffer.length == 0 || obj->buffer.length > sizeof(u32)) {
		acpi_handle_debug(handle,
				"_DSM UUID %s rev %d function 0 evaluation failed\n", uuid, rev);
		goto out;
	}

	ret = *(int *)obj->buffer.pointer;
	acpi_handle_debug(handle, "_DSM UUID %s rev %d function mask: 0x%x\n", uuid, rev, ret);

out:
	ACPI_FREE(obj);
	return ret;
}

struct amd_lps0_hid_device_data {
	const bool check_off_by_one;
};

static const struct amd_lps0_hid_device_data amd_picasso = {
	.check_off_by_one = true,
};

static const struct amd_lps0_hid_device_data amd_cezanne = {
	.check_off_by_one = false,
};

static const struct acpi_device_id amd_hid_ids[] = {
	{"AMD0004",	(kernel_ulong_t)&amd_picasso,	},
	{"AMD0005",	(kernel_ulong_t)&amd_picasso,	},
	{"AMDI0005",	(kernel_ulong_t)&amd_picasso,	},
	{"AMDI0006",	(kernel_ulong_t)&amd_cezanne,	},
	{}
};

static int lps0_device_attach(struct acpi_device *adev,
			      const struct acpi_device_id *not_used)
{
	if (lps0_device_handle)
		return 0;

	lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle,
						    ACPI_LPS0_DSM_UUID_MICROSOFT, 0,
						    &lps0_dsm_guid_microsoft);
	if (acpi_s2idle_vendor_amd()) {
		static const struct acpi_device_id *dev_id;
		const struct amd_lps0_hid_device_data *data;

		for (dev_id = &amd_hid_ids[0]; dev_id->id[0]; dev_id++)
			if (acpi_dev_hid_uid_match(adev, dev_id->id, NULL))
				break;
		if (dev_id->id[0])
			data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data;
		else
			data = &amd_cezanne;
		lps0_dsm_func_mask = validate_dsm(adev->handle,
					ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid);
		if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) {
			lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1;
			acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n",
					  ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask);
		} else if (lps0_dsm_func_mask_microsoft > 0 && rev_id) {
			lps0_dsm_func_mask_microsoft = -EINVAL;
			acpi_handle_debug(adev->handle, "_DSM Using AMD method\n");
		}
	} else {
		rev_id = 1;
		lps0_dsm_func_mask = validate_dsm(adev->handle,
					ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid);
		lps0_dsm_func_mask_microsoft = -EINVAL;
	}

	if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0)
		return 0; //function evaluation failed

	lps0_device_handle = adev->handle;

	if (acpi_s2idle_vendor_amd())
		lpi_device_get_constraints_amd();
	else
		lpi_device_get_constraints();

	/*
	 * Use suspend-to-idle by default if ACPI_FADT_LOW_POWER_S0 is set in
	 * the FADT and the default suspend mode was not set from the command
	 * line.
	 */
	if ((acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) &&
	    mem_sleep_default > PM_SUSPEND_MEM && !acpi_sleep_default_s3) {
		mem_sleep_current = PM_SUSPEND_TO_IDLE;
		pr_info("Low-power S0 idle used by default for system suspend\n");
	}

	/*
	 * Some LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U, require the
	 * EC GPE to be enabled while suspended for certain wakeup devices to
	 * work, so mark it as wakeup-capable.
	 */
	acpi_ec_mark_gpe_for_wake();

	return 0;
}

static struct acpi_scan_handler lps0_handler = {
	.ids = lps0_device_ids,
	.attach = lps0_device_attach,
};

int acpi_s2idle_prepare_late(void)
{
	struct acpi_s2idle_dev_ops *handler;

	if (!lps0_device_handle || sleep_no_lps0)
		return 0;

	if (pm_debug_messages_on)
		lpi_check_constraints();

	/* Screen off */
	if (lps0_dsm_func_mask > 0)
		acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
					ACPI_LPS0_SCREEN_OFF_AMD :
					ACPI_LPS0_SCREEN_OFF,
					lps0_dsm_func_mask, lps0_dsm_guid);

	if (lps0_dsm_func_mask_microsoft > 0)
		acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);

	/* LPS0 entry */
	if (lps0_dsm_func_mask > 0)
		acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
					ACPI_LPS0_ENTRY_AMD :
					ACPI_LPS0_ENTRY,
					lps0_dsm_func_mask, lps0_dsm_guid);
	if (lps0_dsm_func_mask_microsoft > 0) {
		/* modern standby entry */
		acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY,
				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
		acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
	}

	list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) {
		if (handler->prepare)
			handler->prepare();
	}

	return 0;
}

void acpi_s2idle_check(void)
{
	struct acpi_s2idle_dev_ops *handler;

	if (!lps0_device_handle || sleep_no_lps0)
		return;

	list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) {
		if (handler->check)
			handler->check();
	}
}

void acpi_s2idle_restore_early(void)
{
	struct acpi_s2idle_dev_ops *handler;

	if (!lps0_device_handle || sleep_no_lps0)
		return;

	list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node)
		if (handler->restore)
			handler->restore();

	/* LPS0 exit */
	if (lps0_dsm_func_mask > 0)
		acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
					ACPI_LPS0_EXIT_AMD :
					ACPI_LPS0_EXIT,
					lps0_dsm_func_mask, lps0_dsm_guid);
	if (lps0_dsm_func_mask_microsoft > 0)
		acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);

	/* Modern standby exit */
	if (lps0_dsm_func_mask_microsoft > 0)
		acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);

	/* Screen on */
	if (lps0_dsm_func_mask_microsoft > 0)
		acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
	if (lps0_dsm_func_mask > 0)
		acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
					ACPI_LPS0_SCREEN_ON_AMD :
					ACPI_LPS0_SCREEN_ON,
					lps0_dsm_func_mask, lps0_dsm_guid);
}

static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
	.begin = acpi_s2idle_begin,
	.prepare = acpi_s2idle_prepare,
	.prepare_late = acpi_s2idle_prepare_late,
	.check = acpi_s2idle_check,
	.wake = acpi_s2idle_wake,
	.restore_early = acpi_s2idle_restore_early,
	.restore = acpi_s2idle_restore,
	.end = acpi_s2idle_end,
};

void __init acpi_s2idle_setup(void)
{
	acpi_scan_add_handler(&lps0_handler);
	s2idle_set_ops(&acpi_s2idle_ops_lps0);
}

int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg)
{
	unsigned int sleep_flags;

	if (!lps0_device_handle || sleep_no_lps0)
		return -ENODEV;

	sleep_flags = lock_system_sleep();
	list_add(&arg->list_node, &lps0_s2idle_devops_head);
	unlock_system_sleep(sleep_flags);

	return 0;
}
EXPORT_SYMBOL_GPL(acpi_register_lps0_dev);

void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg)
{
	unsigned int sleep_flags;

	if (!lps0_device_handle || sleep_no_lps0)
		return;

	sleep_flags = lock_system_sleep();
	list_del(&arg->list_node);
	unlock_system_sleep(sleep_flags);
}
EXPORT_SYMBOL_GPL(acpi_unregister_lps0_dev);

#endif /* CONFIG_SUSPEND */
