Skip to content

Commit 7677577

Browse files
janaszewskimchehab
authored andcommitted
[media] exynos4-is: Open shouldn't fail when sensor entity is not linked
In order to allow for automatic media device entities linking from the level of libv4l plugin the open system call shouldn't fail, as the libv4l plugins can begin their job not until it succeeds. This patch allows for leaving the pipeline not linked on open and postpones verifying it to the moment when streamon callback is called. Signed-off-by: Jacek Anaszewski <[email protected]> Acked-by: Kyungmin Park <[email protected]> Cc: Sylwester Nawrocki <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 4e63959 commit 7677577

File tree

1 file changed

+76
-19
lines changed

1 file changed

+76
-19
lines changed

drivers/media/platform/exynos4-is/media-dev.c

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,37 @@ static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool on)
185185
return ret;
186186
}
187187

188+
/**
189+
* __fimc_pipeline_enable - enable power of all pipeline subdevs
190+
* and the sensor clock
191+
* @ep: video pipeline structure
192+
* @fmd: fimc media device
193+
*
194+
* Called with the graph mutex held.
195+
*/
196+
static int __fimc_pipeline_enable(struct exynos_media_pipeline *ep,
197+
struct fimc_md *fmd)
198+
{
199+
struct fimc_pipeline *p = to_fimc_pipeline(ep);
200+
int ret;
201+
202+
/* Enable PXLASYNC clock if this pipeline includes FIMC-IS */
203+
if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) {
204+
ret = clk_prepare_enable(fmd->wbclk[CLK_IDX_WB_B]);
205+
if (ret < 0)
206+
return ret;
207+
}
208+
209+
ret = fimc_pipeline_s_power(p, 1);
210+
if (!ret)
211+
return 0;
212+
213+
if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP])
214+
clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]);
215+
216+
return ret;
217+
}
218+
188219
/**
189220
* __fimc_pipeline_open - update the pipeline information, enable power
190221
* of all pipeline subdevs and the sensor clock
@@ -199,7 +230,6 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
199230
struct fimc_md *fmd = entity_to_fimc_mdev(me);
200231
struct fimc_pipeline *p = to_fimc_pipeline(ep);
201232
struct v4l2_subdev *sd;
202-
int ret;
203233

204234
if (WARN_ON(p == NULL || me == NULL))
205235
return -EINVAL;
@@ -208,24 +238,16 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
208238
fimc_pipeline_prepare(p, me);
209239

210240
sd = p->subdevs[IDX_SENSOR];
211-
if (sd == NULL)
212-
return -EINVAL;
213-
214-
/* Disable PXLASYNC clock if this pipeline includes FIMC-IS */
215-
if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) {
216-
ret = clk_prepare_enable(fmd->wbclk[CLK_IDX_WB_B]);
217-
if (ret < 0)
218-
return ret;
219-
}
220-
221-
ret = fimc_pipeline_s_power(p, 1);
222-
if (!ret)
241+
if (sd == NULL) {
242+
pr_warn("%s(): No sensor subdev\n", __func__);
243+
/*
244+
* Pipeline open cannot fail so as to make it possible
245+
* for the user space to configure the pipeline.
246+
*/
223247
return 0;
248+
}
224249

225-
if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP])
226-
clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]);
227-
228-
return ret;
250+
return __fimc_pipeline_enable(ep, fmd);
229251
}
230252

231253
/**
@@ -269,10 +291,43 @@ static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on)
269291
{ IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP },
270292
};
271293
struct fimc_pipeline *p = to_fimc_pipeline(ep);
294+
struct fimc_md *fmd = entity_to_fimc_mdev(&p->subdevs[IDX_CSIS]->entity);
295+
enum fimc_subdev_index sd_id;
272296
int i, ret = 0;
273297

274-
if (p->subdevs[IDX_SENSOR] == NULL)
275-
return -ENODEV;
298+
if (p->subdevs[IDX_SENSOR] == NULL) {
299+
if (!fmd->user_subdev_api) {
300+
/*
301+
* Sensor must be already discovered if we
302+
* aren't in the user_subdev_api mode
303+
*/
304+
return -ENODEV;
305+
}
306+
307+
/* Get pipeline sink entity */
308+
if (p->subdevs[IDX_FIMC])
309+
sd_id = IDX_FIMC;
310+
else if (p->subdevs[IDX_IS_ISP])
311+
sd_id = IDX_IS_ISP;
312+
else if (p->subdevs[IDX_FLITE])
313+
sd_id = IDX_FLITE;
314+
else
315+
return -ENODEV;
316+
317+
/*
318+
* Sensor could have been linked between open and STREAMON -
319+
* check if this is the case.
320+
*/
321+
fimc_pipeline_prepare(p, &p->subdevs[sd_id]->entity);
322+
323+
if (p->subdevs[IDX_SENSOR] == NULL)
324+
return -ENODEV;
325+
326+
ret = __fimc_pipeline_enable(ep, fmd);
327+
if (ret < 0)
328+
return ret;
329+
330+
}
276331

277332
for (i = 0; i < IDX_MAX; i++) {
278333
unsigned int idx = seq[on][i];
@@ -282,8 +337,10 @@ static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on)
282337
if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
283338
goto error;
284339
}
340+
285341
return 0;
286342
error:
343+
fimc_pipeline_s_power(p, !on);
287344
for (; i >= 0; i--) {
288345
unsigned int idx = seq[on][i];
289346
v4l2_subdev_call(p->subdevs[idx], video, s_stream, !on);

0 commit comments

Comments
 (0)