From f8bca4f52947f0d6c10299b10e4ccf5711688acc Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki <s.nawrocki@samsung.com> Date: Tue, 20 Nov 2012 08:54:22 -0300 Subject: [PATCH] [media] s5p-fimc: Ensure proper s_power() call order in the ISP datapaths Since the FIMC-IS firmware communicates with an image sensor directly through the ISP I2C bus controllers the sub-devices power supplies cannot be simply enabled from left to right or disabled from right to left along the processing pipeline. Thus a subdev index to call s_power() on is looked up from a table, rather than doing the op call based on increasing/decreasing indexes. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> --- .../media/platform/s5p-fimc/fimc-mdevice.c | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index b22489907295..77075a4d1145 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -128,23 +128,33 @@ static int __subdev_set_power(struct v4l2_subdev *sd, int on) * * Needs to be called with the graph mutex held. */ -static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state) +static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool on) { - unsigned int i; - int ret; + static const u8 seq[2][IDX_MAX - 1] = { + { IDX_IS_ISP, IDX_SENSOR, IDX_CSIS, IDX_FLITE }, + { IDX_CSIS, IDX_FLITE, IDX_SENSOR, IDX_IS_ISP }, + }; + int i, ret = 0; if (p->subdevs[IDX_SENSOR] == NULL) return -ENXIO; - for (i = 0; i < IDX_MAX; i++) { - unsigned int idx = state ? (IDX_MAX - 1) - i : i; + for (i = 0; i < IDX_MAX - 1; i++) { + unsigned int idx = seq[on][i]; + + ret = __subdev_set_power(p->subdevs[idx], on); + - ret = __subdev_set_power(p->subdevs[idx], state); if (ret < 0 && ret != -ENXIO) - return ret; + goto error; } - return 0; +error: + for (; i >= 0; i--) { + unsigned int idx = seq[on][i]; + __subdev_set_power(p->subdevs[idx], !on); + } + return ret; } /**