aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-05-31 07:40:36 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-08 18:53:16 -0400
commitb4155d7d5b2c4e82238d629c451f7c27c9f37d9c (patch)
tree8ac568ea27b7786ddd68bf408fb2ed6e7b1d6aa2 /drivers/media
parent3cf138a6393d4ae2aeabce4c4b776d7d15cce69b (diff)
[media] exynos4-is: Ensure fimc-is clocks are not enabled until properly configured
Use clk_prepare_enable/clk_unprepare_disable instead of preparing the clocks during the driver initalization and then using just clk_disable/ clk_enable. The clock framework doesn't guarantee a clock will not get enabled during e.g. clk_set_parent if clk_prepare has been called on it. So we ensure clk_prepare() is called only when it is safe to enable the clocks, i.e. the parent clocks and the clocks' frequencies are set. It must be ensured the FIMC-IS clocks have proper frequencies before they are enabled, otherwise the whole system will hang. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyunmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.c13
1 files changed, 3 insertions, 10 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 1adf6dfcb39e..89f28fe42709 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -71,7 +71,6 @@ static void fimc_is_put_clocks(struct fimc_is *is)
71 for (i = 0; i < ISS_CLKS_MAX; i++) { 71 for (i = 0; i < ISS_CLKS_MAX; i++) {
72 if (IS_ERR(is->clocks[i])) 72 if (IS_ERR(is->clocks[i]))
73 continue; 73 continue;
74 clk_unprepare(is->clocks[i]);
75 clk_put(is->clocks[i]); 74 clk_put(is->clocks[i]);
76 is->clocks[i] = ERR_PTR(-EINVAL); 75 is->clocks[i] = ERR_PTR(-EINVAL);
77 } 76 }
@@ -90,12 +89,6 @@ static int fimc_is_get_clocks(struct fimc_is *is)
90 ret = PTR_ERR(is->clocks[i]); 89 ret = PTR_ERR(is->clocks[i]);
91 goto err; 90 goto err;
92 } 91 }
93 ret = clk_prepare(is->clocks[i]);
94 if (ret < 0) {
95 clk_put(is->clocks[i]);
96 is->clocks[i] = ERR_PTR(-EINVAL);
97 goto err;
98 }
99 } 92 }
100 93
101 return 0; 94 return 0;
@@ -103,7 +96,7 @@ err:
103 fimc_is_put_clocks(is); 96 fimc_is_put_clocks(is);
104 dev_err(&is->pdev->dev, "failed to get clock: %s\n", 97 dev_err(&is->pdev->dev, "failed to get clock: %s\n",
105 fimc_is_clocks[i]); 98 fimc_is_clocks[i]);
106 return -ENXIO; 99 return ret;
107} 100}
108 101
109static int fimc_is_setup_clocks(struct fimc_is *is) 102static int fimc_is_setup_clocks(struct fimc_is *is)
@@ -144,7 +137,7 @@ int fimc_is_enable_clocks(struct fimc_is *is)
144 for (i = 0; i < ISS_GATE_CLKS_MAX; i++) { 137 for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
145 if (IS_ERR(is->clocks[i])) 138 if (IS_ERR(is->clocks[i]))
146 continue; 139 continue;
147 ret = clk_enable(is->clocks[i]); 140 ret = clk_prepare_enable(is->clocks[i]);
148 if (ret < 0) { 141 if (ret < 0) {
149 dev_err(&is->pdev->dev, "clock %s enable failed\n", 142 dev_err(&is->pdev->dev, "clock %s enable failed\n",
150 fimc_is_clocks[i]); 143 fimc_is_clocks[i]);
@@ -163,7 +156,7 @@ void fimc_is_disable_clocks(struct fimc_is *is)
163 156
164 for (i = 0; i < ISS_GATE_CLKS_MAX; i++) { 157 for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
165 if (!IS_ERR(is->clocks[i])) { 158 if (!IS_ERR(is->clocks[i])) {
166 clk_disable(is->clocks[i]); 159 clk_disable_unprepare(is->clocks[i]);
167 pr_debug("disabled clock: %s\n", fimc_is_clocks[i]); 160 pr_debug("disabled clock: %s\n", fimc_is_clocks[i]);
168 } 161 }
169 } 162 }