aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-cadence.c
diff options
context:
space:
mode:
authorShubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>2016-04-05 14:07:52 -0400
committerMark Brown <broonie@kernel.org>2016-04-05 14:51:10 -0400
commitd36ccd9f7ea41f343391a15677b8a858376e1107 (patch)
treef1187aafc0c1cbf40b5c46fb7035cd99a9373714 /drivers/spi/spi-cadence.c
parentb4037360e66b90755ed73022976f10108bc82045 (diff)
spi: cadence: Runtime pm adaptation
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>
Diffstat (limited to 'drivers/spi/spi-cadence.c')
-rw-r--r--drivers/spi/spi-cadence.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 8a6fee934364..3b94063b2823 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -19,6 +19,7 @@
19#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/of_address.h> 20#include <linux/of_address.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/pm_runtime.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23 24
24/* Name of this driver */ 25/* Name of this driver */
@@ -37,6 +38,7 @@
37#define CDNS_SPI_SICR 0x24 /* Slave Idle Count Register, RW */ 38#define CDNS_SPI_SICR 0x24 /* Slave Idle Count Register, RW */
38#define CDNS_SPI_THLD 0x28 /* Transmit FIFO Watermark Register,RW */ 39#define CDNS_SPI_THLD 0x28 /* Transmit FIFO Watermark Register,RW */
39 40
41#define SPI_AUTOSUSPEND_TIMEOUT 3000
40/* 42/*
41 * SPI Configuration Register bit Masks 43 * SPI Configuration Register bit Masks
42 * 44 *
@@ -509,6 +511,11 @@ static int cdns_spi_probe(struct platform_device *pdev)
509 goto clk_dis_apb; 511 goto clk_dis_apb;
510 } 512 }
511 513
514 pm_runtime_enable(&pdev->dev);
515 pm_runtime_use_autosuspend(&pdev->dev);
516 pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
517 pm_runtime_set_active(&pdev->dev);
518
512 ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); 519 ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
513 if (ret < 0) 520 if (ret < 0)
514 master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS; 521 master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS;
@@ -523,6 +530,9 @@ static int cdns_spi_probe(struct platform_device *pdev)
523 /* SPI controller initializations */ 530 /* SPI controller initializations */
524 cdns_spi_init_hw(xspi); 531 cdns_spi_init_hw(xspi);
525 532
533 pm_runtime_mark_last_busy(&pdev->dev);
534 pm_runtime_put_autosuspend(&pdev->dev);
535
526 irq = platform_get_irq(pdev, 0); 536 irq = platform_get_irq(pdev, 0);
527 if (irq <= 0) { 537 if (irq <= 0) {
528 ret = -ENXIO; 538 ret = -ENXIO;
@@ -543,6 +553,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
543 master->transfer_one = cdns_transfer_one; 553 master->transfer_one = cdns_transfer_one;
544 master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware; 554 master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
545 master->set_cs = cdns_spi_chipselect; 555 master->set_cs = cdns_spi_chipselect;
556 master->auto_runtime_pm = true;
546 master->mode_bits = SPI_CPOL | SPI_CPHA; 557 master->mode_bits = SPI_CPOL | SPI_CPHA;
547 558
548 /* Set to default valid value */ 559 /* Set to default valid value */
@@ -560,6 +571,8 @@ static int cdns_spi_probe(struct platform_device *pdev)
560 return ret; 571 return ret;
561 572
562clk_dis_all: 573clk_dis_all:
574 pm_runtime_set_suspended(&pdev->dev);
575 pm_runtime_disable(&pdev->dev);
563 clk_disable_unprepare(xspi->ref_clk); 576 clk_disable_unprepare(xspi->ref_clk);
564clk_dis_apb: 577clk_dis_apb:
565 clk_disable_unprepare(xspi->pclk); 578 clk_disable_unprepare(xspi->pclk);
@@ -587,6 +600,8 @@ static int cdns_spi_remove(struct platform_device *pdev)
587 600
588 clk_disable_unprepare(xspi->ref_clk); 601 clk_disable_unprepare(xspi->ref_clk);
589 clk_disable_unprepare(xspi->pclk); 602 clk_disable_unprepare(xspi->pclk);
603 pm_runtime_set_suspended(&pdev->dev);
604 pm_runtime_disable(&pdev->dev);
590 605
591 spi_unregister_master(master); 606 spi_unregister_master(master);
592 607
@@ -649,8 +664,59 @@ static int __maybe_unused cdns_spi_resume(struct device *dev)
649 return 0; 664 return 0;
650} 665}
651 666
652static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend, 667/**
653 cdns_spi_resume); 668 * cdns_spi_runtime_resume - Runtime resume method for the SPI driver
669 * @dev: Address of the platform_device structure
670 *
671 * This function enables the clocks
672 *
673 * Return: 0 on success and error value on error
674 */
675static int cnds_runtime_resume(struct device *dev)
676{
677 struct spi_master *master = dev_get_drvdata(dev);
678 struct cdns_spi *xspi = spi_master_get_devdata(master);
679 int ret;
680
681 ret = clk_prepare_enable(xspi->pclk);
682 if (ret) {
683 dev_err(dev, "Cannot enable APB clock.\n");
684 return ret;
685 }
686
687 ret = clk_prepare_enable(xspi->ref_clk);
688 if (ret) {
689 dev_err(dev, "Cannot enable device clock.\n");
690 clk_disable(xspi->pclk);
691 return ret;
692 }
693 return 0;
694}
695
696/**
697 * cdns_spi_runtime_suspend - Runtime suspend method for the SPI driver
698 * @dev: Address of the platform_device structure
699 *
700 * This function disables the clocks
701 *
702 * Return: Always 0
703 */
704static int cnds_runtime_suspend(struct device *dev)
705{
706 struct spi_master *master = dev_get_drvdata(dev);
707 struct cdns_spi *xspi = spi_master_get_devdata(master);
708
709 clk_disable_unprepare(xspi->ref_clk);
710 clk_disable_unprepare(xspi->pclk);
711
712 return 0;
713}
714
715static const struct dev_pm_ops cdns_spi_dev_pm_ops = {
716 SET_RUNTIME_PM_OPS(cnds_runtime_suspend,
717 cnds_runtime_resume, NULL)
718 SET_SYSTEM_SLEEP_PM_OPS(cdns_spi_suspend, cdns_spi_resume)
719};
654 720
655static const struct of_device_id cdns_spi_of_match[] = { 721static const struct of_device_id cdns_spi_of_match[] = {
656 { .compatible = "xlnx,zynq-spi-r1p6" }, 722 { .compatible = "xlnx,zynq-spi-r1p6" },