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