[PATCH] usb: renesas_usbhs: support multi driver

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

 



Signed-off-by: Kuninori Morimoto <morimoto.kuninori@xxxxxxxxxxx>
---
 drivers/usb/renesas_usbhs/mod_gadget.c |   47 +++++++++++++++++++++++++++----
 1 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index b132865..56c6d5e 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -724,13 +724,15 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
  *		linux usb function
  *
  */
-struct usbhsg_gpriv *the_controller;
+#define THE_CONTROLLER_CNT 2 /* USB0 and USB1 */
+struct usbhsg_gpriv *the_controllers[THE_CONTROLLER_CNT];
 int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 			    int (*bind)(struct usb_gadget *))
 {
-	struct usbhsg_gpriv *gpriv = the_controller;
+	struct usbhsg_gpriv *gpriv = NULL;
 	struct usbhs_priv *priv;
 	struct device *dev;
+	int i;
 	int ret;
 
 	if (!bind		||
@@ -738,10 +740,19 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 	    !driver->setup	||
 	    driver->speed != USB_SPEED_HIGH)
 		return -EINVAL;
+
+	/*
+	 * find unused the_controller
+	 */
+	for (i = 0; i < THE_CONTROLLER_CNT; i++) {
+		if (the_controllers[i] &&
+		    !the_controllers[i]->driver) {
+			gpriv = the_controllers[i];
+			break;
+		}
+	}
 	if (!gpriv)
 		return -ENODEV;
-	if (gpriv->driver)
-		return -EBUSY;
 
 	dev  = usbhsg_gpriv_to_dev(gpriv);
 	priv = usbhsg_gpriv_to_priv(gpriv);
@@ -779,9 +790,20 @@ EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
-	struct usbhsg_gpriv *gpriv = the_controller;
+	struct usbhsg_gpriv *gpriv = NULL;
 	struct usbhs_priv *priv;
 	struct device *dev = usbhsg_gpriv_to_dev(gpriv);
+	int i;
+
+	/*
+	 * find muching driver
+	 */
+	for (i = 0; i < THE_CONTROLLER_CNT; i++) {
+		if (the_controllers[i]->driver == driver) {
+			gpriv = the_controllers[i];
+			break;
+		}
+	}
 
 	if (!gpriv)
 		return -ENODEV;
@@ -836,11 +858,24 @@ static int usbhsg_stop(struct usbhs_priv *priv)
 int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 {
 	struct usbhsg_gpriv *gpriv;
+	struct usbhsg_gpriv **the_controller = NULL;
 	struct usbhsg_uep *uep;
 	struct device *dev = usbhs_priv_to_dev(priv);
 	int pipe_size = usbhs_get_dparam(priv, pipe_size);
 	int i;
 
+	/*
+	 * find empty the_controller
+	 */
+	for (i = 0; i < THE_CONTROLLER_CNT; i++) {
+		if (!the_controllers[i]) {
+			the_controller = &the_controllers[i];
+			break;
+		}
+	}
+	if (!the_controller)
+		return -ENOMEM;
+
 	gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL);
 	if (!gpriv) {
 		dev_err(dev, "Could not allocate gadget priv\n");
@@ -909,7 +944,7 @@ int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 		}
 	}
 
-	the_controller = gpriv;
+	*the_controller = gpriv;
 
 	dev_info(dev, "gadget probed\n");
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

  Powered by Linux