From 205b6b33982f6cbf3d7943d003829ab0859edd1a Mon Sep 17 00:00:00 2001 From: Kyungwoo Kang Date: Tue, 28 Aug 2018 20:09:56 +0900 Subject: [PATCH] [RAMEN9610-11559][COMMON] spi: s3c64xx: Fix runtime PM feature for SPI driver Add protection code for runtime pm at SPI driver. Now spi driver waits for runtime_pm until recovers from suspended mode. Change-Id: I2402e4f13e92e3d941f0b2e91716558ad7ecc8d0 Signed-off-by: Kyungwoo Kang --- drivers/spi/spi-s3c64xx.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 0892201bfe35..754e2e337913 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ static LIST_HEAD(drvdata_list); #define MAX_SPI_PORTS 22 #define SPI_AUTOSUSPEND_TIMEOUT (100) +#define SPI_TIMEOUT (msecs_to_jiffies(100)) /* Registers and bit-fields */ @@ -438,6 +440,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); struct s3c64xx_spi_info *sci = sdd->cntrlr_info; #ifdef CONFIG_PM + unsigned long timeout; int ret; #endif @@ -450,9 +453,24 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) #endif #ifdef CONFIG_PM - ret = pm_runtime_get_sync(&sdd->pdev->dev); - if(ret < 0) + timeout = jiffies + SPI_TIMEOUT; + while(time_before(jiffies, timeout)) { + ret = pm_runtime_get_sync(&sdd->pdev->dev); + if(ret < 0) { + dev_err(&sdd->pdev->dev, "SPI runtime get sync failed, and wait for 1msec ret: %d\n", ret); + usleep_range(1000,1000); + } + else { + ret = 0; + break; + } + } + + if (ret < 0) { + dev_err(&sdd->pdev->dev, "Error: SPI runtime get sync failed after 10msec waiting ret: %d\n", ret); return ret; + } + #endif if (sci->need_hw_init) { @@ -1978,6 +1996,7 @@ static int s3c64xx_spi_resume_operation(struct device *dev) s3c64xx_spi_runtime_resume(dev); if (sci->domain == DOMAIN_TOP) { + /* Enable the clock */ #ifdef CONFIG_ARM64_EXYNOS_CPUIDLE exynos_update_ip_idle_status(sdd->idle_ip_index, 0); @@ -2023,9 +2042,9 @@ static int s3c64xx_spi_suspend(struct device *dev) if (sci->dma_mode != DMA_MODE) return 0; - dev_dbg(dev, "spi suspend is handled in device suspend, dma mode = %d\n", sci->dma_mode); + return s3c64xx_spi_suspend_operation(dev); } @@ -2054,6 +2073,7 @@ static int s3c64xx_spi_resume(struct device *dev) dev_dbg(dev, "spi resume is handled in device resume, dma mode = %d\n", sci->dma_mode); + return s3c64xx_spi_resume_operation(dev); } @@ -2068,6 +2088,7 @@ static int s3c64xx_spi_resume_noirq(struct device *dev) dev_dbg(dev, "spi resume is handled in resume_noirq, dma mode = %d\n", sci->dma_mode); + return s3c64xx_spi_resume_operation(dev); } #else -- 2.20.1