mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
spi: spi-msm-geni: Return error if setup transfer fails
setup_fifo_xfer/setup_gsi_xfer api may fail while transfer preparation, return error to the client in such case instead of advancing with the erroneous transfer to prevent unpredictable transfer scenarios. Change-Id: I559fbc1dd26248c639cd0f0e1844dafbada703ce Signed-off-by: Mukesh Kumar Savaliya <msavaliy@codeaurora.org>
This commit is contained in:
parent
d8534164bb
commit
ff5005a866
1 changed files with 29 additions and 13 deletions
|
|
@ -1254,10 +1254,11 @@ static int spi_geni_unprepare_transfer_hardware(struct spi_master *spi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void setup_fifo_xfer(struct spi_transfer *xfer,
|
||||
static int setup_fifo_xfer(struct spi_transfer *xfer,
|
||||
struct spi_geni_master *mas, u16 mode,
|
||||
struct spi_master *spi)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 m_cmd = 0;
|
||||
u32 m_param = 0;
|
||||
u32 spi_tx_cfg = geni_read_reg(mas->base, SE_SPI_TRANS_CFG);
|
||||
|
|
@ -1270,7 +1271,6 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
|
|||
|
||||
/* Speed and bits per word can be overridden per transfer */
|
||||
if (xfer->speed_hz != mas->cur_speed_hz) {
|
||||
int ret = 0;
|
||||
u32 clk_sel = 0;
|
||||
u32 m_clk_cfg = 0;
|
||||
int idx = 0;
|
||||
|
|
@ -1280,7 +1280,7 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
|
|||
if (ret) {
|
||||
dev_err(mas->dev, "%s:Err setting clks:%d\n",
|
||||
__func__, ret);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
mas->cur_speed_hz = xfer->speed_hz;
|
||||
clk_sel |= (idx & CLK_SEL_MSK);
|
||||
|
|
@ -1346,32 +1346,35 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
|
|||
__func__, trans_len, xfer->len, spi_tx_cfg, m_cmd,
|
||||
xfer->cs_change, mas->cur_xfer_mode);
|
||||
if ((m_cmd & SPI_RX_ONLY) && (mas->cur_xfer_mode == SE_DMA)) {
|
||||
int ret = 0;
|
||||
|
||||
ret = geni_se_rx_dma_prep(mas->wrapper_dev, mas->base,
|
||||
xfer->rx_buf, xfer->len, &xfer->rx_dma);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
GENI_SE_ERR(mas->ipc, true, mas->dev,
|
||||
"Failed to setup Rx dma %d\n", ret);
|
||||
xfer->rx_dma = 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (m_cmd & SPI_TX_ONLY) {
|
||||
if (mas->cur_xfer_mode == FIFO_MODE) {
|
||||
geni_write_reg(mas->tx_wm, mas->base,
|
||||
SE_GENI_TX_WATERMARK_REG);
|
||||
} else if (mas->cur_xfer_mode == SE_DMA) {
|
||||
int ret = 0;
|
||||
|
||||
ret = geni_se_tx_dma_prep(mas->wrapper_dev, mas->base,
|
||||
(void *)xfer->tx_buf, xfer->len,
|
||||
&xfer->tx_dma);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
GENI_SE_ERR(mas->ipc, true, mas->dev,
|
||||
"Failed to setup tx dma %d\n", ret);
|
||||
xfer->tx_dma = 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure all writes are done before the WM interrupt */
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void handle_fifo_timeout(struct spi_geni_master *mas,
|
||||
|
|
@ -1399,7 +1402,7 @@ static void handle_fifo_timeout(struct spi_geni_master *mas,
|
|||
"Failed to cancel/abort m_cmd\n");
|
||||
}
|
||||
if (mas->cur_xfer_mode == SE_DMA) {
|
||||
if (xfer->tx_buf) {
|
||||
if (xfer->tx_buf && xfer->tx_dma) {
|
||||
reinit_completion(&mas->xfer_done);
|
||||
writel_relaxed(1, mas->base +
|
||||
SE_DMA_TX_FSM_RST);
|
||||
|
|
@ -1411,7 +1414,7 @@ static void handle_fifo_timeout(struct spi_geni_master *mas,
|
|||
geni_se_tx_dma_unprep(mas->wrapper_dev,
|
||||
xfer->tx_dma, xfer->len);
|
||||
}
|
||||
if (xfer->rx_buf) {
|
||||
if (xfer->rx_buf && xfer->rx_dma) {
|
||||
reinit_completion(&mas->xfer_done);
|
||||
writel_relaxed(1, mas->base +
|
||||
SE_DMA_RX_FSM_RST);
|
||||
|
|
@ -1448,7 +1451,14 @@ static int spi_geni_transfer_one(struct spi_master *spi,
|
|||
|
||||
if (mas->cur_xfer_mode != GSI_DMA) {
|
||||
reinit_completion(&mas->xfer_done);
|
||||
setup_fifo_xfer(xfer, mas, slv->mode, spi);
|
||||
ret = setup_fifo_xfer(xfer, mas, slv->mode, spi);
|
||||
if (ret) {
|
||||
GENI_SE_ERR(mas->ipc, true, mas->dev,
|
||||
"setup_fifo_xfer failed: %d\n", ret);
|
||||
mas->cur_xfer = NULL;
|
||||
goto err_fifo_geni_transfer_one;
|
||||
}
|
||||
|
||||
timeout = wait_for_completion_timeout(&mas->xfer_done,
|
||||
msecs_to_jiffies(SPI_XFER_TIMEOUT_MS));
|
||||
if (!timeout) {
|
||||
|
|
@ -1477,7 +1487,13 @@ static int spi_geni_transfer_one(struct spi_master *spi,
|
|||
reinit_completion(&mas->tx_cb);
|
||||
reinit_completion(&mas->rx_cb);
|
||||
|
||||
setup_gsi_xfer(xfer, mas, slv, spi);
|
||||
ret = setup_gsi_xfer(xfer, mas, slv, spi);
|
||||
if (ret) {
|
||||
GENI_SE_ERR(mas->ipc, true, mas->dev,
|
||||
"setup_gsi_xfer failed: %d\n", ret);
|
||||
mas->cur_xfer = NULL;
|
||||
goto err_gsi_geni_transfer_one;
|
||||
}
|
||||
if ((mas->num_xfers >= NUM_SPI_XFER) ||
|
||||
(list_is_last(&xfer->transfer_list,
|
||||
&spi->cur_msg->transfers))) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue