Loading drivers/platform/msm/ipa/ipa_v3/ipa_client.c +58 −3 Original line number Original line Diff line number Diff line Loading @@ -1351,6 +1351,7 @@ int ipa3_set_usb_max_packet_size( return 0; return 0; } } /* This function called as part of usb pipe resume */ int ipa3_xdci_connect(u32 clnt_hdl) int ipa3_xdci_connect(u32 clnt_hdl) { { int result; int result; Loading Loading @@ -1390,11 +1391,14 @@ exit: return result; return result; } } /* This function called as part of usb pipe connect */ int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) { { struct ipa3_ep_context *ep; struct ipa3_ep_context *ep; int result = -EFAULT; int result = -EFAULT; enum gsi_status gsi_res; enum gsi_status gsi_res; struct ipa_ep_cfg_ctrl ep_cfg_ctrl; IPADBG("entry\n"); IPADBG("entry\n"); if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || Loading @@ -1416,6 +1420,22 @@ int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) goto write_chan_scratch_fail; goto write_chan_scratch_fail; } } } } if (IPA_CLIENT_IS_PROD(ep->client) && ep->skip_ep_cfg) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = true; ep->ep_delay_set = true; result = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); if (result) IPAERR("client (ep: %d) failed result=%d\n", clnt_hdl, result); else IPADBG("client (ep: %d) success\n", clnt_hdl); } else { ep->ep_delay_set = false; } gsi_res = gsi_start_channel(ep->gsi_chan_hdl); gsi_res = gsi_start_channel(ep->gsi_chan_hdl); if (gsi_res != GSI_STATUS_SUCCESS) { if (gsi_res != GSI_STATUS_SUCCESS) { IPAERR("Error starting channel: %d\n", gsi_res); IPAERR("Error starting channel: %d\n", gsi_res); Loading Loading @@ -1620,13 +1640,15 @@ static int ipa3_xdci_stop_gsi_ch_brute_force(u32 clnt_hdl, /* Clocks should be voted for before invoking this function */ /* Clocks should be voted for before invoking this function */ static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id, static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id, u32 source_pipe_bitmask, bool should_force_clear, u32 clnt_hdl) u32 source_pipe_bitmask, bool should_force_clear, u32 clnt_hdl, bool remove_delay) { { int result; int result; bool is_empty = false; bool is_empty = false; int i; int i; bool stop_in_proc; bool stop_in_proc; struct ipa3_ep_context *ep; struct ipa3_ep_context *ep; struct ipa_ep_cfg_ctrl ep_cfg_ctrl; if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || ipa3_ctx->ep[clnt_hdl].valid == 0) { ipa3_ctx->ep[clnt_hdl].valid == 0) { Loading @@ -1647,6 +1669,22 @@ static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id, if (!stop_in_proc) if (!stop_in_proc) goto exit; goto exit; if (remove_delay && ep->ep_delay_set == true) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = false; result = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); if (result) { IPAERR ("client (ep: %d) failed to remove delay result=%d\n", clnt_hdl, result); } else { IPADBG("client (ep: %d) delay removed\n", clnt_hdl); ep->ep_delay_set = false; } } /* if stop_in_proc, lets wait for emptiness */ /* if stop_in_proc, lets wait for emptiness */ for (i = 0; i < IPA_POLL_FOR_EMPTINESS_NUM; i++) { for (i = 0; i < IPA_POLL_FOR_EMPTINESS_NUM; i++) { result = ipa3_is_xdci_channel_empty(ep, &is_empty); result = ipa3_is_xdci_channel_empty(ep, &is_empty); Loading Loading @@ -1712,6 +1750,21 @@ disable_force_clear_and_exit: if (should_force_clear) if (should_force_clear) ipa3_disable_force_clear(qmi_req_id); ipa3_disable_force_clear(qmi_req_id); exit: exit: if (remove_delay && ep->ep_delay_set == true) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = false; result = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); if (result) { IPAERR ("client (ep: %d) failed to remove delay result=%d\n", clnt_hdl, result); } else { IPADBG("client (ep: %d) delay removed\n", clnt_hdl); ep->ep_delay_set = false; } } return result; return result; } } Loading Loading @@ -1741,7 +1794,8 @@ int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id) source_pipe_bitmask = 1 << source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ep->client); ipa3_get_ep_mapping(ep->client); result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id, result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id, source_pipe_bitmask, should_force_clear, clnt_hdl); source_pipe_bitmask, should_force_clear, clnt_hdl, true); if (result) { if (result) { IPAERR("Fail to stop UL channel with data drain\n"); IPAERR("Fail to stop UL channel with data drain\n"); BUG(); BUG(); Loading Loading @@ -1916,7 +1970,8 @@ int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, if (!is_dpl) { if (!is_dpl) { source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ul_ep->client); source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ul_ep->client); result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id, result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id, source_pipe_bitmask, should_force_clear, ul_clnt_hdl); source_pipe_bitmask, should_force_clear, ul_clnt_hdl, false); if (result) { if (result) { IPAERR("Error stopping UL channel: result = %d\n", IPAERR("Error stopping UL channel: result = %d\n", result); result); Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -610,6 +610,7 @@ struct ipa3_ep_context { u32 uc_offload_state; u32 uc_offload_state; bool disconnect_in_progress; bool disconnect_in_progress; u32 qmi_request_sent; u32 qmi_request_sent; bool ep_delay_set; /* sys MUST be the last element of this struct */ /* sys MUST be the last element of this struct */ struct ipa3_sys_context *sys; struct ipa3_sys_context *sys; Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_client.c +58 −3 Original line number Original line Diff line number Diff line Loading @@ -1351,6 +1351,7 @@ int ipa3_set_usb_max_packet_size( return 0; return 0; } } /* This function called as part of usb pipe resume */ int ipa3_xdci_connect(u32 clnt_hdl) int ipa3_xdci_connect(u32 clnt_hdl) { { int result; int result; Loading Loading @@ -1390,11 +1391,14 @@ exit: return result; return result; } } /* This function called as part of usb pipe connect */ int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) { { struct ipa3_ep_context *ep; struct ipa3_ep_context *ep; int result = -EFAULT; int result = -EFAULT; enum gsi_status gsi_res; enum gsi_status gsi_res; struct ipa_ep_cfg_ctrl ep_cfg_ctrl; IPADBG("entry\n"); IPADBG("entry\n"); if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || Loading @@ -1416,6 +1420,22 @@ int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) goto write_chan_scratch_fail; goto write_chan_scratch_fail; } } } } if (IPA_CLIENT_IS_PROD(ep->client) && ep->skip_ep_cfg) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = true; ep->ep_delay_set = true; result = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); if (result) IPAERR("client (ep: %d) failed result=%d\n", clnt_hdl, result); else IPADBG("client (ep: %d) success\n", clnt_hdl); } else { ep->ep_delay_set = false; } gsi_res = gsi_start_channel(ep->gsi_chan_hdl); gsi_res = gsi_start_channel(ep->gsi_chan_hdl); if (gsi_res != GSI_STATUS_SUCCESS) { if (gsi_res != GSI_STATUS_SUCCESS) { IPAERR("Error starting channel: %d\n", gsi_res); IPAERR("Error starting channel: %d\n", gsi_res); Loading Loading @@ -1620,13 +1640,15 @@ static int ipa3_xdci_stop_gsi_ch_brute_force(u32 clnt_hdl, /* Clocks should be voted for before invoking this function */ /* Clocks should be voted for before invoking this function */ static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id, static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id, u32 source_pipe_bitmask, bool should_force_clear, u32 clnt_hdl) u32 source_pipe_bitmask, bool should_force_clear, u32 clnt_hdl, bool remove_delay) { { int result; int result; bool is_empty = false; bool is_empty = false; int i; int i; bool stop_in_proc; bool stop_in_proc; struct ipa3_ep_context *ep; struct ipa3_ep_context *ep; struct ipa_ep_cfg_ctrl ep_cfg_ctrl; if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || ipa3_ctx->ep[clnt_hdl].valid == 0) { ipa3_ctx->ep[clnt_hdl].valid == 0) { Loading @@ -1647,6 +1669,22 @@ static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id, if (!stop_in_proc) if (!stop_in_proc) goto exit; goto exit; if (remove_delay && ep->ep_delay_set == true) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = false; result = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); if (result) { IPAERR ("client (ep: %d) failed to remove delay result=%d\n", clnt_hdl, result); } else { IPADBG("client (ep: %d) delay removed\n", clnt_hdl); ep->ep_delay_set = false; } } /* if stop_in_proc, lets wait for emptiness */ /* if stop_in_proc, lets wait for emptiness */ for (i = 0; i < IPA_POLL_FOR_EMPTINESS_NUM; i++) { for (i = 0; i < IPA_POLL_FOR_EMPTINESS_NUM; i++) { result = ipa3_is_xdci_channel_empty(ep, &is_empty); result = ipa3_is_xdci_channel_empty(ep, &is_empty); Loading Loading @@ -1712,6 +1750,21 @@ disable_force_clear_and_exit: if (should_force_clear) if (should_force_clear) ipa3_disable_force_clear(qmi_req_id); ipa3_disable_force_clear(qmi_req_id); exit: exit: if (remove_delay && ep->ep_delay_set == true) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = false; result = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); if (result) { IPAERR ("client (ep: %d) failed to remove delay result=%d\n", clnt_hdl, result); } else { IPADBG("client (ep: %d) delay removed\n", clnt_hdl); ep->ep_delay_set = false; } } return result; return result; } } Loading Loading @@ -1741,7 +1794,8 @@ int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id) source_pipe_bitmask = 1 << source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ep->client); ipa3_get_ep_mapping(ep->client); result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id, result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id, source_pipe_bitmask, should_force_clear, clnt_hdl); source_pipe_bitmask, should_force_clear, clnt_hdl, true); if (result) { if (result) { IPAERR("Fail to stop UL channel with data drain\n"); IPAERR("Fail to stop UL channel with data drain\n"); BUG(); BUG(); Loading Loading @@ -1916,7 +1970,8 @@ int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, if (!is_dpl) { if (!is_dpl) { source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ul_ep->client); source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ul_ep->client); result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id, result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id, source_pipe_bitmask, should_force_clear, ul_clnt_hdl); source_pipe_bitmask, should_force_clear, ul_clnt_hdl, false); if (result) { if (result) { IPAERR("Error stopping UL channel: result = %d\n", IPAERR("Error stopping UL channel: result = %d\n", result); result); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -610,6 +610,7 @@ struct ipa3_ep_context { u32 uc_offload_state; u32 uc_offload_state; bool disconnect_in_progress; bool disconnect_in_progress; u32 qmi_request_sent; u32 qmi_request_sent; bool ep_delay_set; /* sys MUST be the last element of this struct */ /* sys MUST be the last element of this struct */ struct ipa3_sys_context *sys; struct ipa3_sys_context *sys; Loading