]>
Commit | Line | Data |
---|---|---|
72fc6108 GKH |
1 | From foo@baz Mon Apr 9 10:16:32 CEST 2018 |
2 | From: Geert Uytterhoeven <geert+renesas@glider.be> | |
3 | Date: Wed, 3 Jan 2018 18:11:14 +0100 | |
4 | Subject: spi: sh-msiof: Fix timeout failures for TX-only DMA transfers | |
5 | ||
6 | From: Geert Uytterhoeven <geert+renesas@glider.be> | |
7 | ||
8 | ||
9 | [ Upstream commit 89434c3c35081439627baa2225622d5bd12242fe ] | |
10 | ||
11 | When using RX (with or without TX), the DMA interrupt triggers | |
12 | completion when the RX FIFO has been emptied, i.e. after the full | |
13 | transfer has finished. | |
14 | ||
15 | However, when using TX without RX, the DMA interrupt triggers completion | |
16 | as soon as the DMA engine has filled the TX FIFO, i.e. before the full | |
17 | transfer has finished. Then sh_msiof_modify_ctr_wait() will spin until | |
18 | the transfer has really finished and the TFSE bit is cleared, for at | |
19 | most 1 ms. For slow speeds and/or large transfers, this may cause | |
20 | timeouts and transfer failures: | |
21 | ||
22 | spi_sh_msiof e6e10000.spi: failed to shut down hardware | |
23 | 74x164 spi2.0: SPI transfer failed: -110 | |
24 | spi_master spi2: failed to transfer one message from queue | |
25 | 74x164 spi2.0: Failed writing: -110 | |
26 | ||
27 | Fix this by waiting explicitly until the TX FIFO has been emptied. | |
28 | ||
29 | Based on a patch in the BSP by Hiromitsu Yamasaki. | |
30 | ||
31 | Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> | |
32 | Signed-off-by: Mark Brown <broonie@kernel.org> | |
33 | Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> | |
34 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
35 | --- | |
36 | drivers/spi/spi-sh-msiof.c | 12 +++++++++++- | |
37 | 1 file changed, 11 insertions(+), 1 deletion(-) | |
38 | ||
39 | --- a/drivers/spi/spi-sh-msiof.c | |
40 | +++ b/drivers/spi/spi-sh-msiof.c | |
41 | @@ -797,11 +797,21 @@ static int sh_msiof_dma_once(struct sh_m | |
42 | goto stop_dma; | |
43 | } | |
44 | ||
45 | - /* wait for tx fifo to be emptied / rx fifo to be filled */ | |
46 | + /* wait for tx/rx DMA completion */ | |
47 | ret = sh_msiof_wait_for_completion(p); | |
48 | if (ret) | |
49 | goto stop_reset; | |
50 | ||
51 | + if (!rx) { | |
52 | + reinit_completion(&p->done); | |
53 | + sh_msiof_write(p, IER, IER_TEOFE); | |
54 | + | |
55 | + /* wait for tx fifo to be emptied */ | |
56 | + ret = sh_msiof_wait_for_completion(p); | |
57 | + if (ret) | |
58 | + goto stop_reset; | |
59 | + } | |
60 | + | |
61 | /* clear status bits */ | |
62 | sh_msiof_reset_str(p); | |
63 |