summaryrefslogtreecommitdiff
path: root/drivers/mtd/devices/spear_smi.c
diff options
context:
space:
mode:
authorVipin Kumar <vipin.kumar@st.com>2012-07-02 09:58:47 +0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-07-06 21:27:48 +0400
commit2c99b8bfb22342ab0c06e07ee54fa0d5e638e52a (patch)
tree63ae3cdccac97eb94433be9b865b297da3d55fba /drivers/mtd/devices/spear_smi.c
parent4dc48c37d1ce968b5ade7d1646927199ee536129 (diff)
downloadlinux-2c99b8bfb22342ab0c06e07ee54fa0d5e638e52a.tar.xz
mtd: spear_smi: handle return value of timeouts properly
Handle timouts in general and return value of 'wait_event_interruptible_timeout' in particular, to capture all conditions. 'wait_event_interruptible_timeout' returns either of the following three values :- * 0 - time out occurred. * negative * -ERESTARTSYS - return because of a signal * other - for a real error * positive - time remaining Fix particularly 'ERESTARTSYS' condition which is not properly handled by the smi driver at a couple of places leading to an erroneous situation. Signed-off-by: Antonio BORNEO <antonio.borneo@st.com> Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com> Signed-off-by: Vipin Kumar <vipin.kumar@st.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/devices/spear_smi.c')
-rw-r--r--drivers/mtd/devices/spear_smi.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
index aec941e74e67..b85f183d24c0 100644
--- a/drivers/mtd/devices/spear_smi.c
+++ b/drivers/mtd/devices/spear_smi.c
@@ -241,8 +241,8 @@ static int spear_smi_read_sr(struct spear_smi *dev, u32 bank)
/* copy dev->status (lower 16 bits) in order to release lock */
if (ret > 0)
ret = dev->status & 0xffff;
- else
- ret = -EIO;
+ else if (ret == 0)
+ ret = -ETIMEDOUT;
/* restore the ctrl regs state */
writel(ctrlreg1, dev->io_base + SMI_CR1);
@@ -270,16 +270,19 @@ static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank,
finish = jiffies + timeout;
do {
status = spear_smi_read_sr(dev, bank);
- if (status < 0)
- continue; /* try till timeout */
- else if (!(status & SR_WIP))
+ if (status < 0) {
+ if (status == -ETIMEDOUT)
+ continue; /* try till finish */
+ return status;
+ } else if (!(status & SR_WIP)) {
return 0;
+ }
cond_resched();
} while (!time_after_eq(jiffies, finish));
dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");
- return status;
+ return -EBUSY;
}
/**
@@ -395,11 +398,11 @@ static int spear_smi_write_enable(struct spear_smi *dev, u32 bank)
writel(ctrlreg1, dev->io_base + SMI_CR1);
writel(0, dev->io_base + SMI_CR2);
- if (ret <= 0) {
+ if (ret == 0) {
ret = -EIO;
dev_err(&dev->pdev->dev,
"smi controller failed on write enable\n");
- } else {
+ } else if (ret > 0) {
/* check whether write mode status is set for required bank */
if (dev->status & (1 << (bank + WM_SHIFT)))
ret = 0;
@@ -466,10 +469,10 @@ static int spear_smi_erase_sector(struct spear_smi *dev,
ret = wait_event_interruptible_timeout(dev->cmd_complete,
dev->status & TFF, SMI_CMD_TIMEOUT);
- if (ret <= 0) {
+ if (ret == 0) {
ret = -EIO;
dev_err(&dev->pdev->dev, "sector erase failed\n");
- } else
+ } else if (ret > 0)
ret = 0; /* success */
/* restore ctrl regs */