diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2014-06-20 06:16:18 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-06-21 06:17:36 -0400 |
commit | 75b82e23a4ea20a9e1a48695ff5e01761889dbb3 (patch) | |
tree | 0b9e314ebbb6aa46abd62e7cb5a81d278348a9ce | |
parent | 76c02e71612533206cb062b875c9609bce83d23a (diff) |
spi: sh-msiof: Improve transfer error handling
- Add a timeout when waiting for the transfer complete interrupt,
- If sh_msiof_spi_stop() fails, there's no need to clear IER, as the
interrupt handler has already done that,
- Propagate transfer failures in sh_msiof_transfer_one().
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | drivers/spi/spi-sh-msiof.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 2cd5fcb86f71..e5894a65c797 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
@@ -575,11 +575,16 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, | |||
575 | ret = sh_msiof_spi_start(p, rx_buf); | 575 | ret = sh_msiof_spi_start(p, rx_buf); |
576 | if (ret) { | 576 | if (ret) { |
577 | dev_err(&p->pdev->dev, "failed to start hardware\n"); | 577 | dev_err(&p->pdev->dev, "failed to start hardware\n"); |
578 | goto err; | 578 | goto stop_ier; |
579 | } | 579 | } |
580 | 580 | ||
581 | /* wait for tx fifo to be emptied / rx fifo to be filled */ | 581 | /* wait for tx fifo to be emptied / rx fifo to be filled */ |
582 | wait_for_completion(&p->done); | 582 | ret = wait_for_completion_timeout(&p->done, HZ); |
583 | if (!ret) { | ||
584 | dev_err(&p->pdev->dev, "PIO timeout\n"); | ||
585 | ret = -ETIMEDOUT; | ||
586 | goto stop_reset; | ||
587 | } | ||
583 | 588 | ||
584 | /* read rx fifo */ | 589 | /* read rx fifo */ |
585 | if (rx_buf) | 590 | if (rx_buf) |
@@ -591,12 +596,15 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, | |||
591 | ret = sh_msiof_spi_stop(p, rx_buf); | 596 | ret = sh_msiof_spi_stop(p, rx_buf); |
592 | if (ret) { | 597 | if (ret) { |
593 | dev_err(&p->pdev->dev, "failed to shut down hardware\n"); | 598 | dev_err(&p->pdev->dev, "failed to shut down hardware\n"); |
594 | goto err; | 599 | return ret; |
595 | } | 600 | } |
596 | 601 | ||
597 | return words; | 602 | return words; |
598 | 603 | ||
599 | err: | 604 | stop_reset: |
605 | sh_msiof_reset_str(p); | ||
606 | sh_msiof_spi_stop(p, rx_buf); | ||
607 | stop_ier: | ||
600 | sh_msiof_write(p, IER, 0); | 608 | sh_msiof_write(p, IER, 0); |
601 | return ret; | 609 | return ret; |
602 | } | 610 | } |
@@ -679,7 +687,7 @@ static int sh_msiof_transfer_one(struct spi_master *master, | |||
679 | rx_buf, | 687 | rx_buf, |
680 | words, bits); | 688 | words, bits); |
681 | if (n < 0) | 689 | if (n < 0) |
682 | break; | 690 | return n; |
683 | 691 | ||
684 | bytes_done += n * bytes_per_word; | 692 | bytes_done += n * bytes_per_word; |
685 | words -= n; | 693 | words -= n; |