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)  * ACPI support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2020, Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "tb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 				    void **return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	struct fwnode_reference_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	struct fwnode_handle *fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	struct tb_nhi *nhi = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	struct acpi_device *adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	if (acpi_bus_get_device(handle, &adev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	fwnode = acpi_fwnode_handle(adev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	ret = fwnode_property_get_reference_args(fwnode, "usb4-host-interface",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 						 NULL, 0, 0, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	/* It needs to reference this NHI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	if (nhi->pdev->dev.fwnode != args.fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	 * Try to find physical device walking upwards to the hierarcy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	 * We need to do this because the xHCI driver might not yet be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	 * bound so the USB3 SuperSpeed ports are not yet created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	dev = acpi_get_first_physical_node(adev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	while (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		adev = adev->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		if (!adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		dev = acpi_get_first_physical_node(adev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	 * Check that the device is PCIe. This is because USB3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	 * SuperSpeed ports have this property and they are not power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	 * managed with the xHCI and the SuperSpeed hub so we create the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	 * link from xHCI instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	while (dev && !dev_is_pci(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		dev = dev->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	 * Check that this actually matches the type of device we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	 * expect. It should either be xHCI or PCIe root/downstream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	 * port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	    (pci_is_pcie(pdev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		 pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		const struct device_link *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		 * Make them both active first to make sure the NHI does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		 * not runtime suspend before the consumer. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		 * pm_runtime_put() below then allows the consumer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		 * runtime suspend again (which then allows NHI runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		 * suspend too now that the device link is established).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		pm_runtime_get_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		link = device_link_add(&pdev->dev, &nhi->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 				       DL_FLAG_AUTOREMOVE_SUPPLIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				       DL_FLAG_RPM_ACTIVE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 				       DL_FLAG_PM_RUNTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		if (link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			dev_dbg(&nhi->pdev->dev, "created link from %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 				dev_name(&pdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			dev_warn(&nhi->pdev->dev, "device link creation from %s failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 				 dev_name(&pdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		pm_runtime_put(&pdev->dev);
^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) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	fwnode_handle_put(args.fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * tb_acpi_add_links() - Add device links based on ACPI description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * @nhi: Pointer to NHI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * Goes over ACPI namespace finding tunneled ports that reference to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * @nhi ACPI node. For each reference a device link is added. The link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * is automatically removed by the driver core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void tb_acpi_add_links(struct tb_nhi *nhi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (!has_acpi_companion(&nhi->pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 * Find all devices that have usb4-host-controller interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	 * property that references to this NHI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 				     tb_acpi_add_link, NULL, nhi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		dev_warn(&nhi->pdev->dev, "failed to enumerate tunneled ports\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }