msm: ipa3: fix channel stop retry logic
Stopping a PROD channel might result in a timeout because the channel is not empty, or IPA is busy. Whether or not to retry a stop operation is determined by channel owner. This change removes the common retry logic of retrying to stop a PROD channel and adds a retry only for the scenario it is actually needed. Change-Id: I7ac1e81f7f99de2b0c3162aa5aaea2102a450838 CRs-Fixed: 2037955 Acked-by: Ady Abraham <adya@qti.qualcomm.com> Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
This commit is contained in:
parent
f1a10f1598
commit
a3488e9398
2 changed files with 32 additions and 12 deletions
|
@ -1515,6 +1515,7 @@ int ipa3_teardown_sys_pipe(u32 clnt_hdl)
|
|||
struct ipa3_ep_context *ep;
|
||||
int empty;
|
||||
int result;
|
||||
int i;
|
||||
|
||||
if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
|
||||
ipa3_ctx->ep[clnt_hdl].valid == 0) {
|
||||
|
@ -1551,7 +1552,17 @@ int ipa3_teardown_sys_pipe(u32 clnt_hdl)
|
|||
cancel_delayed_work_sync(&ep->sys->replenish_rx_work);
|
||||
flush_workqueue(ep->sys->wq);
|
||||
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
|
||||
result = ipa3_stop_gsi_channel(clnt_hdl);
|
||||
/* channel stop might fail on timeout if IPA is busy */
|
||||
for (i = 0; i < IPA_GSI_CHANNEL_STOP_MAX_RETRY; i++) {
|
||||
result = ipa3_stop_gsi_channel(clnt_hdl);
|
||||
if (result == GSI_STATUS_SUCCESS)
|
||||
break;
|
||||
|
||||
if (result != -GSI_STATUS_AGAIN &&
|
||||
result != -GSI_STATUS_TIMED_OUT)
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != GSI_STATUS_SUCCESS) {
|
||||
IPAERR("GSI stop chan err: %d.\n", result);
|
||||
BUG();
|
||||
|
|
|
@ -3582,21 +3582,30 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl)
|
|||
|
||||
memset(&mem, 0, sizeof(mem));
|
||||
|
||||
for (i = 0; i < IPA_GSI_CHANNEL_STOP_MAX_RETRY; i++) {
|
||||
IPADBG("Calling gsi_stop_channel\n");
|
||||
if (IPA_CLIENT_IS_PROD(ep->client)) {
|
||||
IPADBG("Calling gsi_stop_channel ch:%lu\n",
|
||||
ep->gsi_chan_hdl);
|
||||
res = gsi_stop_channel(ep->gsi_chan_hdl);
|
||||
IPADBG("gsi_stop_channel returned %d\n", res);
|
||||
IPADBG("gsi_stop_channel ch: %lu returned %d\n",
|
||||
ep->gsi_chan_hdl, res);
|
||||
goto end_sequence;
|
||||
}
|
||||
|
||||
for (i = 0; i < IPA_GSI_CHANNEL_STOP_MAX_RETRY; i++) {
|
||||
IPADBG("Calling gsi_stop_channel ch:%lu\n",
|
||||
ep->gsi_chan_hdl);
|
||||
res = gsi_stop_channel(ep->gsi_chan_hdl);
|
||||
IPADBG("gsi_stop_channel ch: %lu returned %d\n",
|
||||
ep->gsi_chan_hdl, res);
|
||||
if (res != -GSI_STATUS_AGAIN && res != -GSI_STATUS_TIMED_OUT)
|
||||
goto end_sequence;
|
||||
|
||||
if (IPA_CLIENT_IS_CONS(ep->client)) {
|
||||
IPADBG("Inject a DMA_TASK with 1B packet to IPA\n");
|
||||
/* Send a 1B packet DMA_TASK to IPA and try again */
|
||||
res = ipa3_inject_dma_task_for_gsi();
|
||||
if (res) {
|
||||
IPAERR("Failed to inject DMA TASk for GSI\n");
|
||||
goto end_sequence;
|
||||
}
|
||||
IPADBG("Inject a DMA_TASK with 1B packet to IPA\n");
|
||||
/* Send a 1B packet DMA_TASK to IPA and try again */
|
||||
res = ipa3_inject_dma_task_for_gsi();
|
||||
if (res) {
|
||||
IPAERR("Failed to inject DMA TASk for GSI\n");
|
||||
goto end_sequence;
|
||||
}
|
||||
|
||||
/* sleep for short period to flush IPA */
|
||||
|
|
Loading…
Add table
Reference in a new issue