]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/base/property.c
Merge tag 'kvm-4.13-2' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[karo-tx-linux.git] / drivers / base / property.c
index e1a58ac8840ea8d0d345a7607c9503a06cb75796..edf02c1b5845968bb94844f51057c6f414b83d64 100644 (file)
@@ -253,10 +253,10 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
 {
        bool ret;
 
-       ret = fwnode_call_int_op(fwnode, property_present, propname);
+       ret = fwnode_call_bool_op(fwnode, property_present, propname);
        if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
            !IS_ERR_OR_NULL(fwnode->secondary))
-               ret = fwnode_call_int_op(fwnode->secondary, property_present,
+               ret = fwnode_call_bool_op(fwnode->secondary, property_present,
                                         propname);
        return ret;
 }
@@ -1021,6 +1021,16 @@ void fwnode_handle_put(struct fwnode_handle *fwnode)
 }
 EXPORT_SYMBOL_GPL(fwnode_handle_put);
 
+/**
+ * fwnode_device_is_available - check if a device is available for use
+ * @fwnode: Pointer to the fwnode of the device.
+ */
+bool fwnode_device_is_available(struct fwnode_handle *fwnode)
+{
+       return fwnode_call_bool_op(fwnode, device_is_available);
+}
+EXPORT_SYMBOL_GPL(fwnode_device_is_available);
+
 /**
  * device_get_child_node_count - return the number of child nodes for device
  * @dev: Device to cound the child nodes for
@@ -1160,6 +1170,26 @@ fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode,
 }
 EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
 
+/**
+ * fwnode_graph_get_port_parent - Return the device fwnode of a port endpoint
+ * @endpoint: Endpoint firmware node of the port
+ *
+ * Return: the firmware node of the device the @endpoint belongs to.
+ */
+struct fwnode_handle *
+fwnode_graph_get_port_parent(struct fwnode_handle *endpoint)
+{
+       struct fwnode_handle *port, *parent;
+
+       port = fwnode_get_parent(endpoint);
+       parent = fwnode_call_ptr_op(port, graph_get_port_parent);
+
+       fwnode_handle_put(port);
+
+       return parent;
+}
+EXPORT_SYMBOL_GPL(fwnode_graph_get_port_parent);
+
 /**
  * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
  * @fwnode: Endpoint firmware node pointing to the remote endpoint
@@ -1169,12 +1199,12 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
 struct fwnode_handle *
 fwnode_graph_get_remote_port_parent(struct fwnode_handle *fwnode)
 {
-       struct fwnode_handle *port, *parent;
+       struct fwnode_handle *endpoint, *parent;
 
-       port = fwnode_graph_get_remote_port(fwnode);
-       parent = fwnode_call_ptr_op(port, graph_get_port_parent);
+       endpoint = fwnode_graph_get_remote_endpoint(fwnode);
+       parent = fwnode_graph_get_port_parent(endpoint);
 
-       fwnode_handle_put(port);
+       fwnode_handle_put(endpoint);
 
        return parent;
 }
@@ -1205,6 +1235,43 @@ fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode)
 }
 EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
 
+/**
+ * fwnode_graph_get_remote_node - get remote parent node for given port/endpoint
+ * @fwnode: pointer to parent fwnode_handle containing graph port/endpoint
+ * @port_id: identifier of the parent port node
+ * @endpoint_id: identifier of the endpoint node
+ *
+ * Return: Remote fwnode handle associated with remote endpoint node linked
+ *        to @node. Use fwnode_node_put() on it when done.
+ */
+struct fwnode_handle *fwnode_graph_get_remote_node(struct fwnode_handle *fwnode,
+                                                  u32 port_id, u32 endpoint_id)
+{
+       struct fwnode_handle *endpoint = NULL;
+
+       while ((endpoint = fwnode_graph_get_next_endpoint(fwnode, endpoint))) {
+               struct fwnode_endpoint fwnode_ep;
+               struct fwnode_handle *remote;
+               int ret;
+
+               ret = fwnode_graph_parse_endpoint(endpoint, &fwnode_ep);
+               if (ret < 0)
+                       continue;
+
+               if (fwnode_ep.port != port_id || fwnode_ep.id != endpoint_id)
+                       continue;
+
+               remote = fwnode_graph_get_remote_port_parent(endpoint);
+               if (!remote)
+                       return NULL;
+
+               return fwnode_device_is_available(remote) ? remote : NULL;
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_node);
+
 /**
  * fwnode_graph_parse_endpoint - parse common endpoint node properties
  * @fwnode: pointer to endpoint fwnode_handle