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>
This commit is contained in:
Vipin Kumar 2012-07-02 11:28:47 +05:30 committed by David Woodhouse
parent 4dc48c37d1
commit 2c99b8bfb2

View file

@ -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 */ /* copy dev->status (lower 16 bits) in order to release lock */
if (ret > 0) if (ret > 0)
ret = dev->status & 0xffff; ret = dev->status & 0xffff;
else else if (ret == 0)
ret = -EIO; ret = -ETIMEDOUT;
/* restore the ctrl regs state */ /* restore the ctrl regs state */
writel(ctrlreg1, dev->io_base + SMI_CR1); 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; finish = jiffies + timeout;
do { do {
status = spear_smi_read_sr(dev, bank); status = spear_smi_read_sr(dev, bank);
if (status < 0) if (status < 0) {
continue; /* try till timeout */ if (status == -ETIMEDOUT)
else if (!(status & SR_WIP)) continue; /* try till finish */
return status;
} else if (!(status & SR_WIP)) {
return 0; return 0;
}
cond_resched(); cond_resched();
} while (!time_after_eq(jiffies, finish)); } while (!time_after_eq(jiffies, finish));
dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n"); 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(ctrlreg1, dev->io_base + SMI_CR1);
writel(0, dev->io_base + SMI_CR2); writel(0, dev->io_base + SMI_CR2);
if (ret <= 0) { if (ret == 0) {
ret = -EIO; ret = -EIO;
dev_err(&dev->pdev->dev, dev_err(&dev->pdev->dev,
"smi controller failed on write enable\n"); "smi controller failed on write enable\n");
} else { } else if (ret > 0) {
/* check whether write mode status is set for required bank */ /* check whether write mode status is set for required bank */
if (dev->status & (1 << (bank + WM_SHIFT))) if (dev->status & (1 << (bank + WM_SHIFT)))
ret = 0; ret = 0;
@ -466,10 +469,10 @@ static int spear_smi_erase_sector(struct spear_smi *dev,
ret = wait_event_interruptible_timeout(dev->cmd_complete, ret = wait_event_interruptible_timeout(dev->cmd_complete,
dev->status & TFF, SMI_CMD_TIMEOUT); dev->status & TFF, SMI_CMD_TIMEOUT);
if (ret <= 0) { if (ret == 0) {
ret = -EIO; ret = -EIO;
dev_err(&dev->pdev->dev, "sector erase failed\n"); dev_err(&dev->pdev->dev, "sector erase failed\n");
} else } else if (ret > 0)
ret = 0; /* success */ ret = 0; /* success */
/* restore ctrl regs */ /* restore ctrl regs */