Commit f659b57361c4a351ef2a5fc23b9197428e2e67f0
Committed by
Jagannadha Sutradharudu Teki
1 parent
22052c6236
Exists in
v2017.01-smarct4x
and in
37 other branches
spi, spi_mxc: do not hang in spi_xchg_single
if status register do never set MXC_CSPICTRL_TC, spi_xchg_single endless loops. Add a timeout here to prevent endless hang. Signed-off-by: Heiko Schocher <hs@denx.de> Cc: Dirk Behme <dirk.behme@gmail.com> Reviewed-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
Showing 2 changed files with 19 additions and 2 deletions Side-by-side Diff
README
... | ... | @@ -2597,6 +2597,10 @@ |
2597 | 2597 | Enables the driver for the SPI controllers on i.MX and MXC |
2598 | 2598 | SoCs. Currently i.MX31/35/51 are supported. |
2599 | 2599 | |
2600 | + CONFIG_SYS_SPI_MXC_WAIT | |
2601 | + Timeout for waiting until spi transfer completed. | |
2602 | + default: (CONFIG_SYS_HZ/100) /* 10 ms */ | |
2603 | + | |
2600 | 2604 | - FPGA Support: CONFIG_FPGA |
2601 | 2605 | |
2602 | 2606 | Enables FPGA subsystem. |
drivers/spi/mxc_spi.c
... | ... | @@ -30,6 +30,10 @@ |
30 | 30 | #define reg_read readl |
31 | 31 | #define reg_write(a, v) writel(v, a) |
32 | 32 | |
33 | +#if !defined(CONFIG_SYS_SPI_MXC_WAIT) | |
34 | +#define CONFIG_SYS_SPI_MXC_WAIT (CONFIG_SYS_HZ/100) /* 10 ms */ | |
35 | +#endif | |
36 | + | |
33 | 37 | struct mxc_spi_slave { |
34 | 38 | struct spi_slave slave; |
35 | 39 | unsigned long base; |
... | ... | @@ -212,6 +216,8 @@ |
212 | 216 | int nbytes = DIV_ROUND_UP(bitlen, 8); |
213 | 217 | u32 data, cnt, i; |
214 | 218 | struct cspi_regs *regs = (struct cspi_regs *)mxcs->base; |
219 | + u32 ts; | |
220 | + int status; | |
215 | 221 | |
216 | 222 | debug("%s: bitlen %d dout 0x%x din 0x%x\n", |
217 | 223 | __func__, bitlen, (u32)dout, (u32)din); |
218 | 224 | |
... | ... | @@ -272,9 +278,16 @@ |
272 | 278 | reg_write(®s->ctrl, mxcs->ctrl_reg | |
273 | 279 | MXC_CSPICTRL_EN | MXC_CSPICTRL_XCH); |
274 | 280 | |
281 | + ts = get_timer(0); | |
282 | + status = reg_read(®s->stat); | |
275 | 283 | /* Wait until the TC (Transfer completed) bit is set */ |
276 | - while ((reg_read(®s->stat) & MXC_CSPICTRL_TC) == 0) | |
277 | - ; | |
284 | + while ((status & MXC_CSPICTRL_TC) == 0) { | |
285 | + if (get_timer(ts) > CONFIG_SYS_SPI_MXC_WAIT) { | |
286 | + printf("spi_xchg_single: Timeout!\n"); | |
287 | + return -1; | |
288 | + } | |
289 | + status = reg_read(®s->stat); | |
290 | + } | |
278 | 291 | |
279 | 292 | /* Transfer completed, clear any pending request */ |
280 | 293 | reg_write(®s->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF); |