Skip to content

Commit

Permalink
spi/s3c64xx: Implement runtime PM support
Browse files Browse the repository at this point in the history
Enable and disable the clocks to the SPI controller using runtime PM. This
serves the dual purpose of reducing power consumption a little and letting
the core know when the device is idle.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Heiko Stuebner <heiko@sntech.de>
  • Loading branch information
Mark Brown committed Jan 21, 2012
1 parent e25d0bf commit b97b662
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions drivers/spi/spi-s3c64xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>

#include <mach/dma.h>
Expand Down Expand Up @@ -782,6 +783,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
while (!acquire_dma(sdd))
msleep(10);

pm_runtime_get_sync(&sdd->pdev->dev);

spin_lock_irqsave(&sdd->lock, flags);

while (!list_empty(&sdd->queue)
Expand Down Expand Up @@ -810,6 +813,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
/* Free DMA channels */
sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client);
sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client);

pm_runtime_put(&sdd->pdev->dev);
}

static int s3c64xx_spi_transfer(struct spi_device *spi,
Expand Down Expand Up @@ -892,6 +897,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
goto setup_exit;
}

pm_runtime_get_sync(&sdd->pdev->dev);

/* Check if we can provide the requested rate */
if (!sci->clk_from_cmu) {
u32 psr, speed;
Expand Down Expand Up @@ -924,6 +931,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
err = -EINVAL;
}

pm_runtime_put(&sdd->pdev->dev);

setup_exit:

/* setup() returns with device de-selected */
Expand Down Expand Up @@ -1164,6 +1173,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
mem_res->end, mem_res->start,
sdd->rx_dma.dmach, sdd->tx_dma.dmach);

pm_runtime_enable(&pdev->dev);

return 0;

err9:
Expand Down Expand Up @@ -1197,6 +1208,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
struct resource *mem_res;
unsigned long flags;

pm_runtime_disable(&pdev->dev);

spin_lock_irqsave(&sdd->lock, flags);
sdd->state |= SUSPND;
spin_unlock_irqrestore(&sdd->lock, flags);
Expand Down Expand Up @@ -1277,8 +1290,34 @@ static int s3c64xx_spi_resume(struct device *dev)
}
#endif /* CONFIG_PM */

#ifdef CONFIG_PM_RUNTIME
static int s3c64xx_spi_runtime_suspend(struct device *dev)
{
struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);

clk_disable(sdd->clk);
clk_disable(sdd->src_clk);

return 0;
}

static int s3c64xx_spi_runtime_resume(struct device *dev)
{
struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);

clk_enable(sdd->src_clk);
clk_enable(sdd->clk);

return 0;
}
#endif /* CONFIG_PM_RUNTIME */

static const struct dev_pm_ops s3c64xx_spi_pm = {
SET_SYSTEM_SLEEP_PM_OPS(s3c64xx_spi_suspend, s3c64xx_spi_resume)
SET_RUNTIME_PM_OPS(s3c64xx_spi_runtime_suspend,
s3c64xx_spi_runtime_resume, NULL)
};

static struct platform_driver s3c64xx_spi_driver = {
Expand Down

0 comments on commit b97b662

Please sign in to comment.