Переглянути джерело

usb: cdns3: make dynamic role switching work

We need to the flow as in "Figure 14. Software OTG Control"
in user guide.

This meens we need to request for HOST_BUS_REQ/DEV_BUS_REQ
while starting host/device role respectively.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Roger Quadros 6 роки тому
батько
коміт
688f1c0c30

+ 3 - 21
drivers/usb/cdns3/drd.c

@@ -16,9 +16,6 @@
 #include "drd.h"
 #include "core.h"
 
-static int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on);
-static int cdns3_drd_switch_host(struct cdns3 *cdns, int on);
-
 /**
  * cdns3_set_mode - change mode of OTG Core
  * @cdns: pointer to context structure
@@ -35,12 +32,8 @@ int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode)
 
 	switch (mode) {
 	case USB_DR_MODE_PERIPHERAL:
-		dev_dbg(cdns->dev, "Set controller to Gadget mode\n");
-		ret = cdns3_drd_switch_gadget(cdns, 1);
 		break;
 	case USB_DR_MODE_HOST:
-		dev_dbg(cdns->dev, "Set controller to Host mode\n");
-		ret = cdns3_drd_switch_host(cdns, 1);
 		break;
 	case USB_DR_MODE_OTG:
 		dev_dbg(cdns->dev, "Set controller to OTG mode\n");
@@ -126,7 +119,7 @@ static void cdns3_otg_enable_irq(struct cdns3 *cdns)
  *
  * Returns 0 on success otherwise negative errno
  */
-static int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
+int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
 {
 	int ret;
 	u32 reg = OTGCMD_OTG_DIS;
@@ -163,7 +156,7 @@ static int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
  *
  * Returns 0 on success otherwise negative errno
  */
-static int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
+int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
 {
 	int ret;
 	u32 reg = OTGCMD_OTG_DIS;
@@ -216,14 +209,6 @@ static int cdns3_init_otg_mode(struct cdns3 *cdns)
 	if (ret)
 		return ret;
 
-	if (cdns3_is_host(cdns))
-		ret = cdns3_drd_switch_host(cdns, 1);
-	else
-		ret = cdns3_drd_switch_gadget(cdns, 1);
-
-	if (ret)
-		return ret;
-
 	cdns3_otg_enable_irq(cdns);
 	return ret;
 }
@@ -241,9 +226,6 @@ int cdns3_drd_update_mode(struct cdns3 *cdns)
 	if (cdns->desired_dr_mode == cdns->current_dr_mode)
 		return ret;
 
-	cdns3_drd_switch_gadget(cdns, 0);
-	cdns3_drd_switch_host(cdns, 0);
-
 	switch (cdns->desired_dr_mode) {
 	case USB_DR_MODE_PERIPHERAL:
 		ret = cdns3_set_mode(cdns, USB_DR_MODE_PERIPHERAL);
@@ -372,5 +354,5 @@ int cdns3_drd_init(struct cdns3 *cdns)
 
 int cdns3_drd_exit(struct cdns3 *cdns)
 {
-	return cdns3_drd_switch_host(cdns, 0);
+	return 0;
 }

+ 3 - 0
drivers/usb/cdns3/drd.h

@@ -159,5 +159,8 @@ int cdns3_get_id(struct cdns3 *cdns);
 int cdns3_drd_init(struct cdns3 *cdns);
 int cdns3_drd_exit(struct cdns3 *cdns);
 int cdns3_drd_update_mode(struct cdns3 *cdns);
+int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on);
+int cdns3_drd_switch_host(struct cdns3 *cdns, int on);
+
 
 #endif /* __LINUX_CDNS3_DRD */

+ 3 - 0
drivers/usb/cdns3/gadget.c

@@ -61,6 +61,7 @@
 #include <linux/module.h>
 
 #include "core.h"
+#include "drd.h"
 #include "gadget-export.h"
 #include "gadget.h"
 #include "trace.h"
@@ -2264,6 +2265,7 @@ void cdns3_gadget_exit(struct cdns3 *cdns)
 	kfree(priv_dev->zlp_buf);
 	kfree(priv_dev);
 	cdns->gadget_dev = NULL;
+	cdns3_drd_switch_gadget(cdns, 0);
 }
 
 static int cdns3_gadget_start(struct cdns3 *cdns)
@@ -2372,6 +2374,7 @@ static int __cdns3_gadget_init(struct cdns3 *cdns)
 	struct cdns3_device *priv_dev;
 	int ret = 0;
 
+	cdns3_drd_switch_gadget(cdns, 1);
 	pm_runtime_get_sync(cdns->dev);
 
 	ret = cdns3_gadget_start(cdns);

+ 4 - 0
drivers/usb/cdns3/host.c

@@ -11,12 +11,15 @@
 
 #include <linux/platform_device.h>
 #include "core.h"
+#include "drd.h"
 
 static int __cdns3_host_init(struct cdns3 *cdns)
 {
 	struct platform_device *xhci;
 	int ret;
 
+	cdns3_drd_switch_host(cdns, 1);
+
 	xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
 	if (!xhci) {
 		dev_err(cdns->dev, "couldn't allocate xHCI device\n");
@@ -49,6 +52,7 @@ static void cdns3_host_exit(struct cdns3 *cdns)
 {
 	platform_device_unregister(cdns->host_dev);
 	cdns->host_dev = NULL;
+	cdns3_drd_switch_host(cdns, 0);
 }
 
 int cdns3_host_init(struct cdns3 *cdns)