diff options
author | Robby Cai <r63905@freescale.com> | 2014-12-23 11:47:26 +0800 |
---|---|---|
committer | Robby Cai <r63905@freescale.com> | 2014-12-23 13:27:56 +0800 |
commit | 971603ebc49f11e6d7026e7c9a3d209297e2290b (patch) | |
tree | 073b03ddce8b379e000db1e06b4d1c00c66d689d | |
parent | 4ca9ec417ce3c7fbd5594ada108fe9febdd8f1e2 (diff) |
MLK-10049 csi: turn off clocks when csi module removes
When this module removes, turn off all csi-related clocks
and also disable dummy disp-regulator in order to turn off disp-mix
to save power.
Signed-off-by: Robby Cai <r63905@freescale.com>
-rw-r--r-- | drivers/media/platform/mxc/capture/csi_v4l2_capture.c | 5 | ||||
-rw-r--r-- | drivers/media/platform/mxc/capture/fsl_csi.c | 85 | ||||
-rw-r--r-- | drivers/media/platform/mxc/capture/fsl_csi.h | 8 |
3 files changed, 30 insertions, 68 deletions
diff --git a/drivers/media/platform/mxc/capture/csi_v4l2_capture.c b/drivers/media/platform/mxc/capture/csi_v4l2_capture.c index 6132a9238a5e..77d46e6baa5e 100644 --- a/drivers/media/platform/mxc/capture/csi_v4l2_capture.c +++ b/drivers/media/platform/mxc/capture/csi_v4l2_capture.c @@ -1410,7 +1410,6 @@ static int csi_v4l_open(struct file *file) vidioc_int_g_ifparm(cam->sensor, &ifparm); cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - csi_clk_enable(); clk_prepare_enable(sensor->sensor_clk); vidioc_int_s_power(cam->sensor, 1); vidioc_int_init(cam->sensor); @@ -2271,8 +2270,6 @@ static int csi_v4l2_runtime_suspend(struct device *dev) release_bus_freq(BUS_FREQ_HIGH); dev_dbg(dev, "csi v4l2 busfreq high release.\n"); - csi_regulator_disable(); - return ret; } @@ -2283,8 +2280,6 @@ static int csi_v4l2_runtime_resume(struct device *dev) request_bus_freq(BUS_FREQ_HIGH); dev_dbg(dev, "csi v4l2 busfreq high request.\n"); - csi_regulator_enable(); - return ret; } #else diff --git a/drivers/media/platform/mxc/capture/fsl_csi.c b/drivers/media/platform/mxc/capture/fsl_csi.c index 88fe0200062b..0f28c0b8cfb3 100644 --- a/drivers/media/platform/mxc/capture/fsl_csi.c +++ b/drivers/media/platform/mxc/capture/fsl_csi.c @@ -40,44 +40,6 @@ struct csi_soc csi_array[CSI_MAX_NUM], *csi; static csi_irq_callback_t g_callback; static void *g_callback_data; -static struct clk *disp_axi_clk; -static struct clk *dcic_clk; -static struct clk *csi_clk; -static struct regulator *disp_reg; - -int csi_regulator_enable(void) -{ - int ret = 0; - - if (disp_reg) - ret = regulator_enable(disp_reg); - - return ret; -} -EXPORT_SYMBOL(csi_regulator_enable); - -void csi_regulator_disable(void) -{ - if (disp_reg) - regulator_disable(disp_reg); -} -EXPORT_SYMBOL(csi_regulator_disable); - -void csi_clk_enable(void) -{ - clk_prepare_enable(disp_axi_clk); - clk_prepare_enable(dcic_clk); - clk_prepare_enable(csi_clk); -} -EXPORT_SYMBOL(csi_clk_enable); - -void csi_clk_disable(void) -{ - clk_disable_unprepare(csi_clk); - clk_disable_unprepare(dcic_clk); - clk_disable_unprepare(disp_axi_clk); -} -EXPORT_SYMBOL(csi_clk_disable); static irqreturn_t csi_irq_handler(int irq, void *data) { @@ -498,36 +460,38 @@ static int csi_probe(struct platform_device *pdev) goto err; } - disp_axi_clk = devm_clk_get(&pdev->dev, "disp-axi"); - if (IS_ERR(disp_axi_clk)) { + csi->disp_axi_clk = devm_clk_get(&pdev->dev, "disp-axi"); + if (IS_ERR(csi->disp_axi_clk)) { dev_err(&pdev->dev, "get csi clock failed\n"); - return PTR_ERR(disp_axi_clk); + return PTR_ERR(csi->disp_axi_clk); } - csi_clk = devm_clk_get(&pdev->dev, "csi_mclk"); - if (IS_ERR(csi_clk)) { + csi->csi_clk = devm_clk_get(&pdev->dev, "csi_mclk"); + if (IS_ERR(csi->csi_clk)) { dev_err(&pdev->dev, "get csi mclk failed\n"); - return PTR_ERR(csi_clk); + return PTR_ERR(csi->csi_clk); } - dcic_clk = devm_clk_get(&pdev->dev, "dcic"); - if (IS_ERR(dcic_clk)) { + csi->dcic_clk = devm_clk_get(&pdev->dev, "dcic"); + if (IS_ERR(csi->dcic_clk)) { dev_err(&pdev->dev, "get dcic clk failed\n"); - return PTR_ERR(dcic_clk); + return PTR_ERR(csi->dcic_clk); } - if (disp_reg == NULL) { - disp_reg = devm_regulator_get(&pdev->dev, "disp"); - if (IS_ERR(disp_reg)) { - dev_dbg(&pdev->dev, "display regulator is not ready\n"); - disp_reg = NULL; - } + csi->disp_reg = devm_regulator_get(&pdev->dev, "disp"); + if (IS_ERR(csi->disp_reg)) { + dev_dbg(&pdev->dev, "display regulator is not ready\n"); + csi->disp_reg = NULL; } platform_set_drvdata(pdev, csi); - csi_regulator_enable(); + if (csi->disp_reg) + ret = regulator_enable(csi->disp_reg); + + clk_prepare_enable(csi->disp_axi_clk); + clk_prepare_enable(csi->dcic_clk); + clk_prepare_enable(csi->csi_clk); - csi_clk_enable(); csihw_reset(csi); csi_init_interface(csi); csi_dmareq_rff_disable(csi); @@ -542,6 +506,13 @@ static int csi_remove(struct platform_device *pdev) struct csi_soc *csi = platform_get_drvdata(pdev); csi->online = false; + + clk_disable_unprepare(csi->csi_clk); + clk_disable_unprepare(csi->dcic_clk); + clk_disable_unprepare(csi->disp_axi_clk); + + if (csi->disp_reg) + regulator_disable(csi->disp_reg); platform_set_drvdata(pdev, NULL); return 0; @@ -561,13 +532,9 @@ static int csi_resume(struct device *dev) { struct csi_soc *csi = dev_get_drvdata(dev); - csi_regulator_enable(); - csi_clk_enable(); csihw_reset(csi); csi_init_interface(csi); csi_dmareq_rff_disable(csi); - csi_clk_disable(); - csi_regulator_disable(); csi->online = true; diff --git a/drivers/media/platform/mxc/capture/fsl_csi.h b/drivers/media/platform/mxc/capture/fsl_csi.h index 161c27b6929e..732b6bc00565 100644 --- a/drivers/media/platform/mxc/capture/fsl_csi.h +++ b/drivers/media/platform/mxc/capture/fsl_csi.h @@ -195,6 +195,10 @@ struct csi_config_t { struct csi_soc { bool online; int irq_nr; + struct clk *disp_axi_clk; + struct clk *dcic_clk; + struct clk *csi_clk; + struct regulator *disp_reg; void __iomem *regbase; }; @@ -214,10 +218,6 @@ void csi_deinterlace_enable(cam_data *cam, bool enable); void csi_tvdec_enable(cam_data *cam, bool enable); void csi_enable(cam_data *cam, int arg); void csi_disable_int(cam_data *cam); -int csi_regulator_enable(void); -void csi_regulator_disable(void); -void csi_clk_enable(void); -void csi_clk_disable(void); void csi_dmareq_rff_enable(struct csi_soc *csi); void csi_dmareq_rff_disable(struct csi_soc *csi); static inline int csi_read(struct csi_soc *csi, unsigned int offset) |