summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-xilinx.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2018-01-03 12:14:04 +0300
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2018-01-03 12:14:04 +0300
commit3bdf481e39ff1d36c1f2e1b3862db2ac329b12cd (patch)
tree91ad50553511f1cb4583edce10c16371f69fa7aa /drivers/spi/spi-xilinx.c
parentd0c8f6ad8b381dd572576ac50b9696d4d31142bb (diff)
parent30a7acd573899fd8b8ac39236eff6468b195ac7d (diff)
downloadlinux-3bdf481e39ff1d36c1f2e1b3862db2ac329b12cd.tar.xz
Merge tag 'v4.15-rc6' into patchwork
Linux 4.15-rc6 * tag 'v4.15-rc6': (734 commits) Linux 4.15-rc6 MAINTAINERS: mark arch/blackfin/ and its gubbins as orphaned x86/ldt: Make LDT pgtable free conditional x86/ldt: Plug memory leak in error path x86/mm: Remove preempt_disable/enable() from __native_flush_tlb() x86/smpboot: Remove stale TLB flush invocations objtool: Fix seg fault with clang-compiled objects objtool: Fix seg fault caused by missing parameter kbuild: add '-fno-stack-check' to kernel build options timerqueue: Document return values of timerqueue_add/del() timers: Invoke timer_start_debug() where it makes sense nohz: Prevent a timer interrupt storm in tick_nohz_stop_sched_tick() timers: Reinitialize per cpu bases on hotplug timers: Use deferrable base independent of base::nohz_active genirq/msi, x86/vector: Prevent reservation mode for non maskable MSI genirq/irqdomain: Rename early argument of irq_domain_activate_irq() x86/vector: Use IRQD_CAN_RESERVE flag genirq: Introduce IRQD_CAN_RESERVE flag genirq/msi: Handle reactivation only on success gpio: brcmstb: Make really use of the new lockdep class ...
Diffstat (limited to 'drivers/spi/spi-xilinx.c')
-rw-r--r--drivers/spi/spi-xilinx.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index bc7100b93dfc..e0b9fe1d0e37 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -271,6 +271,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
while (remaining_words) {
int n_words, tx_words, rx_words;
u32 sr;
+ int stalled;
n_words = min(remaining_words, xspi->buffer_size);
@@ -299,7 +300,17 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
/* Read out all the data from the Rx FIFO */
rx_words = n_words;
+ stalled = 10;
while (rx_words) {
+ if (rx_words == n_words && !(stalled--) &&
+ !(sr & XSPI_SR_TX_EMPTY_MASK) &&
+ (sr & XSPI_SR_RX_EMPTY_MASK)) {
+ dev_err(&spi->dev,
+ "Detected stall. Check C_SPI_MODE and C_SPI_MEMORY\n");
+ xspi_init_hw(xspi);
+ return -EIO;
+ }
+
if ((sr & XSPI_SR_TX_EMPTY_MASK) && (rx_words > 1)) {
xilinx_spi_rx(xspi);
rx_words--;