Linux-USB Archive on lore.kernel.org
 help / color / Atom feed
* [PATCHv2 0/7] musb host improvments mostly for omap2430 glue
@ 2019-10-09 21:21 Tony Lindgren
  2019-10-09 21:21 ` [PATCH 1/7] usb: musb: omap2430: Get rid of musb .set_vbus " Tony Lindgren
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Tony Lindgren @ 2019-10-09 21:21 UTC (permalink / raw)
  To: Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

Hi,

Here's v2 set of musb clean-up mostly for the 2430 glue layer.

Regards,

Tony


Changes since v1:

- Get rid of set_vbus stuff


Tony Lindgren (7):
  usb: musb: omap2430: Get rid of musb .set_vbus for omap2430 glue
  usb: musb: omap2430: Wait on enable to avoid babble
  usb: musb: omap2430: Handle multiple ID ground interrupts
  usb: musb: Add musb_set_host and peripheral and use them for omap2430
  usb: musb: omap2430: Clean up enable and remove devctl tinkering
  usb: musb: omap2430: Idle musb on init
  usb: musb: Get rid of omap2430_musb_set_vbus()

 drivers/usb/musb/musb_core.c | 103 ++++++++++++++++++++++
 drivers/usb/musb/musb_core.h |   3 +
 drivers/usb/musb/omap2430.c  | 164 ++++++++++-------------------------
 3 files changed, 152 insertions(+), 118 deletions(-)

-- 
2.23.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/7] usb: musb: omap2430: Get rid of musb .set_vbus for omap2430 glue
  2019-10-09 21:21 [PATCHv2 0/7] musb host improvments mostly for omap2430 glue Tony Lindgren
@ 2019-10-09 21:21 ` " Tony Lindgren
  2019-10-09 21:21 ` [PATCH 2/7] usb: musb: omap2430: Wait on enable to avoid babble Tony Lindgren
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2019-10-09 21:21 UTC (permalink / raw)
  To: Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Pavel Machek,
	Jacopo Mondi, Marcel Partap, Merlijn Wajer, Michael Scott, NeKit,
	Sebastian Reichel

We currently have musb_set_vbus() called from two different paths. Mostly
it gets called from the USB PHY via omap_musb_set_mailbox(), but in some
cases it can get also called from musb_stage0_irq() rather via .set_vbus:

(musb_set_host [musb_hdrc])
(omap2430_musb_set_vbus [omap2430])
(musb_stage0_irq [musb_hdrc])
(musb_interrupt [musb_hdrc])
(omap2430_musb_interrupt [omap2430])

This is racy and will not work with introducing generic helper functions
for musb_set_host() and musb_set_peripheral(). We want to get rid of the
busy loops in favor of usleep_range().

Let's just get rid of .set_vbus for omap2430 glue layer and let the PHY
code handle VBUS with musb_set_vbus(). Note that in the follow-up patch
we can completely remove omap2430_musb_set_vbus(), but let's do it in a
separate patch as this change may actually turn out to be needed as a
fix.

Reported-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/musb/omap2430.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -361,8 +361,6 @@ static const struct musb_platform_ops omap2430_ops = {
 	.init		= omap2430_musb_init,
 	.exit		= omap2430_musb_exit,
 
-	.set_vbus	= omap2430_musb_set_vbus,
-
 	.enable		= omap2430_musb_enable,
 	.disable	= omap2430_musb_disable,
 
-- 
2.23.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/7] usb: musb: omap2430: Wait on enable to avoid babble
  2019-10-09 21:21 [PATCHv2 0/7] musb host improvments mostly for omap2430 glue Tony Lindgren
  2019-10-09 21:21 ` [PATCH 1/7] usb: musb: omap2430: Get rid of musb .set_vbus " Tony Lindgren
@ 2019-10-09 21:21 ` Tony Lindgren
  2019-10-10  9:46   ` Sergei Shtylyov
  2019-10-09 21:21 ` [PATCH 3/7] usb: musb: omap2430: Handle multiple ID ground interrupts Tony Lindgren
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2019-10-09 21:21 UTC (permalink / raw)
  To: Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

We can babble interrupt if we attempt to switch to USB host mode too
soon after enabling musb. Let's fix the issue by waiting a bit in
runtime_resume.

Cc: Jacopo Mondi <jacopo@jmondi.org>
Cc: Marcel Partap <mpartap@gmx.net>
Cc: Merlijn Wajer <merlijn@wizzup.org>
Cc: Michael Scott <hashcode0f@gmail.com>
Cc: NeKit <nekit1000@gmail.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/musb/omap2430.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -550,6 +550,9 @@ static int omap2430_runtime_resume(struct device *dev)
 	musb_writel(musb->mregs, OTG_INTERFSEL,
 		    musb->context.otg_interfsel);
 
+	/* Wait for musb to get oriented. Otherwise we can get babble */
+	usleep_range(200000, 250000);
+
 	return 0;
 }
 
-- 
2.23.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/7] usb: musb: omap2430: Handle multiple ID ground interrupts
  2019-10-09 21:21 [PATCHv2 0/7] musb host improvments mostly for omap2430 glue Tony Lindgren
  2019-10-09 21:21 ` [PATCH 1/7] usb: musb: omap2430: Get rid of musb .set_vbus " Tony Lindgren
  2019-10-09 21:21 ` [PATCH 2/7] usb: musb: omap2430: Wait on enable to avoid babble Tony Lindgren
@ 2019-10-09 21:21 ` Tony Lindgren
  2019-10-13 11:32   ` Pavel Machek
  2019-10-09 21:21 ` [PATCH 4/7] usb: musb: Add musb_set_host and peripheral and use them for omap2430 Tony Lindgren
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2019-10-09 21:21 UTC (permalink / raw)
  To: Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

We currently get "unhandled DISCONNECT transition" warnings from musb core
on device disconnect as things are wrongly set to OTG_STATE_A_IDLE in
host mode when enumerating devices. We can also get "Failed to write reg
index" errors after enumerating.

This is happening at least with cpcap phy where we get multiple ID ground
interrupts. Looks like it's VBUS keeps timing out and needs to be kicked
when the phy sends multiple ID ground interrupts during host mode.

Cc: Jacopo Mondi <jacopo@jmondi.org>
Cc: Marcel Partap <mpartap@gmx.net>
Cc: Merlijn Wajer <merlijn@wizzup.org>
Cc: Michael Scott <hashcode0f@gmail.com>
Cc: NeKit <nekit1000@gmail.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/musb/omap2430.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -151,13 +151,26 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 	switch (glue->status) {
 	case MUSB_ID_GROUND:
 		dev_dbg(musb->controller, "ID GND\n");
-
-		musb->xceiv->otg->state = OTG_STATE_A_IDLE;
-		musb->xceiv->last_event = USB_EVENT_ID;
-		if (musb->gadget_driver) {
-			omap_control_usb_set_mode(glue->control_otghs,
-				USB_MODE_HOST);
+		switch (musb->xceiv->otg->state) {
+		case OTG_STATE_A_WAIT_VRISE:
+		case OTG_STATE_A_WAIT_BCON:
+		case OTG_STATE_A_HOST:
+		case OTG_STATE_A_IDLE:
+			/*
+			 * On multiple ID ground interrupts just keep enabling
+			 * VBUS. At least cpcap VBUS shuts down otherwise.
+			 */
 			omap2430_musb_set_vbus(musb, 1);
+			break;
+		default:
+			musb->xceiv->otg->state = OTG_STATE_A_IDLE;
+			musb->xceiv->last_event = USB_EVENT_ID;
+			if (musb->gadget_driver) {
+				omap_control_usb_set_mode(glue->control_otghs,
+							  USB_MODE_HOST);
+				omap2430_musb_set_vbus(musb, 1);
+			}
+			break;
 		}
 		break;
 
-- 
2.23.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/7] usb: musb: Add musb_set_host and peripheral and use them for omap2430
  2019-10-09 21:21 [PATCHv2 0/7] musb host improvments mostly for omap2430 glue Tony Lindgren
                   ` (2 preceding siblings ...)
  2019-10-09 21:21 ` [PATCH 3/7] usb: musb: omap2430: Handle multiple ID ground interrupts Tony Lindgren
@ 2019-10-09 21:21 ` Tony Lindgren
  2019-10-09 21:21 ` [PATCH 5/7] usb: musb: omap2430: Clean up enable and remove devctl tinkering Tony Lindgren
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2019-10-09 21:21 UTC (permalink / raw)
  To: Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

At least some revisions of musb core need to set devctl session bit
in peripheral mode to force musb to host mode. And we have places
clearing the devctl session bit.

Let's add a generic function to do this, and use it for omap2430.
This should get us a bit closer to completely removing devctl register
tinkering in the SoC glue code.

Before making use of this code for the other glue layers, things need
to be tested carefully as there may be a approximately a 200 ms delay
needed between powering up musb and calling musb_set_host() to avoid.
Otherwise the system hangs at least with omap2430 glue layer.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/musb/musb_core.c | 103 +++++++++++++++++++++++++++++++++++
 drivers/usb/musb/musb_core.h |   3 +
 drivers/usb/musb/omap2430.c  |  70 +++++++-----------------
 3 files changed, 127 insertions(+), 49 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -73,6 +73,7 @@
 #include <linux/prefetch.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/dma-mapping.h>
 #include <linux/usb.h>
 #include <linux/usb/of.h>
@@ -414,6 +415,108 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
 	return hw_ep->musb->io.write_fifo(hw_ep, len, src);
 }
 
+static u8 musb_read_devctl(struct musb *musb)
+{
+	return musb_readb(musb->mregs, MUSB_DEVCTL);
+}
+
+/**
+ * musb_set_host - set and initialize host mode
+ * @musb: musb controller driver data
+ *
+ * At least some musb revisions need to enable devctl session bit in
+ * peripheral mode to switch to host mode. Initializes things to host
+ * mode and sets A_IDLE. SoC glue needs to advance state further
+ * based on phy provided VBUS state.
+ *
+ * Note that the SoC glue code may need to wait for musb to settle
+ * on enable before calling this to avoid babble.
+ */
+int musb_set_host(struct musb *musb)
+{
+	int error = 0;
+	u8 devctl;
+
+	if (!musb)
+		return -EINVAL;
+
+	devctl = musb_read_devctl(musb);
+	if (!(devctl & MUSB_DEVCTL_BDEVICE)) {
+		dev_info(musb->controller,
+			 "%s: already in host mode: %02x\n",
+			 __func__, devctl);
+		goto init_data;
+	}
+
+	devctl |= MUSB_DEVCTL_SESSION;
+	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+	error = readx_poll_timeout(musb_read_devctl, musb, devctl,
+				   !(devctl & MUSB_DEVCTL_BDEVICE), 5000,
+				   1000000);
+	if (error) {
+		dev_err(musb->controller, "%s: could not set host: %02x\n",
+			__func__, devctl);
+
+		return error;
+	}
+
+init_data:
+	musb->is_active = 1;
+	musb->xceiv->otg->state = OTG_STATE_A_IDLE;
+	MUSB_HST_MODE(musb);
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(musb_set_host);
+
+/**
+ * musb_set_peripheral - set and initialize peripheral mode
+ * @musb: musb controller driver data
+ *
+ * Clears devctl session bit and initializes things for peripheral
+ * mode and sets B_IDLE. SoC glue needs to advance state further
+ * based on phy provided VBUS state.
+ */
+int musb_set_peripheral(struct musb *musb)
+{
+	int error = 0;
+	u8 devctl;
+
+	if (!musb)
+		return -EINVAL;
+
+	devctl = musb_read_devctl(musb);
+	if (devctl & MUSB_DEVCTL_BDEVICE) {
+		dev_info(musb->controller,
+			 "%s: already in peripheral mode: %02x\n",
+			 __func__, devctl);
+
+		goto init_data;
+	}
+
+	devctl &= ~MUSB_DEVCTL_SESSION;
+	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+	error = readx_poll_timeout(musb_read_devctl, musb, devctl,
+				   devctl & MUSB_DEVCTL_BDEVICE, 5000,
+				   1000000);
+	if (error) {
+		dev_err(musb->controller, "%s: could not set periperal: %02x\n",
+			__func__, devctl);
+
+		return error;
+	}
+
+init_data:
+	musb->is_active = 0;
+	musb->xceiv->otg->state = OTG_STATE_B_IDLE;
+	MUSB_DEV_MODE(musb);
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(musb_set_peripheral);
+
 /*-------------------------------------------------------------------------*/
 
 /* for high speed test mode; see USB 2.0 spec 7.1.20 */
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -487,6 +487,9 @@ extern void musb_start(struct musb *musb);
 extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
 extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst);
 
+extern int musb_set_host(struct musb *musb);
+extern int musb_set_peripheral(struct musb *musb);
+
 extern void musb_load_testpacket(struct musb *);
 
 extern irqreturn_t musb_interrupt(struct musb *);
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -38,65 +38,37 @@ struct omap2430_glue {
 
 static struct omap2430_glue	*_glue;
 
+/*
+ * HDRC controls CPEN, but beware current surges during device connect.
+ * They can trigger transient overcurrent conditions that must be ignored.
+ *
+ * Note that we're skipping A_WAIT_VFALL -> A_IDLE and jumping right to B_IDLE
+ * as set by musb_set_peripheral().
+ */
 static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
 {
-	struct usb_otg	*otg = musb->xceiv->otg;
-	u8		devctl;
-	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
-	/* HDRC controls CPEN, but beware current surges during device
-	 * connect.  They can trigger transient overcurrent conditions
-	 * that must be ignored.
-	 */
-
-	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+	struct usb_otg *otg = musb->xceiv->otg;
+	int error;
 
 	if (is_on) {
-		if (musb->xceiv->otg->state == OTG_STATE_A_IDLE) {
-			int loops = 100;
-			/* start the session */
-			devctl |= MUSB_DEVCTL_SESSION;
-			musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
-			/*
-			 * Wait for the musb to set as A device to enable the
-			 * VBUS
-			 */
-			while (musb_readb(musb->mregs, MUSB_DEVCTL) &
-			       MUSB_DEVCTL_BDEVICE) {
-
-				mdelay(5);
-				cpu_relax();
-
-				if (time_after(jiffies, timeout)
-				    || loops-- <= 0) {
-					dev_err(musb->controller,
-					"configured as A device timeout");
-					break;
-				}
+		switch (musb->xceiv->otg->state) {
+		case OTG_STATE_A_IDLE:
+			error = musb_set_host(musb);
+			if (!error) {
+				musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
+				otg_set_vbus(otg, 1);
 			}
-
+			break;
+		default:
 			otg_set_vbus(otg, 1);
-		} else {
-			musb->is_active = 1;
-			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
-			devctl |= MUSB_DEVCTL_SESSION;
-			MUSB_HST_MODE(musb);
+			break;
 		}
 	} else {
-		musb->is_active = 0;
-
-		/* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
-		 * jumping right to B_IDLE...
-		 */
-
-		musb->xceiv->otg->state = OTG_STATE_B_IDLE;
-		devctl &= ~MUSB_DEVCTL_SESSION;
-
-		MUSB_DEV_MODE(musb);
+		error = musb_set_peripheral(musb);
+		otg_set_vbus(otg, 0);
 	}
-	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 
-	dev_dbg(musb->controller, "VBUS %s, devctl %02x "
-		/* otg %3x conf %08x prcm %08x */ "\n",
+	dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
 		usb_otg_state_string(musb->xceiv->otg->state),
 		musb_readb(musb->mregs, MUSB_DEVCTL));
 }
-- 
2.23.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 5/7] usb: musb: omap2430: Clean up enable and remove devctl tinkering
  2019-10-09 21:21 [PATCHv2 0/7] musb host improvments mostly for omap2430 glue Tony Lindgren
                   ` (3 preceding siblings ...)
  2019-10-09 21:21 ` [PATCH 4/7] usb: musb: Add musb_set_host and peripheral and use them for omap2430 Tony Lindgren
@ 2019-10-09 21:21 ` Tony Lindgren
  2019-10-09 21:21 ` [PATCH 6/7] usb: musb: omap2430: Idle musb on init Tony Lindgren
  2019-10-09 21:21 ` [PATCH 7/7] usb: musb: Get rid of omap2430_musb_set_vbus() Tony Lindgren
  6 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2019-10-09 21:21 UTC (permalink / raw)
  To: Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

There should be no need to tinker with devctl in enable in the SoC glue
code. We have musb_start() to take care of handling it already.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/musb/omap2430.c | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -275,33 +275,13 @@ static int omap2430_musb_init(struct musb *musb)
 
 static void omap2430_musb_enable(struct musb *musb)
 {
-	u8		devctl;
-	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
 	struct device *dev = musb->controller;
 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
-	struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev);
-	struct omap_musb_board_data *data = pdata->board_data;
-
 
 	switch (glue->status) {
 
 	case MUSB_ID_GROUND:
 		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST);
-		if (data->interface_type != MUSB_INTERFACE_UTMI)
-			break;
-		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
-		/* start the session */
-		devctl |= MUSB_DEVCTL_SESSION;
-		musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
-		while (musb_readb(musb->mregs, MUSB_DEVCTL) &
-				MUSB_DEVCTL_BDEVICE) {
-			cpu_relax();
-
-			if (time_after(jiffies, timeout)) {
-				dev_err(dev, "configured as A device timeout");
-				break;
-			}
-		}
 		break;
 
 	case MUSB_VBUS_VALID:
-- 
2.23.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 6/7] usb: musb: omap2430: Idle musb on init
  2019-10-09 21:21 [PATCHv2 0/7] musb host improvments mostly for omap2430 glue Tony Lindgren
                   ` (4 preceding siblings ...)
  2019-10-09 21:21 ` [PATCH 5/7] usb: musb: omap2430: Clean up enable and remove devctl tinkering Tony Lindgren
@ 2019-10-09 21:21 ` Tony Lindgren
  2019-10-09 21:21 ` [PATCH 7/7] usb: musb: Get rid of omap2430_musb_set_vbus() Tony Lindgren
  6 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2019-10-09 21:21 UTC (permalink / raw)
  To: Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

We want to configure musb state in omap2430_musb_enable() instead of
omap2430_musb_init(). Otherwise musb may not idle properly until
USB cable has been connected at least once.

And we already have omap_musb_set_mailbox() configure mode with
omap_control_usb_set_mode() so we can remove those calls from
omap2430_musb_enable().

Cc: Jacopo Mondi <jacopo@jmondi.org>
Cc: Marcel Partap <mpartap@gmx.net>
Cc: Merlijn Wajer <merlijn@wizzup.org>
Cc: Michael Scott <hashcode0f@gmail.com>
Cc: NeKit <nekit1000@gmail.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/musb/omap2430.c | 20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -211,7 +211,6 @@ static int omap2430_musb_init(struct musb *musb)
 	u32 l;
 	int status = 0;
 	struct device *dev = musb->controller;
-	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 	struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
 	struct omap_musb_board_data *data = plat->board_data;
 
@@ -267,9 +266,6 @@ static int omap2430_musb_init(struct musb *musb)
 			musb_readl(musb->mregs, OTG_INTERFSEL),
 			musb_readl(musb->mregs, OTG_SIMENABLE));
 
-	if (glue->status != MUSB_UNKNOWN)
-		omap_musb_set_mailbox(glue);
-
 	return 0;
 }
 
@@ -278,19 +274,9 @@ static void omap2430_musb_enable(struct musb *musb)
 	struct device *dev = musb->controller;
 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 
-	switch (glue->status) {
-
-	case MUSB_ID_GROUND:
-		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST);
-		break;
-
-	case MUSB_VBUS_VALID:
-		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
-		break;
-
-	default:
-		break;
-	}
+	if (glue->status == MUSB_UNKNOWN)
+		glue->status = MUSB_VBUS_OFF;
+	omap_musb_set_mailbox(glue);
 }
 
 static void omap2430_musb_disable(struct musb *musb)
-- 
2.23.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 7/7] usb: musb: Get rid of omap2430_musb_set_vbus()
  2019-10-09 21:21 [PATCHv2 0/7] musb host improvments mostly for omap2430 glue Tony Lindgren
                   ` (5 preceding siblings ...)
  2019-10-09 21:21 ` [PATCH 6/7] usb: musb: omap2430: Idle musb on init Tony Lindgren
@ 2019-10-09 21:21 ` Tony Lindgren
  2019-10-13 14:34   ` Pavel Machek
  6 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2019-10-09 21:21 UTC (permalink / raw)
  To: Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

Now that we've removed direct calls from interrupt handler to
omap2430_musb_set_vbus(), let's make things less confusing and
configure VBUS directly in omap_musb_set_mailbox().

We have omap_musb_set_mailbox() called from the PHYs, and that's
all we need.

Note that we can now also drop the check for MUSB_INTERFACE_UTMI,
we've been already calling otg_set_vbus(musb->xceiv->otg, 0)
unconditionally via omap2430_musb_set_vbus() and we should only
need to call it once.

And we want to disable VBUS unconditionally on disconnect even
without musb->gadget_driver, so let's drop that check too.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/musb/omap2430.c | 70 ++++++++++++-------------------------
 1 file changed, 23 insertions(+), 47 deletions(-)

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -38,41 +38,6 @@ struct omap2430_glue {
 
 static struct omap2430_glue	*_glue;
 
-/*
- * HDRC controls CPEN, but beware current surges during device connect.
- * They can trigger transient overcurrent conditions that must be ignored.
- *
- * Note that we're skipping A_WAIT_VFALL -> A_IDLE and jumping right to B_IDLE
- * as set by musb_set_peripheral().
- */
-static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
-{
-	struct usb_otg *otg = musb->xceiv->otg;
-	int error;
-
-	if (is_on) {
-		switch (musb->xceiv->otg->state) {
-		case OTG_STATE_A_IDLE:
-			error = musb_set_host(musb);
-			if (!error) {
-				musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
-				otg_set_vbus(otg, 1);
-			}
-			break;
-		default:
-			otg_set_vbus(otg, 1);
-			break;
-		}
-	} else {
-		error = musb_set_peripheral(musb);
-		otg_set_vbus(otg, 0);
-	}
-
-	dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
-		usb_otg_state_string(musb->xceiv->otg->state),
-		musb_readb(musb->mregs, MUSB_DEVCTL));
-}
-
 static inline void omap2430_low_level_exit(struct musb *musb)
 {
 	u32 l;
@@ -112,27 +77,42 @@ static int omap2430_musb_mailbox(enum musb_vbus_id_status status)
 	return 0;
 }
 
+/*
+ * HDRC controls CPEN, but beware current surges during device connect.
+ * They can trigger transient overcurrent conditions that must be ignored.
+ *
+ * Note that we're skipping A_WAIT_VFALL -> A_IDLE and jumping right to B_IDLE
+ * as set by musb_set_peripheral().
+ */
 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 {
 	struct musb *musb = glue_to_musb(glue);
-	struct musb_hdrc_platform_data *pdata =
-		dev_get_platdata(musb->controller);
-	struct omap_musb_board_data *data = pdata->board_data;
+	int error;
 
 	pm_runtime_get_sync(musb->controller);
+
+	dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
+		usb_otg_state_string(musb->xceiv->otg->state),
+		musb_readb(musb->mregs, MUSB_DEVCTL));
+
 	switch (glue->status) {
 	case MUSB_ID_GROUND:
 		dev_dbg(musb->controller, "ID GND\n");
 		switch (musb->xceiv->otg->state) {
+		case OTG_STATE_A_IDLE:
+			error = musb_set_host(musb);
+			if (error)
+				break;
+			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
+			/* Fall through */
 		case OTG_STATE_A_WAIT_VRISE:
 		case OTG_STATE_A_WAIT_BCON:
 		case OTG_STATE_A_HOST:
-		case OTG_STATE_A_IDLE:
 			/*
 			 * On multiple ID ground interrupts just keep enabling
 			 * VBUS. At least cpcap VBUS shuts down otherwise.
 			 */
-			omap2430_musb_set_vbus(musb, 1);
+			otg_set_vbus(musb->xceiv->otg, 1);
 			break;
 		default:
 			musb->xceiv->otg->state = OTG_STATE_A_IDLE;
@@ -140,7 +120,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 			if (musb->gadget_driver) {
 				omap_control_usb_set_mode(glue->control_otghs,
 							  USB_MODE_HOST);
-				omap2430_musb_set_vbus(musb, 1);
+				otg_set_vbus(musb->xceiv->otg, 1);
 			}
 			break;
 		}
@@ -159,12 +139,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 		dev_dbg(musb->controller, "VBUS Disconnect\n");
 
 		musb->xceiv->last_event = USB_EVENT_NONE;
-		if (musb->gadget_driver)
-			omap2430_musb_set_vbus(musb, 0);
-
-		if (data->interface_type == MUSB_INTERFACE_UTMI)
-			otg_set_vbus(musb->xceiv->otg, 0);
-
+		musb_set_peripheral(musb);
+		otg_set_vbus(musb->xceiv->otg, 0);
 		omap_control_usb_set_mode(glue->control_otghs,
 			USB_MODE_DISCONNECT);
 		break;
-- 
2.23.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/7] usb: musb: omap2430: Wait on enable to avoid babble
  2019-10-09 21:21 ` [PATCH 2/7] usb: musb: omap2430: Wait on enable to avoid babble Tony Lindgren
@ 2019-10-10  9:46   ` Sergei Shtylyov
  2019-10-16 15:39     ` Tony Lindgren
  0 siblings, 1 reply; 12+ messages in thread
From: Sergei Shtylyov @ 2019-10-10  9:46 UTC (permalink / raw)
  To: Tony Lindgren, Bin Liu
  Cc: Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

Hello!

On 10.10.2019 0:21, Tony Lindgren wrote:

> We can babble interrupt if we attempt to switch to USB host mode too
         ^ verb missing?

> soon after enabling musb. Let's fix the issue by waiting a bit in
> runtime_resume.
> 
> Cc: Jacopo Mondi <jacopo@jmondi.org>
> Cc: Marcel Partap <mpartap@gmx.net>
> Cc: Merlijn Wajer <merlijn@wizzup.org>
> Cc: Michael Scott <hashcode0f@gmail.com>
> Cc: NeKit <nekit1000@gmail.com>
> Cc: Pavel Machek <pavel@ucw.cz>
> Cc: Sebastian Reichel <sre@kernel.org>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
[...]

MBR, Sergei

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/7] usb: musb: omap2430: Handle multiple ID ground interrupts
  2019-10-09 21:21 ` [PATCH 3/7] usb: musb: omap2430: Handle multiple ID ground interrupts Tony Lindgren
@ 2019-10-13 11:32   ` Pavel Machek
  0 siblings, 0 replies; 12+ messages in thread
From: Pavel Machek @ 2019-10-13 11:32 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Bin Liu, Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit,
	Sebastian Reichel

[-- Attachment #1: Type: text/plain, Size: 727 bytes --]

On Wed 2019-10-09 14:21:40, Tony Lindgren wrote:
> We currently get "unhandled DISCONNECT transition" warnings from musb core
> on device disconnect as things are wrongly set to OTG_STATE_A_IDLE in
> host mode when enumerating devices. We can also get "Failed to write reg
> index" errors after enumerating.
> 
> This is happening at least with cpcap phy where we get multiple ID ground
> interrupts. Looks like it's VBUS keeps timing out and needs to be kicked
> when the phy sends multiple ID ground interrupts during host mode.

1-3: Acked-by: Pavel Machek <pavel@ucw.cz>

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 7/7] usb: musb: Get rid of omap2430_musb_set_vbus()
  2019-10-09 21:21 ` [PATCH 7/7] usb: musb: Get rid of omap2430_musb_set_vbus() Tony Lindgren
@ 2019-10-13 14:34   ` Pavel Machek
  0 siblings, 0 replies; 12+ messages in thread
From: Pavel Machek @ 2019-10-13 14:34 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Bin Liu, Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit,
	Sebastian Reichel

[-- Attachment #1: Type: text/plain, Size: 927 bytes --]

On Wed 2019-10-09 14:21:44, Tony Lindgren wrote:
> Now that we've removed direct calls from interrupt handler to
> omap2430_musb_set_vbus(), let's make things less confusing and
> configure VBUS directly in omap_musb_set_mailbox().
> 
> We have omap_musb_set_mailbox() called from the PHYs, and that's
> all we need.
> 
> Note that we can now also drop the check for MUSB_INTERFACE_UTMI,
> we've been already calling otg_set_vbus(musb->xceiv->otg, 0)
> unconditionally via omap2430_musb_set_vbus() and we should only
> need to call it once.
> 
> And we want to disable VBUS unconditionally on disconnect even
> without musb->gadget_driver, so let's drop that check too.
> 
> Signed-off-by: Tony Lindgren <tony@atomide.com>

4-7: Acked-by: Pavel Machek <pavel@ucw.cz>

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/7] usb: musb: omap2430: Wait on enable to avoid babble
  2019-10-10  9:46   ` Sergei Shtylyov
@ 2019-10-16 15:39     ` Tony Lindgren
  0 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2019-10-16 15:39 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Bin Liu, Greg Kroah-Hartman, linux-usb, linux-omap, Jacopo Mondi,
	Marcel Partap, Merlijn Wajer, Michael Scott, NeKit, Pavel Machek,
	Sebastian Reichel

* Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> [191010 09:46]:
> Hello!
> 
> On 10.10.2019 0:21, Tony Lindgren wrote:
> 
> > We can babble interrupt if we attempt to switch to USB host mode too
>         ^ verb missing?

Thanks for catching it, it should say "We can get babble...".

Bin, do you need a resend of the whole series if no
other comments?

Regards,

Tony

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, back to index

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-09 21:21 [PATCHv2 0/7] musb host improvments mostly for omap2430 glue Tony Lindgren
2019-10-09 21:21 ` [PATCH 1/7] usb: musb: omap2430: Get rid of musb .set_vbus " Tony Lindgren
2019-10-09 21:21 ` [PATCH 2/7] usb: musb: omap2430: Wait on enable to avoid babble Tony Lindgren
2019-10-10  9:46   ` Sergei Shtylyov
2019-10-16 15:39     ` Tony Lindgren
2019-10-09 21:21 ` [PATCH 3/7] usb: musb: omap2430: Handle multiple ID ground interrupts Tony Lindgren
2019-10-13 11:32   ` Pavel Machek
2019-10-09 21:21 ` [PATCH 4/7] usb: musb: Add musb_set_host and peripheral and use them for omap2430 Tony Lindgren
2019-10-09 21:21 ` [PATCH 5/7] usb: musb: omap2430: Clean up enable and remove devctl tinkering Tony Lindgren
2019-10-09 21:21 ` [PATCH 6/7] usb: musb: omap2430: Idle musb on init Tony Lindgren
2019-10-09 21:21 ` [PATCH 7/7] usb: musb: Get rid of omap2430_musb_set_vbus() Tony Lindgren
2019-10-13 14:34   ` Pavel Machek

Linux-USB Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-usb/0 linux-usb/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-usb linux-usb/ https://lore.kernel.org/linux-usb \
		linux-usb@vger.kernel.org linux-usb@archiver.kernel.org
	public-inbox-index linux-usb

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-usb


AGPL code for this site: git clone https://public-inbox.org/ public-inbox