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:
parent
4dc48c37d1
commit
2c99b8bfb2
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue