Since the runtime PM support was added in musb, dsps relies on the timer
calling otg_timer() to activate the usb subsystem. However the driver
doesn't enable the timer for peripheral port, then the peripheral port is
unable to be enumerated by a host if the other usb port is disabled or in
peripheral mode too.

So let's start the timer for peripheral port too.

Fixes: ea2f35c01d5e ("usb: musb: Fix sleeping function called from invalid 
context for hdrc glue")
Cc: sta...@vger.kernel.org # v4.9+
Signed-off-by: Bin Liu <b-...@ti.com>
---
 drivers/usb/musb/musb_dsps.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 1e6d78b1334e..dd8c9deaedbf 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -181,9 +181,11 @@ static void dsps_musb_enable(struct musb *musb)
 
        musb_writel(reg_base, wrp->epintr_set, epmask);
        musb_writel(reg_base, wrp->coreintr_set, coremask);
-       /* start polling for ID change in dual-role idle mode */
-       if (musb->xceiv->otg->state == OTG_STATE_B_IDLE &&
-                       musb->port_mode == MUSB_OTG)
+       /*
+        * start polling for runtime PM active and idle,
+        * and for for ID change in dual-role idle mode.
+        */
+       if (musb->xceiv->otg->state == OTG_STATE_B_IDLE)
                dsps_mod_timer(glue, -1);
 }
 
@@ -254,6 +256,10 @@ static int dsps_check_status(struct musb *musb, void 
*unused)
                                musb->xceiv->otg->state = OTG_STATE_A_IDLE;
                                MUSB_HST_MODE(musb);
                        }
+
+                       if (musb->port_mode == MUSB_PERIPHERAL)
+                               skip_session = 1;
+
                        if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session)
                                musb_writeb(mregs, MUSB_DEVCTL,
                                            MUSB_DEVCTL_SESSION);
-- 
2.17.1

Reply via email to