Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07bb80d4 authored by Mika Westerberg's avatar Mika Westerberg Committed by Rafael J. Wysocki
Browse files

device property: Add support for remote endpoints



This follows DT implementation of of_graph_* APIs but we call them
fwnode_graph_* instead. For DT nodes the existing of_graph_* implementation
will be used. For ACPI we use the new ACPI graph implementation instead.

Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 79389a83
Loading
Loading
Loading
Loading
+123 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_graph.h>
#include <linux/property.h>
#include <linux/etherdevice.h>
#include <linux/phy.h>
@@ -1176,3 +1177,125 @@ void *device_get_mac_address(struct device *dev, char *addr, int alen)
	return device_get_mac_addr(dev, "address", addr, alen);
}
EXPORT_SYMBOL(device_get_mac_address);

/**
 * device_graph_get_next_endpoint - Get next endpoint firmware node
 * @fwnode: Pointer to the parent firmware node
 * @prev: Previous endpoint node or %NULL to get the first
 *
 * Returns an endpoint firmware node pointer or %NULL if no more endpoints
 * are available.
 */
struct fwnode_handle *
fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode,
			       struct fwnode_handle *prev)
{
	struct fwnode_handle *endpoint = NULL;

	if (is_of_node(fwnode)) {
		struct device_node *node;

		node = of_graph_get_next_endpoint(to_of_node(fwnode),
						  to_of_node(prev));

		if (node)
			endpoint = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		endpoint = acpi_graph_get_next_endpoint(fwnode, prev);
		if (IS_ERR(endpoint))
			endpoint = NULL;
	}

	return endpoint;

}
EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);

/**
 * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
 * @fwnode: Endpoint firmware node pointing to the remote endpoint
 *
 * Extracts firmware node of a remote device the @fwnode points to.
 */
struct fwnode_handle *
fwnode_graph_get_remote_port_parent(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *parent = NULL;

	if (is_of_node(fwnode)) {
		struct device_node *node;

		node = of_graph_get_remote_port_parent(to_of_node(fwnode));
		if (node)
			parent = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		int ret;

		ret = acpi_graph_get_remote_endpoint(fwnode, &parent, NULL,
						     NULL);
		if (ret)
			return NULL;
	}

	return parent;
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);

/**
 * fwnode_graph_get_remote_port - Return fwnode of a remote port
 * @fwnode: Endpoint firmware node pointing to the remote endpoint
 *
 * Extracts firmware node of a remote port the @fwnode points to.
 */
struct fwnode_handle *fwnode_graph_get_remote_port(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *port = NULL;

	if (is_of_node(fwnode)) {
		struct device_node *node;

		node = of_graph_get_remote_port(to_of_node(fwnode));
		if (node)
			port = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		int ret;

		ret = acpi_graph_get_remote_endpoint(fwnode, NULL, &port, NULL);
		if (ret)
			return NULL;
	}

	return port;
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);

/**
 * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint
 * @fwnode: Endpoint firmware node pointing to the remote endpoint
 *
 * Extracts firmware node of a remote endpoint the @fwnode points to.
 */
struct fwnode_handle *
fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *endpoint = NULL;

	if (is_of_node(fwnode)) {
		struct device_node *node;

		node = of_parse_phandle(to_of_node(fwnode), "remote-endpoint",
					0);
		if (node)
			endpoint = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		int ret;

		ret = acpi_graph_get_remote_endpoint(fwnode, NULL, NULL,
						     &endpoint);
		if (ret)
			return NULL;
	}

	return endpoint;
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
+9 −0
Original line number Diff line number Diff line
@@ -268,4 +268,13 @@ int device_get_phy_mode(struct device *dev);

void *device_get_mac_address(struct device *dev, char *addr, int alen);

struct fwnode_handle *fwnode_graph_get_next_endpoint(
	struct fwnode_handle *fwnode, struct fwnode_handle *prev);
struct fwnode_handle *fwnode_graph_get_remote_port_parent(
	struct fwnode_handle *fwnode);
struct fwnode_handle *fwnode_graph_get_remote_port(
	struct fwnode_handle *fwnode);
struct fwnode_handle *fwnode_graph_get_remote_endpoint(
	struct fwnode_handle *fwnode);

#endif /* _LINUX_PROPERTY_H_ */