|
@@ -477,7 +477,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
|
|
tx->sgl, tx->nents, DMA_TO_DEVICE,
|
|
tx->sgl, tx->nents, DMA_TO_DEVICE,
|
|
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
|
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
|
if (!desc_tx)
|
|
if (!desc_tx)
|
|
- return -EIO;
|
|
|
|
|
|
+ goto no_dma;
|
|
|
|
|
|
irq_mask |= SPCR_SPTIE;
|
|
irq_mask |= SPCR_SPTIE;
|
|
}
|
|
}
|
|
@@ -486,7 +486,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
|
|
rx->sgl, rx->nents, DMA_FROM_DEVICE,
|
|
rx->sgl, rx->nents, DMA_FROM_DEVICE,
|
|
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
|
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
|
if (!desc_rx)
|
|
if (!desc_rx)
|
|
- return -EIO;
|
|
|
|
|
|
+ goto no_dma;
|
|
|
|
|
|
irq_mask |= SPCR_SPRIE;
|
|
irq_mask |= SPCR_SPRIE;
|
|
}
|
|
}
|
|
@@ -540,6 +540,12 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
|
|
enable_irq(rspi->rx_irq);
|
|
enable_irq(rspi->rx_irq);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
|
|
+
|
|
|
|
+no_dma:
|
|
|
|
+ pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
|
|
|
|
+ dev_driver_string(&rspi->master->dev),
|
|
|
|
+ dev_name(&rspi->master->dev));
|
|
|
|
+ return -EAGAIN;
|
|
}
|
|
}
|
|
|
|
|
|
static void rspi_receive_init(const struct rspi_data *rspi)
|
|
static void rspi_receive_init(const struct rspi_data *rspi)
|
|
@@ -593,8 +599,10 @@ static int rspi_common_transfer(struct rspi_data *rspi,
|
|
|
|
|
|
if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
|
|
if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
|
|
/* rx_buf can be NULL on RSPI on SH in TX-only Mode */
|
|
/* rx_buf can be NULL on RSPI on SH in TX-only Mode */
|
|
- return rspi_dma_transfer(rspi, &xfer->tx_sg,
|
|
|
|
- xfer->rx_buf ? &xfer->rx_sg : NULL);
|
|
|
|
|
|
+ ret = rspi_dma_transfer(rspi, &xfer->tx_sg,
|
|
|
|
+ xfer->rx_buf ? &xfer->rx_sg : NULL);
|
|
|
|
+ if (ret != -EAGAIN)
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len);
|
|
ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len);
|
|
@@ -648,8 +656,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer))
|
|
|
|
- return rspi_dma_transfer(rspi, &xfer->tx_sg, NULL);
|
|
|
|
|
|
+ if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
|
|
|
|
+ ret = rspi_dma_transfer(rspi, &xfer->tx_sg, NULL);
|
|
|
|
+ if (ret != -EAGAIN)
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
|
|
ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len);
|
|
ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len);
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
@@ -663,8 +674,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
|
|
|
|
|
|
static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
|
|
static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
|
|
{
|
|
{
|
|
- if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer))
|
|
|
|
- return rspi_dma_transfer(rspi, NULL, &xfer->rx_sg);
|
|
|
|
|
|
+ if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
|
|
|
|
+ int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg);
|
|
|
|
+ if (ret != -EAGAIN)
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
|
|
return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len);
|
|
return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len);
|
|
}
|
|
}
|