Skip to content

Commit

Permalink
device property: Add support for remote endpoints
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mika Westerberg authored and Rafael J. Wysocki committed Mar 28, 2017
1 parent 79389a8 commit 07bb80d
Showing 2 changed files with 132 additions and 0 deletions.
123 changes: 123 additions & 0 deletions drivers/base/property.c
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions include/linux/property.h
Original file line number Diff line number Diff line change
@@ -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_ */

0 comments on commit 07bb80d

Please sign in to comment.