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 <avuyyuru@codeaurora.org>
tirimbino
Ashok Vuyyuru 6 years ago committed by Gerrit - the friendly Code Review server
parent c93d9386aa
commit 023fc26373
  1. 17
      drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
  2. 34
      drivers/platform/msm/ipa/ipa_v3/ipa_client.c
  3. 6
      drivers/platform/msm/ipa/ipa_v3/ipa_i.h

@ -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))

@ -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;
}

@ -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,

Loading…
Cancel
Save