diff options
Diffstat (limited to 'drivers/media/platform')
-rw-r--r-- | drivers/media/platform/s5p-fimc/fimc-mdevice.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index 2b0587204868..d940454a0297 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -708,35 +708,54 @@ static int fimc_md_create_links(struct fimc_md *fmd) /* * The peripheral sensor clock management. */ +static void fimc_md_put_clocks(struct fimc_md *fmd) +{ + int i = FIMC_MAX_CAMCLKS; + + while (--i >= 0) { + if (IS_ERR(fmd->camclk[i].clock)) + continue; + clk_unprepare(fmd->camclk[i].clock); + clk_put(fmd->camclk[i].clock); + fmd->camclk[i].clock = ERR_PTR(-EINVAL); + } +} + static int fimc_md_get_clocks(struct fimc_md *fmd) { + struct device *dev = NULL; char clk_name[32]; struct clk *clock; - int i; + int ret, i; + + for (i = 0; i < FIMC_MAX_CAMCLKS; i++) + fmd->camclk[i].clock = ERR_PTR(-EINVAL); + + if (fmd->pdev->dev.of_node) + dev = &fmd->pdev->dev; for (i = 0; i < FIMC_MAX_CAMCLKS; i++) { snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i); - clock = clk_get(NULL, clk_name); + clock = clk_get(dev, clk_name); + if (IS_ERR(clock)) { - v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s", - clk_name); - return -ENXIO; + dev_err(&fmd->pdev->dev, "Failed to get clock: %s\n", + clk_name); + ret = PTR_ERR(clock); + break; + } + ret = clk_prepare(clock); + if (ret < 0) { + clk_put(clock); + fmd->camclk[i].clock = ERR_PTR(-EINVAL); + break; } fmd->camclk[i].clock = clock; } - return 0; -} - -static void fimc_md_put_clocks(struct fimc_md *fmd) -{ - int i = FIMC_MAX_CAMCLKS; + if (ret) + fimc_md_put_clocks(fmd); - while (--i >= 0) { - if (IS_ERR_OR_NULL(fmd->camclk[i].clock)) - continue; - clk_put(fmd->camclk[i].clock); - fmd->camclk[i].clock = NULL; - } + return ret; } static int __fimc_md_set_camclk(struct fimc_md *fmd, |