diff options
author | Lad, Prabhakar <prabhakar.csengg@gmail.com> | 2013-03-22 03:53:12 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-14 19:08:09 -0400 |
commit | 9a3e89b10f5e48c0d8cca7896c02bf4d76d0ae46 (patch) | |
tree | 2b1d3c265b377a87f2fd89945333936e733f0e96 /drivers | |
parent | 407ccc65bfd2899ed008c4f8900f23ac15f75f9f (diff) |
[media] media: davinci: vpss: enable vpss clocks
By default the VPSS clocks were enabled in capture driver
for davinci family which creates duplicates for dm355/dm365/dm644x.
This patch adds support to enable the VPSS clocks in VPSS driver,
which avoids duplication of code and also adding clock aliases.
This patch uses PM runtime API to enable/disable clock, instead
of DaVinci clock framework. con_ids for master and slave clocks of
vpss is added in pm_domain.
This patch cleanups the VPSS clock enabling in the capture driver,
and also removes the clock alias in machine file. Along side adds
a vpss slave clock for DM365 as mentioned by Sekhar
(https://patchwork.kernel.org/patch/1221261/).
The Suspend/Resume in dm644x_ccdc.c which enabled/disabled the VPSS clock
is now implemented as part of the VPSS driver.
Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
Acked-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/platform/davinci/dm355_ccdc.c | 39 | ||||
-rw-r--r-- | drivers/media/platform/davinci/dm644x_ccdc.c | 44 | ||||
-rw-r--r-- | drivers/media/platform/davinci/isif.c | 28 | ||||
-rw-r--r-- | drivers/media/platform/davinci/vpss.c | 25 |
4 files changed, 30 insertions, 106 deletions
diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index 2364dbab8046..05f8fb7f7b70 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
39 | #include <linux/videodev2.h> | 39 | #include <linux/videodev2.h> |
40 | #include <linux/clk.h> | ||
41 | #include <linux/err.h> | 40 | #include <linux/err.h> |
42 | #include <linux/module.h> | 41 | #include <linux/module.h> |
43 | 42 | ||
@@ -59,10 +58,6 @@ static struct ccdc_oper_config { | |||
59 | struct ccdc_params_raw bayer; | 58 | struct ccdc_params_raw bayer; |
60 | /* YCbCr configuration */ | 59 | /* YCbCr configuration */ |
61 | struct ccdc_params_ycbcr ycbcr; | 60 | struct ccdc_params_ycbcr ycbcr; |
62 | /* Master clock */ | ||
63 | struct clk *mclk; | ||
64 | /* slave clock */ | ||
65 | struct clk *sclk; | ||
66 | /* ccdc base address */ | 61 | /* ccdc base address */ |
67 | void __iomem *base_addr; | 62 | void __iomem *base_addr; |
68 | } ccdc_cfg = { | 63 | } ccdc_cfg = { |
@@ -997,32 +992,10 @@ static int dm355_ccdc_probe(struct platform_device *pdev) | |||
997 | goto fail_nomem; | 992 | goto fail_nomem; |
998 | } | 993 | } |
999 | 994 | ||
1000 | /* Get and enable Master clock */ | ||
1001 | ccdc_cfg.mclk = clk_get(&pdev->dev, "master"); | ||
1002 | if (IS_ERR(ccdc_cfg.mclk)) { | ||
1003 | status = PTR_ERR(ccdc_cfg.mclk); | ||
1004 | goto fail_nomap; | ||
1005 | } | ||
1006 | if (clk_prepare_enable(ccdc_cfg.mclk)) { | ||
1007 | status = -ENODEV; | ||
1008 | goto fail_mclk; | ||
1009 | } | ||
1010 | |||
1011 | /* Get and enable Slave clock */ | ||
1012 | ccdc_cfg.sclk = clk_get(&pdev->dev, "slave"); | ||
1013 | if (IS_ERR(ccdc_cfg.sclk)) { | ||
1014 | status = PTR_ERR(ccdc_cfg.sclk); | ||
1015 | goto fail_mclk; | ||
1016 | } | ||
1017 | if (clk_prepare_enable(ccdc_cfg.sclk)) { | ||
1018 | status = -ENODEV; | ||
1019 | goto fail_sclk; | ||
1020 | } | ||
1021 | |||
1022 | /* Platform data holds setup_pinmux function ptr */ | 995 | /* Platform data holds setup_pinmux function ptr */ |
1023 | if (NULL == pdev->dev.platform_data) { | 996 | if (NULL == pdev->dev.platform_data) { |
1024 | status = -ENODEV; | 997 | status = -ENODEV; |
1025 | goto fail_sclk; | 998 | goto fail_nomap; |
1026 | } | 999 | } |
1027 | setup_pinmux = pdev->dev.platform_data; | 1000 | setup_pinmux = pdev->dev.platform_data; |
1028 | /* | 1001 | /* |
@@ -1033,12 +1006,6 @@ static int dm355_ccdc_probe(struct platform_device *pdev) | |||
1033 | ccdc_cfg.dev = &pdev->dev; | 1006 | ccdc_cfg.dev = &pdev->dev; |
1034 | printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); | 1007 | printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); |
1035 | return 0; | 1008 | return 0; |
1036 | fail_sclk: | ||
1037 | clk_disable_unprepare(ccdc_cfg.sclk); | ||
1038 | clk_put(ccdc_cfg.sclk); | ||
1039 | fail_mclk: | ||
1040 | clk_disable_unprepare(ccdc_cfg.mclk); | ||
1041 | clk_put(ccdc_cfg.mclk); | ||
1042 | fail_nomap: | 1009 | fail_nomap: |
1043 | iounmap(ccdc_cfg.base_addr); | 1010 | iounmap(ccdc_cfg.base_addr); |
1044 | fail_nomem: | 1011 | fail_nomem: |
@@ -1052,10 +1019,6 @@ static int dm355_ccdc_remove(struct platform_device *pdev) | |||
1052 | { | 1019 | { |
1053 | struct resource *res; | 1020 | struct resource *res; |
1054 | 1021 | ||
1055 | clk_disable_unprepare(ccdc_cfg.sclk); | ||
1056 | clk_disable_unprepare(ccdc_cfg.mclk); | ||
1057 | clk_put(ccdc_cfg.mclk); | ||
1058 | clk_put(ccdc_cfg.sclk); | ||
1059 | iounmap(ccdc_cfg.base_addr); | 1022 | iounmap(ccdc_cfg.base_addr); |
1060 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1023 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1061 | if (res) | 1024 | if (res) |
diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index 971d639b6674..30fa08405d61 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
39 | #include <linux/videodev2.h> | 39 | #include <linux/videodev2.h> |
40 | #include <linux/gfp.h> | 40 | #include <linux/gfp.h> |
41 | #include <linux/clk.h> | ||
42 | #include <linux/err.h> | 41 | #include <linux/err.h> |
43 | #include <linux/module.h> | 42 | #include <linux/module.h> |
44 | 43 | ||
@@ -60,10 +59,6 @@ static struct ccdc_oper_config { | |||
60 | struct ccdc_params_raw bayer; | 59 | struct ccdc_params_raw bayer; |
61 | /* YCbCr configuration */ | 60 | /* YCbCr configuration */ |
62 | struct ccdc_params_ycbcr ycbcr; | 61 | struct ccdc_params_ycbcr ycbcr; |
63 | /* Master clock */ | ||
64 | struct clk *mclk; | ||
65 | /* slave clock */ | ||
66 | struct clk *sclk; | ||
67 | /* ccdc base address */ | 62 | /* ccdc base address */ |
68 | void __iomem *base_addr; | 63 | void __iomem *base_addr; |
69 | } ccdc_cfg = { | 64 | } ccdc_cfg = { |
@@ -991,38 +986,9 @@ static int dm644x_ccdc_probe(struct platform_device *pdev) | |||
991 | goto fail_nomem; | 986 | goto fail_nomem; |
992 | } | 987 | } |
993 | 988 | ||
994 | /* Get and enable Master clock */ | ||
995 | ccdc_cfg.mclk = clk_get(&pdev->dev, "master"); | ||
996 | if (IS_ERR(ccdc_cfg.mclk)) { | ||
997 | status = PTR_ERR(ccdc_cfg.mclk); | ||
998 | goto fail_nomap; | ||
999 | } | ||
1000 | if (clk_prepare_enable(ccdc_cfg.mclk)) { | ||
1001 | status = -ENODEV; | ||
1002 | goto fail_mclk; | ||
1003 | } | ||
1004 | |||
1005 | /* Get and enable Slave clock */ | ||
1006 | ccdc_cfg.sclk = clk_get(&pdev->dev, "slave"); | ||
1007 | if (IS_ERR(ccdc_cfg.sclk)) { | ||
1008 | status = PTR_ERR(ccdc_cfg.sclk); | ||
1009 | goto fail_mclk; | ||
1010 | } | ||
1011 | if (clk_prepare_enable(ccdc_cfg.sclk)) { | ||
1012 | status = -ENODEV; | ||
1013 | goto fail_sclk; | ||
1014 | } | ||
1015 | ccdc_cfg.dev = &pdev->dev; | 989 | ccdc_cfg.dev = &pdev->dev; |
1016 | printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); | 990 | printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name); |
1017 | return 0; | 991 | return 0; |
1018 | fail_sclk: | ||
1019 | clk_disable_unprepare(ccdc_cfg.sclk); | ||
1020 | clk_put(ccdc_cfg.sclk); | ||
1021 | fail_mclk: | ||
1022 | clk_disable_unprepare(ccdc_cfg.mclk); | ||
1023 | clk_put(ccdc_cfg.mclk); | ||
1024 | fail_nomap: | ||
1025 | iounmap(ccdc_cfg.base_addr); | ||
1026 | fail_nomem: | 992 | fail_nomem: |
1027 | release_mem_region(res->start, resource_size(res)); | 993 | release_mem_region(res->start, resource_size(res)); |
1028 | fail_nores: | 994 | fail_nores: |
@@ -1034,10 +1000,6 @@ static int dm644x_ccdc_remove(struct platform_device *pdev) | |||
1034 | { | 1000 | { |
1035 | struct resource *res; | 1001 | struct resource *res; |
1036 | 1002 | ||
1037 | clk_disable_unprepare(ccdc_cfg.mclk); | ||
1038 | clk_disable_unprepare(ccdc_cfg.sclk); | ||
1039 | clk_put(ccdc_cfg.mclk); | ||
1040 | clk_put(ccdc_cfg.sclk); | ||
1041 | iounmap(ccdc_cfg.base_addr); | 1003 | iounmap(ccdc_cfg.base_addr); |
1042 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1004 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1043 | if (res) | 1005 | if (res) |
@@ -1052,18 +1014,12 @@ static int dm644x_ccdc_suspend(struct device *dev) | |||
1052 | ccdc_save_context(); | 1014 | ccdc_save_context(); |
1053 | /* Disable CCDC */ | 1015 | /* Disable CCDC */ |
1054 | ccdc_enable(0); | 1016 | ccdc_enable(0); |
1055 | /* Disable both master and slave clock */ | ||
1056 | clk_disable_unprepare(ccdc_cfg.mclk); | ||
1057 | clk_disable_unprepare(ccdc_cfg.sclk); | ||
1058 | 1017 | ||
1059 | return 0; | 1018 | return 0; |
1060 | } | 1019 | } |
1061 | 1020 | ||
1062 | static int dm644x_ccdc_resume(struct device *dev) | 1021 | static int dm644x_ccdc_resume(struct device *dev) |
1063 | { | 1022 | { |
1064 | /* Enable both master and slave clock */ | ||
1065 | clk_prepare_enable(ccdc_cfg.mclk); | ||
1066 | clk_prepare_enable(ccdc_cfg.sclk); | ||
1067 | /* Restore CCDC context */ | 1023 | /* Restore CCDC context */ |
1068 | ccdc_restore_context(); | 1024 | ccdc_restore_context(); |
1069 | 1025 | ||
diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index abc3ae36645c..3332cca632e5 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davinci/isif.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/videodev2.h> | 34 | #include <linux/videodev2.h> |
35 | #include <linux/clk.h> | ||
36 | #include <linux/err.h> | 35 | #include <linux/err.h> |
37 | #include <linux/module.h> | 36 | #include <linux/module.h> |
38 | 37 | ||
@@ -88,8 +87,6 @@ static struct isif_oper_config { | |||
88 | struct isif_ycbcr_config ycbcr; | 87 | struct isif_ycbcr_config ycbcr; |
89 | struct isif_params_raw bayer; | 88 | struct isif_params_raw bayer; |
90 | enum isif_data_pack data_pack; | 89 | enum isif_data_pack data_pack; |
91 | /* Master clock */ | ||
92 | struct clk *mclk; | ||
93 | /* ISIF base address */ | 90 | /* ISIF base address */ |
94 | void __iomem *base_addr; | 91 | void __iomem *base_addr; |
95 | /* ISIF Linear Table 0 */ | 92 | /* ISIF Linear Table 0 */ |
@@ -1039,6 +1036,10 @@ static int isif_probe(struct platform_device *pdev) | |||
1039 | void *__iomem addr; | 1036 | void *__iomem addr; |
1040 | int status = 0, i; | 1037 | int status = 0, i; |
1041 | 1038 | ||
1039 | /* Platform data holds setup_pinmux function ptr */ | ||
1040 | if (!pdev->dev.platform_data) | ||
1041 | return -ENODEV; | ||
1042 | |||
1042 | /* | 1043 | /* |
1043 | * first try to register with vpfe. If not correct platform, then we | 1044 | * first try to register with vpfe. If not correct platform, then we |
1044 | * don't have to iomap | 1045 | * don't have to iomap |
@@ -1047,22 +1048,6 @@ static int isif_probe(struct platform_device *pdev) | |||
1047 | if (status < 0) | 1048 | if (status < 0) |
1048 | return status; | 1049 | return status; |
1049 | 1050 | ||
1050 | /* Get and enable Master clock */ | ||
1051 | isif_cfg.mclk = clk_get(&pdev->dev, "master"); | ||
1052 | if (IS_ERR(isif_cfg.mclk)) { | ||
1053 | status = PTR_ERR(isif_cfg.mclk); | ||
1054 | goto fail_mclk; | ||
1055 | } | ||
1056 | if (clk_prepare_enable(isif_cfg.mclk)) { | ||
1057 | status = -ENODEV; | ||
1058 | goto fail_mclk; | ||
1059 | } | ||
1060 | |||
1061 | /* Platform data holds setup_pinmux function ptr */ | ||
1062 | if (NULL == pdev->dev.platform_data) { | ||
1063 | status = -ENODEV; | ||
1064 | goto fail_mclk; | ||
1065 | } | ||
1066 | setup_pinmux = pdev->dev.platform_data; | 1051 | setup_pinmux = pdev->dev.platform_data; |
1067 | /* | 1052 | /* |
1068 | * setup Mux configuration for ccdc which may be different for | 1053 | * setup Mux configuration for ccdc which may be different for |
@@ -1124,9 +1109,6 @@ fail_nobase_res: | |||
1124 | release_mem_region(res->start, resource_size(res)); | 1109 | release_mem_region(res->start, resource_size(res)); |
1125 | i--; | 1110 | i--; |
1126 | } | 1111 | } |
1127 | fail_mclk: | ||
1128 | clk_disable_unprepare(isif_cfg.mclk); | ||
1129 | clk_put(isif_cfg.mclk); | ||
1130 | vpfe_unregister_ccdc_device(&isif_hw_dev); | 1112 | vpfe_unregister_ccdc_device(&isif_hw_dev); |
1131 | return status; | 1113 | return status; |
1132 | } | 1114 | } |
@@ -1146,8 +1128,6 @@ static int isif_remove(struct platform_device *pdev) | |||
1146 | i++; | 1128 | i++; |
1147 | } | 1129 | } |
1148 | vpfe_unregister_ccdc_device(&isif_hw_dev); | 1130 | vpfe_unregister_ccdc_device(&isif_hw_dev); |
1149 | clk_disable_unprepare(isif_cfg.mclk); | ||
1150 | clk_put(isif_cfg.mclk); | ||
1151 | return 0; | 1131 | return 0; |
1152 | } | 1132 | } |
1153 | 1133 | ||
diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c index a19c552232d1..d36429d1bd69 100644 --- a/drivers/media/platform/davinci/vpss.c +++ b/drivers/media/platform/davinci/vpss.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <linux/compiler.h> | 26 | #include <linux/compiler.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/pm_runtime.h> | ||
29 | |||
28 | #include <media/davinci/vpss.h> | 30 | #include <media/davinci/vpss.h> |
29 | 31 | ||
30 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
@@ -490,6 +492,10 @@ static int vpss_probe(struct platform_device *pdev) | |||
490 | } else | 492 | } else |
491 | oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow; | 493 | oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow; |
492 | 494 | ||
495 | pm_runtime_enable(&pdev->dev); | ||
496 | |||
497 | pm_runtime_get(&pdev->dev); | ||
498 | |||
493 | spin_lock_init(&oper_cfg.vpss_lock); | 499 | spin_lock_init(&oper_cfg.vpss_lock); |
494 | dev_info(&pdev->dev, "%s vpss probe success\n", platform_name); | 500 | dev_info(&pdev->dev, "%s vpss probe success\n", platform_name); |
495 | return 0; | 501 | return 0; |
@@ -507,6 +513,7 @@ static int vpss_remove(struct platform_device *pdev) | |||
507 | { | 513 | { |
508 | struct resource *res; | 514 | struct resource *res; |
509 | 515 | ||
516 | pm_runtime_disable(&pdev->dev); | ||
510 | iounmap(oper_cfg.vpss_regs_base0); | 517 | iounmap(oper_cfg.vpss_regs_base0); |
511 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 518 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
512 | release_mem_region(res->start, resource_size(res)); | 519 | release_mem_region(res->start, resource_size(res)); |
@@ -518,10 +525,28 @@ static int vpss_remove(struct platform_device *pdev) | |||
518 | return 0; | 525 | return 0; |
519 | } | 526 | } |
520 | 527 | ||
528 | static int vpss_suspend(struct device *dev) | ||
529 | { | ||
530 | pm_runtime_put(dev); | ||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static int vpss_resume(struct device *dev) | ||
535 | { | ||
536 | pm_runtime_get(dev); | ||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | static const struct dev_pm_ops vpss_pm_ops = { | ||
541 | .suspend = vpss_suspend, | ||
542 | .resume = vpss_resume, | ||
543 | }; | ||
544 | |||
521 | static struct platform_driver vpss_driver = { | 545 | static struct platform_driver vpss_driver = { |
522 | .driver = { | 546 | .driver = { |
523 | .name = "vpss", | 547 | .name = "vpss", |
524 | .owner = THIS_MODULE, | 548 | .owner = THIS_MODULE, |
549 | .pm = &vpss_pm_ops, | ||
525 | }, | 550 | }, |
526 | .remove = vpss_remove, | 551 | .remove = vpss_remove, |
527 | .probe = vpss_probe, | 552 | .probe = vpss_probe, |