musb_core: don't call musb_platform_exit() twice
[pandora-kernel.git] / drivers / usb / musb / musb_core.c
index b4bbf8f..508fd58 100644 (file)
@@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
                                u8 devctl, u8 power)
 {
        irqreturn_t handled = IRQ_NONE;
-       void __iomem *mbase = musb->mregs;
 
        DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
                int_usb);
@@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
 
                if (devctl & MUSB_DEVCTL_HM) {
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
+                       void __iomem *mbase = musb->mregs;
+
                        switch (musb->xceiv->state) {
                        case OTG_STATE_A_SUSPEND:
                                /* remote wakeup?  later, GetPortStatus
@@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        /* see manual for the order of the tests */
        if (int_usb & MUSB_INTR_SESSREQ) {
+               void __iomem *mbase = musb->mregs;
+
                DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb));
 
                /* IRQ arrives from ID pin sense or (later, if VBUS power
@@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
                case OTG_STATE_A_WAIT_BCON:
                case OTG_STATE_A_WAIT_VRISE:
                        if (musb->vbuserr_retry) {
+                               void __iomem *mbase = musb->mregs;
+
                                musb->vbuserr_retry--;
                                ignore = 1;
                                devctl |= MUSB_DEVCTL_SESSION;
@@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
 
        if (int_usb & MUSB_INTR_CONNECT) {
                struct usb_hcd *hcd = musb_to_hcd(musb);
+               void __iomem *mbase = musb->mregs;
 
                handled = IRQ_HANDLED;
                musb->is_active = 1;
@@ -959,10 +965,8 @@ static void musb_shutdown(struct platform_device *pdev)
        spin_lock_irqsave(&musb->lock, flags);
        musb_platform_disable(musb);
        musb_generic_disable(musb);
-       if (musb->clock) {
+       if (musb->clock)
                clk_put(musb->clock);
-               musb->clock = NULL;
-       }
        spin_unlock_irqrestore(&musb->lock, flags);
 
        /* FIXME power down */
@@ -1847,15 +1851,6 @@ static void musb_free(struct musb *musb)
        put_device(musb->xceiv->dev);
 #endif
 
-       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-       musb_platform_exit(musb);
-       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-
-       if (musb->clock) {
-               clk_disable(musb->clock);
-               clk_put(musb->clock);
-       }
-
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        usb_put_hcd(musb_to_hcd(musb));
 #else
@@ -2007,7 +2002,6 @@ bad_config:
        /* host side needs more setup */
        if (is_host_enabled(musb)) {
                struct usb_hcd  *hcd = musb_to_hcd(musb);
-               u8 busctl;
 
                otg_set_host(musb->xceiv, &hcd->self);
 
@@ -2018,9 +2012,9 @@ bad_config:
 
                /* program PHY to use external vBus if required */
                if (plat->extvbus) {
-                       busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL);
+                       u8 busctl = musb_read_ulpi_buscontrol(musb->mregs);
                        busctl |= MUSB_ULPI_USE_EXTVBUS;
-                       musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl);
+                       musb_write_ulpi_buscontrol(musb->mregs, busctl);
                }
        }
 
@@ -2034,8 +2028,6 @@ bad_config:
                musb->xceiv->state = OTG_STATE_A_IDLE;
 
                status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
-               if (status)
-                       goto fail;
 
                DBG(1, "%s mode, status %d, devctl %02x %c\n",
                        "HOST", status,
@@ -2050,8 +2042,6 @@ bad_config:
                musb->xceiv->state = OTG_STATE_B_IDLE;
 
                status = musb_gadget_setup(musb);
-               if (status)
-                       goto fail;
 
                DBG(1, "%s mode, status %d, dev%02x\n",
                        is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
@@ -2059,12 +2049,14 @@ bad_config:
                        musb_readb(musb->mregs, MUSB_DEVCTL));
 
        }
+       if (status < 0)
+               goto fail2;
 
 #ifdef CONFIG_SYSFS
        status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
-#endif
        if (status)
                goto fail2;
+#endif
 
        dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
                        ({char *s;
@@ -2127,7 +2119,6 @@ static int __init musb_probe(struct platform_device *pdev)
        /* clobbered by use_dma=n */
        orig_dma_mask = dev->dma_mask;
 #endif
-
        status = musb_init_controller(dev, irq, base);
        if (status < 0)
                iounmap(base);
@@ -2150,6 +2141,10 @@ static int __exit musb_remove(struct platform_device *pdev)
        if (musb->board_mode == MUSB_HOST)
                usb_remove_hcd(musb_to_hcd(musb));
 #endif
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+       musb_platform_exit(musb);
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+
        musb_free(musb);
        iounmap(ctrl_base);
        device_init_wakeup(&pdev->dev, 0);
@@ -2171,6 +2166,7 @@ void musb_save_context(struct musb *musb)
        if (is_host_enabled(musb)) {
                musb_context.frame = musb_readw(musb_base, MUSB_FRAME);
                musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
+               musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
        }
        musb_context.power = musb_readb(musb_base, MUSB_POWER);
        musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
@@ -2242,6 +2238,7 @@ void musb_restore_context(struct musb *musb)
        if (is_host_enabled(musb)) {
                musb_writew(musb_base, MUSB_FRAME, musb_context.frame);
                musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode);
+               musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl);
        }
        musb_writeb(musb_base, MUSB_POWER, musb_context.power);
        musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe);