Loading drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c +33 −8 Original line number Diff line number Diff line Loading @@ -171,6 +171,7 @@ struct imp_qmi_cache { struct ipa_mhi_ready_indication_msg_v01 ready_ind; struct ipa_mhi_alloc_channel_req_msg_v01 alloc_ch_req; struct ipa_mhi_alloc_channel_resp_msg_v01 alloc_ch_resp; struct ipa_mhi_clk_vote_resp_msg_v01 clk_vote_resp; }; struct imp_mhi_driver { Loading Loading @@ -387,7 +388,12 @@ static int __imp_configure_mhi_device( ridx++; resp->alloc_resp_arr_len = ridx; resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE if mhi not active */ if (mhi_is_active(imp_ctx->md.mhi_dev)) resp->resp.error = IPA_QMI_ERR_INVALID_ID_V01; else resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; return -EINVAL; } Loading Loading @@ -443,6 +449,7 @@ static int __imp_configure_mhi_device( IMP_DBG("Configuring MHI device for ch %d\n", ch->props.id); ret = mhi_device_configure(imp_ctx->md.mhi_dev, ch->props.dir, ch_config, 2); /* configure mhi-host, no need check mhi state */ if (ret) { IMP_ERR("mhi_device_configure failed for ch %d\n", req->tr_info_arr[i].ch_id); Loading Loading @@ -485,7 +492,7 @@ struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( if (imp_ctx->state != IMP_READY) { IMP_ERR("invalid state %d\n", imp_ctx->state); resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; resp->resp.error = IPA_QMI_ERR_INTERNAL_V01; mutex_unlock(&imp_ctx->mutex); return resp; } Loading Loading @@ -549,7 +556,11 @@ struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( .is_success = 0; resp->alloc_resp_arr_len++; resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE if mhi not active */ if (mhi_is_active(imp_ctx->md.mhi_dev)) resp->resp.error = IPA_QMI_ERR_INTERNAL_V01; else resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; goto fail_smmu; } Loading Loading @@ -599,23 +610,29 @@ struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( * * Return: 0 on success, negative otherwise */ int imp_handle_vote_req(bool vote) struct ipa_mhi_clk_vote_resp_msg_v01 *imp_handle_vote_req(bool vote) { int ret; struct ipa_mhi_clk_vote_resp_msg_v01 *resp = &imp_ctx->qmi.clk_vote_resp; IMP_DBG_LOW("vote %d\n", vote); memset(resp, 0, sizeof(struct ipa_mhi_clk_vote_resp_msg_v01)); resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; resp->resp.error = IPA_QMI_ERR_INTERNAL_V01; mutex_lock(&imp_ctx->mutex); if (imp_ctx->state != IMP_STARTED) { IMP_ERR("unexpected vote when in state %d\n", imp_ctx->state); mutex_unlock(&imp_ctx->mutex); return -EPERM; return resp; } if (vote == imp_ctx->lpm_disabled) { IMP_ERR("already voted/devoted %d\n", vote); mutex_unlock(&imp_ctx->mutex); return -EPERM; return resp; } mutex_unlock(&imp_ctx->mutex); Loading @@ -629,7 +646,14 @@ int imp_handle_vote_req(bool vote) ret = mhi_device_get_sync(imp_ctx->md.mhi_dev); if (ret) { IMP_ERR("mhi_sync_get failed %d\n", ret); return ret; resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE if mhi not active */ if (mhi_is_active(imp_ctx->md.mhi_dev)) resp->resp.error = IPA_QMI_ERR_INVALID_ID_V01; else resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; return resp; } } else { mhi_device_put(imp_ctx->md.mhi_dev); Loading @@ -642,7 +666,8 @@ int imp_handle_vote_req(bool vote) imp_ctx->lpm_disabled = false; mutex_unlock(&imp_ctx->mutex); return 0; resp->resp.result = IPA_QMI_RESULT_SUCCESS_V01; return resp; } static int imp_read_iova_from_dtsi(const char *node, struct imp_iova_addr *out) Loading drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.h +4 −3 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ void imp_handle_modem_ready(void); struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( struct ipa_mhi_alloc_channel_req_msg_v01 *req); int imp_handle_vote_req(bool vote); struct ipa_mhi_clk_vote_resp_msg_v01 *imp_handle_vote_req(bool vote); void imp_handle_modem_shutdown(void); Loading @@ -40,9 +40,10 @@ static inline struct ipa_mhi_alloc_channel_resp_msg_v01 return NULL; } static inline int imp_handle_vote_req(bool vote) static inline struct ipa_mhi_clk_vote_resp_msg_v01 *imp_handle_vote_req(bool vote) { return -EPERM; return NULL; } static inline void imp_handle_modem_shutdown(void) Loading drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +3 −9 Original line number Diff line number Diff line Loading @@ -293,25 +293,19 @@ static void ipa3_handle_mhi_vote_req(struct qmi_handle *qmi_handle, const void *decoded_msg) { struct ipa_mhi_clk_vote_req_msg_v01 *vote_req; struct ipa_mhi_clk_vote_resp_msg_v01 resp; struct ipa_mhi_clk_vote_resp_msg_v01 *resp; int rc; vote_req = (struct ipa_mhi_clk_vote_req_msg_v01 *)decoded_msg; IPAWANDBG("Received QMI_IPA_MHI_CLK_VOTE_REQ_V01(%d)\n", vote_req->mhi_vote); rc = imp_handle_vote_req(vote_req->mhi_vote); if (rc) { resp.resp.result = IPA_QMI_RESULT_FAILURE_V01; resp.resp.error = IPA_QMI_ERR_INTERNAL_V01; } else { resp.resp.result = IPA_QMI_RESULT_SUCCESS_V01; } resp = imp_handle_vote_req(vote_req->mhi_vote); IPAWANDBG("start sending QMI_IPA_MHI_CLK_VOTE_RESP_V01\n"); rc = qmi_send_response(qmi_handle, sq, txn, QMI_IPA_MHI_CLK_VOTE_RESP_V01, IPA_MHI_CLK_VOTE_RESP_MSG_V01_MAX_MSG_LEN, ipa_mhi_clk_vote_resp_msg_v01_ei, &resp); resp); if (rc < 0) IPAWANERR("QMI_IPA_MHI_CLK_VOTE_RESP_V01 failed\n"); Loading include/linux/mhi.h +13 −0 Original line number Diff line number Diff line Loading @@ -634,6 +634,19 @@ enum mhi_dev_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl); void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_dev_state state); /** * mhi_is_active - helper function to determine if MHI in active state * @mhi_dev: client device */ static inline bool mhi_is_active(struct mhi_device *mhi_dev) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; return (mhi_cntrl->dev_state >= MHI_STATE_M0 && mhi_cntrl->dev_state <= MHI_STATE_M3); } #ifndef CONFIG_ARCH_QCOM #ifdef CONFIG_MHI_DEBUG Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.c +33 −8 Original line number Diff line number Diff line Loading @@ -171,6 +171,7 @@ struct imp_qmi_cache { struct ipa_mhi_ready_indication_msg_v01 ready_ind; struct ipa_mhi_alloc_channel_req_msg_v01 alloc_ch_req; struct ipa_mhi_alloc_channel_resp_msg_v01 alloc_ch_resp; struct ipa_mhi_clk_vote_resp_msg_v01 clk_vote_resp; }; struct imp_mhi_driver { Loading Loading @@ -387,7 +388,12 @@ static int __imp_configure_mhi_device( ridx++; resp->alloc_resp_arr_len = ridx; resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE if mhi not active */ if (mhi_is_active(imp_ctx->md.mhi_dev)) resp->resp.error = IPA_QMI_ERR_INVALID_ID_V01; else resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; return -EINVAL; } Loading Loading @@ -443,6 +449,7 @@ static int __imp_configure_mhi_device( IMP_DBG("Configuring MHI device for ch %d\n", ch->props.id); ret = mhi_device_configure(imp_ctx->md.mhi_dev, ch->props.dir, ch_config, 2); /* configure mhi-host, no need check mhi state */ if (ret) { IMP_ERR("mhi_device_configure failed for ch %d\n", req->tr_info_arr[i].ch_id); Loading Loading @@ -485,7 +492,7 @@ struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( if (imp_ctx->state != IMP_READY) { IMP_ERR("invalid state %d\n", imp_ctx->state); resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; resp->resp.error = IPA_QMI_ERR_INTERNAL_V01; mutex_unlock(&imp_ctx->mutex); return resp; } Loading Loading @@ -549,7 +556,11 @@ struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( .is_success = 0; resp->alloc_resp_arr_len++; resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE if mhi not active */ if (mhi_is_active(imp_ctx->md.mhi_dev)) resp->resp.error = IPA_QMI_ERR_INTERNAL_V01; else resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; goto fail_smmu; } Loading Loading @@ -599,23 +610,29 @@ struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( * * Return: 0 on success, negative otherwise */ int imp_handle_vote_req(bool vote) struct ipa_mhi_clk_vote_resp_msg_v01 *imp_handle_vote_req(bool vote) { int ret; struct ipa_mhi_clk_vote_resp_msg_v01 *resp = &imp_ctx->qmi.clk_vote_resp; IMP_DBG_LOW("vote %d\n", vote); memset(resp, 0, sizeof(struct ipa_mhi_clk_vote_resp_msg_v01)); resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; resp->resp.error = IPA_QMI_ERR_INTERNAL_V01; mutex_lock(&imp_ctx->mutex); if (imp_ctx->state != IMP_STARTED) { IMP_ERR("unexpected vote when in state %d\n", imp_ctx->state); mutex_unlock(&imp_ctx->mutex); return -EPERM; return resp; } if (vote == imp_ctx->lpm_disabled) { IMP_ERR("already voted/devoted %d\n", vote); mutex_unlock(&imp_ctx->mutex); return -EPERM; return resp; } mutex_unlock(&imp_ctx->mutex); Loading @@ -629,7 +646,14 @@ int imp_handle_vote_req(bool vote) ret = mhi_device_get_sync(imp_ctx->md.mhi_dev); if (ret) { IMP_ERR("mhi_sync_get failed %d\n", ret); return ret; resp->resp.result = IPA_QMI_RESULT_FAILURE_V01; /* return INCOMPATIBLE_STATE if mhi not active */ if (mhi_is_active(imp_ctx->md.mhi_dev)) resp->resp.error = IPA_QMI_ERR_INVALID_ID_V01; else resp->resp.error = IPA_QMI_ERR_INCOMPATIBLE_STATE_V01; return resp; } } else { mhi_device_put(imp_ctx->md.mhi_dev); Loading @@ -642,7 +666,8 @@ int imp_handle_vote_req(bool vote) imp_ctx->lpm_disabled = false; mutex_unlock(&imp_ctx->mutex); return 0; resp->resp.result = IPA_QMI_RESULT_SUCCESS_V01; return resp; } static int imp_read_iova_from_dtsi(const char *node, struct imp_iova_addr *out) Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mhi_proxy.h +4 −3 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ void imp_handle_modem_ready(void); struct ipa_mhi_alloc_channel_resp_msg_v01 *imp_handle_allocate_channel_req( struct ipa_mhi_alloc_channel_req_msg_v01 *req); int imp_handle_vote_req(bool vote); struct ipa_mhi_clk_vote_resp_msg_v01 *imp_handle_vote_req(bool vote); void imp_handle_modem_shutdown(void); Loading @@ -40,9 +40,10 @@ static inline struct ipa_mhi_alloc_channel_resp_msg_v01 return NULL; } static inline int imp_handle_vote_req(bool vote) static inline struct ipa_mhi_clk_vote_resp_msg_v01 *imp_handle_vote_req(bool vote) { return -EPERM; return NULL; } static inline void imp_handle_modem_shutdown(void) Loading
drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +3 −9 Original line number Diff line number Diff line Loading @@ -293,25 +293,19 @@ static void ipa3_handle_mhi_vote_req(struct qmi_handle *qmi_handle, const void *decoded_msg) { struct ipa_mhi_clk_vote_req_msg_v01 *vote_req; struct ipa_mhi_clk_vote_resp_msg_v01 resp; struct ipa_mhi_clk_vote_resp_msg_v01 *resp; int rc; vote_req = (struct ipa_mhi_clk_vote_req_msg_v01 *)decoded_msg; IPAWANDBG("Received QMI_IPA_MHI_CLK_VOTE_REQ_V01(%d)\n", vote_req->mhi_vote); rc = imp_handle_vote_req(vote_req->mhi_vote); if (rc) { resp.resp.result = IPA_QMI_RESULT_FAILURE_V01; resp.resp.error = IPA_QMI_ERR_INTERNAL_V01; } else { resp.resp.result = IPA_QMI_RESULT_SUCCESS_V01; } resp = imp_handle_vote_req(vote_req->mhi_vote); IPAWANDBG("start sending QMI_IPA_MHI_CLK_VOTE_RESP_V01\n"); rc = qmi_send_response(qmi_handle, sq, txn, QMI_IPA_MHI_CLK_VOTE_RESP_V01, IPA_MHI_CLK_VOTE_RESP_MSG_V01_MAX_MSG_LEN, ipa_mhi_clk_vote_resp_msg_v01_ei, &resp); resp); if (rc < 0) IPAWANERR("QMI_IPA_MHI_CLK_VOTE_RESP_V01 failed\n"); Loading
include/linux/mhi.h +13 −0 Original line number Diff line number Diff line Loading @@ -634,6 +634,19 @@ enum mhi_dev_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl); void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_dev_state state); /** * mhi_is_active - helper function to determine if MHI in active state * @mhi_dev: client device */ static inline bool mhi_is_active(struct mhi_device *mhi_dev) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; return (mhi_cntrl->dev_state >= MHI_STATE_M0 && mhi_cntrl->dev_state <= MHI_STATE_M3); } #ifndef CONFIG_ARCH_QCOM #ifdef CONFIG_MHI_DEBUG Loading