mirror of https://gitee.com/openkylin/linux.git
[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>
This commit is contained in:
parent
3cf138a639
commit
b4155d7d5b
|
@ -71,7 +71,6 @@ static void fimc_is_put_clocks(struct fimc_is *is)
|
||||||
for (i = 0; i < ISS_CLKS_MAX; i++) {
|
for (i = 0; i < ISS_CLKS_MAX; i++) {
|
||||||
if (IS_ERR(is->clocks[i]))
|
if (IS_ERR(is->clocks[i]))
|
||||||
continue;
|
continue;
|
||||||
clk_unprepare(is->clocks[i]);
|
|
||||||
clk_put(is->clocks[i]);
|
clk_put(is->clocks[i]);
|
||||||
is->clocks[i] = ERR_PTR(-EINVAL);
|
is->clocks[i] = ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
@ -90,12 +89,6 @@ static int fimc_is_get_clocks(struct fimc_is *is)
|
||||||
ret = PTR_ERR(is->clocks[i]);
|
ret = PTR_ERR(is->clocks[i]);
|
||||||
goto err;
|
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;
|
return 0;
|
||||||
|
@ -103,7 +96,7 @@ static int fimc_is_get_clocks(struct fimc_is *is)
|
||||||
fimc_is_put_clocks(is);
|
fimc_is_put_clocks(is);
|
||||||
dev_err(&is->pdev->dev, "failed to get clock: %s\n",
|
dev_err(&is->pdev->dev, "failed to get clock: %s\n",
|
||||||
fimc_is_clocks[i]);
|
fimc_is_clocks[i]);
|
||||||
return -ENXIO;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fimc_is_setup_clocks(struct fimc_is *is)
|
static int fimc_is_setup_clocks(struct fimc_is *is)
|
||||||
|
@ -144,7 +137,7 @@ int fimc_is_enable_clocks(struct fimc_is *is)
|
||||||
for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
|
for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
|
||||||
if (IS_ERR(is->clocks[i]))
|
if (IS_ERR(is->clocks[i]))
|
||||||
continue;
|
continue;
|
||||||
ret = clk_enable(is->clocks[i]);
|
ret = clk_prepare_enable(is->clocks[i]);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&is->pdev->dev, "clock %s enable failed\n",
|
dev_err(&is->pdev->dev, "clock %s enable failed\n",
|
||||||
fimc_is_clocks[i]);
|
fimc_is_clocks[i]);
|
||||||
|
@ -163,7 +156,7 @@ void fimc_is_disable_clocks(struct fimc_is *is)
|
||||||
|
|
||||||
for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
|
for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
|
||||||
if (!IS_ERR(is->clocks[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]);
|
pr_debug("disabled clock: %s\n", fimc_is_clocks[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue