Skip to content

Commit

Permalink
[media] exynos4-is: Ensure fimc-is clocks are not enabled until prope…
Browse files Browse the repository at this point in the history
…rly 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>
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed Jun 8, 2013
1 parent 3cf138a commit b4155d7
Showing 1 changed file with 3 additions and 10 deletions.
13 changes: 3 additions & 10 deletions drivers/media/platform/exynos4-is/fimc-is.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ static void fimc_is_put_clocks(struct fimc_is *is)
for (i = 0; i < ISS_CLKS_MAX; i++) {
if (IS_ERR(is->clocks[i]))
continue;
clk_unprepare(is->clocks[i]);
clk_put(is->clocks[i]);
is->clocks[i] = ERR_PTR(-EINVAL);
}
Expand All @@ -90,20 +89,14 @@ static int fimc_is_get_clocks(struct fimc_is *is)
ret = PTR_ERR(is->clocks[i]);
goto err;
}
ret = clk_prepare(is->clocks[i]);
if (ret < 0) {
clk_put(is->clocks[i]);
is->clocks[i] = ERR_PTR(-EINVAL);
goto err;
}
}

return 0;
err:
fimc_is_put_clocks(is);
dev_err(&is->pdev->dev, "failed to get clock: %s\n",
fimc_is_clocks[i]);
return -ENXIO;
return ret;
}

static int fimc_is_setup_clocks(struct fimc_is *is)
Expand Down Expand Up @@ -144,7 +137,7 @@ int fimc_is_enable_clocks(struct fimc_is *is)
for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
if (IS_ERR(is->clocks[i]))
continue;
ret = clk_enable(is->clocks[i]);
ret = clk_prepare_enable(is->clocks[i]);
if (ret < 0) {
dev_err(&is->pdev->dev, "clock %s enable failed\n",
fimc_is_clocks[i]);
Expand All @@ -163,7 +156,7 @@ void fimc_is_disable_clocks(struct fimc_is *is)

for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
if (!IS_ERR(is->clocks[i])) {
clk_disable(is->clocks[i]);
clk_disable_unprepare(is->clocks[i]);
pr_debug("disabled clock: %s\n", fimc_is_clocks[i]);
}
}
Expand Down

0 comments on commit b4155d7

Please sign in to comment.