From 4702914e34a1cd3dc04f1396d549a120918abb58 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Mon, 7 May 2018 14:28:53 -0700 Subject: acpi: device: Walk up the tree to find identifier Instead of just checking the immediate parent for an device name, walk up the tree to check if any parent can identify the device. This allows devices to be nested more than one level deep and still have them identified in one place by the SOC. The recursive method calling this function has been changed to handle a null return from acpi_device_name and abort instead of continuing and perhaps forming an invalid ACPI path. Change-Id: Ic17c5b6facdcb1a0ac696912867d62652b2bf18e Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/26487 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones Reviewed-by: Aaron Durbin Reviewed-by: Furquan Shaikh --- src/arch/x86/acpi_device.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c index c8d313e037..a5984da1d7 100644 --- a/src/arch/x86/acpi_device.c +++ b/src/arch/x86/acpi_device.c @@ -55,6 +55,9 @@ static void acpi_device_fill_len(void *ptr) /* Locate and return the ACPI name for this device */ const char *acpi_device_name(struct device *dev) { + struct device *pdev = dev; + const char *name = NULL; + if (!dev) return NULL; @@ -62,30 +65,44 @@ const char *acpi_device_name(struct device *dev) if (dev->ops->acpi_name) return dev->ops->acpi_name(dev); - /* Check parent device in case it has a global handler */ - if (dev->bus && dev->bus->dev->ops->acpi_name) - return dev->bus->dev->ops->acpi_name(dev); + /* Walk up the tree to find if any parent can identify this device */ + while (pdev->bus) { + pdev = pdev->bus->dev; + if (!pdev) + break; + if (pdev->path.type == DEVICE_PATH_ROOT) + break; + if (pdev->ops && pdev->ops->acpi_name) + name = pdev->ops->acpi_name(dev); + if (name) + return name; + } return NULL; } /* Recursive function to find the root device and print a path from there */ -static size_t acpi_device_path_fill(struct device *dev, char *buf, - size_t buf_len, size_t cur) +static ssize_t acpi_device_path_fill(struct device *dev, char *buf, + size_t buf_len, size_t cur) { const char *name = acpi_device_name(dev); - size_t next = 0; + ssize_t next = 0; + + if (!name) + return -1; /* * Make sure this name segment will fit, including the path segment * separator and possible NUL terminator if this is the last segment. */ - if (!dev || !name || (cur + strlen(name) + 2) > buf_len) + if (!dev || (cur + strlen(name) + 2) > buf_len) return cur; /* Walk up the tree to the root device */ if (dev->path.type != DEVICE_PATH_ROOT && dev->bus && dev->bus->dev) next = acpi_device_path_fill(dev->bus->dev, buf, buf_len, cur); + if (next < 0) + return next; /* Fill in the path from the root device */ next += snprintf(buf + next, buf_len - next, "%s%s", -- cgit v1.2.3