static int msm_otg_set_suspend(struct otg_transceiver *xceiv, int suspend) { struct msm_otg *dev = container_of(xceiv, struct msm_otg, otg); if (!dev || (dev != the_msm_otg)) return -ENODEV; if (suspend) msm_otg_suspend(dev); else { unsigned long timeout; disable_irq(dev->irq); msm_otg_resume(dev); if (!is_phy_clk_disabled()) goto out; timeout = jiffies + msecs_to_jiffies(500); enable_phy_clk(); while (is_phy_clk_disabled()) { if (time_after(jiffies, timeout)) { pr_err("%s: Unable to wakeup phy\n", __func__); otg_reset(dev); break; } msleep(1); } out: enable_irq(dev->irq); } return 0; }
static int msm_otg_set_suspend(struct otg_transceiver *xceiv, int suspend) { struct msm_otg *dev = container_of(xceiv, struct msm_otg, otg); enum usb_otg_state state; unsigned long flags; if (!dev || (dev != the_msm_otg)) return -ENODEV; spin_lock_irqsave(&dev->lock, flags); state = dev->otg.state; spin_unlock_irqrestore(&dev->lock, flags); pr_debug("suspend request in state: %s\n", state_string(state)); if (suspend) { switch (state) { case OTG_STATE_A_HOST: clear_bit(A_BUS_REQ, &dev->inputs); wake_lock(&dev->wlock); queue_work(dev->wq, &dev->sm_work); break; case OTG_STATE_B_PERIPHERAL: if (xceiv->gadget->b_hnp_enable) { set_bit(A_BUS_SUSPEND, &dev->inputs); set_bit(B_BUS_REQ, &dev->inputs); wake_lock(&dev->wlock); queue_work(dev->wq, &dev->sm_work); } break; case OTG_STATE_A_PERIPHERAL: msm_otg_start_timer(dev, TA_BIDL_ADIS, A_BIDL_ADIS); break; default: break; } } else { unsigned long timeout; switch (state) { case OTG_STATE_A_PERIPHERAL: /* A-peripheral observed activity on bus. * clear A_BIDL_ADIS timer. */ msm_otg_del_timer(dev); break; case OTG_STATE_A_SUSPEND: /* Remote wakeup or resume */ set_bit(A_BUS_REQ, &dev->inputs); spin_lock_irqsave(&dev->lock, flags); dev->otg.state = OTG_STATE_A_HOST; spin_unlock_irqrestore(&dev->lock, flags); break; default: break; } if (suspend == atomic_read(&dev->in_lpm)) return 0; disable_irq(dev->irq); if (dev->pmic_notif_supp) dev->pdata->pmic_enable_ldo(1); msm_otg_resume(dev); if (!is_phy_clk_disabled()) goto out; timeout = jiffies + usecs_to_jiffies(100); enable_phy_clk(); while (is_phy_clk_disabled()) { if (time_after(jiffies, timeout)) { pr_err("%s: Unable to wakeup phy\n", __func__); /* Reset both phy and link */ otg_reset(dev, 1); break; } udelay(10); } out: enable_irq(dev->irq); } return 0; }