summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@google.com>2018-05-07 14:28:53 -0700
committerPatrick Georgi <pgeorgi@google.com>2018-05-28 16:08:23 +0000
commit4702914e34a1cd3dc04f1396d549a120918abb58 (patch)
tree38de493f80ae98f6eb519c8fa66af4f942505f44 /src/arch/x86
parent696545db7bf3dd2682a1d636db5411fe0e7c0c54 (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/arch/x86')
-rw-r--r--src/arch/x86/acpi_device.c31
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",