|
12 | 12 | #include <linux/gpio/consumer.h>
|
13 | 13 | #include <linux/interrupt.h>
|
14 | 14 | #include <linux/io.h>
|
| 15 | +#include <linux/kernel.h> |
15 | 16 | #include <linux/module.h>
|
16 | 17 | #include <linux/of_irq.h>
|
17 | 18 | #include <linux/of_address.h>
|
@@ -301,47 +302,43 @@ static int cdns_spi_setup_transfer(struct spi_device *spi,
|
301 | 302 | }
|
302 | 303 |
|
303 | 304 | /**
|
304 |
| - * cdns_spi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible |
| 305 | + * cdns_spi_process_fifo - Fills the TX FIFO, and drain the RX FIFO |
305 | 306 | * @xspi: Pointer to the cdns_spi structure
|
| 307 | + * @ntx: Number of bytes to pack into the TX FIFO |
| 308 | + * @nrx: Number of bytes to drain from the RX FIFO |
306 | 309 | */
|
307 |
| -static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi, unsigned int avail) |
| 310 | +static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx) |
308 | 311 | {
|
309 |
| - unsigned long trans_cnt = 0; |
| 312 | + ntx = clamp(ntx, 0, xspi->tx_bytes); |
| 313 | + nrx = clamp(nrx, 0, xspi->rx_bytes); |
310 | 314 |
|
311 |
| - while ((trans_cnt < avail) && (xspi->tx_bytes > 0)) { |
| 315 | + xspi->tx_bytes -= ntx; |
| 316 | + xspi->rx_bytes -= nrx; |
| 317 | + |
| 318 | + while (ntx || nrx) { |
312 | 319 | /* When xspi in busy condition, bytes may send failed,
|
313 | 320 | * then spi control did't work thoroughly, add one byte delay
|
314 | 321 | */
|
315 |
| - if (cdns_spi_read(xspi, CDNS_SPI_ISR) & |
316 |
| - CDNS_SPI_IXR_TXFULL) |
| 322 | + if (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_TXFULL) |
317 | 323 | udelay(10);
|
318 | 324 |
|
319 |
| - if (xspi->txbuf) |
320 |
| - cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); |
321 |
| - else |
322 |
| - cdns_spi_write(xspi, CDNS_SPI_TXD, 0); |
| 325 | + if (ntx) { |
| 326 | + if (xspi->txbuf) |
| 327 | + cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); |
| 328 | + else |
| 329 | + cdns_spi_write(xspi, CDNS_SPI_TXD, 0); |
323 | 330 |
|
324 |
| - xspi->tx_bytes--; |
325 |
| - trans_cnt++; |
326 |
| - } |
327 |
| -} |
| 331 | + ntx--; |
| 332 | + } |
328 | 333 |
|
329 |
| -/** |
330 |
| - * cdns_spi_read_rx_fifo - Reads the RX FIFO with as many bytes as possible |
331 |
| - * @xspi: Pointer to the cdns_spi structure |
332 |
| - * @count: Read byte count |
333 |
| - */ |
334 |
| -static void cdns_spi_read_rx_fifo(struct cdns_spi *xspi, unsigned long count) |
335 |
| -{ |
336 |
| - u8 data; |
337 |
| - |
338 |
| - /* Read out the data from the RX FIFO */ |
339 |
| - while (count > 0) { |
340 |
| - data = cdns_spi_read(xspi, CDNS_SPI_RXD); |
341 |
| - if (xspi->rxbuf) |
342 |
| - *xspi->rxbuf++ = data; |
343 |
| - xspi->rx_bytes--; |
344 |
| - count--; |
| 334 | + if (nrx) { |
| 335 | + u8 data = cdns_spi_read(xspi, CDNS_SPI_RXD); |
| 336 | + |
| 337 | + if (xspi->rxbuf) |
| 338 | + *xspi->rxbuf++ = data; |
| 339 | + |
| 340 | + nrx--; |
| 341 | + } |
345 | 342 | }
|
346 | 343 | }
|
347 | 344 |
|
@@ -391,11 +388,10 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
|
391 | 388 | if (xspi->tx_bytes < xspi->tx_fifo_depth >> 1)
|
392 | 389 | cdns_spi_write(xspi, CDNS_SPI_THLD, 1);
|
393 | 390 |
|
394 |
| - cdns_spi_read_rx_fifo(xspi, trans_cnt); |
395 |
| - |
396 | 391 | if (xspi->tx_bytes) {
|
397 |
| - cdns_spi_fill_tx_fifo(xspi, trans_cnt); |
| 392 | + cdns_spi_process_fifo(xspi, trans_cnt, trans_cnt); |
398 | 393 | } else {
|
| 394 | + cdns_spi_process_fifo(xspi, 0, trans_cnt); |
399 | 395 | cdns_spi_write(xspi, CDNS_SPI_IDR,
|
400 | 396 | CDNS_SPI_IXR_DEFAULT);
|
401 | 397 | spi_finalize_current_transfer(ctlr);
|
@@ -448,7 +444,7 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
|
448 | 444 | cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
|
449 | 445 | }
|
450 | 446 |
|
451 |
| - cdns_spi_fill_tx_fifo(xspi, xspi->tx_fifo_depth); |
| 447 | + cdns_spi_process_fifo(xspi, xspi->tx_fifo_depth, 0); |
452 | 448 | spi_transfer_delay_exec(transfer);
|
453 | 449 |
|
454 | 450 | cdns_spi_write(xspi, CDNS_SPI_IER, CDNS_SPI_IXR_DEFAULT);
|
|
0 commit comments