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