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>
This commit is contained in:
committed by
Patrick Georgi
parent
696545db7b
commit
4702914e34
@@ -55,6 +55,9 @@ static void acpi_device_fill_len(void *ptr)
|
|||||||
/* Locate and return the ACPI name for this device */
|
/* Locate and return the ACPI name for this device */
|
||||||
const char *acpi_device_name(struct device *dev)
|
const char *acpi_device_name(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct device *pdev = dev;
|
||||||
|
const char *name = NULL;
|
||||||
|
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -62,30 +65,44 @@ const char *acpi_device_name(struct device *dev)
|
|||||||
if (dev->ops->acpi_name)
|
if (dev->ops->acpi_name)
|
||||||
return dev->ops->acpi_name(dev);
|
return dev->ops->acpi_name(dev);
|
||||||
|
|
||||||
/* Check parent device in case it has a global handler */
|
/* Walk up the tree to find if any parent can identify this device */
|
||||||
if (dev->bus && dev->bus->dev->ops->acpi_name)
|
while (pdev->bus) {
|
||||||
return dev->bus->dev->ops->acpi_name(dev);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recursive function to find the root device and print a path from there */
|
/* 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,
|
static ssize_t acpi_device_path_fill(struct device *dev, char *buf,
|
||||||
size_t buf_len, size_t cur)
|
size_t buf_len, size_t cur)
|
||||||
{
|
{
|
||||||
const char *name = acpi_device_name(dev);
|
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
|
* Make sure this name segment will fit, including the path segment
|
||||||
* separator and possible NUL terminator if this is the last 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;
|
return cur;
|
||||||
|
|
||||||
/* Walk up the tree to the root device */
|
/* Walk up the tree to the root device */
|
||||||
if (dev->path.type != DEVICE_PATH_ROOT && dev->bus && dev->bus->dev)
|
if (dev->path.type != DEVICE_PATH_ROOT && dev->bus && dev->bus->dev)
|
||||||
next = acpi_device_path_fill(dev->bus->dev, buf, buf_len, cur);
|
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 */
|
/* Fill in the path from the root device */
|
||||||
next += snprintf(buf + next, buf_len - next, "%s%s",
|
next += snprintf(buf + next, buf_len - next, "%s%s",
|
||||||
|
Reference in New Issue
Block a user