diff options
author | Duncan Laurie <dlaurie@google.com> | 2018-05-07 14:28:53 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2018-05-28 16:08:23 +0000 |
commit | 4702914e34a1cd3dc04f1396d549a120918abb58 (patch) | |
tree | 38de493f80ae98f6eb519c8fa66af4f942505f44 /src | |
parent | 696545db7bf3dd2682a1d636db5411fe0e7c0c54 (diff) |
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 <dlaurie@google.com>
Reviewed-on: https://review.coreboot.org/26487
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Marc Jones <marc@marcjonesconsulting.com>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/acpi_device.c | 31 |
1 files changed, 24 insertions, 7 deletions
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", |