diff options
| author | Deven Patel <cdevenp@codeaurora.org> | 2016-02-22 14:12:02 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-25 16:03:13 -0700 |
| commit | 3e36cd9a4228712f040adb806818d5b08e227282 (patch) | |
| tree | e93edabd88ba417caed5f7df27ad88c0a4b946b0 /drivers/soc | |
| parent | c594314ae595d80b3551e2286aedf2cae920c5e5 (diff) | |
drivers: soc: put APR Tx buffer back into queue in error scenario
When underlying channel fails to send the APR buffer to the remote
end, APR should put the Tx buffer back into queue to avoid memory
leak.
CRs-fixed: 979283
Change-Id: I4f94daa3c9be748a30d532cf9cc8f3aa2284c060
Signed-off-by: Deven Patel <cdevenp@codeaurora.org>
Diffstat (limited to 'drivers/soc')
| -rw-r--r-- | drivers/soc/qcom/qdsp6v2/apr_tal_glink.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c index fb3ce963a1a9..7aa075c4cff1 100644 --- a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c +++ b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c @@ -92,6 +92,20 @@ static int apr_get_free_buf(int len, void **buf) return 0; } +static void apr_buf_add_tail(void *buf) +{ + struct apr_tx_buf *list; + unsigned long flags; + + if (!buf) + return; + + spin_lock_irqsave(&buf_list.lock, flags); + list = container_of(buf, struct apr_tx_buf, buf); + list_add_tail(&list->list, &buf_list.list); + spin_unlock_irqrestore(&buf_list.lock, flags); +} + static int __apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, struct apr_pkt_priv *pkt_priv, int len) { @@ -137,8 +151,11 @@ int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, rc = __apr_tal_write(apr_ch, pkt_data, pkt_priv, len); } while (rc == -EAGAIN && retries++ < APR_MAXIMUM_NUM_OF_RETRIES); - if (rc == -EAGAIN) - pr_err("%s: TIMEOUT for write\n", __func__); + if (rc < 0) { + pr_err("%s: Unable to send the packet, rc:%d\n", __func__, rc); + if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) + apr_buf_add_tail(pkt_data); + } exit: return rc; } @@ -177,12 +194,8 @@ void apr_tal_notify_tx_done(void *handle, const void *priv, pr_debug("%s: tx_done received\n", __func__); - if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) { - spin_lock_irqsave(&buf_list.lock, flags); - buf = container_of(ptr, struct apr_tx_buf, list); - list_add_tail(&buf->list, &buf_list.list); - spin_unlock_irqrestore(&buf_list.lock, flags); - } + if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) + apr_buf_add_tail(ptr); } bool apr_tal_notify_rx_intent_req(void *handle, const void *priv, |
