Loading drivers/platform/msm/ipa/ipa_api.c +18 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,24 @@ int ipa_reset_endpoint(u32 clnt_hdl) } EXPORT_SYMBOL(ipa_reset_endpoint); /** * ipa_disable_endpoint() - Disable an endpoint from IPA perspective * @clnt_hdl: [in] IPA client handle * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_disable_endpoint(u32 clnt_hdl) { int ret; IPA_API_DISPATCH_RETURN(ipa_disable_endpoint, clnt_hdl); return ret; } EXPORT_SYMBOL(ipa_disable_endpoint); /** * ipa_cfg_ep - IPA end-point configuration Loading drivers/platform/msm/ipa/ipa_api.h +2 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ struct ipa_api_controller { int (*ipa_clear_endpoint_delay)(u32 clnt_hdl); int (*ipa_disable_endpoint)(u32 clnt_hdl); int (*ipa_cfg_ep)(u32 clnt_hdl, const struct ipa_ep_cfg *ipa_ep_cfg); int (*ipa_cfg_ep_nat)(u32 clnt_hdl, Loading drivers/platform/msm/ipa/ipa_v2/ipa_client.c +96 −15 Original line number Diff line number Diff line Loading @@ -560,23 +560,31 @@ int ipa2_disconnect(u32 clnt_hdl) if (!ep->keep_ipa_awake) IPA_ACTIVE_CLIENTS_INC_EP(client_type); /* For USB 2.0 controller, first the ep will be disabled. * so this sequence is not needed again when disconnecting the pipe. */ if (!ep->ep_disabled) { /* Set Disconnect in Progress flag. */ spin_lock(&ipa_ctx->disconnect_lock); ep->disconnect_in_progress = true; spin_unlock(&ipa_ctx->disconnect_lock); /* Notify uc to stop monitoring holb on USB BAM Producer pipe. */ /* Notify uc to stop monitoring holb on USB BAM * Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(ep->client)) { ipa_uc_monitor_holb(ep->client, false); IPADBG("Disabling holb monitor for client: %d\n", ep->client); IPADBG("Disabling holb monitor for client: %d\n", ep->client); } result = ipa_disable_data_path(clnt_hdl); if (result) { IPAERR("disable data path failed res=%d clnt=%d.\n", result, clnt_hdl); IPAERR("disable data path failed res=%d clnt=%d.\n", result, clnt_hdl); return -EPERM; } } result = sps_disconnect(ep->ep_hdl); if (result) { Loading Loading @@ -783,6 +791,79 @@ int ipa2_clear_endpoint_delay(u32 clnt_hdl) return 0; } /** * ipa2_disable_endpoint() - low-level IPA client disable endpoint * @clnt_hdl: [in] opaque client handle assigned by IPA to client * * Should be called by the driver of the peripheral that wants to * disable the pipe from IPA in BAM-BAM mode. * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa2_disable_endpoint(u32 clnt_hdl) { int result; struct ipa_ep_context *ep; enum ipa_client_type client_type; unsigned long bam; if (unlikely(!ipa_ctx)) { IPAERR("IPA driver was not initialized\n"); return -EINVAL; } if (clnt_hdl >= ipa_ctx->ipa_num_pipes || ipa_ctx->ep[clnt_hdl].valid == 0) { IPAERR("bad parm.\n"); return -EINVAL; } ep = &ipa_ctx->ep[clnt_hdl]; client_type = ipa2_get_client_mapping(clnt_hdl); if (!ep->keep_ipa_awake) IPA_ACTIVE_CLIENTS_INC_EP(client_type); /* Set Disconnect in Progress flag. */ spin_lock(&ipa_ctx->disconnect_lock); ep->disconnect_in_progress = true; spin_unlock(&ipa_ctx->disconnect_lock); /* Notify uc to stop monitoring holb on USB BAM Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(ep->client)) { ipa_uc_monitor_holb(ep->client, false); IPADBG("Disabling holb monitor for client: %d\n", ep->client); } result = ipa_disable_data_path(clnt_hdl); if (result) { IPAERR("disable data path failed res=%d clnt=%d.\n", result, clnt_hdl); return -EPERM; } if (IPA_CLIENT_IS_CONS(ep->client)) bam = ep->connect.source; else bam = ep->connect.destination; result = sps_pipe_reset(bam, clnt_hdl); if (result) { IPAERR("SPS pipe reset failed.\n"); return -EPERM; } ep->ep_disabled = true; IPA_ACTIVE_CLIENTS_DEC_EP(client_type); IPADBG("client (ep: %d) disabled\n", clnt_hdl); return 0; } /** * ipa_sps_connect_safe() - connect endpoint from BAM prespective * @h: [in] sps pipe handle Loading drivers/platform/msm/ipa/ipa_v2/ipa_i.h +6 −0 Original line number Diff line number Diff line Loading @@ -546,6 +546,7 @@ struct ipa_ep_context { bool disconnect_in_progress; u32 qmi_request_sent; enum ipa_wakelock_ref_client wakelock_client; bool ep_disabled; /* sys MUST be the last element of this struct */ struct ipa_sys_context *sys; Loading Loading @@ -1417,6 +1418,11 @@ int ipa2_reset_endpoint(u32 clnt_hdl); */ int ipa2_clear_endpoint_delay(u32 clnt_hdl); /* * Disable ep */ int ipa2_disable_endpoint(u32 clnt_hdl); /* * Configuration */ Loading drivers/platform/msm/ipa/ipa_v2/ipa_utils.c +1 −0 Original line number Diff line number Diff line Loading @@ -4984,6 +4984,7 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type, api_ctrl->ipa_disconnect = ipa2_disconnect; api_ctrl->ipa_reset_endpoint = ipa2_reset_endpoint; api_ctrl->ipa_clear_endpoint_delay = ipa2_clear_endpoint_delay; api_ctrl->ipa_disable_endpoint = ipa2_disable_endpoint; api_ctrl->ipa_cfg_ep = ipa2_cfg_ep; api_ctrl->ipa_cfg_ep_nat = ipa2_cfg_ep_nat; api_ctrl->ipa_cfg_ep_hdr = ipa2_cfg_ep_hdr; Loading Loading
drivers/platform/msm/ipa/ipa_api.c +18 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,24 @@ int ipa_reset_endpoint(u32 clnt_hdl) } EXPORT_SYMBOL(ipa_reset_endpoint); /** * ipa_disable_endpoint() - Disable an endpoint from IPA perspective * @clnt_hdl: [in] IPA client handle * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_disable_endpoint(u32 clnt_hdl) { int ret; IPA_API_DISPATCH_RETURN(ipa_disable_endpoint, clnt_hdl); return ret; } EXPORT_SYMBOL(ipa_disable_endpoint); /** * ipa_cfg_ep - IPA end-point configuration Loading
drivers/platform/msm/ipa/ipa_api.h +2 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ struct ipa_api_controller { int (*ipa_clear_endpoint_delay)(u32 clnt_hdl); int (*ipa_disable_endpoint)(u32 clnt_hdl); int (*ipa_cfg_ep)(u32 clnt_hdl, const struct ipa_ep_cfg *ipa_ep_cfg); int (*ipa_cfg_ep_nat)(u32 clnt_hdl, Loading
drivers/platform/msm/ipa/ipa_v2/ipa_client.c +96 −15 Original line number Diff line number Diff line Loading @@ -560,23 +560,31 @@ int ipa2_disconnect(u32 clnt_hdl) if (!ep->keep_ipa_awake) IPA_ACTIVE_CLIENTS_INC_EP(client_type); /* For USB 2.0 controller, first the ep will be disabled. * so this sequence is not needed again when disconnecting the pipe. */ if (!ep->ep_disabled) { /* Set Disconnect in Progress flag. */ spin_lock(&ipa_ctx->disconnect_lock); ep->disconnect_in_progress = true; spin_unlock(&ipa_ctx->disconnect_lock); /* Notify uc to stop monitoring holb on USB BAM Producer pipe. */ /* Notify uc to stop monitoring holb on USB BAM * Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(ep->client)) { ipa_uc_monitor_holb(ep->client, false); IPADBG("Disabling holb monitor for client: %d\n", ep->client); IPADBG("Disabling holb monitor for client: %d\n", ep->client); } result = ipa_disable_data_path(clnt_hdl); if (result) { IPAERR("disable data path failed res=%d clnt=%d.\n", result, clnt_hdl); IPAERR("disable data path failed res=%d clnt=%d.\n", result, clnt_hdl); return -EPERM; } } result = sps_disconnect(ep->ep_hdl); if (result) { Loading Loading @@ -783,6 +791,79 @@ int ipa2_clear_endpoint_delay(u32 clnt_hdl) return 0; } /** * ipa2_disable_endpoint() - low-level IPA client disable endpoint * @clnt_hdl: [in] opaque client handle assigned by IPA to client * * Should be called by the driver of the peripheral that wants to * disable the pipe from IPA in BAM-BAM mode. * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa2_disable_endpoint(u32 clnt_hdl) { int result; struct ipa_ep_context *ep; enum ipa_client_type client_type; unsigned long bam; if (unlikely(!ipa_ctx)) { IPAERR("IPA driver was not initialized\n"); return -EINVAL; } if (clnt_hdl >= ipa_ctx->ipa_num_pipes || ipa_ctx->ep[clnt_hdl].valid == 0) { IPAERR("bad parm.\n"); return -EINVAL; } ep = &ipa_ctx->ep[clnt_hdl]; client_type = ipa2_get_client_mapping(clnt_hdl); if (!ep->keep_ipa_awake) IPA_ACTIVE_CLIENTS_INC_EP(client_type); /* Set Disconnect in Progress flag. */ spin_lock(&ipa_ctx->disconnect_lock); ep->disconnect_in_progress = true; spin_unlock(&ipa_ctx->disconnect_lock); /* Notify uc to stop monitoring holb on USB BAM Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(ep->client)) { ipa_uc_monitor_holb(ep->client, false); IPADBG("Disabling holb monitor for client: %d\n", ep->client); } result = ipa_disable_data_path(clnt_hdl); if (result) { IPAERR("disable data path failed res=%d clnt=%d.\n", result, clnt_hdl); return -EPERM; } if (IPA_CLIENT_IS_CONS(ep->client)) bam = ep->connect.source; else bam = ep->connect.destination; result = sps_pipe_reset(bam, clnt_hdl); if (result) { IPAERR("SPS pipe reset failed.\n"); return -EPERM; } ep->ep_disabled = true; IPA_ACTIVE_CLIENTS_DEC_EP(client_type); IPADBG("client (ep: %d) disabled\n", clnt_hdl); return 0; } /** * ipa_sps_connect_safe() - connect endpoint from BAM prespective * @h: [in] sps pipe handle Loading
drivers/platform/msm/ipa/ipa_v2/ipa_i.h +6 −0 Original line number Diff line number Diff line Loading @@ -546,6 +546,7 @@ struct ipa_ep_context { bool disconnect_in_progress; u32 qmi_request_sent; enum ipa_wakelock_ref_client wakelock_client; bool ep_disabled; /* sys MUST be the last element of this struct */ struct ipa_sys_context *sys; Loading Loading @@ -1417,6 +1418,11 @@ int ipa2_reset_endpoint(u32 clnt_hdl); */ int ipa2_clear_endpoint_delay(u32 clnt_hdl); /* * Disable ep */ int ipa2_disable_endpoint(u32 clnt_hdl); /* * Configuration */ Loading
drivers/platform/msm/ipa/ipa_v2/ipa_utils.c +1 −0 Original line number Diff line number Diff line Loading @@ -4984,6 +4984,7 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type, api_ctrl->ipa_disconnect = ipa2_disconnect; api_ctrl->ipa_reset_endpoint = ipa2_reset_endpoint; api_ctrl->ipa_clear_endpoint_delay = ipa2_clear_endpoint_delay; api_ctrl->ipa_disable_endpoint = ipa2_disable_endpoint; api_ctrl->ipa_cfg_ep = ipa2_cfg_ep; api_ctrl->ipa_cfg_ep_nat = ipa2_cfg_ep_nat; api_ctrl->ipa_cfg_ep_hdr = ipa2_cfg_ep_hdr; Loading