summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAjitpal.Singh <ajitpal.singh@stericsson.com>2012-02-29 15:14:14 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:06:36 +0200
commitf8078997500faad868cdd6374abfdb0f17f34026 (patch)
tree64f73886013bb36ecad34cd826ccaa9bb188178c
parent7dafd98f73a6a55a257305eeacfc8c65b085bdbe (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.c43
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);