Skip to content

Commit

Permalink
spi: cadence: Runtime pm adaptation
Browse files Browse the repository at this point in the history
Currently the clocks are enabled at probe and disabled
at remove. This patch moves the clock enable to the
start of transaction and disables at the end.

Signed-off-by: Shubhrajyoti Datta <shubhraj@xilinx.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Shubhrajyoti Datta authored and Mark Brown committed Apr 5, 2016
1 parent b403736 commit d36ccd9
Showing 1 changed file with 68 additions and 2 deletions.
70 changes: 68 additions & 2 deletions drivers/spi/spi-cadence.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>

/* Name of this driver */
Expand All @@ -37,6 +38,7 @@
#define CDNS_SPI_SICR 0x24 /* Slave Idle Count Register, RW */
#define CDNS_SPI_THLD 0x28 /* Transmit FIFO Watermark Register,RW */

#define SPI_AUTOSUSPEND_TIMEOUT 3000
/*
* SPI Configuration Register bit Masks
*
Expand Down Expand Up @@ -509,6 +511,11 @@ static int cdns_spi_probe(struct platform_device *pdev)
goto clk_dis_apb;
}

pm_runtime_enable(&pdev->dev);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
pm_runtime_set_active(&pdev->dev);

ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
if (ret < 0)
master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS;
Expand All @@ -523,6 +530,9 @@ static int cdns_spi_probe(struct platform_device *pdev)
/* SPI controller initializations */
cdns_spi_init_hw(xspi);

pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);

irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
ret = -ENXIO;
Expand All @@ -543,6 +553,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
master->transfer_one = cdns_transfer_one;
master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
master->set_cs = cdns_spi_chipselect;
master->auto_runtime_pm = true;
master->mode_bits = SPI_CPOL | SPI_CPHA;

/* Set to default valid value */
Expand All @@ -560,6 +571,8 @@ static int cdns_spi_probe(struct platform_device *pdev)
return ret;

clk_dis_all:
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(xspi->ref_clk);
clk_dis_apb:
clk_disable_unprepare(xspi->pclk);
Expand Down Expand Up @@ -587,6 +600,8 @@ static int cdns_spi_remove(struct platform_device *pdev)

clk_disable_unprepare(xspi->ref_clk);
clk_disable_unprepare(xspi->pclk);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_disable(&pdev->dev);

spi_unregister_master(master);

Expand Down Expand Up @@ -649,8 +664,59 @@ static int __maybe_unused cdns_spi_resume(struct device *dev)
return 0;
}

static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend,
cdns_spi_resume);
/**
* cdns_spi_runtime_resume - Runtime resume method for the SPI driver
* @dev: Address of the platform_device structure
*
* This function enables the clocks
*
* Return: 0 on success and error value on error
*/
static int cnds_runtime_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct cdns_spi *xspi = spi_master_get_devdata(master);
int ret;

ret = clk_prepare_enable(xspi->pclk);
if (ret) {
dev_err(dev, "Cannot enable APB clock.\n");
return ret;
}

ret = clk_prepare_enable(xspi->ref_clk);
if (ret) {
dev_err(dev, "Cannot enable device clock.\n");
clk_disable(xspi->pclk);
return ret;
}
return 0;
}

/**
* cdns_spi_runtime_suspend - Runtime suspend method for the SPI driver
* @dev: Address of the platform_device structure
*
* This function disables the clocks
*
* Return: Always 0
*/
static int cnds_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct cdns_spi *xspi = spi_master_get_devdata(master);

clk_disable_unprepare(xspi->ref_clk);
clk_disable_unprepare(xspi->pclk);

return 0;
}

static const struct dev_pm_ops cdns_spi_dev_pm_ops = {
SET_RUNTIME_PM_OPS(cnds_runtime_suspend,
cnds_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(cdns_spi_suspend, cdns_spi_resume)
};

static const struct of_device_id cdns_spi_of_match[] = {
{ .compatible = "xlnx,zynq-spi-r1p6" },
Expand Down

0 comments on commit d36ccd9

Please sign in to comment.