diff options
author | Miquel Raynal <miquel.raynal@bootlin.com> | 2025-04-03 09:39:03 +0200 |
---|---|---|
committer | Fabio Estevam <festevam@gmail.com> | 2025-04-10 22:32:55 -0300 |
commit | 04fcddac28c9f28239f40c9b90e3e76ed5f5cb13 (patch) | |
tree | b09be132bdcedb8705ea2946657ba02158bd8ad9 | |
parent | 9fe367bb60d377402617bb818796bff59e82e7c6 (diff) |
dm: core: Add a helper to retrieve devices through graph endpoints
There are already several helpers to find a udevice based on its
position in a device tree, like getting a child or a node pointed by a
phandle, but there was no support for graph endpoints, which are very
common in display pipelines.
Add a new helper, named uclass_get_device_by_endpoint() which enters the
child graph reprensentation, looks for a specific port, then follows the
remote endpoint, and finally retrieves the first parent of the given
uclass_id.
This is a very handy and straightforward way to get a bridge or a panel
handle.
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-rw-r--r-- | drivers/core/uclass.c | 19 | ||||
-rw-r--r-- | include/dm/uclass.h | 24 |
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index f846a35d6b2..ce5e61bbaa6 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -16,6 +16,7 @@ #include <dm/device.h> #include <dm/device-internal.h> #include <dm/lists.h> +#include <dm/ofnode_graph.h> #include <dm/uclass.h> #include <dm/uclass-internal.h> #include <dm/util.h> @@ -582,6 +583,24 @@ int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent, ret = uclass_find_device_by_phandle(id, parent, name, &dev); return uclass_get_device_tail(dev, ret, devp); } + +int uclass_get_device_by_endpoint(enum uclass_id class_id, struct udevice *dev, + int port_idx, int ep_idx, struct udevice **devp) +{ + ofnode node_source = dev_ofnode(dev); + ofnode node_dest = ofnode_graph_get_remote_node(node_source, port_idx, ep_idx); + struct udevice *target = NULL; + int ret; + + if (!ofnode_valid(node_dest)) + return -EINVAL; + + ret = uclass_find_device_by_ofnode(class_id, node_dest, &target); + if (ret) + return -ENODEV; + + return uclass_get_device_tail(target, 0, devp); +} #endif /* diff --git a/include/dm/uclass.h b/include/dm/uclass.h index c2793040923..8fdd7272511 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -334,6 +334,30 @@ int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv, struct udevice **devp); /** + * uclass_get_device_by_endpoint() - Get a uclass device for a remote endpoint + * + * This searches through the parents of the specified remote endpoint + * for the first device matching the uclass. Said otherwise, this helper + * goes through the graph (endpoint) representation and searches for + * matching devices. Endpoints can be subnodes of the "port" node or + * subnodes of ports identified with a reg property, themselves in a + * "ports" container. + * + * The device is probed to activate it ready for use. + * + * @class_id: uclass ID to look up + * @dev: Device to start from + * @port_idx: Index of the port to follow, -1 if there is a single 'port' + * node without reg. + * @ep_idx: Index of the endpoint to follow, -1 if there is a single 'endpoint' + * node without reg. + * @target: Returns pointer to the first device matching the expected uclass. + * Return: 0 if OK, -ve on error + */ +int uclass_get_device_by_endpoint(enum uclass_id class_id, struct udevice *dev, + int port_idx, int ep_idx, struct udevice **target); + +/** * uclass_first_device() - Get the first device in a uclass * * The device returned is probed if necessary, and ready for use |