Loading drivers/bus/mhi/controllers/mhi_arch_qcom.c +0 −3 Original line number Diff line number Diff line Loading @@ -292,9 +292,6 @@ static void mhi_boot_monitor(void *data, async_cookie_t cookie) if (boot_dev) mhi_unprepare_from_transfer(boot_dev); /* enable link inactivity timer to start auto suspend */ msm_pcie_l1ss_timeout_enable(mhi_dev->pci_dev); if (!mhi_dev->drv_supported || arch_info->drv_connected) pm_runtime_allow(&mhi_dev->pci_dev->dev); } Loading drivers/bus/mhi/controllers/mhi_qcom.c +53 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,47 @@ int mhi_system_suspend(struct device *dev) return ret; } static int mhi_force_suspend(struct mhi_controller *mhi_cntrl) { int ret = -EIO; const u32 delayms = 100; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); int itr = DIV_ROUND_UP(mhi_cntrl->timeout_ms, delayms); MHI_LOG("Entered\n"); mutex_lock(&mhi_cntrl->pm_mutex); for (; itr; itr--) { /* * This function get called soon as device entered mission mode * so most of the channels are still in disabled state. However, * sbl channels are active and clients could be trying to close * channels while we trying to suspend the link. So, we need to * re-try if MHI is busy */ ret = mhi_pm_suspend(mhi_cntrl); if (!ret || ret != -EBUSY) break; MHI_LOG("MHI busy, sleeping and retry\n"); msleep(delayms); } if (ret) goto exit_force_suspend; mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND; ret = mhi_arch_link_suspend(mhi_cntrl); exit_force_suspend: MHI_LOG("Force suspend ret with %d\n", ret); mutex_unlock(&mhi_cntrl->pm_mutex); return ret; } /* checks if link is down */ static int mhi_link_status(struct mhi_controller *mhi_cntrl, void *priv) { Loading Loading @@ -558,6 +599,7 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl, { struct mhi_dev *mhi_dev = priv; struct device *dev = &mhi_dev->pci_dev->dev; int ret; switch (reason) { case MHI_CB_IDLE: Loading @@ -569,6 +611,17 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl, if (mhi_dev->bw_scale) mhi_dev->bw_scale(mhi_cntrl, mhi_dev); break; case MHI_CB_EE_MISSION_MODE: /* * we need to force a suspend so device can switch to * mission mode pcie phy settings. */ pm_runtime_get(dev); ret = mhi_force_suspend(mhi_cntrl); if (!ret) mhi_runtime_resume(dev); pm_runtime_put(dev); break; default: MHI_ERR("Unhandled cb:0x%x\n", reason); } Loading drivers/bus/mhi/core/mhi_pm.c +14 −12 Original line number Diff line number Diff line Loading @@ -436,27 +436,31 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) MHI_LOG("Processing Mission Mode Transition\n"); /* force MHI to be in M0 state before continuing */ ret = __mhi_device_get_sync(mhi_cntrl); if (ret) return ret; ret = -EIO; write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); write_unlock_irq(&mhi_cntrl->pm_lock); read_lock_bh(&mhi_cntrl->pm_lock); if (!MHI_IN_MISSION_MODE(mhi_cntrl->ee)) goto error_mission_mode; return -EIO; wake_up_all(&mhi_cntrl->state_event); mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_EE_MISSION_MODE); /* force MHI to be in M0 state before continuing */ ret = __mhi_device_get_sync(mhi_cntrl); if (ret) return ret; read_lock_bh(&mhi_cntrl->pm_lock); /* add elements to all HW event rings */ if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { ret = -EIO; goto error_mission_mode; } mhi_event = mhi_cntrl->mhi_event; for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { Loading Loading @@ -490,8 +494,6 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) /* setup sysfs nodes for userspace votes */ mhi_create_vote_sysfs(mhi_cntrl); ret = 0; read_lock_bh(&mhi_cntrl->pm_lock); error_mission_mode: Loading drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +1 −0 Original line number Diff line number Diff line Loading @@ -2259,6 +2259,7 @@ static void ipa_mpm_mhi_status_cb(struct mhi_device *mhi_dev, case MHI_CB_SYS_ERROR: case MHI_CB_FATAL_ERROR: case MHI_CB_BW_REQ: case MHI_CB_EE_MISSION_MODE: IPA_MPM_ERR("unexpected event %d\n", mhi_cb); break; } Loading include/linux/mhi.h +2 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ struct mhi_buf_info; * @MHI_CB_LPM_ENTER: MHI host entered low power mode * @MHI_CB_LPM_EXIT: MHI host about to exit low power mode * @MHI_CB_EE_RDDM: MHI device entered RDDM execution enviornment * @MHI_CB_EE_MISSION_MODE: MHI device entered Mission Mode ee * @MHI_CB_SYS_ERROR: MHI device enter error state (may recover) * @MHI_CB_FATAL_ERROR: MHI device entered fatal error * @MHI_CB_BW_REQ: Received a bandwidth switch request from device Loading @@ -30,6 +31,7 @@ enum MHI_CB { MHI_CB_LPM_ENTER, MHI_CB_LPM_EXIT, MHI_CB_EE_RDDM, MHI_CB_EE_MISSION_MODE, MHI_CB_SYS_ERROR, MHI_CB_FATAL_ERROR, MHI_CB_BW_REQ, Loading Loading
drivers/bus/mhi/controllers/mhi_arch_qcom.c +0 −3 Original line number Diff line number Diff line Loading @@ -292,9 +292,6 @@ static void mhi_boot_monitor(void *data, async_cookie_t cookie) if (boot_dev) mhi_unprepare_from_transfer(boot_dev); /* enable link inactivity timer to start auto suspend */ msm_pcie_l1ss_timeout_enable(mhi_dev->pci_dev); if (!mhi_dev->drv_supported || arch_info->drv_connected) pm_runtime_allow(&mhi_dev->pci_dev->dev); } Loading
drivers/bus/mhi/controllers/mhi_qcom.c +53 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,47 @@ int mhi_system_suspend(struct device *dev) return ret; } static int mhi_force_suspend(struct mhi_controller *mhi_cntrl) { int ret = -EIO; const u32 delayms = 100; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); int itr = DIV_ROUND_UP(mhi_cntrl->timeout_ms, delayms); MHI_LOG("Entered\n"); mutex_lock(&mhi_cntrl->pm_mutex); for (; itr; itr--) { /* * This function get called soon as device entered mission mode * so most of the channels are still in disabled state. However, * sbl channels are active and clients could be trying to close * channels while we trying to suspend the link. So, we need to * re-try if MHI is busy */ ret = mhi_pm_suspend(mhi_cntrl); if (!ret || ret != -EBUSY) break; MHI_LOG("MHI busy, sleeping and retry\n"); msleep(delayms); } if (ret) goto exit_force_suspend; mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND; ret = mhi_arch_link_suspend(mhi_cntrl); exit_force_suspend: MHI_LOG("Force suspend ret with %d\n", ret); mutex_unlock(&mhi_cntrl->pm_mutex); return ret; } /* checks if link is down */ static int mhi_link_status(struct mhi_controller *mhi_cntrl, void *priv) { Loading Loading @@ -558,6 +599,7 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl, { struct mhi_dev *mhi_dev = priv; struct device *dev = &mhi_dev->pci_dev->dev; int ret; switch (reason) { case MHI_CB_IDLE: Loading @@ -569,6 +611,17 @@ static void mhi_status_cb(struct mhi_controller *mhi_cntrl, if (mhi_dev->bw_scale) mhi_dev->bw_scale(mhi_cntrl, mhi_dev); break; case MHI_CB_EE_MISSION_MODE: /* * we need to force a suspend so device can switch to * mission mode pcie phy settings. */ pm_runtime_get(dev); ret = mhi_force_suspend(mhi_cntrl); if (!ret) mhi_runtime_resume(dev); pm_runtime_put(dev); break; default: MHI_ERR("Unhandled cb:0x%x\n", reason); } Loading
drivers/bus/mhi/core/mhi_pm.c +14 −12 Original line number Diff line number Diff line Loading @@ -436,27 +436,31 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) MHI_LOG("Processing Mission Mode Transition\n"); /* force MHI to be in M0 state before continuing */ ret = __mhi_device_get_sync(mhi_cntrl); if (ret) return ret; ret = -EIO; write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); write_unlock_irq(&mhi_cntrl->pm_lock); read_lock_bh(&mhi_cntrl->pm_lock); if (!MHI_IN_MISSION_MODE(mhi_cntrl->ee)) goto error_mission_mode; return -EIO; wake_up_all(&mhi_cntrl->state_event); mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_EE_MISSION_MODE); /* force MHI to be in M0 state before continuing */ ret = __mhi_device_get_sync(mhi_cntrl); if (ret) return ret; read_lock_bh(&mhi_cntrl->pm_lock); /* add elements to all HW event rings */ if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { ret = -EIO; goto error_mission_mode; } mhi_event = mhi_cntrl->mhi_event; for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { Loading Loading @@ -490,8 +494,6 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) /* setup sysfs nodes for userspace votes */ mhi_create_vote_sysfs(mhi_cntrl); ret = 0; read_lock_bh(&mhi_cntrl->pm_lock); error_mission_mode: Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +1 −0 Original line number Diff line number Diff line Loading @@ -2259,6 +2259,7 @@ static void ipa_mpm_mhi_status_cb(struct mhi_device *mhi_dev, case MHI_CB_SYS_ERROR: case MHI_CB_FATAL_ERROR: case MHI_CB_BW_REQ: case MHI_CB_EE_MISSION_MODE: IPA_MPM_ERR("unexpected event %d\n", mhi_cb); break; } Loading
include/linux/mhi.h +2 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ struct mhi_buf_info; * @MHI_CB_LPM_ENTER: MHI host entered low power mode * @MHI_CB_LPM_EXIT: MHI host about to exit low power mode * @MHI_CB_EE_RDDM: MHI device entered RDDM execution enviornment * @MHI_CB_EE_MISSION_MODE: MHI device entered Mission Mode ee * @MHI_CB_SYS_ERROR: MHI device enter error state (may recover) * @MHI_CB_FATAL_ERROR: MHI device entered fatal error * @MHI_CB_BW_REQ: Received a bandwidth switch request from device Loading @@ -30,6 +31,7 @@ enum MHI_CB { MHI_CB_LPM_ENTER, MHI_CB_LPM_EXIT, MHI_CB_EE_RDDM, MHI_CB_EE_MISSION_MODE, MHI_CB_SYS_ERROR, MHI_CB_FATAL_ERROR, MHI_CB_BW_REQ, Loading