[PATCH v1 07/12] usb: roles: Find the usb role switch by also matching against the device node

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds code for supporting find usb role switch by matching against
the device node described using of_graph.

Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Cc: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>
Cc: Hans de Goede <hdegoede@xxxxxxxxxx>
Cc: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>
Cc: John Stultz <john.stultz@xxxxxxxxxx>
Signed-off-by: Yu Chen <chenyu56@xxxxxxxxxx>
---
 drivers/usb/common/roles.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/usb/common/roles.c b/drivers/usb/common/roles.c
index 99116af07f1d..0f48090c5c30 100644
--- a/drivers/usb/common/roles.c
+++ b/drivers/usb/common/roles.c
@@ -12,6 +12,8 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
 
 static struct class *role_class;
 
@@ -100,6 +102,38 @@ static void *usb_role_switch_match(struct device_connection *con, int ep,
 	return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER);
 }
 
+static int __switch_match_by_of_node(struct device *dev, const void *name)
+{
+	if (!dev->parent || !dev->parent->of_node)
+		return 0;
+
+	return of_node_name_eq(dev->parent->of_node, (const char *)name);
+}
+
+static void *of_graph_find_match_by_type(struct device *dev, const char *ep_type)
+{
+	struct device_node *ep;
+	struct device_node *remote_parent;
+	struct device *role_switch;
+
+	for_each_endpoint_of_node(dev_of_node(dev), ep) {
+		if (!ep->type || strcmp(ep->type, ep_type))
+			continue;
+
+		remote_parent = of_graph_get_remote_port_parent(ep);
+		if (!remote_parent || !remote_parent->name)
+			continue;
+
+		role_switch = class_find_device(role_class, NULL,
+				remote_parent->name, __switch_match_by_of_node);
+
+		return role_switch ? to_role_switch(role_switch) :
+			ERR_PTR(-EPROBE_DEFER);
+	}
+
+	return NULL;
+}
+
 /**
  * usb_role_switch_get - Find USB role switch linked with the caller
  * @dev: The caller device
@@ -114,6 +148,12 @@ struct usb_role_switch *usb_role_switch_get(struct device *dev)
 	sw = device_connection_find_match(dev, "usb-role-switch", NULL,
 					  usb_role_switch_match);
 
+	if (!IS_ERR_OR_NULL(sw)) {
+		WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
+		return sw;
+	}
+
+	sw = of_graph_find_match_by_type(dev, "usb-role-switch");
 	if (!IS_ERR_OR_NULL(sw))
 		WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
 
-- 
2.15.0-rc2




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux