mirror of
https://xff.cz/git/u-boot/
synced 2025-09-01 08:42:12 +02:00
acpi: Add a function to get a device path and scope
Add a function to build up the ACPI path for a device and another for its scope. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += acpi_device.o
|
||||
obj-y += acpi_table.o
|
||||
|
83
lib/acpi/acpi_device.c
Normal file
83
lib/acpi/acpi_device.c
Normal file
@@ -0,0 +1,83 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Generation of tables for particular device types
|
||||
*
|
||||
* Copyright 2019 Google LLC
|
||||
* Mostly taken from coreboot file of the same name
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <log.h>
|
||||
#include <acpi/acpi_device.h>
|
||||
#include <dm/acpi.h>
|
||||
|
||||
/**
|
||||
* acpi_device_path_fill() - Find the root device and build a path from there
|
||||
*
|
||||
* This recursively reaches back to the root device and progressively adds path
|
||||
* elements until the device is reached.
|
||||
*
|
||||
* @dev: Device to return path of
|
||||
* @buf: Buffer to hold the path
|
||||
* @buf_len: Length of buffer
|
||||
* @cur: Current position in the buffer
|
||||
* @return new position in buffer after adding @dev, or -ve on error
|
||||
*/
|
||||
static int acpi_device_path_fill(const struct udevice *dev, char *buf,
|
||||
size_t buf_len, int cur)
|
||||
{
|
||||
char name[ACPI_NAME_MAX];
|
||||
int next = 0;
|
||||
int ret;
|
||||
|
||||
ret = acpi_get_name(dev, name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Make sure this name segment will fit, including the path segment
|
||||
* separator and possible NULL terminator, if this is the last segment.
|
||||
*/
|
||||
if (cur + strlen(name) + 2 > buf_len)
|
||||
return -ENOSPC;
|
||||
|
||||
/* Walk up the tree to the root device */
|
||||
if (dev_get_parent(dev)) {
|
||||
next = acpi_device_path_fill(dev_get_parent(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",
|
||||
dev_get_parent(dev) && *name ? "." : "", name);
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
int acpi_device_path(const struct udevice *dev, char *buf, int maxlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = acpi_device_path_fill(dev, buf, maxlen, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_device_scope(const struct udevice *dev, char *scope, int maxlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!dev_get_parent(dev))
|
||||
return log_msg_ret("noparent", -EINVAL);
|
||||
|
||||
ret = acpi_device_path_fill(dev_get_parent(dev), scope, maxlen, 0);
|
||||
if (ret < 0)
|
||||
return log_msg_ret("fill", ret);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user