summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2016-05-31 17:05:08 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-06-01 23:58:59 +0200
commita60d541a2d402c8645d5bb2ec8dabe474b66e018 (patch)
treed0abaf2d3f99adcdf6ee60c58b4c7d54330bcece /drivers/usb/musb
parentusb: musb: sunxi: Add set_mode platform function (diff)
downloadlinux-a60d541a2d402c8645d5bb2ec8dabe474b66e018.tar.xz
linux-a60d541a2d402c8645d5bb2ec8dabe474b66e018.zip
usb: musb: sunxi: Set state to A_WAIT_VRISE when enabling Vbus
When the board is powering attached usb devices via the otg port sometimes / on some devices it takes slightly too long for the Vbus detection code in phy-sun4i-usb.c to signal that Vbus is high after enabling Vbus and the musb hardware signals a MUSB_INTR_VBUSERROR interrupt. This commit sets the otg state to A_WAIT_VRISE upon enabling Vbus making musb_stage0_irq() ignore the first VBUSERR_RETRY_COUNT VBUSERROR interrupts, fixing connection issues in these cases. Signed-off-by: Hans de Goede <hdegoede@redhat.com> [b-liu@ti.com: revise subject prefix] Signed-off-by: Bin Liu <b-liu@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/sunxi.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index 2c33d9bca587..e7d46179b485 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -112,7 +112,7 @@ static void sunxi_musb_work(struct work_struct *work)
if (test_bit(SUNXI_MUSB_FL_HOSTMODE, &glue->flags)) {
set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
musb->xceiv->otg->default_a = 1;
- musb->xceiv->otg->state = OTG_STATE_A_IDLE;
+ musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
MUSB_HST_MODE(musb);
devctl |= MUSB_DEVCTL_SESSION;
} else {
@@ -145,10 +145,12 @@ static void sunxi_musb_set_vbus(struct musb *musb, int is_on)
{
struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
- if (is_on)
+ if (is_on) {
set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
- else
+ musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
+ } else {
clear_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
+ }
schedule_work(&glue->work);
}
@@ -325,6 +327,7 @@ static int sunxi_set_mode(struct musb *musb, u8 mode)
set_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags);
/* Stop musb work from turning vbus off again */
set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags);
+ musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
}
return 0;