mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-05-26 11:40:24 +02:00
Merge tag 'spi-fix-v6.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown: "A couple of driver specific fixes, an error handling fix for the Atmel QuadSPI driver and a fix for a nasty synchronisation issue in the data path for the Microchip driver which affects larger transfers. There's also a MAINTAINERS update for the Samsung driver" * tag 'spi-fix-v6.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: spi: microchip-core: prevent RX overflows when transmit size > FIFO size MAINTAINERS: add tambarus as R for Samsung SPI spi: atmel-quadspi: remove references to runtime PM on error path
This commit is contained in:
@@ -21089,6 +21089,7 @@ F: include/linux/clk/samsung.h
|
||||
|
||||
SAMSUNG SPI DRIVERS
|
||||
M: Andi Shyti <andi.shyti@kernel.org>
|
||||
R: Tudor Ambarus <tudor.ambarus@linaro.org>
|
||||
L: linux-spi@vger.kernel.org
|
||||
L: linux-samsung-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
@@ -930,11 +930,8 @@ static int atmel_qspi_sama7g5_transfer(struct spi_mem *mem,
|
||||
|
||||
/* Release the chip-select. */
|
||||
ret = atmel_qspi_reg_sync(aq);
|
||||
if (ret) {
|
||||
pm_runtime_mark_last_busy(&aq->pdev->dev);
|
||||
pm_runtime_put_autosuspend(&aq->pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR);
|
||||
|
||||
return atmel_qspi_wait_for_completion(aq, QSPI_SR_CSRA);
|
||||
|
||||
@@ -70,8 +70,7 @@
|
||||
#define INT_RX_CHANNEL_OVERFLOW BIT(2)
|
||||
#define INT_TX_CHANNEL_UNDERRUN BIT(3)
|
||||
|
||||
#define INT_ENABLE_MASK (CONTROL_RX_DATA_INT | CONTROL_TX_DATA_INT | \
|
||||
CONTROL_RX_OVER_INT | CONTROL_TX_UNDER_INT)
|
||||
#define INT_ENABLE_MASK (CONTROL_RX_OVER_INT | CONTROL_TX_UNDER_INT)
|
||||
|
||||
#define REG_CONTROL (0x00)
|
||||
#define REG_FRAME_SIZE (0x04)
|
||||
@@ -133,10 +132,15 @@ static inline void mchp_corespi_disable(struct mchp_corespi *spi)
|
||||
mchp_corespi_write(spi, REG_CONTROL, control);
|
||||
}
|
||||
|
||||
static inline void mchp_corespi_read_fifo(struct mchp_corespi *spi)
|
||||
static inline void mchp_corespi_read_fifo(struct mchp_corespi *spi, int fifo_max)
|
||||
{
|
||||
while (spi->rx_len >= spi->n_bytes && !(mchp_corespi_read(spi, REG_STATUS) & STATUS_RXFIFO_EMPTY)) {
|
||||
u32 data = mchp_corespi_read(spi, REG_RX_DATA);
|
||||
for (int i = 0; i < fifo_max; i++) {
|
||||
u32 data;
|
||||
|
||||
while (mchp_corespi_read(spi, REG_STATUS) & STATUS_RXFIFO_EMPTY)
|
||||
;
|
||||
|
||||
data = mchp_corespi_read(spi, REG_RX_DATA);
|
||||
|
||||
spi->rx_len -= spi->n_bytes;
|
||||
|
||||
@@ -211,11 +215,10 @@ static inline void mchp_corespi_set_xfer_size(struct mchp_corespi *spi, int len)
|
||||
mchp_corespi_write(spi, REG_FRAMESUP, len);
|
||||
}
|
||||
|
||||
static inline void mchp_corespi_write_fifo(struct mchp_corespi *spi)
|
||||
static inline void mchp_corespi_write_fifo(struct mchp_corespi *spi, int fifo_max)
|
||||
{
|
||||
int fifo_max, i = 0;
|
||||
int i = 0;
|
||||
|
||||
fifo_max = DIV_ROUND_UP(min(spi->tx_len, FIFO_DEPTH), spi->n_bytes);
|
||||
mchp_corespi_set_xfer_size(spi, fifo_max);
|
||||
|
||||
while ((i < fifo_max) && !(mchp_corespi_read(spi, REG_STATUS) & STATUS_TXFIFO_FULL)) {
|
||||
@@ -413,19 +416,6 @@ static irqreturn_t mchp_corespi_interrupt(int irq, void *dev_id)
|
||||
if (intfield == 0)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (intfield & INT_TXDONE)
|
||||
mchp_corespi_write(spi, REG_INT_CLEAR, INT_TXDONE);
|
||||
|
||||
if (intfield & INT_RXRDY) {
|
||||
mchp_corespi_write(spi, REG_INT_CLEAR, INT_RXRDY);
|
||||
|
||||
if (spi->rx_len)
|
||||
mchp_corespi_read_fifo(spi);
|
||||
}
|
||||
|
||||
if (!spi->rx_len && !spi->tx_len)
|
||||
finalise = true;
|
||||
|
||||
if (intfield & INT_RX_CHANNEL_OVERFLOW) {
|
||||
mchp_corespi_write(spi, REG_INT_CLEAR, INT_RX_CHANNEL_OVERFLOW);
|
||||
finalise = true;
|
||||
@@ -512,9 +502,14 @@ static int mchp_corespi_transfer_one(struct spi_controller *host,
|
||||
|
||||
mchp_corespi_write(spi, REG_SLAVE_SELECT, spi->pending_slave_select);
|
||||
|
||||
while (spi->tx_len)
|
||||
mchp_corespi_write_fifo(spi);
|
||||
while (spi->tx_len) {
|
||||
int fifo_max = DIV_ROUND_UP(min(spi->tx_len, FIFO_DEPTH), spi->n_bytes);
|
||||
|
||||
mchp_corespi_write_fifo(spi, fifo_max);
|
||||
mchp_corespi_read_fifo(spi, fifo_max);
|
||||
}
|
||||
|
||||
spi_finalize_current_transfer(host);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user