From a9f5a5997a2035fd79e27fa7c7475ec55c4ff4ba Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 29 Aug 2012 17:12:05 +0530 Subject: spi: tegra: Add stub runtime power management Add stub runtime_pm calls which go through the flow of enabling and disabling but don't actually do anything with the device itself as there's nothing useful we can do. This provides the core PM framework with information about when the device is idle, enabling chip wide power savings. Change-Id: Ie795c16840ccbe07e1a8bfac1a1c5a87281e6849 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/128184 Reviewed-by: Bitan Biswas Reviewed-by: Pavan Kunapuli GVS: Gerrit_Virtual_Submit --- drivers/spi/spi-tegra.c | 93 +++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 73 deletions(-) (limited to 'drivers/spi/spi-tegra.c') diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index 1d08b7f20c93..5006ca975897 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c @@ -43,8 +43,6 @@ #include #include -#define SPI_PM_RUNTIME_ENABLE 0 - #define SLINK_COMMAND 0x000 #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) #define SLINK_WORD_SIZE(x) (((x) & 0x1f) << 5) @@ -250,9 +248,6 @@ struct spi_tegra_data { struct work_struct spi_transfer_work; }; -static int tegra_spi_runtime_idle(struct device *dev); -static int tegra_spi_runtime_resume(struct device *dev); - static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, unsigned long reg) { @@ -309,22 +304,6 @@ static int tegra_spi_clk_enable(struct spi_tegra_data *tspi) return 0; } -#if SPI_PM_RUNTIME_ENABLE -#define spi_pm_runtime_get_sync(dev) pm_runtime_get_sync(dev) -#define spi_pm_runtime_put_sync(dev) pm_runtime_put_sync(dev) -#define spi_pm_runtime_enable(dev) pm_runtime_enable(dev) -#define spi_pm_runtime_disable(dev) pm_runtime_disable(dev) -#define spi_pm_runtime_enabled(dev) pm_runtime_enabled(dev) -#define spi_pm_runtime_status_suspended(dev) pm_runtime_status_suspended(dev) -#else -#define spi_pm_runtime_get_sync(dev) tegra_spi_runtime_resume(dev) -#define spi_pm_runtime_put_sync(dev) tegra_spi_runtime_idle(dev) -#define spi_pm_runtime_enable(dev) do { } while(0) -#define spi_pm_runtime_disable(dev) do { } while(0) -#define spi_pm_runtime_enabled(dev) true -#define spi_pm_runtime_status_suspended(dev) true -#endif - static void cancel_dma(struct tegra_dma_channel *dma_chan, struct tegra_dma_req *req) { @@ -795,12 +774,8 @@ static void spi_tegra_start_transfer(struct spi_device *spi, command2 = tspi->def_command2_reg; if (is_first_of_msg) { - if ((ret = spi_pm_runtime_get_sync(&tspi->pdev->dev)) < 0) { - dev_err(&tspi->pdev->dev, - "%s: spi_pm_runtime_get_sync() returns %d\n", - __func__, ret); - return; - } + pm_runtime_get_sync(&tspi->pdev->dev); + tegra_spi_clk_enable(tspi); spi_tegra_clear_status(tspi); @@ -912,7 +887,8 @@ static int spi_tegra_setup(struct spi_device *spi) return -EINVAL; } - spi_pm_runtime_get_sync(&tspi->pdev->dev); + pm_runtime_get_sync(&tspi->pdev->dev); + tegra_spi_clk_enable(tspi); spin_lock_irqsave(&tspi->lock, flags); val = tspi->def_command_reg; @@ -924,7 +900,8 @@ static int spi_tegra_setup(struct spi_device *spi) spi_tegra_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); spin_unlock_irqrestore(&tspi->lock, flags); - spi_pm_runtime_put_sync(&tspi->pdev->dev); + tegra_spi_clk_disable(tspi); + pm_runtime_put_sync(&tspi->pdev->dev); return 0; } @@ -1069,7 +1046,8 @@ static void spi_tegra_curr_transfer_complete(struct spi_tegra_data *tspi, /* Provide delay to stablize the signal state */ spin_unlock_irqrestore(&tspi->lock, *irq_flags); udelay(10); - spi_pm_runtime_put_sync(&tspi->pdev->dev); + tegra_spi_clk_disable(tspi); + pm_runtime_put_sync(&tspi->pdev->dev); spin_lock_irqsave(&tspi->lock, *irq_flags); tspi->is_transfer_in_progress = false; /* Check if any new request has come between @@ -1475,18 +1453,11 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) tspi->def_command2_reg = SLINK_CS_ACTIVE_BETWEEN; skip_dma_alloc: - spi_pm_runtime_enable(&pdev->dev); - if (!spi_pm_runtime_enabled(&pdev->dev)) { - ret = tegra_spi_runtime_resume(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "runtime resume failed %d", ret); - goto exit_pm_disable; - } - } + pm_runtime_enable(&pdev->dev); /* Enable clock if it is require to be enable always */ if (tspi->is_clkon_always) - spi_pm_runtime_get_sync(&pdev->dev); + tegra_spi_clk_enable(tspi); /* create the workqueue for the spi transfer */ snprintf(spi_wq_name, sizeof(spi_wq_name), "spi_tegra-%d", pdev->id); @@ -1513,13 +1484,9 @@ exit_destry_wq: exit_fail_wq: if (tspi->is_clkon_always) - spi_pm_runtime_put_sync(&pdev->dev); - - if (!spi_pm_runtime_status_suspended(&pdev->dev)) - tegra_spi_runtime_idle(&pdev->dev); + tegra_spi_clk_disable(tspi); -exit_pm_disable: - spi_pm_runtime_disable(&pdev->dev); + pm_runtime_disable(&pdev->dev); spi_tegra_deinit_dma_param(tspi, false); @@ -1549,11 +1516,9 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev) /* Disable clock if it is always enabled */ if (tspi->is_clkon_always) - spi_pm_runtime_put_sync(&pdev->dev); + tegra_spi_clk_disable(tspi); - spi_pm_runtime_disable(&pdev->dev); - if (!spi_pm_runtime_status_suspended(&pdev->dev)) - tegra_spi_runtime_idle(&pdev->dev); + pm_runtime_disable(&pdev->dev); destroy_workqueue(tspi->spi_workqueue); @@ -1608,7 +1573,7 @@ static int spi_tegra_suspend(struct device *dev) /* Disable clock if it is always enabled */ if (tspi->is_clkon_always) - spi_pm_runtime_put_sync(dev); + tegra_spi_clk_disable(tspi); return 0; } @@ -1625,11 +1590,13 @@ static int spi_tegra_resume(struct device *dev) /* Enable clock if it is always enabled */ if (tspi->is_clkon_always) - spi_pm_runtime_get_sync(dev); + tegra_spi_clk_enable(tspi); - spi_pm_runtime_get_sync(dev); + pm_runtime_get_sync(dev); + tegra_spi_clk_enable(tspi); spi_tegra_writel(tspi, tspi->command_reg, SLINK_COMMAND); - spi_pm_runtime_put_sync(dev); + tegra_spi_clk_disable(tspi); + pm_runtime_put_sync(dev); spin_lock_irqsave(&tspi->lock, flags); @@ -1652,27 +1619,7 @@ static int spi_tegra_resume(struct device *dev) } #endif -static int tegra_spi_runtime_idle(struct device *dev) -{ - struct spi_master *master = dev_get_drvdata(dev); - struct spi_tegra_data *tspi = spi_master_get_devdata(master); - - return tegra_spi_clk_disable(tspi); -} - -static int tegra_spi_runtime_resume(struct device *dev) -{ - struct spi_master *master = dev_get_drvdata(dev); - struct spi_tegra_data *tspi = spi_master_get_devdata(master); - - return tegra_spi_clk_enable(tspi); -} - static const struct dev_pm_ops tegra_spi_dev_pm_ops = { -#if defined(CONFIG_PM_RUNTIME) - .runtime_idle = tegra_spi_runtime_idle, - .runtime_resume = tegra_spi_runtime_resume, -#endif #ifdef CONFIG_PM .suspend = spi_tegra_suspend, .resume = spi_tegra_resume, -- cgit v1.2.3