Create a new function that does most of the work of starting a
channel.  What's different is that it takes a flag indicating
whether the channel should really be started or not.  Create
another new function __gsi_channel_stop() that behaves similarly.

IPA v3.5.1 implements suspend using a special SUSPEND endpoint
setting.  If the endpoint is suspended when an I/O completes on the
underlying GSI channel, a SUSPEND interrupt is generated.

Newer versions of IPA do not implement the SUSPEND endpoint mode.
Instead, endpoint suspend is implemented by simply stopping the
underlying GSI channel.  In this case, a completing I/O on a
*stopped* channel causes the SUSPEND interrupt condition.

These new functions put all activity related to starting or stopping
a channel (including "thawing/freezing" the channel) in one place,
whether or not the channel is actually started or stopped.

Signed-off-by: Alex Elder <el...@linaro.org>
---
 drivers/net/ipa/gsi.c | 71 ++++++++++++++++++++++---------------------
 1 file changed, 37 insertions(+), 34 deletions(-)

diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index bd1bf388d9892..bba64887fe969 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -873,23 +873,30 @@ static void gsi_channel_deprogram(struct gsi_channel 
*channel)
        /* Nothing to do */
 }
 
+static int __gsi_channel_start(struct gsi_channel *channel, bool start)
+{
+       struct gsi *gsi = channel->gsi;
+       int ret;
+
+       mutex_lock(&gsi->mutex);
+
+       ret = start ? gsi_channel_start_command(channel) : 0;
+
+       mutex_unlock(&gsi->mutex);
+
+       /* Thaw the channel if successful */
+       if (!ret)
+               gsi_channel_thaw(channel);
+
+       return ret;
+}
+
 /* Start an allocated GSI channel */
 int gsi_channel_start(struct gsi *gsi, u32 channel_id)
 {
        struct gsi_channel *channel = &gsi->channel[channel_id];
-       int ret;
 
-       mutex_lock(&gsi->mutex);
-
-       ret = gsi_channel_start_command(channel);
-
-       mutex_unlock(&gsi->mutex);
-
-       /* Thaw the channel if successful */
-       if (!ret)
-               gsi_channel_thaw(channel);
-
-       return ret;
+       return __gsi_channel_start(channel, true);
 }
 
 static int gsi_channel_stop_retry(struct gsi_channel *channel)
@@ -912,21 +919,27 @@ static int gsi_channel_stop_retry(struct gsi_channel 
*channel)
        return ret;
 }
 
+static int __gsi_channel_stop(struct gsi_channel *channel, bool stop)
+{
+       int ret;
+
+       gsi_channel_freeze(channel);
+
+       ret = stop ? gsi_channel_stop_retry(channel) : 0;
+
+       /* Re-thaw the channel if an error occurred while stopping */
+       if (ret)
+               gsi_channel_thaw(channel);
+
+       return ret;
+}
+
 /* Stop a started channel */
 int gsi_channel_stop(struct gsi *gsi, u32 channel_id)
 {
        struct gsi_channel *channel = &gsi->channel[channel_id];
-       int ret;
 
-       gsi_channel_freeze(channel);
-
-       ret = gsi_channel_stop_retry(channel);
-
-       /* Re-thaw the channel if an error occurred while stopping */
-       if (ret)
-               gsi_channel_thaw(channel);
-
-       return ret;
+       return __gsi_channel_stop(channel, true);
 }
 
 /* Reset and reconfigure a channel, (possibly) enabling the doorbell engine */
@@ -952,12 +965,7 @@ int gsi_channel_suspend(struct gsi *gsi, u32 channel_id, 
bool stop)
 {
        struct gsi_channel *channel = &gsi->channel[channel_id];
 
-       if (stop)
-               return gsi_channel_stop(gsi, channel_id);
-
-       gsi_channel_freeze(channel);
-
-       return 0;
+       return __gsi_channel_stop(channel, stop);
 }
 
 /* Resume a suspended channel (starting will be requested if STOPPED) */
@@ -965,12 +973,7 @@ int gsi_channel_resume(struct gsi *gsi, u32 channel_id, 
bool start)
 {
        struct gsi_channel *channel = &gsi->channel[channel_id];
 
-       if (start)
-               return gsi_channel_start(gsi, channel_id);
-
-       gsi_channel_thaw(channel);
-
-       return 0;
+       return __gsi_channel_start(channel, start);
 }
 
 /**
-- 
2.27.0

Reply via email to