The sunxi musb has a bug where sometimes it will generate a babble
error on device disconnect instead of a disconnect irq. When this
happens the musb-controller switches from host mode to device mode
gets stuck in this state.

Clearing this requires reporting Vbus low for 200 or more ms, but
on some devices Vbus is simply always high (host-only mode, no Vbus

This commit calls sun4i_usb_phy_force_session_end() on babble errors
in host-mode, fixing the musb controller being stuck in this state
on systems without Vbus control; and also fixes the need to unplug
the usb-b -> usb-a cable to get out of this state on systems with
Vbus control.

Signed-off-by: Hans de Goede <>
 drivers/usb/musb/sunxi.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index 1408245..5079d90 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -192,8 +192,18 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void 
         * normally babble never happens treat it as disconnect.
        if ((musb->int_usb & MUSB_INTR_BABBLE) && is_host_active(musb)) {
+               struct sunxi_glue *glue =
+                               dev_get_drvdata(musb->controller->parent);
+               dev_warn(musb->controller->parent, "babble, treating as 
                musb->int_usb &= ~MUSB_INTR_BABBLE;
                musb->int_usb |= MUSB_INTR_DISCONNECT;
+               /*
+                * Fix the musb controller sometimes getting stuck in
+                * bdevice state after a babble error.
+                */
+               sun4i_usb_phy_force_session_end(glue->phy);
        if ((musb->int_usb & MUSB_INTR_RESET) && !is_host_active(musb)) {

To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to
More majordomo info at

Reply via email to