summaryrefslogtreecommitdiff
path: root/drivers/usb/musb/musb_gadget.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r--drivers/usb/musb/musb_gadget.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 6704a62a1665..31c44325e828 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1523,7 +1523,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)
spin_lock_irqsave(&musb->lock, flags);
- switch (musb->xceiv->otg->state) {
+ switch (musb_get_state(musb)) {
case OTG_STATE_B_PERIPHERAL:
/* NOTE: OTG state machine doesn't include B_SUSPENDED;
* that's part of the standard usb 1.1 state machine, and
@@ -1552,9 +1552,11 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)
break;
}
- spin_unlock_irqrestore(&musb->lock, flags);
- otg_start_srp(musb->xceiv->otg);
- spin_lock_irqsave(&musb->lock, flags);
+ if (musb->xceiv) {
+ spin_unlock_irqrestore(&musb->lock, flags);
+ otg_start_srp(musb->xceiv->otg);
+ spin_lock_irqsave(&musb->lock, flags);
+ }
/* Block idling for at least 1s */
musb_platform_try_idle(musb,
@@ -1564,7 +1566,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)
goto done;
default:
musb_dbg(musb, "Unhandled wake: %s",
- usb_otg_state_string(musb->xceiv->otg->state));
+ musb_otg_state_string(musb));
goto done;
}
@@ -1628,8 +1630,6 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
{
struct musb *musb = gadget_to_musb(gadget);
- if (!musb->xceiv->set_power)
- return -EOPNOTSUPP;
return usb_phy_set_power(musb->xceiv, mA);
}
@@ -1787,7 +1787,7 @@ int musb_gadget_setup(struct musb *musb)
musb->g.speed = USB_SPEED_UNKNOWN;
MUSB_DEV_MODE(musb);
- musb->xceiv->otg->state = OTG_STATE_B_IDLE;
+ musb_set_state(musb, OTG_STATE_B_IDLE);
/* this "gadget" abstracts/virtualizes the controller */
musb->g.name = musb_driver_name;
@@ -1834,7 +1834,6 @@ static int musb_gadget_start(struct usb_gadget *g,
struct usb_gadget_driver *driver)
{
struct musb *musb = gadget_to_musb(g);
- struct usb_otg *otg = musb->xceiv->otg;
unsigned long flags;
int retval = 0;
@@ -1851,8 +1850,12 @@ static int musb_gadget_start(struct usb_gadget *g,
spin_lock_irqsave(&musb->lock, flags);
musb->is_active = 1;
- otg_set_peripheral(otg, &musb->g);
- musb->xceiv->otg->state = OTG_STATE_B_IDLE;
+ if (musb->xceiv)
+ otg_set_peripheral(musb->xceiv->otg, &musb->g);
+ else
+ phy_set_mode(musb->phy, PHY_MODE_USB_DEVICE);
+
+ musb_set_state(musb, OTG_STATE_B_IDLE);
spin_unlock_irqrestore(&musb->lock, flags);
musb_start(musb);
@@ -1861,7 +1864,7 @@ static int musb_gadget_start(struct usb_gadget *g,
* handles power budgeting ... this way also
* ensures HdrcStart is indirectly called.
*/
- if (musb->xceiv->last_event == USB_EVENT_ID)
+ if (musb->xceiv && musb->xceiv->last_event == USB_EVENT_ID)
musb_platform_set_vbus(musb, 1);
pm_runtime_mark_last_busy(musb->controller);
@@ -1897,9 +1900,13 @@ static int musb_gadget_stop(struct usb_gadget *g)
(void) musb_gadget_vbus_draw(&musb->g, 0);
- musb->xceiv->otg->state = OTG_STATE_UNDEFINED;
+ musb_set_state(musb, OTG_STATE_UNDEFINED);
musb_stop(musb);
- otg_set_peripheral(musb->xceiv->otg, NULL);
+
+ if (musb->xceiv)
+ otg_set_peripheral(musb->xceiv->otg, NULL);
+ else
+ phy_set_mode(musb->phy, PHY_MODE_INVALID);
musb->is_active = 0;
musb->gadget_driver = NULL;
@@ -1926,7 +1933,7 @@ static int musb_gadget_stop(struct usb_gadget *g)
void musb_g_resume(struct musb *musb)
{
musb->is_suspended = 0;
- switch (musb->xceiv->otg->state) {
+ switch (musb_get_state(musb)) {
case OTG_STATE_B_IDLE:
break;
case OTG_STATE_B_WAIT_ACON:
@@ -1940,7 +1947,7 @@ void musb_g_resume(struct musb *musb)
break;
default:
WARNING("unhandled RESUME transition (%s)\n",
- usb_otg_state_string(musb->xceiv->otg->state));
+ musb_otg_state_string(musb));
}
}
@@ -1952,10 +1959,10 @@ void musb_g_suspend(struct musb *musb)
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
musb_dbg(musb, "musb_g_suspend: devctl %02x", devctl);
- switch (musb->xceiv->otg->state) {
+ switch (musb_get_state(musb)) {
case OTG_STATE_B_IDLE:
if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
- musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL;
+ musb_set_state(musb, OTG_STATE_B_PERIPHERAL);
break;
case OTG_STATE_B_PERIPHERAL:
musb->is_suspended = 1;
@@ -1970,7 +1977,7 @@ void musb_g_suspend(struct musb *musb)
* A_PERIPHERAL may need care too
*/
WARNING("unhandled SUSPEND transition (%s)",
- usb_otg_state_string(musb->xceiv->otg->state));
+ musb_otg_state_string(musb));
}
}
@@ -2001,22 +2008,22 @@ void musb_g_disconnect(struct musb *musb)
spin_lock(&musb->lock);
}
- switch (musb->xceiv->otg->state) {
+ switch (musb_get_state(musb)) {
default:
musb_dbg(musb, "Unhandled disconnect %s, setting a_idle",
- usb_otg_state_string(musb->xceiv->otg->state));
- musb->xceiv->otg->state = OTG_STATE_A_IDLE;
+ musb_otg_state_string(musb));
+ musb_set_state(musb, OTG_STATE_A_IDLE);
MUSB_HST_MODE(musb);
break;
case OTG_STATE_A_PERIPHERAL:
- musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON;
+ musb_set_state(musb, OTG_STATE_A_WAIT_BCON);
MUSB_HST_MODE(musb);
break;
case OTG_STATE_B_WAIT_ACON:
case OTG_STATE_B_HOST:
case OTG_STATE_B_PERIPHERAL:
case OTG_STATE_B_IDLE:
- musb->xceiv->otg->state = OTG_STATE_B_IDLE;
+ musb_set_state(musb, OTG_STATE_B_IDLE);
break;
case OTG_STATE_B_SRP_INIT:
break;
@@ -2080,13 +2087,13 @@ __acquires(musb->lock)
* In that case, do not rely on devctl for setting
* peripheral mode.
*/
- musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL;
+ musb_set_state(musb, OTG_STATE_B_PERIPHERAL);
musb->g.is_a_peripheral = 0;
} else if (devctl & MUSB_DEVCTL_BDEVICE) {
- musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL;
+ musb_set_state(musb, OTG_STATE_B_PERIPHERAL);
musb->g.is_a_peripheral = 0;
} else {
- musb->xceiv->otg->state = OTG_STATE_A_PERIPHERAL;
+ musb_set_state(musb, OTG_STATE_A_PERIPHERAL);
musb->g.is_a_peripheral = 1;
}