summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Cai <r63905@freescale.com>2014-12-23 11:47:26 +0800
committerRobby Cai <r63905@freescale.com>2014-12-23 13:27:56 +0800
commit971603ebc49f11e6d7026e7c9a3d209297e2290b (patch)
tree073b03ddce8b379e000db1e06b4d1c00c66d689d
parent4ca9ec417ce3c7fbd5594ada108fe9febdd8f1e2 (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.c5
-rw-r--r--drivers/media/platform/mxc/capture/fsl_csi.c85
-rw-r--r--drivers/media/platform/mxc/capture/fsl_csi.h8
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)