From 023fc26373ab1df0dce025e30243b605fdbe1d4a Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Mon, 11 Mar 2019 13:43:36 +0530 Subject: [PATCH] msm: ipa3: Fix to start/stop gsi channel USB pipe connected Observing the race condition without USB pipe connected try to start/stop channel during SSR. Added changes to start/stop channel only if when USB connected. Change-Id: I06756481c93395885a527b5d01b75719ccf9405e Signed-off-by: Ashok Vuyyuru --- .../platform/msm/ipa/ipa_clients/ipa_usb.c | 17 ++++++++-- drivers/platform/msm/ipa/ipa_v3/ipa_client.c | 34 ++++++++++++++----- drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 6 ++-- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c index ac3d62e4de0b..abcd5a12cd29 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c @@ -296,6 +296,17 @@ static char *ipa3_usb_notify_event_to_string(enum ipa_usb_notify_event event) return "UNSUPPORTED"; } +static bool ipa3_usb_get_teth_port_state(void) +{ + if (ipa3_usb_ctx == NULL) + return false; + if (ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_TETH].state == + IPA_USB_CONNECTED) + return true; + else + return false; +} + static bool ipa3_usb_set_state(enum ipa3_usb_state new_state, bool err_permit, enum ipa3_usb_transport_type ttype) { @@ -2238,8 +2249,8 @@ int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, * For IPA_USB_DIAG/DPL config there will not be any UL ep. */ if (connect_params->teth_prot != IPA_USB_DIAG) - ipa3_register_lock_unlock_callback(&ipa_usb_set_lock_unlock, - ul_out_params->clnt_hdl); + ipa3_register_client_callback(&ipa_usb_set_lock_unlock, + &ipa3_usb_get_teth_port_state, ul_out_params->clnt_hdl); IPA_USB_DBG_LOW("exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); @@ -2325,7 +2336,7 @@ static int ipa_usb_xdci_dismiss_channels(u32 ul_clnt_hdl, u32 dl_clnt_hdl, * For IPA_USB_DIAG/DPL config there will not be any UL config. */ if (!IPA3_USB_IS_TTYPE_DPL(ttype)) - ipa3_deregister_lock_unlock_callback(ul_clnt_hdl); + ipa3_deregister_client_callback(ul_clnt_hdl); /* Change state to STOPPED */ if (!ipa3_usb_set_state(IPA_USB_STOPPED, false, ttype)) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 47996a42b60e..1b50a19a1806 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -393,8 +393,8 @@ static enum ipa_client_cb_type ipa_get_client_cb_type( return client_cb; } -void ipa3_register_lock_unlock_callback(int (*client_cb)(bool is_lock), - u32 ipa_ep_idx) +void ipa3_register_client_callback(int (*client_cb)(bool is_lock), + bool (*teth_port_state)(void), u32 ipa_ep_idx) { enum ipa_client_cb_type client; enum ipa_client_type client_type; @@ -413,10 +413,12 @@ void ipa3_register_lock_unlock_callback(int (*client_cb)(bool is_lock), if (!ipa3_ctx->client_lock_unlock[client]) ipa3_ctx->client_lock_unlock[client] = client_cb; + if (!ipa3_ctx->get_teth_port_state[client]) + ipa3_ctx->get_teth_port_state[client] = teth_port_state; IPADBG("exit\n"); } -void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx) +void ipa3_deregister_client_callback(u32 ipa_ep_idx) { enum ipa_client_cb_type client_cb; enum ipa_client_type client_type; @@ -428,12 +430,14 @@ void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx) if (client_cb == IPA_MAX_CLNT) return; - if (ipa3_ctx->client_lock_unlock[client_cb] == NULL) { + if (ipa3_ctx->client_lock_unlock[client_cb] == NULL && + ipa3_ctx->get_teth_port_state[client_cb] == NULL) { IPAERR("client_lock_unlock is already NULL"); return; } ipa3_ctx->client_lock_unlock[client_cb] = NULL; + ipa3_ctx->get_teth_port_state[client_cb] = NULL; IPADBG("exit\n"); } @@ -1142,6 +1146,18 @@ int ipa3_set_reset_client_prod_pipe_delay(bool set_reset, return result; } +static bool ipa3_get_teth_port_status(enum ipa_client_type client) +{ + enum ipa_client_cb_type client_cb; + + client_cb = ipa_get_client_cb_type(client); + if (client_cb == IPA_MAX_CLNT) + return false; + if (ipa3_ctx->get_teth_port_state[client_cb]) + return ipa3_ctx->get_teth_port_state[client_cb](); + return false; +} + /* * Start/stop the CLIENT PROD pipes in SSR scenarios */ @@ -1167,10 +1183,12 @@ int ipa3_start_stop_client_prod_gsi_chnl(enum ipa_client_type client, client_lock_unlock_cb(client, true); ep = &ipa3_ctx->ep[pipe_idx]; - if (start_chnl) - result = ipa3_start_gsi_channel(pipe_idx); - else - result = ipa3_stop_gsi_channel(pipe_idx); + if (ep->valid && ep->skip_ep_cfg && ipa3_get_teth_port_status(client)) { + if (start_chnl) + result = ipa3_start_gsi_channel(pipe_idx); + else + result = ipa3_stop_gsi_channel(pipe_idx); + } client_lock_unlock_cb(client, false); return result; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index a7a85374923c..28ac79b4f149 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1722,6 +1722,7 @@ struct ipa3_context { int uc_mailbox17_mismatch; int (*client_lock_unlock[IPA_MAX_CLNT])(bool is_lock); atomic_t is_ssr; + bool (*get_teth_port_state[IPA_MAX_CLNT])(void); }; struct ipa3_plat_drv_res { @@ -2044,8 +2045,9 @@ int ipa3_xdci_connect(u32 clnt_hdl); int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id); void ipa3_xdci_ep_delay_rm(u32 clnt_hdl); -void ipa3_register_lock_unlock_callback(int (*client_cb)(bool), u32 ipa_ep_idx); -void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx); +void ipa3_register_client_callback(int (*client_cb)(bool), + bool (*teth_port_state)(void), u32 ipa_ep_idx); +void ipa3_deregister_client_callback(u32 ipa_ep_idx); int ipa3_set_reset_client_prod_pipe_delay(bool set_reset, enum ipa_client_type client); int ipa3_start_stop_client_prod_gsi_chnl(enum ipa_client_type client,