// SPDX-License-Identifier: GPL-2.0
/*
 * ACPI support
 *
 * Copyright (C) 2020, Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/acpi.h>
#include <linux/pm_runtime.h>

#include "tb.h"

static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
				    void **return_value)
{
	struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
	struct fwnode_reference_args args;
	struct fwnode_handle *fwnode;
	struct tb_nhi *nhi = data;
	struct pci_dev *pdev;
	struct device *dev;
	int ret;

	if (!adev)
		return AE_OK;

	fwnode = acpi_fwnode_handle(adev);
	ret = fwnode_property_get_reference_args(fwnode, "usb4-host-interface",
						 NULL, 0, 0, &args);
	if (ret)
		return AE_OK;

	/* It needs to reference this NHI */
	if (dev_fwnode(&nhi->pdev->dev) != args.fwnode)
		goto out_put;

	/*
	 * Try to find physical device walking upwards to the hierarcy.
	 * We need to do this because the xHCI driver might not yet be
	 * bound so the USB3 SuperSpeed ports are not yet created.
	 */
	dev = acpi_get_first_physical_node(adev);
	while (!dev) {
		adev = adev->parent;
		if (!adev)
			break;
		dev = acpi_get_first_physical_node(adev);
	}

	if (!dev)
		goto out_put;

	/*
	 * Check that the device is PCIe. This is because USB3
	 * SuperSpeed ports have this property and they are not power
	 * managed with the xHCI and the SuperSpeed hub so we create the
	 * link from xHCI instead.
	 */
	while (dev && !dev_is_pci(dev))
		dev = dev->parent;

	if (!dev)
		goto out_put;

	/*
	 * Check that this actually matches the type of device we
	 * expect. It should either be xHCI or PCIe root/downstream
	 * port.
	 */
	pdev = to_pci_dev(dev);
	if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI ||
	    (pci_is_pcie(pdev) &&
		(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
		 pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM))) {
		const struct device_link *link;

		/*
		 * Make them both active first to make sure the NHI does
		 * not runtime suspend before the consumer. The
		 * pm_runtime_put() below then allows the consumer to
		 * runtime suspend again (which then allows NHI runtime
		 * suspend too now that the device link is established).
		 */
		pm_runtime_get_sync(&pdev->dev);

		link = device_link_add(&pdev->dev, &nhi->pdev->dev,
				       DL_FLAG_AUTOREMOVE_SUPPLIER |
				       DL_FLAG_RPM_ACTIVE |
				       DL_FLAG_PM_RUNTIME);
		if (link) {
			dev_dbg(&nhi->pdev->dev, "created link from %s\n",
				dev_name(&pdev->dev));
		} else {
			dev_warn(&nhi->pdev->dev, "device link creation from %s failed\n",
				 dev_name(&pdev->dev));
		}

		pm_runtime_put(&pdev->dev);
	}

out_put:
	fwnode_handle_put(args.fwnode);
	return AE_OK;
}

/**
 * tb_acpi_add_links() - Add device links based on ACPI description
 * @nhi: Pointer to NHI
 *
 * Goes over ACPI namespace finding tunneled ports that reference to
 * @nhi ACPI node. For each reference a device link is added. The link
 * is automatically removed by the driver core.
 */
void tb_acpi_add_links(struct tb_nhi *nhi)
{
	acpi_status status;

	if (!has_acpi_companion(&nhi->pdev->dev))
		return;

	/*
	 * Find all devices that have usb4-host-controller interface
	 * property that references to this NHI.
	 */
	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 32,
				     tb_acpi_add_link, NULL, nhi, NULL);
	if (ACPI_FAILURE(status))
		dev_warn(&nhi->pdev->dev, "failed to enumerate tunneled ports\n");
}

/**
 * tb_acpi_is_native() - Did the platform grant native TBT/USB4 control
 *
 * Returns %true if the platform granted OS native control over
 * TBT/USB4. In this case software based connection manager can be used,
 * otherwise there is firmware based connection manager running.
 */
bool tb_acpi_is_native(void)
{
	return osc_sb_native_usb4_support_confirmed &&
	       osc_sb_native_usb4_control;
}

/**
 * tb_acpi_may_tunnel_usb3() - Is USB3 tunneling allowed by the platform
 *
 * When software based connection manager is used, this function
 * returns %true if platform allows native USB3 tunneling.
 */
bool tb_acpi_may_tunnel_usb3(void)
{
	if (tb_acpi_is_native())
		return osc_sb_native_usb4_control & OSC_USB_USB3_TUNNELING;
	return true;
}

/**
 * tb_acpi_may_tunnel_dp() - Is DisplayPort tunneling allowed by the platform
 *
 * When software based connection manager is used, this function
 * returns %true if platform allows native DP tunneling.
 */
bool tb_acpi_may_tunnel_dp(void)
{
	if (tb_acpi_is_native())
		return osc_sb_native_usb4_control & OSC_USB_DP_TUNNELING;
	return true;
}

/**
 * tb_acpi_may_tunnel_pcie() - Is PCIe tunneling allowed by the platform
 *
 * When software based connection manager is used, this function
 * returns %true if platform allows native PCIe tunneling.
 */
bool tb_acpi_may_tunnel_pcie(void)
{
	if (tb_acpi_is_native())
		return osc_sb_native_usb4_control & OSC_USB_PCIE_TUNNELING;
	return true;
}

/**
 * tb_acpi_is_xdomain_allowed() - Are XDomain connections allowed
 *
 * When software based connection manager is used, this function
 * returns %true if platform allows XDomain connections.
 */
bool tb_acpi_is_xdomain_allowed(void)
{
	if (tb_acpi_is_native())
		return osc_sb_native_usb4_control & OSC_USB_XDOMAIN;
	return true;
}

/* UUID for retimer _DSM: e0053122-795b-4122-8a5e-57be1d26acb3 */
static const guid_t retimer_dsm_guid =
	GUID_INIT(0xe0053122, 0x795b, 0x4122,
		  0x8a, 0x5e, 0x57, 0xbe, 0x1d, 0x26, 0xac, 0xb3);

#define RETIMER_DSM_QUERY_ONLINE_STATE	1
#define RETIMER_DSM_SET_ONLINE_STATE	2

static int tb_acpi_retimer_set_power(struct tb_port *port, bool power)
{
	struct usb4_port *usb4 = port->usb4;
	union acpi_object argv4[2];
	struct acpi_device *adev;
	union acpi_object *obj;
	int ret;

	if (!usb4->can_offline)
		return 0;

	adev = ACPI_COMPANION(&usb4->dev);
	if (WARN_ON(!adev))
		return 0;

	/* Check if we are already powered on (and in correct mode) */
	obj = acpi_evaluate_dsm_typed(adev->handle, &retimer_dsm_guid, 1,
				      RETIMER_DSM_QUERY_ONLINE_STATE, NULL,
				      ACPI_TYPE_INTEGER);
	if (!obj) {
		tb_port_warn(port, "ACPI: query online _DSM failed\n");
		return -EIO;
	}

	ret = obj->integer.value;
	ACPI_FREE(obj);

	if (power == ret)
		return 0;

	tb_port_dbg(port, "ACPI: calling _DSM to power %s retimers\n",
		    power ? "on" : "off");

	argv4[0].type = ACPI_TYPE_PACKAGE;
	argv4[0].package.count = 1;
	argv4[0].package.elements = &argv4[1];
	argv4[1].integer.type = ACPI_TYPE_INTEGER;
	argv4[1].integer.value = power;

	obj = acpi_evaluate_dsm_typed(adev->handle, &retimer_dsm_guid, 1,
				      RETIMER_DSM_SET_ONLINE_STATE, argv4,
				      ACPI_TYPE_INTEGER);
	if (!obj) {
		tb_port_warn(port,
			     "ACPI: set online state _DSM evaluation failed\n");
		return -EIO;
	}

	ret = obj->integer.value;
	ACPI_FREE(obj);

	if (ret >= 0) {
		if (power)
			return ret == 1 ? 0 : -EBUSY;
		return 0;
	}

	tb_port_warn(port, "ACPI: set online state _DSM failed with error %d\n", ret);
	return -EIO;
}

/**
 * tb_acpi_power_on_retimers() - Call platform to power on retimers
 * @port: USB4 port
 *
 * Calls platform to turn on power to all retimers behind this USB4
 * port. After this function returns successfully the caller can
 * continue with the normal retimer flows (as specified in the USB4
 * spec). Note if this returns %-EBUSY it means the type-C port is in
 * non-USB4/TBT mode (there is non-USB4/TBT device connected).
 *
 * This should only be called if the USB4/TBT link is not up.
 *
 * Returns %0 on success.
 */
int tb_acpi_power_on_retimers(struct tb_port *port)
{
	return tb_acpi_retimer_set_power(port, true);
}

/**
 * tb_acpi_power_off_retimers() - Call platform to power off retimers
 * @port: USB4 port
 *
 * This is the opposite of tb_acpi_power_on_retimers(). After returning
 * successfully the normal operations with the @port can continue.
 *
 * Returns %0 on success.
 */
int tb_acpi_power_off_retimers(struct tb_port *port)
{
	return tb_acpi_retimer_set_power(port, false);
}

static bool tb_acpi_bus_match(struct device *dev)
{
	return tb_is_switch(dev) || tb_is_usb4_port_device(dev);
}

static struct acpi_device *tb_acpi_find_port(struct acpi_device *adev,
					     const struct tb_port *port)
{
	struct acpi_device *port_adev;

	if (!adev)
		return NULL;

	/*
	 * Device routers exists under the downstream facing USB4 port
	 * of the parent router. Their _ADR is always 0.
	 */
	list_for_each_entry(port_adev, &adev->children, node) {
		if (acpi_device_adr(port_adev) == port->port)
			return port_adev;
	}

	return NULL;
}

static struct acpi_device *tb_acpi_switch_find_companion(struct tb_switch *sw)
{
	struct acpi_device *adev = NULL;
	struct tb_switch *parent_sw;

	parent_sw = tb_switch_parent(sw);
	if (parent_sw) {
		struct tb_port *port = tb_port_at(tb_route(sw), parent_sw);
		struct acpi_device *port_adev;

		port_adev = tb_acpi_find_port(ACPI_COMPANION(&parent_sw->dev), port);
		if (port_adev)
			adev = acpi_find_child_device(port_adev, 0, false);
	} else {
		struct tb_nhi *nhi = sw->tb->nhi;
		struct acpi_device *parent_adev;

		parent_adev = ACPI_COMPANION(&nhi->pdev->dev);
		if (parent_adev)
			adev = acpi_find_child_device(parent_adev, 0, false);
	}

	return adev;
}

static struct acpi_device *tb_acpi_find_companion(struct device *dev)
{
	/*
	 * The Thunderbolt/USB4 hierarchy looks like following:
	 *
	 * Device (NHI)
	 *   Device (HR)		// Host router _ADR == 0
	 *      Device (DFP0)		// Downstream port _ADR == lane 0 adapter
	 *        Device (DR)		// Device router _ADR == 0
	 *          Device (UFP)	// Upstream port _ADR == lane 0 adapter
	 *      Device (DFP1)		// Downstream port _ADR == lane 0 adapter number
	 *
	 * At the moment we bind the host router to the corresponding
	 * Linux device.
	 */
	if (tb_is_switch(dev))
		return tb_acpi_switch_find_companion(tb_to_switch(dev));
	else if (tb_is_usb4_port_device(dev))
		return tb_acpi_find_port(ACPI_COMPANION(dev->parent),
					 tb_to_usb4_port_device(dev)->port);
	return NULL;
}

static void tb_acpi_setup(struct device *dev)
{
	struct acpi_device *adev = ACPI_COMPANION(dev);
	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);

	if (!adev || !usb4)
		return;

	if (acpi_check_dsm(adev->handle, &retimer_dsm_guid, 1,
			   BIT(RETIMER_DSM_QUERY_ONLINE_STATE) |
			   BIT(RETIMER_DSM_SET_ONLINE_STATE)))
		usb4->can_offline = true;
}

static struct acpi_bus_type tb_acpi_bus = {
	.name = "thunderbolt",
	.match = tb_acpi_bus_match,
	.find_companion = tb_acpi_find_companion,
	.setup = tb_acpi_setup,
};

int tb_acpi_init(void)
{
	return register_acpi_bus_type(&tb_acpi_bus);
}

void tb_acpi_exit(void)
{
	unregister_acpi_bus_type(&tb_acpi_bus);
}
