OSDN Git Service

msm: ipa3: fix channel stop retry logic
authorSkylar Chang <chiaweic@codeaurora.org>
Mon, 24 Apr 2017 17:05:05 +0000 (10:05 -0700)
committerSkylar Chang <chiaweic@codeaurora.org>
Mon, 1 May 2017 19:18:40 +0000 (12:18 -0700)
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>
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
drivers/platform/msm/ipa/ipa_v3/ipa_utils.c

index c5b56f1..f230627 100644 (file)
@@ -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();
index f4a7319..5ffc1f2 100644 (file)
@@ -3582,21 +3582,30 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl)
 
        memset(&mem, 0, sizeof(mem));
 
+       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 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\n");
+               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);
                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 */