Loading drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +49 −25 Original line number Original line Diff line number Diff line Loading @@ -375,12 +375,6 @@ struct ipa_mpm_mhi_driver { bool init_complete; bool init_complete; /* General MPM mutex to protect concurrent update of MPM GSI states */ /* General MPM mutex to protect concurrent update of MPM GSI states */ struct mutex mutex; struct mutex mutex; /* * Mutex to protect IPA clock vote/unvote to make sure IPA isn't double * devoted for concurrency scenarios such as SSR and LPM mode CB * concurrency. */ struct mutex lpm_mutex; /* /* * Mutex to protect mhi_dev update/ access, for concurrency such as * Mutex to protect mhi_dev update/ access, for concurrency such as * 5G SSR and USB disconnect/connect. * 5G SSR and USB disconnect/connect. Loading Loading @@ -1357,7 +1351,6 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx) ipa_mpm_clean_mhip_chan(mhip_idx, dl_cons_chan); ipa_mpm_clean_mhip_chan(mhip_idx, dl_cons_chan); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); if (!ipa_mpm_ctx->md[mhip_idx].in_lpm) { if (!ipa_mpm_ctx->md[mhip_idx].in_lpm) { ipa_mpm_vote_unvote_ipa_clk(CLK_OFF, mhip_idx); ipa_mpm_vote_unvote_ipa_clk(CLK_OFF, mhip_idx); /* while in modem shutdown scenarios such as SSR, no explicit /* while in modem shutdown scenarios such as SSR, no explicit Loading @@ -1365,10 +1358,8 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx) */ */ ipa_mpm_ctx->md[mhip_idx].in_lpm = true; ipa_mpm_ctx->md[mhip_idx].in_lpm = true; } } mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); ipa_mpm_ctx->md[mhip_idx].mhi_dev = NULL; ipa_mpm_ctx->md[mhip_idx].mhi_dev = NULL; ipa_mpm_ctx->md[mhip_idx].init_complete = false; mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); IPA_MPM_FUNC_EXIT(); IPA_MPM_FUNC_EXIT(); } } Loading Loading @@ -1399,6 +1390,18 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, return 0; return 0; } } if (!ipa_mpm_ctx->md[probe_id].init_complete) { /* * SSR might be in progress, dont have to vote/unvote for * IPA clocks as it will be taken care in remove_cb/subsequent * probe. */ IPA_MPM_DBG("SSR in progress, return\n"); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; } mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); IPA_MPM_ERR("PCIe clock vote/unvote = %d probe_id = %d clk_cnt = %d\n", IPA_MPM_ERR("PCIe clock vote/unvote = %d probe_id = %d clk_cnt = %d\n", vote, probe_id, vote, probe_id, atomic_read(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt)); atomic_read(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt)); Loading @@ -1409,7 +1412,6 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, if (result) { if (result) { IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", result, probe_id); result, probe_id); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return result; return result; } } Loading @@ -1423,7 +1425,6 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, IPA_MPM_DBG("probe_id %d PCIE clock already devoted\n", IPA_MPM_DBG("probe_id %d PCIE clock already devoted\n", probe_id); probe_id); WARN_ON(1); WARN_ON(1); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; return 0; } } mhi_device_put(ipa_mpm_ctx->md[probe_id].mhi_dev, MHI_VOTE_BUS); mhi_device_put(ipa_mpm_ctx->md[probe_id].mhi_dev, MHI_VOTE_BUS); Loading @@ -1431,8 +1432,6 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); } } mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return result; return result; } } Loading Loading @@ -1482,11 +1481,9 @@ static int ipa_mpm_start_stop_remote_mhip_chan( return ret; return ret; } } mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); /* For error state, expect modem SSR to recover from error */ /* For error state, expect modem SSR to recover from error */ if (ipa_mpm_ctx->md[probe_id].remote_state == MPM_MHIP_REMOTE_ERR) { if (ipa_mpm_ctx->md[probe_id].remote_state == MPM_MHIP_REMOTE_ERR) { IPA_MPM_ERR("Remote channels in err state for %d\n", probe_id); IPA_MPM_ERR("Remote channels in err state for %d\n", probe_id); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return -EFAULT; return -EFAULT; } } Loading @@ -1497,12 +1494,14 @@ static int ipa_mpm_start_stop_remote_mhip_chan( probe_id); probe_id); } else { } else { ret = mhi_resume_transfer(mhi_dev); ret = mhi_resume_transfer(mhi_dev); mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (ret) if (ret) ipa_mpm_ctx->md[probe_id].remote_state = ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_ERR; MPM_MHIP_REMOTE_ERR; else else ipa_mpm_ctx->md[probe_id].remote_state = ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_START; MPM_MHIP_REMOTE_START; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); } } } else { } else { if (ipa_mpm_ctx->md[probe_id].remote_state == if (ipa_mpm_ctx->md[probe_id].remote_state == Loading @@ -1511,15 +1510,16 @@ static int ipa_mpm_start_stop_remote_mhip_chan( probe_id); probe_id); } else { } else { ret = mhi_pause_transfer(mhi_dev); ret = mhi_pause_transfer(mhi_dev); mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (ret) if (ret) ipa_mpm_ctx->md[probe_id].remote_state = ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_ERR; MPM_MHIP_REMOTE_ERR; else else ipa_mpm_ctx->md[probe_id].remote_state = ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_STOP; MPM_MHIP_REMOTE_STOP; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); } } } } mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return ret; return ret; } } Loading Loading @@ -1563,6 +1563,15 @@ static enum mhip_status_type ipa_mpm_start_stop_mhip_chan( IPA_MPM_ERR("fail to get EP# for idx %d\n", ipa_ep_idx); IPA_MPM_ERR("fail to get EP# for idx %d\n", ipa_ep_idx); return MHIP_STATUS_EP_NOT_FOUND; return MHIP_STATUS_EP_NOT_FOUND; } } mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (!ipa_mpm_ctx->md[probe_id].init_complete) { IPA_MPM_ERR("MHIP probe %d not initialized\n", probe_id); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return MHIP_STATUS_EP_NOT_READY; } mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); ep = &ipa3_ctx->ep[ipa_ep_idx]; ep = &ipa3_ctx->ep[ipa_ep_idx]; if (mhip_chan == IPA_MPM_MHIP_CHAN_UL) { if (mhip_chan == IPA_MPM_MHIP_CHAN_UL) { Loading Loading @@ -1951,10 +1960,8 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_STOP; ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_STOP; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); mutex_lock(&ipa_mpm_ctx->md[probe_id].lpm_mutex); ipa_mpm_vote_unvote_ipa_clk(CLK_ON, probe_id); ipa_mpm_vote_unvote_ipa_clk(CLK_ON, probe_id); ipa_mpm_ctx->md[probe_id].in_lpm = false; ipa_mpm_ctx->md[probe_id].in_lpm = false; mutex_unlock(&ipa_mpm_ctx->md[probe_id].lpm_mutex); IPA_MPM_DBG("ul chan = %d, dl_chan = %d\n", ul_prod, dl_cons); IPA_MPM_DBG("ul chan = %d, dl_chan = %d\n", ul_prod, dl_cons); /* /* Loading Loading @@ -2089,8 +2096,10 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, * to MHI driver. remove_cb will be called eventually when * to MHI driver. remove_cb will be called eventually when * Device side comes from where pending cleanup happens. * Device side comes from where pending cleanup happens. */ */ mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); atomic_inc(&ipa_mpm_ctx->probe_cnt); atomic_inc(&ipa_mpm_ctx->probe_cnt); ipa_mpm_ctx->md[probe_id].init_complete = true; ipa_mpm_ctx->md[probe_id].init_complete = false; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); IPA_MPM_FUNC_EXIT(); IPA_MPM_FUNC_EXIT(); return 0; return 0; } } Loading Loading @@ -2271,8 +2280,6 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, } } atomic_inc(&ipa_mpm_ctx->probe_cnt); atomic_inc(&ipa_mpm_ctx->probe_cnt); ipa_mpm_ctx->md[probe_id].init_complete = true; /* Check if ODL pipe is connected to MHIP DPL pipe before probe */ /* Check if ODL pipe is connected to MHIP DPL pipe before probe */ if (probe_id == IPA_MPM_MHIP_CH_ID_2 && if (probe_id == IPA_MPM_MHIP_CH_ID_2 && ipa3_is_odl_connected()) { ipa3_is_odl_connected()) { Loading @@ -2280,7 +2287,9 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ret = ipa_mpm_set_dma_mode(IPA_CLIENT_MHI_PRIME_DPL_PROD, ret = ipa_mpm_set_dma_mode(IPA_CLIENT_MHI_PRIME_DPL_PROD, IPA_CLIENT_USB_DPL_CONS, false); IPA_CLIENT_USB_DPL_CONS, false); } } mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); ipa_mpm_ctx->md[probe_id].init_complete = true; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); IPA_MPM_FUNC_EXIT(); IPA_MPM_FUNC_EXIT(); return 0; return 0; Loading Loading @@ -2349,6 +2358,11 @@ static void ipa_mpm_mhi_remove_cb(struct mhi_device *mhi_dev) } } IPA_MPM_DBG("remove_cb for mhip_idx = %d", mhip_idx); IPA_MPM_DBG("remove_cb for mhip_idx = %d", mhip_idx); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); ipa_mpm_ctx->md[mhip_idx].init_complete = false; mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); ipa_mpm_mhip_shutdown(mhip_idx); ipa_mpm_mhip_shutdown(mhip_idx); atomic_dec(&ipa_mpm_ctx->probe_cnt); atomic_dec(&ipa_mpm_ctx->probe_cnt); Loading Loading @@ -2387,7 +2401,19 @@ static void ipa_mpm_mhi_status_cb(struct mhi_device *mhi_dev, return; return; } } mutex_lock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); if (!ipa_mpm_ctx->md[mhip_idx].init_complete) { /* * SSR might be in progress, dont have to vote/unvote for * IPA clocks as it will be taken care in remove_cb/subsequent * probe. */ IPA_MPM_DBG("SSR in progress, return\n"); mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); return; } mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); switch (mhi_cb) { switch (mhi_cb) { case MHI_CB_IDLE: case MHI_CB_IDLE: break; break; Loading Loading @@ -2424,7 +2450,6 @@ static void ipa_mpm_mhi_status_cb(struct mhi_device *mhi_dev, IPA_MPM_ERR("unexpected event %d\n", mhi_cb); IPA_MPM_ERR("unexpected event %d\n", mhi_cb); break; break; } } mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); } } static void ipa_mpm_mhip_map_prot(enum ipa_usb_teth_prot prot, static void ipa_mpm_mhip_map_prot(enum ipa_usb_teth_prot prot, Loading Loading @@ -2778,7 +2803,6 @@ static int ipa_mpm_probe(struct platform_device *pdev) for (i = 0; i < IPA_MPM_MHIP_CH_ID_MAX; i++) { for (i = 0; i < IPA_MPM_MHIP_CH_ID_MAX; i++) { mutex_init(&ipa_mpm_ctx->md[i].mutex); mutex_init(&ipa_mpm_ctx->md[i].mutex); mutex_init(&ipa_mpm_ctx->md[i].mhi_mutex); mutex_init(&ipa_mpm_ctx->md[i].mhi_mutex); mutex_init(&ipa_mpm_ctx->md[i].lpm_mutex); } } ipa_mpm_ctx->dev_info.pdev = pdev; ipa_mpm_ctx->dev_info.pdev = pdev; Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +49 −25 Original line number Original line Diff line number Diff line Loading @@ -375,12 +375,6 @@ struct ipa_mpm_mhi_driver { bool init_complete; bool init_complete; /* General MPM mutex to protect concurrent update of MPM GSI states */ /* General MPM mutex to protect concurrent update of MPM GSI states */ struct mutex mutex; struct mutex mutex; /* * Mutex to protect IPA clock vote/unvote to make sure IPA isn't double * devoted for concurrency scenarios such as SSR and LPM mode CB * concurrency. */ struct mutex lpm_mutex; /* /* * Mutex to protect mhi_dev update/ access, for concurrency such as * Mutex to protect mhi_dev update/ access, for concurrency such as * 5G SSR and USB disconnect/connect. * 5G SSR and USB disconnect/connect. Loading Loading @@ -1357,7 +1351,6 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx) ipa_mpm_clean_mhip_chan(mhip_idx, dl_cons_chan); ipa_mpm_clean_mhip_chan(mhip_idx, dl_cons_chan); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); if (!ipa_mpm_ctx->md[mhip_idx].in_lpm) { if (!ipa_mpm_ctx->md[mhip_idx].in_lpm) { ipa_mpm_vote_unvote_ipa_clk(CLK_OFF, mhip_idx); ipa_mpm_vote_unvote_ipa_clk(CLK_OFF, mhip_idx); /* while in modem shutdown scenarios such as SSR, no explicit /* while in modem shutdown scenarios such as SSR, no explicit Loading @@ -1365,10 +1358,8 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx) */ */ ipa_mpm_ctx->md[mhip_idx].in_lpm = true; ipa_mpm_ctx->md[mhip_idx].in_lpm = true; } } mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); ipa_mpm_ctx->md[mhip_idx].mhi_dev = NULL; ipa_mpm_ctx->md[mhip_idx].mhi_dev = NULL; ipa_mpm_ctx->md[mhip_idx].init_complete = false; mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); IPA_MPM_FUNC_EXIT(); IPA_MPM_FUNC_EXIT(); } } Loading Loading @@ -1399,6 +1390,18 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, return 0; return 0; } } if (!ipa_mpm_ctx->md[probe_id].init_complete) { /* * SSR might be in progress, dont have to vote/unvote for * IPA clocks as it will be taken care in remove_cb/subsequent * probe. */ IPA_MPM_DBG("SSR in progress, return\n"); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; } mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); IPA_MPM_ERR("PCIe clock vote/unvote = %d probe_id = %d clk_cnt = %d\n", IPA_MPM_ERR("PCIe clock vote/unvote = %d probe_id = %d clk_cnt = %d\n", vote, probe_id, vote, probe_id, atomic_read(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt)); atomic_read(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt)); Loading @@ -1409,7 +1412,6 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, if (result) { if (result) { IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", result, probe_id); result, probe_id); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return result; return result; } } Loading @@ -1423,7 +1425,6 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, IPA_MPM_DBG("probe_id %d PCIE clock already devoted\n", IPA_MPM_DBG("probe_id %d PCIE clock already devoted\n", probe_id); probe_id); WARN_ON(1); WARN_ON(1); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; return 0; } } mhi_device_put(ipa_mpm_ctx->md[probe_id].mhi_dev, MHI_VOTE_BUS); mhi_device_put(ipa_mpm_ctx->md[probe_id].mhi_dev, MHI_VOTE_BUS); Loading @@ -1431,8 +1432,6 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); } } mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return result; return result; } } Loading Loading @@ -1482,11 +1481,9 @@ static int ipa_mpm_start_stop_remote_mhip_chan( return ret; return ret; } } mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); /* For error state, expect modem SSR to recover from error */ /* For error state, expect modem SSR to recover from error */ if (ipa_mpm_ctx->md[probe_id].remote_state == MPM_MHIP_REMOTE_ERR) { if (ipa_mpm_ctx->md[probe_id].remote_state == MPM_MHIP_REMOTE_ERR) { IPA_MPM_ERR("Remote channels in err state for %d\n", probe_id); IPA_MPM_ERR("Remote channels in err state for %d\n", probe_id); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return -EFAULT; return -EFAULT; } } Loading @@ -1497,12 +1494,14 @@ static int ipa_mpm_start_stop_remote_mhip_chan( probe_id); probe_id); } else { } else { ret = mhi_resume_transfer(mhi_dev); ret = mhi_resume_transfer(mhi_dev); mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (ret) if (ret) ipa_mpm_ctx->md[probe_id].remote_state = ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_ERR; MPM_MHIP_REMOTE_ERR; else else ipa_mpm_ctx->md[probe_id].remote_state = ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_START; MPM_MHIP_REMOTE_START; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); } } } else { } else { if (ipa_mpm_ctx->md[probe_id].remote_state == if (ipa_mpm_ctx->md[probe_id].remote_state == Loading @@ -1511,15 +1510,16 @@ static int ipa_mpm_start_stop_remote_mhip_chan( probe_id); probe_id); } else { } else { ret = mhi_pause_transfer(mhi_dev); ret = mhi_pause_transfer(mhi_dev); mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (ret) if (ret) ipa_mpm_ctx->md[probe_id].remote_state = ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_ERR; MPM_MHIP_REMOTE_ERR; else else ipa_mpm_ctx->md[probe_id].remote_state = ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_STOP; MPM_MHIP_REMOTE_STOP; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); } } } } mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return ret; return ret; } } Loading Loading @@ -1563,6 +1563,15 @@ static enum mhip_status_type ipa_mpm_start_stop_mhip_chan( IPA_MPM_ERR("fail to get EP# for idx %d\n", ipa_ep_idx); IPA_MPM_ERR("fail to get EP# for idx %d\n", ipa_ep_idx); return MHIP_STATUS_EP_NOT_FOUND; return MHIP_STATUS_EP_NOT_FOUND; } } mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (!ipa_mpm_ctx->md[probe_id].init_complete) { IPA_MPM_ERR("MHIP probe %d not initialized\n", probe_id); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return MHIP_STATUS_EP_NOT_READY; } mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); ep = &ipa3_ctx->ep[ipa_ep_idx]; ep = &ipa3_ctx->ep[ipa_ep_idx]; if (mhip_chan == IPA_MPM_MHIP_CHAN_UL) { if (mhip_chan == IPA_MPM_MHIP_CHAN_UL) { Loading Loading @@ -1951,10 +1960,8 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_STOP; ipa_mpm_ctx->md[probe_id].remote_state = MPM_MHIP_REMOTE_STOP; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); mutex_lock(&ipa_mpm_ctx->md[probe_id].lpm_mutex); ipa_mpm_vote_unvote_ipa_clk(CLK_ON, probe_id); ipa_mpm_vote_unvote_ipa_clk(CLK_ON, probe_id); ipa_mpm_ctx->md[probe_id].in_lpm = false; ipa_mpm_ctx->md[probe_id].in_lpm = false; mutex_unlock(&ipa_mpm_ctx->md[probe_id].lpm_mutex); IPA_MPM_DBG("ul chan = %d, dl_chan = %d\n", ul_prod, dl_cons); IPA_MPM_DBG("ul chan = %d, dl_chan = %d\n", ul_prod, dl_cons); /* /* Loading Loading @@ -2089,8 +2096,10 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, * to MHI driver. remove_cb will be called eventually when * to MHI driver. remove_cb will be called eventually when * Device side comes from where pending cleanup happens. * Device side comes from where pending cleanup happens. */ */ mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); atomic_inc(&ipa_mpm_ctx->probe_cnt); atomic_inc(&ipa_mpm_ctx->probe_cnt); ipa_mpm_ctx->md[probe_id].init_complete = true; ipa_mpm_ctx->md[probe_id].init_complete = false; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); IPA_MPM_FUNC_EXIT(); IPA_MPM_FUNC_EXIT(); return 0; return 0; } } Loading Loading @@ -2271,8 +2280,6 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, } } atomic_inc(&ipa_mpm_ctx->probe_cnt); atomic_inc(&ipa_mpm_ctx->probe_cnt); ipa_mpm_ctx->md[probe_id].init_complete = true; /* Check if ODL pipe is connected to MHIP DPL pipe before probe */ /* Check if ODL pipe is connected to MHIP DPL pipe before probe */ if (probe_id == IPA_MPM_MHIP_CH_ID_2 && if (probe_id == IPA_MPM_MHIP_CH_ID_2 && ipa3_is_odl_connected()) { ipa3_is_odl_connected()) { Loading @@ -2280,7 +2287,9 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ret = ipa_mpm_set_dma_mode(IPA_CLIENT_MHI_PRIME_DPL_PROD, ret = ipa_mpm_set_dma_mode(IPA_CLIENT_MHI_PRIME_DPL_PROD, IPA_CLIENT_USB_DPL_CONS, false); IPA_CLIENT_USB_DPL_CONS, false); } } mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); ipa_mpm_ctx->md[probe_id].init_complete = true; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); IPA_MPM_FUNC_EXIT(); IPA_MPM_FUNC_EXIT(); return 0; return 0; Loading Loading @@ -2349,6 +2358,11 @@ static void ipa_mpm_mhi_remove_cb(struct mhi_device *mhi_dev) } } IPA_MPM_DBG("remove_cb for mhip_idx = %d", mhip_idx); IPA_MPM_DBG("remove_cb for mhip_idx = %d", mhip_idx); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); ipa_mpm_ctx->md[mhip_idx].init_complete = false; mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); ipa_mpm_mhip_shutdown(mhip_idx); ipa_mpm_mhip_shutdown(mhip_idx); atomic_dec(&ipa_mpm_ctx->probe_cnt); atomic_dec(&ipa_mpm_ctx->probe_cnt); Loading Loading @@ -2387,7 +2401,19 @@ static void ipa_mpm_mhi_status_cb(struct mhi_device *mhi_dev, return; return; } } mutex_lock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); mutex_lock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); if (!ipa_mpm_ctx->md[mhip_idx].init_complete) { /* * SSR might be in progress, dont have to vote/unvote for * IPA clocks as it will be taken care in remove_cb/subsequent * probe. */ IPA_MPM_DBG("SSR in progress, return\n"); mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); return; } mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].mhi_mutex); switch (mhi_cb) { switch (mhi_cb) { case MHI_CB_IDLE: case MHI_CB_IDLE: break; break; Loading Loading @@ -2424,7 +2450,6 @@ static void ipa_mpm_mhi_status_cb(struct mhi_device *mhi_dev, IPA_MPM_ERR("unexpected event %d\n", mhi_cb); IPA_MPM_ERR("unexpected event %d\n", mhi_cb); break; break; } } mutex_unlock(&ipa_mpm_ctx->md[mhip_idx].lpm_mutex); } } static void ipa_mpm_mhip_map_prot(enum ipa_usb_teth_prot prot, static void ipa_mpm_mhip_map_prot(enum ipa_usb_teth_prot prot, Loading Loading @@ -2778,7 +2803,6 @@ static int ipa_mpm_probe(struct platform_device *pdev) for (i = 0; i < IPA_MPM_MHIP_CH_ID_MAX; i++) { for (i = 0; i < IPA_MPM_MHIP_CH_ID_MAX; i++) { mutex_init(&ipa_mpm_ctx->md[i].mutex); mutex_init(&ipa_mpm_ctx->md[i].mutex); mutex_init(&ipa_mpm_ctx->md[i].mhi_mutex); mutex_init(&ipa_mpm_ctx->md[i].mhi_mutex); mutex_init(&ipa_mpm_ctx->md[i].lpm_mutex); } } ipa_mpm_ctx->dev_info.pdev = pdev; ipa_mpm_ctx->dev_info.pdev = pdev; Loading