diff options
Diffstat (limited to 'drivers/usb/musb/musb_core.c')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 54 |
1 files changed, 25 insertions, 29 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index fca288bbc800..d8bae6ca8904 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -594,11 +594,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | MUSB_PORT_STAT_RESUME; musb->rh_timer = jiffies + msecs_to_jiffies(USB_RESUME_TIMEOUT); - musb->need_finish_resume = 1; - musb->xceiv->otg->state = OTG_STATE_A_HOST; musb->is_active = 1; musb_host_resume_root_hub(musb); + schedule_delayed_work(&musb->finish_resume_work, + msecs_to_jiffies(USB_RESUME_TIMEOUT)); break; case OTG_STATE_B_WAIT_ACON: musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; @@ -1040,16 +1040,6 @@ static void musb_enable_interrupts(struct musb *musb) } -static void musb_generic_disable(struct musb *musb) -{ - void __iomem *mbase = musb->mregs; - - musb_disable_interrupts(musb); - - /* off */ - musb_writeb(mbase, MUSB_DEVCTL, 0); -} - /* * Program the HDRC to start (enable interrupts, dma, etc.). */ @@ -1106,8 +1096,8 @@ void musb_stop(struct musb *musb) { /* stop IRQs, timers, ... */ musb_platform_disable(musb); - musb_generic_disable(musb); - musb_dbg(musb, "HDRC disabled"); + musb_disable_interrupts(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); /* FIXME * - mark host and/or peripheral drivers unusable/inactive @@ -1879,6 +1869,7 @@ static void musb_pm_runtime_check_session(struct musb *musb) return; } + /* fall through */ case MUSB_QUIRK_A_DISCONNECT_19: if (musb->quirk_retries--) { musb_dbg(musb, @@ -1925,6 +1916,14 @@ static void musb_pm_runtime_check_session(struct musb *musb) static void musb_irq_work(struct work_struct *data) { struct musb *musb = container_of(data, struct musb, irq_work.work); + int error; + + error = pm_runtime_get_sync(musb->controller); + if (error < 0) { + dev_err(musb->controller, "Could not enable: %i\n", error); + + return; + } musb_pm_runtime_check_session(musb); @@ -1932,6 +1931,9 @@ static void musb_irq_work(struct work_struct *data) musb->xceiv_old_state = musb->xceiv->otg->state; sysfs_notify(&musb->controller->kobj, NULL, "mode"); } + + pm_runtime_mark_last_busy(musb->controller); + pm_runtime_put_autosuspend(musb->controller); } static void musb_recover_from_babble(struct musb *musb) @@ -2312,7 +2314,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) /* be sure interrupts are disabled before connecting ISR */ musb_platform_disable(musb); - musb_generic_disable(musb); + musb_disable_interrupts(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); /* Init IRQ workqueue before request_irq */ INIT_DELAYED_WORK(&musb->irq_work, musb_irq_work); @@ -2486,11 +2489,13 @@ static int musb_remove(struct platform_device *pdev) pm_runtime_get_sync(musb->controller); musb_host_cleanup(musb); musb_gadget_cleanup(musb); + spin_lock_irqsave(&musb->lock, flags); musb_platform_disable(musb); - musb_generic_disable(musb); - spin_unlock_irqrestore(&musb->lock, flags); + musb_disable_interrupts(musb); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + spin_unlock_irqrestore(&musb->lock, flags); + pm_runtime_dont_use_autosuspend(musb->controller); pm_runtime_put_sync(musb->controller); pm_runtime_disable(musb->controller); @@ -2665,7 +2670,9 @@ static int musb_suspend(struct device *dev) unsigned long flags; musb_platform_disable(musb); - musb_generic_disable(musb); + musb_disable_interrupts(musb); + if (!(musb->io.quirks & MUSB_PRESERVE_SESSION)) + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); WARN_ON(!list_empty(&musb->pending_list)); spin_lock_irqsave(&musb->lock, flags); @@ -2710,11 +2717,6 @@ static int musb_resume(struct device *dev) mask = MUSB_DEVCTL_BDEVICE | MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV; if ((devctl & mask) != (musb->context.devctl & mask)) musb->port1_status = 0; - if (musb->need_finish_resume) { - musb->need_finish_resume = 0; - schedule_delayed_work(&musb->finish_resume_work, - msecs_to_jiffies(USB_RESUME_TIMEOUT)); - } /* * The USB HUB code expects the device to be in RPM_ACTIVE once it came @@ -2766,12 +2768,6 @@ static int musb_runtime_resume(struct device *dev) musb_restore_context(musb); - if (musb->need_finish_resume) { - musb->need_finish_resume = 0; - schedule_delayed_work(&musb->finish_resume_work, - msecs_to_jiffies(USB_RESUME_TIMEOUT)); - } - spin_lock_irqsave(&musb->lock, flags); error = musb_run_resume_work(musb); if (error) |