|
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