diff options
author | Ajitpal.Singh <ajitpal.singh@stericsson.com> | 2012-02-29 15:14:14 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:06:36 +0200 |
commit | f8078997500faad868cdd6374abfdb0f17f34026 (patch) | |
tree | 64f73886013bb36ecad34cd826ccaa9bb188178c | |
parent | 7dafd98f73a6a55a257305eeacfc8c65b085bdbe (diff) |
cw1200: Retry sdio read/write in case of error
SDIO read/write API sometimes returns error due to
signal integrity issues on the SDIO bus.
In such cases, sometimes retrying the operation instead of
exiting can help in recovery.
ST-Ericsson ID: 357764, 364168
ST-Ericsson FOSS-OUT ID: NA
Signed-off-by: Ajitpal.Singh <ajitpal.singh@stericsson.com>
Change-Id: Iede20c48447467a27ee7f9a49578ef7709cdd83f
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33205
Reviewed-by: QABUILD
Reviewed-by: QATEST
Reviewed-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
Tested-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
-rw-r--r-- | drivers/staging/cw1200/hwio.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/drivers/staging/cw1200/hwio.c b/drivers/staging/cw1200/hwio.c index 094ce8234f0..b544a0a4a80 100644 --- a/drivers/staging/cw1200/hwio.c +++ b/drivers/staging/cw1200/hwio.c @@ -27,6 +27,7 @@ | (((mpf) & 1) << 6) \ | (((rfu) & 1) << 5) \ | (((reg_id_ofs) & 0x1F) << 0)) +#define MAX_RETRY 3 static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr, @@ -113,16 +114,25 @@ int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf, int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len) { - int ret; + int ret, retry = 1; BUG_ON(!priv->sbus_ops); priv->sbus_ops->lock(priv->sbus_priv); { int buf_id_rx = priv->buf_id_rx; - ret = __cw1200_reg_read(priv, ST90TDS_IN_OUT_QUEUE_REG_ID, buf, - buf_len, buf_id_rx + 1); - if (!ret) { - buf_id_rx = (buf_id_rx + 1) & 3; - priv->buf_id_rx = buf_id_rx; + while (retry <= MAX_RETRY) { + ret = __cw1200_reg_read(priv, + ST90TDS_IN_OUT_QUEUE_REG_ID, buf, + buf_len, buf_id_rx + 1); + if (!ret) { + buf_id_rx = (buf_id_rx + 1) & 3; + priv->buf_id_rx = buf_id_rx; + break; + } else { + retry++; + mdelay(1); + cw1200_dbg(CW1200_DBG_ERROR, "%s,error :[%d]\n", + __func__, ret); + } } } priv->sbus_ops->unlock(priv->sbus_priv); @@ -132,16 +142,25 @@ int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len) int cw1200_data_write(struct cw1200_common *priv, const void *buf, size_t buf_len) { - int ret; + int ret, retry = 1; BUG_ON(!priv->sbus_ops); priv->sbus_ops->lock(priv->sbus_priv); { int buf_id_tx = priv->buf_id_tx; - ret = __cw1200_reg_write(priv, ST90TDS_IN_OUT_QUEUE_REG_ID, buf, - buf_len, buf_id_tx); - if (!ret) { - buf_id_tx = (buf_id_tx + 1) & 31; - priv->buf_id_tx = buf_id_tx; + while (retry <= MAX_RETRY) { + ret = __cw1200_reg_write(priv, + ST90TDS_IN_OUT_QUEUE_REG_ID, buf, + buf_len, buf_id_tx); + if (!ret) { + buf_id_tx = (buf_id_tx + 1) & 31; + priv->buf_id_tx = buf_id_tx; + break; + } else { + retry++; + mdelay(1); + cw1200_dbg(CW1200_DBG_ERROR, "%s,error :[%d]\n", + __func__, ret); + } } } priv->sbus_ops->unlock(priv->sbus_priv); |