From 210a4cb60767ce70e5b5e88ef1a1dda0a5505735 Mon Sep 17 00:00:00 2001 From: Ashish Kori Date: Thu, 15 Oct 2020 10:56:45 +0530 Subject: [PATCH] spi: spi-msm-geni: Calculate transfer timeout dynamically Calculate SPI transfer timeout dynamically based on the transfer size and add flag for fixed timeout. Change-Id: Idb4dd232bc97d52e5df74f3cb931f5aa6cbcaaa1 Signed-off-by: Ashish Kori --- drivers/spi/spi-msm-geni.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-msm-geni.c b/drivers/spi/spi-msm-geni.c index 632c493d19de..cb7f77eb61f9 100644 --- a/drivers/spi/spi-msm-geni.c +++ b/drivers/spi/spi-msm-geni.c @@ -175,6 +175,7 @@ struct spi_geni_master { bool slave_setup; bool slave_state; bool slave_cross_connected; + bool use_fixed_timeout; }; static void spi_slv_setup(struct spi_geni_master *mas); @@ -1575,7 +1576,7 @@ static int spi_geni_transfer_one(struct spi_master *spi, { int ret = 0; struct spi_geni_master *mas = spi_master_get_devdata(spi); - unsigned long timeout; + unsigned long timeout, xfer_timeout; if ((xfer->tx_buf == NULL) && (xfer->rx_buf == NULL)) { dev_err(mas->dev, "Invalid xfer both tx rx are NULL\n"); @@ -1588,6 +1589,15 @@ static int spi_geni_transfer_one(struct spi_master *spi, return -EINVAL; } + if (mas->use_fixed_timeout) + xfer_timeout = msecs_to_jiffies(SPI_XFER_TIMEOUT_MS); + else + xfer_timeout = + 100 * msecs_to_jiffies(DIV_ROUND_UP(xfer->len * 8, + DIV_ROUND_UP(xfer->speed_hz, MSEC_PER_SEC))); + GENI_SE_DBG(mas->ipc, false, mas->dev, + "current xfer_timeout:%lu ms.\n", xfer_timeout); + if (mas->cur_xfer_mode != GSI_DMA) { reinit_completion(&mas->xfer_done); ret = setup_fifo_xfer(xfer, mas, slv->mode, spi); @@ -1601,7 +1611,7 @@ static int spi_geni_transfer_one(struct spi_master *spi, if (spi->slave) mas->slave_state = true; timeout = wait_for_completion_timeout(&mas->xfer_done, - msecs_to_jiffies(SPI_XFER_TIMEOUT_MS)); + xfer_timeout); if (spi->slave) mas->slave_state = false; @@ -1646,8 +1656,7 @@ static int spi_geni_transfer_one(struct spi_master *spi, for (i = 0 ; i < mas->num_tx_eot; i++) { timeout = wait_for_completion_timeout( - &mas->tx_cb, - msecs_to_jiffies(SPI_XFER_TIMEOUT_MS)); + &mas->tx_cb, xfer_timeout); if (timeout <= 0) { GENI_SE_ERR(mas->ipc, true, mas->dev, "Tx[%d] timeout%lu\n", i, timeout); @@ -1658,8 +1667,7 @@ static int spi_geni_transfer_one(struct spi_master *spi, for (i = 0 ; i < mas->num_rx_eot; i++) { timeout = wait_for_completion_timeout( - &mas->rx_cb, - msecs_to_jiffies(SPI_XFER_TIMEOUT_MS)); + &mas->rx_cb, xfer_timeout); if (timeout <= 0) { GENI_SE_ERR(mas->ipc, true, mas->dev, "Rx[%d] timeout%lu\n", i, timeout); @@ -2026,7 +2034,9 @@ static int spi_geni_probe(struct platform_device *pdev) geni_mas->dis_autosuspend = of_property_read_bool(pdev->dev.of_node, "qcom,disable-autosuspend"); - + geni_mas->use_fixed_timeout = + of_property_read_bool(pdev->dev.of_node, + "qcom,use-fixed-timeout"); /* * shared_se property is set when spi is being used simultaneously * from two Execution Environments.