musb: proper hookup to transceiver drivers

Let the otg_transceiver in MUSB be managed by an external driver;
don't assume it's integrated.  OMAP3 chips need it to be external,
and there may be ways to interact with the transceiver which add
functionality to the system.

Platform init code is responsible for setting up the transeciver,
probably using the NOP transceiver for integrated transceivers.
External ones will use whatever the board init code provided,
such as twl4030 or something more hands-off.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index bc197b28..8dfad11 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1406,7 +1406,7 @@
 
 	spin_lock_irqsave(&musb->lock, flags);
 
-	switch (musb->xceiv.state) {
+	switch (musb->xceiv->state) {
 	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
@@ -1508,9 +1508,9 @@
 {
 	struct musb	*musb = gadget_to_musb(gadget);
 
-	if (!musb->xceiv.set_power)
+	if (!musb->xceiv->set_power)
 		return -EOPNOTSUPP;
-	return otg_set_power(&musb->xceiv, mA);
+	return otg_set_power(musb->xceiv, mA);
 }
 
 static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on)
@@ -1733,11 +1733,7 @@
 
 		spin_lock_irqsave(&musb->lock, flags);
 
-		/* REVISIT always use otg_set_peripheral(), handling
-		 * issues including the root hub one below ...
-		 */
-		musb->xceiv.gadget = &musb->g;
-		musb->xceiv.state = OTG_STATE_B_IDLE;
+		otg_set_peripheral(musb->xceiv, &musb->g);
 		musb->is_active = 1;
 
 		/* FIXME this ignores the softconnect flag.  Drivers are
@@ -1749,6 +1745,8 @@
 		if (!is_otg_enabled(musb))
 			musb_start(musb);
 
+		otg_set_peripheral(musb->xceiv, &musb->g);
+
 		spin_unlock_irqrestore(&musb->lock, flags);
 
 		if (is_otg_enabled(musb)) {
@@ -1762,8 +1760,7 @@
 			if (retval < 0) {
 				DBG(1, "add_hcd failed, %d\n", retval);
 				spin_lock_irqsave(&musb->lock, flags);
-				musb->xceiv.gadget = NULL;
-				musb->xceiv.state = OTG_STATE_UNDEFINED;
+				otg_set_peripheral(musb->xceiv, NULL);
 				musb->gadget_driver = NULL;
 				musb->g.dev.driver = NULL;
 				spin_unlock_irqrestore(&musb->lock, flags);
@@ -1846,8 +1843,9 @@
 
 		(void) musb_gadget_vbus_draw(&musb->g, 0);
 
-		musb->xceiv.state = OTG_STATE_UNDEFINED;
+		musb->xceiv->state = OTG_STATE_UNDEFINED;
 		stop_activity(musb, driver);
+		otg_set_peripheral(musb->xceiv, NULL);
 
 		DBG(3, "unregistering driver %s\n", driver->function);
 		spin_unlock_irqrestore(&musb->lock, flags);
@@ -1883,7 +1881,7 @@
 void musb_g_resume(struct musb *musb)
 {
 	musb->is_suspended = 0;
-	switch (musb->xceiv.state) {
+	switch (musb->xceiv->state) {
 	case OTG_STATE_B_IDLE:
 		break;
 	case OTG_STATE_B_WAIT_ACON:
@@ -1909,10 +1907,10 @@
 	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
 	DBG(3, "devctl %02x\n", devctl);
 
-	switch (musb->xceiv.state) {
+	switch (musb->xceiv->state) {
 	case OTG_STATE_B_IDLE:
 		if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
-			musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
+			musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
 		break;
 	case OTG_STATE_B_PERIPHERAL:
 		musb->is_suspended = 1;
@@ -1958,22 +1956,22 @@
 		spin_lock(&musb->lock);
 	}
 
-	switch (musb->xceiv.state) {
+	switch (musb->xceiv->state) {
 	default:
 #ifdef	CONFIG_USB_MUSB_OTG
 		DBG(2, "Unhandled disconnect %s, setting a_idle\n",
 			otg_state_string(musb));
-		musb->xceiv.state = OTG_STATE_A_IDLE;
+		musb->xceiv->state = OTG_STATE_A_IDLE;
 		break;
 	case OTG_STATE_A_PERIPHERAL:
-		musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
+		musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
 		break;
 	case OTG_STATE_B_WAIT_ACON:
 	case OTG_STATE_B_HOST:
 #endif
 	case OTG_STATE_B_PERIPHERAL:
 	case OTG_STATE_B_IDLE:
-		musb->xceiv.state = OTG_STATE_B_IDLE;
+		musb->xceiv->state = OTG_STATE_B_IDLE;
 		break;
 	case OTG_STATE_B_SRP_INIT:
 		break;
@@ -2029,10 +2027,10 @@
 	 * or else after HNP, as A-Device
 	 */
 	if (devctl & MUSB_DEVCTL_BDEVICE) {
-		musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
+		musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
 		musb->g.is_a_peripheral = 0;
 	} else if (is_otg_enabled(musb)) {
-		musb->xceiv.state = OTG_STATE_A_PERIPHERAL;
+		musb->xceiv->state = OTG_STATE_A_PERIPHERAL;
 		musb->g.is_a_peripheral = 1;
 	} else
 		WARN_ON(1);