Commit 0a71d8b9 authored by Hanjun Guo's avatar Hanjun Guo Committed by Lorenzo Pieralisi
Browse files

ACPI/IORT: Look up IORT node through struct fwnode_handle pointer



Current IORT code provides a function (ie iort_get_fwnode())
which looks up a struct fwnode_handle pointer through a
struct acpi_iort_node pointer for SMMU components but it
lacks a function that implements the reverse look-up, namely
struct fwnode_handle* -> struct acpi_iort_node*.

Devices that are not IORT named components cannot be retrieved through
their associated IORT named component scan interface because they just
are not represented in the ACPI namespace; the reverse look-up is
therefore required for all platform devices that represent IORT nodes
(eg SMMUs) so that the struct acpi_iort_node* can be retrieved from the
struct device->fwnode pointer.

Signed-off-by: default avatarHanjun Guo <hanjun.guo@linaro.org>
[lorenzo.pieralisi@arm.com: re-indented/rewrote the commit log]
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
parent 896dd2c3
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -126,6 +126,31 @@ static inline void iort_delete_fwnode(struct acpi_iort_node *node)
	spin_unlock(&iort_fwnode_lock);
}

/**
 * iort_get_iort_node() - Retrieve iort_node associated with an fwnode
 *
 * @fwnode: fwnode associated with device to be looked-up
 *
 * Returns: iort_node pointer on success, NULL on failure
 */
static inline struct acpi_iort_node *iort_get_iort_node(
			struct fwnode_handle *fwnode)
{
	struct iort_fwnode *curr;
	struct acpi_iort_node *iort_node = NULL;

	spin_lock(&iort_fwnode_lock);
	list_for_each_entry(curr, &iort_fwnode_list, list) {
		if (curr->fwnode == fwnode) {
			iort_node = curr->iort_node;
			break;
		}
	}
	spin_unlock(&iort_fwnode_lock);

	return iort_node;
}

typedef acpi_status (*iort_find_node_callback)
	(struct acpi_iort_node *node, void *context);

@@ -422,9 +447,25 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
{
	struct pci_bus *pbus;

	if (!dev_is_pci(dev))
	if (!dev_is_pci(dev)) {
		struct acpi_iort_node *node;
		/*
		 * scan iort_fwnode_list to see if it's an iort platform
		 * device (such as SMMU, PMCG),its iort node already cached
		 * and associated with fwnode when iort platform devices
		 * were initialized.
		 */
		node = iort_get_iort_node(dev->fwnode);
		if (node)
			return node;

		/*
		 * if not, then it should be a platform device defined in
		 * DSDT/SSDT (with Named Component node in IORT)
		 */
		return iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
				      iort_match_node_callback, dev);
	}

	/* Find a PCI root bus */
	pbus = to_pci_dev(dev)->bus;