aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoojin Kim <boojin.kim@samsung.com>2011-09-01 20:44:29 -0400
committerVinod Koul <vinod.koul@intel.com>2011-09-14 01:40:00 -0400
commita2f5203fec3c06d68a6bb45ad41f2adebf9ac5e0 (patch)
tree86ae77b928884c0c10c9c0076dca3886ab6538f7
parent7703eac96abd119dcfbb04f287a5127462d18269 (diff)
DMA: PL330: Add support runtime PM for PL330 DMAC
Signed-off-by: Boojin Kim <boojin.kim@samsung.com> Acked-by: Jassi Brar <jassisinghbrar@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Vinod Koul <vinod.koul@intel.com> Cc: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/pl330.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 00eee59e8b33..0b99af18f9a1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -17,6 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/amba/bus.h> 18#include <linux/amba/bus.h>
19#include <linux/amba/pl330.h> 19#include <linux/amba/pl330.h>
20#include <linux/pm_runtime.h>
20 21
21#define NR_DEFAULT_DESC 16 22#define NR_DEFAULT_DESC 16
22 23
@@ -83,6 +84,8 @@ struct dma_pl330_dmac {
83 84
84 /* Peripheral channels connected to this DMAC */ 85 /* Peripheral channels connected to this DMAC */
85 struct dma_pl330_chan *peripherals; /* keep at end */ 86 struct dma_pl330_chan *peripherals; /* keep at end */
87
88 struct clk *clk;
86}; 89};
87 90
88struct dma_pl330_desc { 91struct dma_pl330_desc {
@@ -696,6 +699,30 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
696 goto probe_err1; 699 goto probe_err1;
697 } 700 }
698 701
702 pdmac->clk = clk_get(&adev->dev, "dma");
703 if (IS_ERR(pdmac->clk)) {
704 dev_err(&adev->dev, "Cannot get operation clock.\n");
705 ret = -EINVAL;
706 goto probe_err1;
707 }
708
709 amba_set_drvdata(adev, pdmac);
710
711#ifdef CONFIG_PM_RUNTIME
712 /* to use the runtime PM helper functions */
713 pm_runtime_enable(&adev->dev);
714
715 /* enable the power domain */
716 if (pm_runtime_get_sync(&adev->dev)) {
717 dev_err(&adev->dev, "failed to get runtime pm\n");
718 ret = -ENODEV;
719 goto probe_err1;
720 }
721#else
722 /* enable dma clk */
723 clk_enable(pdmac->clk);
724#endif
725
699 irq = adev->irq[0]; 726 irq = adev->irq[0];
700 ret = request_irq(irq, pl330_irq_handler, 0, 727 ret = request_irq(irq, pl330_irq_handler, 0,
701 dev_name(&adev->dev), pi); 728 dev_name(&adev->dev), pi);
@@ -771,8 +798,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
771 goto probe_err4; 798 goto probe_err4;
772 } 799 }
773 800
774 amba_set_drvdata(adev, pdmac);
775
776 dev_info(&adev->dev, 801 dev_info(&adev->dev,
777 "Loaded driver for PL330 DMAC-%d\n", adev->periphid); 802 "Loaded driver for PL330 DMAC-%d\n", adev->periphid);
778 dev_info(&adev->dev, 803 dev_info(&adev->dev,
@@ -833,6 +858,13 @@ static int __devexit pl330_remove(struct amba_device *adev)
833 res = &adev->res; 858 res = &adev->res;
834 release_mem_region(res->start, resource_size(res)); 859 release_mem_region(res->start, resource_size(res));
835 860
861#ifdef CONFIG_PM_RUNTIME
862 pm_runtime_put(&adev->dev);
863 pm_runtime_disable(&adev->dev);
864#else
865 clk_disable(pdmac->clk);
866#endif
867
836 kfree(pdmac); 868 kfree(pdmac);
837 869
838 return 0; 870 return 0;
@@ -846,10 +878,49 @@ static struct amba_id pl330_ids[] = {
846 { 0, 0 }, 878 { 0, 0 },
847}; 879};
848 880
881#ifdef CONFIG_PM_RUNTIME
882static int pl330_runtime_suspend(struct device *dev)
883{
884 struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
885
886 if (!pdmac) {
887 dev_err(dev, "failed to get dmac\n");
888 return -ENODEV;
889 }
890
891 clk_disable(pdmac->clk);
892
893 return 0;
894}
895
896static int pl330_runtime_resume(struct device *dev)
897{
898 struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
899
900 if (!pdmac) {
901 dev_err(dev, "failed to get dmac\n");
902 return -ENODEV;
903 }
904
905 clk_enable(pdmac->clk);
906
907 return 0;
908}
909#else
910#define pl330_runtime_suspend NULL
911#define pl330_runtime_resume NULL
912#endif /* CONFIG_PM_RUNTIME */
913
914static const struct dev_pm_ops pl330_pm_ops = {
915 .runtime_suspend = pl330_runtime_suspend,
916 .runtime_resume = pl330_runtime_resume,
917};
918
849static struct amba_driver pl330_driver = { 919static struct amba_driver pl330_driver = {
850 .drv = { 920 .drv = {
851 .owner = THIS_MODULE, 921 .owner = THIS_MODULE,
852 .name = "dma-pl330", 922 .name = "dma-pl330",
923 .pm = &pl330_pm_ops,
853 }, 924 },
854 .id_table = pl330_ids, 925 .id_table = pl330_ids,
855 .probe = pl330_probe, 926 .probe = pl330_probe,