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: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Mika Westerberg 2017-03-28 10:52:21 +03:00 committed by Rafael J. Wysocki
parent 79389a83bc
commit 07bb80d40b
2 changed files with 132 additions and 0 deletions

View File

@ -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);

View File

@ -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_ */