spi: spi_qsd: Poll for valid state after software Reset

For SPI slave, software reset performs long pulse
reset. Software should wait for QUP to be in valid
state before doing operations on QUP.

Change-Id: Ifbed295df87a6c5c383cedb431b368b3dffca676
Signed-off-by: Dilip Kota <dkota@codeaurora.org>
This commit is contained in:
Dilip Kota 2017-12-04 12:50:45 +05:30
parent 200011cad3
commit 7dd15c2403

View file

@ -54,6 +54,7 @@ static inline void msm_spi_dma_unmap_buffers(struct msm_spi *dd);
static int get_local_resources(struct msm_spi *dd); static int get_local_resources(struct msm_spi *dd);
static void put_local_resources(struct msm_spi *dd); static void put_local_resources(struct msm_spi *dd);
static void msm_spi_slv_setup(struct msm_spi *dd); static void msm_spi_slv_setup(struct msm_spi *dd);
static inline int msm_spi_wait_valid(struct msm_spi *dd);
static inline int msm_spi_configure_gsbi(struct msm_spi *dd, static inline int msm_spi_configure_gsbi(struct msm_spi *dd,
struct platform_device *pdev) struct platform_device *pdev)
@ -84,18 +85,22 @@ static inline int msm_spi_configure_gsbi(struct msm_spi *dd,
return 0; return 0;
} }
static inline void msm_spi_register_init(struct msm_spi *dd) static inline int msm_spi_register_init(struct msm_spi *dd)
{ {
if (dd->pdata->is_slv_ctrl) if (dd->pdata->is_slv_ctrl) {
writel_relaxed(0x00000002, dd->base + SPI_SW_RESET); writel_relaxed(0x00000002, dd->base + SPI_SW_RESET);
else if (msm_spi_wait_valid(dd))
return -EIO;
} else {
writel_relaxed(0x00000001, dd->base + SPI_SW_RESET); writel_relaxed(0x00000001, dd->base + SPI_SW_RESET);
}
msm_spi_set_state(dd, SPI_OP_STATE_RESET); msm_spi_set_state(dd, SPI_OP_STATE_RESET);
writel_relaxed(0x00000000, dd->base + SPI_OPERATIONAL); writel_relaxed(0x00000000, dd->base + SPI_OPERATIONAL);
writel_relaxed(0x00000000, dd->base + SPI_CONFIG); writel_relaxed(0x00000000, dd->base + SPI_CONFIG);
writel_relaxed(0x00000000, dd->base + SPI_IO_MODES); writel_relaxed(0x00000000, dd->base + SPI_IO_MODES);
if (dd->qup_ver) if (dd->qup_ver)
writel_relaxed(0x00000000, dd->base + QUP_OPERATIONAL_MASK); writel_relaxed(0x00000000, dd->base + QUP_OPERATIONAL_MASK);
return 0;
} }
static int msm_spi_pinctrl_init(struct msm_spi *dd) static int msm_spi_pinctrl_init(struct msm_spi *dd)
@ -1561,10 +1566,11 @@ static inline void msm_spi_set_cs(struct spi_device *spi, bool set_flag)
pm_runtime_put_autosuspend(dd->dev); pm_runtime_put_autosuspend(dd->dev);
} }
static void reset_core(struct msm_spi *dd) static int reset_core(struct msm_spi *dd)
{ {
u32 spi_ioc; u32 spi_ioc;
msm_spi_register_init(dd); if (msm_spi_register_init(dd))
return -EIO;
/* /*
* The SPI core generates a bogus input overrun error on some targets, * The SPI core generates a bogus input overrun error on some targets,
* when a transition from run to reset state occurs and if the FIFO has * when a transition from run to reset state occurs and if the FIFO has
@ -1581,6 +1587,7 @@ static void reset_core(struct msm_spi *dd)
*/ */
mb(); mb();
msm_spi_set_state(dd, SPI_OP_STATE_RESET); msm_spi_set_state(dd, SPI_OP_STATE_RESET);
return 0;
} }
static void put_local_resources(struct msm_spi *dd) static void put_local_resources(struct msm_spi *dd)
@ -1694,7 +1701,11 @@ static int msm_spi_transfer_one(struct spi_master *master,
return -EINVAL; return -EINVAL;
} }
reset_core(dd); if (reset_core(dd)) {
mutex_unlock(&dd->core_lock);
spi_finalize_current_message(master);
return -EIO;
}
if (dd->use_dma) { if (dd->use_dma) {
msm_spi_bam_pipe_connect(dd, &dd->bam.prod, msm_spi_bam_pipe_connect(dd, &dd->bam.prod,
&dd->bam.prod.config); &dd->bam.prod.config);
@ -2450,7 +2461,8 @@ static int init_resources(struct platform_device *pdev)
} }
} }
msm_spi_register_init(dd); if (msm_spi_register_init(dd))
goto err_spi_state;
/* /*
* The SPI core generates a bogus input overrun error on some targets, * The SPI core generates a bogus input overrun error on some targets,
* when a transition from run to reset state occurs and if the FIFO has * when a transition from run to reset state occurs and if the FIFO has