Commit df8f348e authored by David S. Miller's avatar David S. Miller

Merge branch 'net-ipa-dont-cache-channel-state'

Alex Elder says:

====================
net: ipa: don't cache channel state

This series removes a field that holds a copy of a channel's state
at the time it was last fetched.  In principle the state can change
at any time, so it's better to just fetch it whenever needed.  The
first patch is just preparatory, simplifying the arguments to
gsi_channel_state().
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b7052ba7 a2003b30
...@@ -415,13 +415,14 @@ static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id) ...@@ -415,13 +415,14 @@ static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id)
evt_ring->state); evt_ring->state);
} }
/* Return the hardware's notion of the current state of a channel */ /* Fetch the current state of a channel from hardware */
static enum gsi_channel_state static enum gsi_channel_state gsi_channel_state(struct gsi_channel *channel)
gsi_channel_state(struct gsi *gsi, u32 channel_id)
{ {
u32 channel_id = gsi_channel_id(channel);
void *virt = channel->gsi->virt;
u32 val; u32 val;
val = ioread32(gsi->virt + GSI_CH_C_CNTXT_0_OFFSET(channel_id)); val = ioread32(virt + GSI_CH_C_CNTXT_0_OFFSET(channel_id));
return u32_get_bits(val, CHSTATE_FMASK); return u32_get_bits(val, CHSTATE_FMASK);
} }
...@@ -432,16 +433,18 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode) ...@@ -432,16 +433,18 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode)
{ {
struct completion *completion = &channel->completion; struct completion *completion = &channel->completion;
u32 channel_id = gsi_channel_id(channel); u32 channel_id = gsi_channel_id(channel);
struct gsi *gsi = channel->gsi;
u32 val; u32 val;
val = u32_encode_bits(channel_id, CH_CHID_FMASK); val = u32_encode_bits(channel_id, CH_CHID_FMASK);
val |= u32_encode_bits(opcode, CH_OPCODE_FMASK); val |= u32_encode_bits(opcode, CH_OPCODE_FMASK);
if (gsi_command(channel->gsi, GSI_CH_CMD_OFFSET, val, completion)) if (gsi_command(gsi, GSI_CH_CMD_OFFSET, val, completion))
return 0; /* Success! */ return 0; /* Success! */
dev_err(channel->gsi->dev, "GSI command %u to channel %u timed out " dev_err(gsi->dev,
"(state is %u)\n", opcode, channel_id, channel->state); "GSI command %u to channel %u timed out (state is %u)\n",
opcode, channel_id, gsi_channel_state(channel));
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -450,18 +453,21 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode) ...@@ -450,18 +453,21 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode)
static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id) static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id)
{ {
struct gsi_channel *channel = &gsi->channel[channel_id]; struct gsi_channel *channel = &gsi->channel[channel_id];
enum gsi_channel_state state;
int ret; int ret;
/* Get initial channel state */ /* Get initial channel state */
channel->state = gsi_channel_state(gsi, channel_id); state = gsi_channel_state(channel);
if (state != GSI_CHANNEL_STATE_NOT_ALLOCATED)
if (channel->state != GSI_CHANNEL_STATE_NOT_ALLOCATED)
return -EINVAL; return -EINVAL;
ret = gsi_channel_command(channel, GSI_CH_ALLOCATE); ret = gsi_channel_command(channel, GSI_CH_ALLOCATE);
if (!ret && channel->state != GSI_CHANNEL_STATE_ALLOCATED) {
/* Channel state will normally have been updated */
state = gsi_channel_state(channel);
if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) {
dev_err(gsi->dev, "bad channel state (%u) after alloc\n", dev_err(gsi->dev, "bad channel state (%u) after alloc\n",
channel->state); state);
ret = -EIO; ret = -EIO;
} }
...@@ -471,18 +477,21 @@ static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id) ...@@ -471,18 +477,21 @@ static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id)
/* Start an ALLOCATED channel */ /* Start an ALLOCATED channel */
static int gsi_channel_start_command(struct gsi_channel *channel) static int gsi_channel_start_command(struct gsi_channel *channel)
{ {
enum gsi_channel_state state = channel->state; enum gsi_channel_state state;
int ret; int ret;
state = gsi_channel_state(channel);
if (state != GSI_CHANNEL_STATE_ALLOCATED && if (state != GSI_CHANNEL_STATE_ALLOCATED &&
state != GSI_CHANNEL_STATE_STOPPED) state != GSI_CHANNEL_STATE_STOPPED)
return -EINVAL; return -EINVAL;
ret = gsi_channel_command(channel, GSI_CH_START); ret = gsi_channel_command(channel, GSI_CH_START);
if (!ret && channel->state != GSI_CHANNEL_STATE_STARTED) {
/* Channel state will normally have been updated */
state = gsi_channel_state(channel);
if (!ret && state != GSI_CHANNEL_STATE_STARTED) {
dev_err(channel->gsi->dev, dev_err(channel->gsi->dev,
"bad channel state (%u) after start\n", "bad channel state (%u) after start\n", state);
channel->state);
ret = -EIO; ret = -EIO;
} }
...@@ -492,23 +501,27 @@ static int gsi_channel_start_command(struct gsi_channel *channel) ...@@ -492,23 +501,27 @@ static int gsi_channel_start_command(struct gsi_channel *channel)
/* Stop a GSI channel in STARTED state */ /* Stop a GSI channel in STARTED state */
static int gsi_channel_stop_command(struct gsi_channel *channel) static int gsi_channel_stop_command(struct gsi_channel *channel)
{ {
enum gsi_channel_state state = channel->state; enum gsi_channel_state state;
int ret; int ret;
state = gsi_channel_state(channel);
if (state != GSI_CHANNEL_STATE_STARTED && if (state != GSI_CHANNEL_STATE_STARTED &&
state != GSI_CHANNEL_STATE_STOP_IN_PROC) state != GSI_CHANNEL_STATE_STOP_IN_PROC)
return -EINVAL; return -EINVAL;
ret = gsi_channel_command(channel, GSI_CH_STOP); ret = gsi_channel_command(channel, GSI_CH_STOP);
if (ret || channel->state == GSI_CHANNEL_STATE_STOPPED)
/* Channel state will normally have been updated */
state = gsi_channel_state(channel);
if (ret || state == GSI_CHANNEL_STATE_STOPPED)
return ret; return ret;
/* We may have to try again if stop is in progress */ /* We may have to try again if stop is in progress */
if (channel->state == GSI_CHANNEL_STATE_STOP_IN_PROC) if (state == GSI_CHANNEL_STATE_STOP_IN_PROC)
return -EAGAIN; return -EAGAIN;
dev_err(channel->gsi->dev, "bad channel state (%u) after stop\n", dev_err(channel->gsi->dev,
channel->state); "bad channel state (%u) after stop\n", state);
return -EIO; return -EIO;
} }
...@@ -516,41 +529,49 @@ static int gsi_channel_stop_command(struct gsi_channel *channel) ...@@ -516,41 +529,49 @@ static int gsi_channel_stop_command(struct gsi_channel *channel)
/* Reset a GSI channel in ALLOCATED or ERROR state. */ /* Reset a GSI channel in ALLOCATED or ERROR state. */
static void gsi_channel_reset_command(struct gsi_channel *channel) static void gsi_channel_reset_command(struct gsi_channel *channel)
{ {
enum gsi_channel_state state;
int ret; int ret;
msleep(1); /* A short delay is required before a RESET command */ msleep(1); /* A short delay is required before a RESET command */
if (channel->state != GSI_CHANNEL_STATE_STOPPED && state = gsi_channel_state(channel);
channel->state != GSI_CHANNEL_STATE_ERROR) { if (state != GSI_CHANNEL_STATE_STOPPED &&
state != GSI_CHANNEL_STATE_ERROR) {
dev_err(channel->gsi->dev, dev_err(channel->gsi->dev,
"bad channel state (%u) before reset\n", "bad channel state (%u) before reset\n", state);
channel->state);
return; return;
} }
ret = gsi_channel_command(channel, GSI_CH_RESET); ret = gsi_channel_command(channel, GSI_CH_RESET);
if (!ret && channel->state != GSI_CHANNEL_STATE_ALLOCATED)
/* Channel state will normally have been updated */
state = gsi_channel_state(channel);
if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED)
dev_err(channel->gsi->dev, dev_err(channel->gsi->dev,
"bad channel state (%u) after reset\n", "bad channel state (%u) after reset\n", state);
channel->state);
} }
/* Deallocate an ALLOCATED GSI channel */ /* Deallocate an ALLOCATED GSI channel */
static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id) static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id)
{ {
struct gsi_channel *channel = &gsi->channel[channel_id]; struct gsi_channel *channel = &gsi->channel[channel_id];
enum gsi_channel_state state;
int ret; int ret;
if (channel->state != GSI_CHANNEL_STATE_ALLOCATED) { state = gsi_channel_state(channel);
dev_err(gsi->dev, "bad channel state (%u) before dealloc\n", if (state != GSI_CHANNEL_STATE_ALLOCATED) {
channel->state); dev_err(gsi->dev,
"bad channel state (%u) before dealloc\n", state);
return; return;
} }
ret = gsi_channel_command(channel, GSI_CH_DE_ALLOC); ret = gsi_channel_command(channel, GSI_CH_DE_ALLOC);
if (!ret && channel->state != GSI_CHANNEL_STATE_NOT_ALLOCATED)
dev_err(gsi->dev, "bad channel state (%u) after dealloc\n", /* Channel state will normally have been updated */
channel->state); state = gsi_channel_state(channel);
if (!ret && state != GSI_CHANNEL_STATE_NOT_ALLOCATED)
dev_err(gsi->dev,
"bad channel state (%u) after dealloc\n", state);
} }
/* Ring an event ring doorbell, reporting the last entry processed by the AP. /* Ring an event ring doorbell, reporting the last entry processed by the AP.
...@@ -777,6 +798,7 @@ int gsi_channel_start(struct gsi *gsi, u32 channel_id) ...@@ -777,6 +798,7 @@ int gsi_channel_start(struct gsi *gsi, u32 channel_id)
int gsi_channel_stop(struct gsi *gsi, u32 channel_id) int gsi_channel_stop(struct gsi *gsi, u32 channel_id)
{ {
struct gsi_channel *channel = &gsi->channel[channel_id]; struct gsi_channel *channel = &gsi->channel[channel_id];
enum gsi_channel_state state;
u32 retries; u32 retries;
int ret; int ret;
...@@ -786,7 +808,8 @@ int gsi_channel_stop(struct gsi *gsi, u32 channel_id) ...@@ -786,7 +808,8 @@ int gsi_channel_stop(struct gsi *gsi, u32 channel_id)
* STOP command timed out. We won't stop a channel if stopping it * STOP command timed out. We won't stop a channel if stopping it
* was successful previously (so we still want the freeze above). * was successful previously (so we still want the freeze above).
*/ */
if (channel->state == GSI_CHANNEL_STATE_STOPPED) state = gsi_channel_state(channel);
if (state == GSI_CHANNEL_STATE_STOPPED)
return 0; return 0;
/* RX channels might require a little time to enter STOPPED state */ /* RX channels might require a little time to enter STOPPED state */
...@@ -940,7 +963,6 @@ static void gsi_isr_chan_ctrl(struct gsi *gsi) ...@@ -940,7 +963,6 @@ static void gsi_isr_chan_ctrl(struct gsi *gsi)
channel_mask ^= BIT(channel_id); channel_mask ^= BIT(channel_id);
channel = &gsi->channel[channel_id]; channel = &gsi->channel[channel_id];
channel->state = gsi_channel_state(gsi, channel_id);
complete(&channel->completion); complete(&channel->completion);
} }
......
...@@ -113,8 +113,7 @@ struct gsi_channel { ...@@ -113,8 +113,7 @@ struct gsi_channel {
u16 tre_count; u16 tre_count;
u16 event_count; u16 event_count;
struct completion completion; /* signals channel state changes */ struct completion completion; /* signals channel command completion */
enum gsi_channel_state state;
struct gsi_ring tre_ring; struct gsi_ring tre_ring;
u32 evt_ring_id; u32 evt_ring_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment