Loading drivers/usb/gadget/ci13xxx_msm.c +16 −0 Original line number Diff line number Diff line Loading @@ -197,6 +197,21 @@ static bool ci13xxx_msm_in_lpm(struct ci13xxx *udc) return (atomic_read(&otg->in_lpm) != 0); } static void ci13xxx_msm_set_fpr_flag(struct ci13xxx *udc) { struct msm_otg *otg; if (udc == NULL) return; if (udc->transceiver == NULL) return; otg = container_of(udc->transceiver, struct msm_otg, phy); atomic_set(&otg->set_fpr_with_lpm_exit, 1); } static irqreturn_t ci13xxx_msm_resume_irq(int irq, void *data) { struct ci13xxx *udc = _udc; Loading @@ -220,6 +235,7 @@ static struct ci13xxx_udc_driver ci13xxx_msm_udc_driver = { .nz_itc = 0, .notify_event = ci13xxx_msm_notify_event, .in_lpm = ci13xxx_msm_in_lpm, .set_fpr_flag = ci13xxx_msm_set_fpr_flag, }; static int ci13xxx_msm_install_wake_gpio(struct platform_device *pdev, Loading drivers/usb/gadget/ci13xxx_udc.c +26 −7 Original line number Diff line number Diff line Loading @@ -1612,6 +1612,7 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget) { struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); unsigned long flags; bool skip_fpr = false; int ret = 0; trace(); Loading @@ -1624,19 +1625,37 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget) } spin_unlock_irqrestore(udc->lock, flags); if ((udc->udc_driver->in_lpm != NULL) && (udc->udc_driver->in_lpm(udc))) { if (udc->udc_driver->set_fpr_flag) { /* When USB HW is in low-power mode we set a flag * for the OTG layer to set the FPR bit during the * low-power mode mode exit sequence. */ udc->udc_driver->set_fpr_flag(udc); skip_fpr = true; } } udc->udc_driver->notify_event(udc, CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT); if (udc->transceiver) usb_phy_set_suspend(udc->transceiver, 0); while (udc->udc_driver->in_lpm(udc)) usleep(1); spin_lock_irqsave(udc->lock, flags); if (!skip_fpr) { if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) { ret = -EINVAL; dbg_trace("port is not suspended\n"); goto out; } hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR); } out: spin_unlock_irqrestore(udc->lock, flags); return ret; Loading Loading @@ -1970,7 +1989,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) } /* MSM Specific: updating the request as required for * SPS mode. Enable MSM proprietary DMA engine acording * SPS mode. Enable MSM DMA engine acording * to the UDC private data in the request. */ if (CI13XX_REQ_VENDOR_ID(mReq->req.udc_priv) == MSM_VENDOR_ID) { Loading Loading @@ -2218,7 +2237,7 @@ __acquires(mEp->lock) struct ci13xxx_req, queue); list_del_init(&mReq->queue); /* MSM Specific: Clear end point proprietary register */ /* MSM Specific: Clear end point specific register */ if (CI13XX_REQ_VENDOR_ID(mReq->req.udc_priv) == MSM_VENDOR_ID) { if (mReq->req.udc_priv & MSM_SPS_MODE) { val = hw_cread(CAP_ENDPTPIPEID + Loading drivers/usb/gadget/ci13xxx_udc.h +1 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,7 @@ struct ci13xxx_udc_driver { void (*notify_event) (struct ci13xxx *udc, unsigned event); bool (*in_lpm) (struct ci13xxx *udc); void (*set_fpr_flag) (struct ci13xxx *udc); }; /* CI13XXX UDC descriptor & global resources */ Loading drivers/usb/phy/phy-msm-usb.c +6 −3 Original line number Diff line number Diff line Loading @@ -1206,9 +1206,10 @@ static int msm_otg_resume(struct msm_otg *motg) is_remote_wakeup = in_device_mode && bus_is_suspended; if (is_remote_wakeup && pdata->rw_during_lpm_workaround) { /* * In some targets there is a HW issue with remote wakeup if (is_remote_wakeup && (atomic_read(&(motg->set_fpr_with_lpm_exit)) || pdata->rw_during_lpm_workaround)) { /* In some targets there is a HW issue with remote wakeup * during low-power mode. As a workaround, the FPR bit * is written simultaneously with the clearing of the * PHCD bit. Loading @@ -1217,6 +1218,8 @@ static int msm_otg_resume(struct msm_otg *motg) (readl_relaxed(USB_PORTSC) & ~PORTSC_PHCD) | PORTSC_FPR_MASK, USB_PORTSC); atomic_set(&(motg->set_fpr_with_lpm_exit), 0); } else { writel_relaxed(readl_relaxed(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); Loading include/linux/usb/msm_hsusb.h +7 −3 Original line number Diff line number Diff line Loading @@ -230,9 +230,12 @@ enum usb_vdd_value { * @l1_supported: enable link power management support. * @dpdm_pulldown_added: Indicates whether pull down resistors are * connected on data lines or not. * @vddmin_gpio: dedictaed gpio in the platform that is used * for pullup the D+ line in case of bus suspend * with phy retention. * @vddmin_gpio: dedictaed gpio in the platform that is used for * pullup the D+ line in case of bus suspend with * phy retention. * @rw_during_lpm_workaround: Determines whether remote-wakeup * during low-power mode workaround will be * applied. */ struct msm_otg_platform_data { int *phy_init_seq; Loading Loading @@ -383,6 +386,7 @@ struct msm_otg { bool sm_work_pending; atomic_t pm_suspended; atomic_t in_lpm; atomic_t set_fpr_with_lpm_exit; int async_int; unsigned cur_power; struct delayed_work chg_work; Loading Loading
drivers/usb/gadget/ci13xxx_msm.c +16 −0 Original line number Diff line number Diff line Loading @@ -197,6 +197,21 @@ static bool ci13xxx_msm_in_lpm(struct ci13xxx *udc) return (atomic_read(&otg->in_lpm) != 0); } static void ci13xxx_msm_set_fpr_flag(struct ci13xxx *udc) { struct msm_otg *otg; if (udc == NULL) return; if (udc->transceiver == NULL) return; otg = container_of(udc->transceiver, struct msm_otg, phy); atomic_set(&otg->set_fpr_with_lpm_exit, 1); } static irqreturn_t ci13xxx_msm_resume_irq(int irq, void *data) { struct ci13xxx *udc = _udc; Loading @@ -220,6 +235,7 @@ static struct ci13xxx_udc_driver ci13xxx_msm_udc_driver = { .nz_itc = 0, .notify_event = ci13xxx_msm_notify_event, .in_lpm = ci13xxx_msm_in_lpm, .set_fpr_flag = ci13xxx_msm_set_fpr_flag, }; static int ci13xxx_msm_install_wake_gpio(struct platform_device *pdev, Loading
drivers/usb/gadget/ci13xxx_udc.c +26 −7 Original line number Diff line number Diff line Loading @@ -1612,6 +1612,7 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget) { struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); unsigned long flags; bool skip_fpr = false; int ret = 0; trace(); Loading @@ -1624,19 +1625,37 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget) } spin_unlock_irqrestore(udc->lock, flags); if ((udc->udc_driver->in_lpm != NULL) && (udc->udc_driver->in_lpm(udc))) { if (udc->udc_driver->set_fpr_flag) { /* When USB HW is in low-power mode we set a flag * for the OTG layer to set the FPR bit during the * low-power mode mode exit sequence. */ udc->udc_driver->set_fpr_flag(udc); skip_fpr = true; } } udc->udc_driver->notify_event(udc, CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT); if (udc->transceiver) usb_phy_set_suspend(udc->transceiver, 0); while (udc->udc_driver->in_lpm(udc)) usleep(1); spin_lock_irqsave(udc->lock, flags); if (!skip_fpr) { if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) { ret = -EINVAL; dbg_trace("port is not suspended\n"); goto out; } hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR); } out: spin_unlock_irqrestore(udc->lock, flags); return ret; Loading Loading @@ -1970,7 +1989,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) } /* MSM Specific: updating the request as required for * SPS mode. Enable MSM proprietary DMA engine acording * SPS mode. Enable MSM DMA engine acording * to the UDC private data in the request. */ if (CI13XX_REQ_VENDOR_ID(mReq->req.udc_priv) == MSM_VENDOR_ID) { Loading Loading @@ -2218,7 +2237,7 @@ __acquires(mEp->lock) struct ci13xxx_req, queue); list_del_init(&mReq->queue); /* MSM Specific: Clear end point proprietary register */ /* MSM Specific: Clear end point specific register */ if (CI13XX_REQ_VENDOR_ID(mReq->req.udc_priv) == MSM_VENDOR_ID) { if (mReq->req.udc_priv & MSM_SPS_MODE) { val = hw_cread(CAP_ENDPTPIPEID + Loading
drivers/usb/gadget/ci13xxx_udc.h +1 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,7 @@ struct ci13xxx_udc_driver { void (*notify_event) (struct ci13xxx *udc, unsigned event); bool (*in_lpm) (struct ci13xxx *udc); void (*set_fpr_flag) (struct ci13xxx *udc); }; /* CI13XXX UDC descriptor & global resources */ Loading
drivers/usb/phy/phy-msm-usb.c +6 −3 Original line number Diff line number Diff line Loading @@ -1206,9 +1206,10 @@ static int msm_otg_resume(struct msm_otg *motg) is_remote_wakeup = in_device_mode && bus_is_suspended; if (is_remote_wakeup && pdata->rw_during_lpm_workaround) { /* * In some targets there is a HW issue with remote wakeup if (is_remote_wakeup && (atomic_read(&(motg->set_fpr_with_lpm_exit)) || pdata->rw_during_lpm_workaround)) { /* In some targets there is a HW issue with remote wakeup * during low-power mode. As a workaround, the FPR bit * is written simultaneously with the clearing of the * PHCD bit. Loading @@ -1217,6 +1218,8 @@ static int msm_otg_resume(struct msm_otg *motg) (readl_relaxed(USB_PORTSC) & ~PORTSC_PHCD) | PORTSC_FPR_MASK, USB_PORTSC); atomic_set(&(motg->set_fpr_with_lpm_exit), 0); } else { writel_relaxed(readl_relaxed(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); Loading
include/linux/usb/msm_hsusb.h +7 −3 Original line number Diff line number Diff line Loading @@ -230,9 +230,12 @@ enum usb_vdd_value { * @l1_supported: enable link power management support. * @dpdm_pulldown_added: Indicates whether pull down resistors are * connected on data lines or not. * @vddmin_gpio: dedictaed gpio in the platform that is used * for pullup the D+ line in case of bus suspend * with phy retention. * @vddmin_gpio: dedictaed gpio in the platform that is used for * pullup the D+ line in case of bus suspend with * phy retention. * @rw_during_lpm_workaround: Determines whether remote-wakeup * during low-power mode workaround will be * applied. */ struct msm_otg_platform_data { int *phy_init_seq; Loading Loading @@ -383,6 +386,7 @@ struct msm_otg { bool sm_work_pending; atomic_t pm_suspended; atomic_t in_lpm; atomic_t set_fpr_with_lpm_exit; int async_int; unsigned cur_power; struct delayed_work chg_work; Loading