Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbb1ebe9 authored by Mukesh Kumar Savaliya's avatar Mukesh Kumar Savaliya Committed by Gerrit - the friendly Code Review server
Browse files

spi: spi_qsd: serve set_cs call only for valid device status



when set_cs() is called by framework, first check the device suspend
status and if not suspended then proceed for register access. Let system
suspend call SPI runtime suspend but make sure set_cs doesn't race with
it by holding the mutex.

Change-Id: Id6d05ac37227bf3358438eeedf279ddd1c9aab8b
Signed-off-by: default avatarMukesh Kumar Savaliya <msavaliy@codeaurora.org>
parent 28c1f5d2
Loading
Loading
Loading
Loading
+15 −2
Original line number Original line Diff line number Diff line
@@ -1494,11 +1494,11 @@ static inline void msm_spi_set_cs(struct spi_device *spi, bool set_flag)
	struct msm_spi *dd = spi_master_get_devdata(spi->master);
	struct msm_spi *dd = spi_master_get_devdata(spi->master);
	u32 spi_ioc;
	u32 spi_ioc;
	u32 spi_ioc_orig;
	u32 spi_ioc_orig;
	int rc;
	int rc = 0;


	rc = pm_runtime_get_sync(dd->dev);
	rc = pm_runtime_get_sync(dd->dev);
	if (rc < 0) {
	if (rc < 0) {
		dev_err(dd->dev, "Failure during runtime get");
		dev_err(dd->dev, "Failure during runtime get,rc=%d", rc);
		return;
		return;
	}
	}


@@ -1513,6 +1513,15 @@ static inline void msm_spi_set_cs(struct spi_device *spi, bool set_flag)
	if (!(spi->mode & SPI_CS_HIGH))
	if (!(spi->mode & SPI_CS_HIGH))
		set_flag = !set_flag;
		set_flag = !set_flag;


	/* Serve only under mutex lock as RT suspend may cause a race */
	mutex_lock(&dd->core_lock);
	if (dd->suspended) {
		dev_err(dd->dev, "%s: SPI operational state=%d Invalid\n",
			__func__, dd->suspended);
		mutex_unlock(&dd->core_lock);
		return;
	}

	spi_ioc = readl_relaxed(dd->base + SPI_IO_CONTROL);
	spi_ioc = readl_relaxed(dd->base + SPI_IO_CONTROL);
	spi_ioc_orig = spi_ioc;
	spi_ioc_orig = spi_ioc;
	if (set_flag)
	if (set_flag)
@@ -1524,6 +1533,8 @@ static inline void msm_spi_set_cs(struct spi_device *spi, bool set_flag)
		writel_relaxed(spi_ioc, dd->base + SPI_IO_CONTROL);
		writel_relaxed(spi_ioc, dd->base + SPI_IO_CONTROL);
	if (dd->pdata->is_shared)
	if (dd->pdata->is_shared)
		put_local_resources(dd);
		put_local_resources(dd);
	mutex_unlock(&dd->core_lock);

	pm_runtime_mark_last_busy(dd->dev);
	pm_runtime_mark_last_busy(dd->dev);
	pm_runtime_put_autosuspend(dd->dev);
	pm_runtime_put_autosuspend(dd->dev);
}
}
@@ -2615,6 +2626,7 @@ static int msm_spi_pm_suspend_runtime(struct device *device)
	wait_event_interruptible(dd->continue_suspend,
	wait_event_interruptible(dd->continue_suspend,
		!dd->transfer_pending);
		!dd->transfer_pending);


	mutex_lock(&dd->core_lock);
	if (dd->pdata && !dd->pdata->is_shared && dd->use_dma) {
	if (dd->pdata && !dd->pdata->is_shared && dd->use_dma) {
		msm_spi_bam_pipe_disconnect(dd, &dd->bam.prod);
		msm_spi_bam_pipe_disconnect(dd, &dd->bam.prod);
		msm_spi_bam_pipe_disconnect(dd, &dd->bam.cons);
		msm_spi_bam_pipe_disconnect(dd, &dd->bam.cons);
@@ -2624,6 +2636,7 @@ static int msm_spi_pm_suspend_runtime(struct device *device)


	if (dd->pdata)
	if (dd->pdata)
		msm_spi_clk_path_vote(dd, 0);
		msm_spi_clk_path_vote(dd, 0);
	mutex_unlock(&dd->core_lock);


suspend_exit:
suspend_exit:
	return 0;
	return 0;