Commit f659b57361c4a351ef2a5fc23b9197428e2e67f0

Authored by Heiko Schocher
Committed by Jagannadha Sutradharudu Teki
1 parent 22052c6236

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

... ... @@ -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(&regs->ctrl, mxcs->ctrl_reg |
273 279 MXC_CSPICTRL_EN | MXC_CSPICTRL_XCH);
274 280  
  281 + ts = get_timer(0);
  282 + status = reg_read(&regs->stat);
275 283 /* Wait until the TC (Transfer completed) bit is set */
276   - while ((reg_read(&regs->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(&regs->stat);
  290 + }
278 291  
279 292 /* Transfer completed, clear any pending request */
280 293 reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF);