diff options
author | Vipin Kumar <vipin.kumar@st.com> | 2012-07-02 01:58:47 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-07-06 13:27:48 -0400 |
commit | 2c99b8bfb22342ab0c06e07ee54fa0d5e638e52a (patch) | |
tree | 63ae3cdccac97eb94433be9b865b297da3d55fba /drivers/mtd/devices | |
parent | 4dc48c37d1ce968b5ade7d1646927199ee536129 (diff) |
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')
-rw-r--r-- | drivers/mtd/devices/spear_smi.c | 23 |
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) | |||
241 | /* copy dev->status (lower 16 bits) in order to release lock */ | 241 | /* copy dev->status (lower 16 bits) in order to release lock */ |
242 | if (ret > 0) | 242 | if (ret > 0) |
243 | ret = dev->status & 0xffff; | 243 | ret = dev->status & 0xffff; |
244 | else | 244 | else if (ret == 0) |
245 | ret = -EIO; | 245 | ret = -ETIMEDOUT; |
246 | 246 | ||
247 | /* restore the ctrl regs state */ | 247 | /* restore the ctrl regs state */ |
248 | writel(ctrlreg1, dev->io_base + SMI_CR1); | 248 | writel(ctrlreg1, dev->io_base + SMI_CR1); |
@@ -270,16 +270,19 @@ static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank, | |||
270 | finish = jiffies + timeout; | 270 | finish = jiffies + timeout; |
271 | do { | 271 | do { |
272 | status = spear_smi_read_sr(dev, bank); | 272 | status = spear_smi_read_sr(dev, bank); |
273 | if (status < 0) | 273 | if (status < 0) { |
274 | continue; /* try till timeout */ | 274 | if (status == -ETIMEDOUT) |
275 | else if (!(status & SR_WIP)) | 275 | continue; /* try till finish */ |
276 | return status; | ||
277 | } else if (!(status & SR_WIP)) { | ||
276 | return 0; | 278 | return 0; |
279 | } | ||
277 | 280 | ||
278 | cond_resched(); | 281 | cond_resched(); |
279 | } while (!time_after_eq(jiffies, finish)); | 282 | } while (!time_after_eq(jiffies, finish)); |
280 | 283 | ||
281 | dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n"); | 284 | dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n"); |
282 | return status; | 285 | return -EBUSY; |
283 | } | 286 | } |
284 | 287 | ||
285 | /** | 288 | /** |
@@ -395,11 +398,11 @@ static int spear_smi_write_enable(struct spear_smi *dev, u32 bank) | |||
395 | writel(ctrlreg1, dev->io_base + SMI_CR1); | 398 | writel(ctrlreg1, dev->io_base + SMI_CR1); |
396 | writel(0, dev->io_base + SMI_CR2); | 399 | writel(0, dev->io_base + SMI_CR2); |
397 | 400 | ||
398 | if (ret <= 0) { | 401 | if (ret == 0) { |
399 | ret = -EIO; | 402 | ret = -EIO; |
400 | dev_err(&dev->pdev->dev, | 403 | dev_err(&dev->pdev->dev, |
401 | "smi controller failed on write enable\n"); | 404 | "smi controller failed on write enable\n"); |
402 | } else { | 405 | } else if (ret > 0) { |
403 | /* check whether write mode status is set for required bank */ | 406 | /* check whether write mode status is set for required bank */ |
404 | if (dev->status & (1 << (bank + WM_SHIFT))) | 407 | if (dev->status & (1 << (bank + WM_SHIFT))) |
405 | ret = 0; | 408 | ret = 0; |
@@ -466,10 +469,10 @@ static int spear_smi_erase_sector(struct spear_smi *dev, | |||
466 | ret = wait_event_interruptible_timeout(dev->cmd_complete, | 469 | ret = wait_event_interruptible_timeout(dev->cmd_complete, |
467 | dev->status & TFF, SMI_CMD_TIMEOUT); | 470 | dev->status & TFF, SMI_CMD_TIMEOUT); |
468 | 471 | ||
469 | if (ret <= 0) { | 472 | if (ret == 0) { |
470 | ret = -EIO; | 473 | ret = -EIO; |
471 | dev_err(&dev->pdev->dev, "sector erase failed\n"); | 474 | dev_err(&dev->pdev->dev, "sector erase failed\n"); |
472 | } else | 475 | } else if (ret > 0) |
473 | ret = 0; /* success */ | 476 | ret = 0; /* success */ |
474 | 477 | ||
475 | /* restore ctrl regs */ | 478 | /* restore ctrl regs */ |