diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c index db82ae48e402..447165e980ea 100644 --- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -284,11 +284,12 @@ static struct gsi_trans *ipa_endpoint_trans_alloc(struct ipa_endpoint *endpoint, /* suspend_delay represents suspend for RX, delay for TX endpoints. * Note that suspend is not supported starting with IPA v4.0. */ -static int +static bool ipa_endpoint_init_ctrl(struct ipa_endpoint *endpoint, bool suspend_delay) { u32 offset = IPA_REG_ENDP_INIT_CTRL_N_OFFSET(endpoint->endpoint_id); struct ipa *ipa = endpoint->ipa; + bool state; u32 mask; u32 val; @@ -296,13 +297,14 @@ ipa_endpoint_init_ctrl(struct ipa_endpoint *endpoint, bool suspend_delay) mask = endpoint->toward_ipa ? ENDP_DELAY_FMASK : ENDP_SUSPEND_FMASK; val = ioread32(ipa->reg_virt + offset); - if (suspend_delay == !!(val & mask)) - return -EALREADY; /* Already set to desired state */ + /* Don't bother if it's already in the requested state */ + state = !!(val & mask); + if (suspend_delay != state) { + val ^= mask; + iowrite32(val, ipa->reg_virt + offset); + } - val ^= mask; - iowrite32(val, ipa->reg_virt + offset); - - return 0; + return state; } /* Enable or disable delay or suspend mode on all modem endpoints */ @@ -1164,8 +1166,7 @@ static int ipa_endpoint_reset_rx_aggr(struct ipa_endpoint *endpoint) /* Make sure the channel isn't suspended */ if (endpoint->ipa->version == IPA_VERSION_3_5_1) - if (!ipa_endpoint_init_ctrl(endpoint, false)) - endpoint_suspended = true; + endpoint_suspended = ipa_endpoint_init_ctrl(endpoint, false); /* Start channel and do a 1 byte read */ ret = gsi_channel_start(gsi, endpoint->channel_id); @@ -1318,21 +1319,20 @@ static void ipa_endpoint_program(struct ipa_endpoint *endpoint) if (endpoint->toward_ipa) { bool delay_mode = endpoint->data->tx.delay; - ret = ipa_endpoint_init_ctrl(endpoint, delay_mode); /* Endpoint is expected to not be in delay mode */ - if (!ret != delay_mode) { + if (ipa_endpoint_init_ctrl(endpoint, delay_mode)) dev_warn(dev, "TX endpoint %u was %sin delay mode\n", endpoint->endpoint_id, delay_mode ? "already " : ""); - } ipa_endpoint_init_hdr_ext(endpoint); ipa_endpoint_init_aggr(endpoint); ipa_endpoint_init_deaggr(endpoint); ipa_endpoint_init_seq(endpoint); } else { + /* Endpoint is expected to not be suspended */ if (endpoint->ipa->version == IPA_VERSION_3_5_1) { - if (!ipa_endpoint_init_ctrl(endpoint, false)) + if (ipa_endpoint_init_ctrl(endpoint, false)) dev_warn(dev, "RX endpoint %u was suspended\n", endpoint->endpoint_id); @@ -1471,7 +1471,7 @@ void ipa_endpoint_resume_one(struct ipa_endpoint *endpoint) /* IPA v3.5.1 doesn't use channel start for resume */ start_channel = endpoint->ipa->version != IPA_VERSION_3_5_1; if (!endpoint->toward_ipa && !start_channel) - WARN_ON(ipa_endpoint_init_ctrl(endpoint, false)); + WARN_ON(!ipa_endpoint_init_ctrl(endpoint, false)); ret = gsi_channel_resume(gsi, endpoint->channel_id, start_channel); if (ret)