aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2012-08-14 09:46:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-01 19:25:32 -0400
commitb9ee31e621128ef7ad112daaba215357223b8cdd (patch)
tree06e8817add0f8abdcf60a1ae50f1283f2aa102a1
parentb5146c96d1795ed75bb90dc4d3189b2c4206c56d (diff)
[media] s5p-fimc: Add pipeline ops to separate FIMC-LITE module
In order to reuse the FIMC-LITE module on Exynos4 and Exynos5 SoC introduce a set of callbacks for the media pipeline control from within FIMC/FIMC-LITE video node. It lets us avoid symbol dependencies between FIMC-LITE and the whole media device driver, which simplifies the initialization sequences and doesn't introduce issues preventing common kernel image for exynos4 and exynos5 SoCs. This patch also corrects following build errors: drivers/built-in.o: In function `buffer_queue': drivers/media/video/s5p-fimc/fimc-lite.c:414: undefined reference to `fimc_pipeline_s_stream' drivers/built-in.o: In function `fimc_lite_resume': drivers/media/video/s5p-fimc/fimc-lite.c:1518: undefined reference to `fimc_pipeline_initialize' drivers/built-in.o: In function `fimc_lite_suspend': drivers/media/video/s5p-fimc/fimc-lite.c:1544: undefined reference to `fimc_pipeline_shutdown' when only CONFIG_VIDEO_EXYNOS_FIMC_LITE is selected, without CONFIG_VIDEO_S5P_FIMC. Reported-by: Sachin Kamat <sachin.kamat@linaro.org> 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>
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-capture.c21
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-core.h1
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-lite.c21
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-lite.h2
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-mdevice.c52
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-mdevice.h6
-rw-r--r--include/media/s5p_fimc.h18
7 files changed, 77 insertions, 44 deletions
diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c
index ac2ca36039e4..6792fd4236c6 100644
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -118,7 +118,8 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
118 spin_unlock_irqrestore(&fimc->slock, flags); 118 spin_unlock_irqrestore(&fimc->slock, flags);
119 119
120 if (streaming) 120 if (streaming)
121 return fimc_pipeline_s_stream(&fimc->pipeline, 0); 121 return fimc_pipeline_call(fimc, set_stream,
122 &fimc->pipeline, 0);
122 else 123 else
123 return 0; 124 return 0;
124} 125}
@@ -264,7 +265,8 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
264 fimc_activate_capture(ctx); 265 fimc_activate_capture(ctx);
265 266
266 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) 267 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
267 fimc_pipeline_s_stream(&fimc->pipeline, 1); 268 fimc_pipeline_call(fimc, set_stream,
269 &fimc->pipeline, 1);
268 } 270 }
269 271
270 return 0; 272 return 0;
@@ -288,7 +290,7 @@ int fimc_capture_suspend(struct fimc_dev *fimc)
288 int ret = fimc_stop_capture(fimc, suspend); 290 int ret = fimc_stop_capture(fimc, suspend);
289 if (ret) 291 if (ret)
290 return ret; 292 return ret;
291 return fimc_pipeline_shutdown(&fimc->pipeline); 293 return fimc_pipeline_call(fimc, close, &fimc->pipeline);
292} 294}
293 295
294static void buffer_queue(struct vb2_buffer *vb); 296static void buffer_queue(struct vb2_buffer *vb);
@@ -304,8 +306,8 @@ int fimc_capture_resume(struct fimc_dev *fimc)
304 306
305 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); 307 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
306 vid_cap->buf_index = 0; 308 vid_cap->buf_index = 0;
307 fimc_pipeline_initialize(&fimc->pipeline, &vid_cap->vfd.entity, 309 fimc_pipeline_call(fimc, open, &fimc->pipeline,
308 false); 310 &vid_cap->vfd.entity, false);
309 fimc_capture_hw_init(fimc); 311 fimc_capture_hw_init(fimc);
310 312
311 clear_bit(ST_CAPT_SUSPENDED, &fimc->state); 313 clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
@@ -422,7 +424,8 @@ static void buffer_queue(struct vb2_buffer *vb)
422 spin_unlock_irqrestore(&fimc->slock, flags); 424 spin_unlock_irqrestore(&fimc->slock, flags);
423 425
424 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) 426 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
425 fimc_pipeline_s_stream(&fimc->pipeline, 1); 427 fimc_pipeline_call(fimc, set_stream,
428 &fimc->pipeline, 1);
426 return; 429 return;
427 } 430 }
428 spin_unlock_irqrestore(&fimc->slock, flags); 431 spin_unlock_irqrestore(&fimc->slock, flags);
@@ -502,8 +505,8 @@ static int fimc_capture_open(struct file *file)
502 } 505 }
503 506
504 if (++fimc->vid_cap.refcnt == 1) { 507 if (++fimc->vid_cap.refcnt == 1) {
505 ret = fimc_pipeline_initialize(&fimc->pipeline, 508 ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
506 &fimc->vid_cap.vfd.entity, true); 509 &fimc->vid_cap.vfd.entity, true);
507 510
508 if (!ret && !fimc->vid_cap.user_subdev_api) 511 if (!ret && !fimc->vid_cap.user_subdev_api)
509 ret = fimc_capture_set_default_format(fimc); 512 ret = fimc_capture_set_default_format(fimc);
@@ -536,7 +539,7 @@ static int fimc_capture_close(struct file *file)
536 if (--fimc->vid_cap.refcnt == 0) { 539 if (--fimc->vid_cap.refcnt == 0) {
537 clear_bit(ST_CAPT_BUSY, &fimc->state); 540 clear_bit(ST_CAPT_BUSY, &fimc->state);
538 fimc_stop_capture(fimc, false); 541 fimc_stop_capture(fimc, false);
539 fimc_pipeline_shutdown(&fimc->pipeline); 542 fimc_pipeline_call(fimc, close, &fimc->pipeline);
540 clear_bit(ST_CAPT_SUSPENDED, &fimc->state); 543 clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
541 } 544 }
542 545
diff --git a/drivers/media/platform/s5p-fimc/fimc-core.h b/drivers/media/platform/s5p-fimc/fimc-core.h
index d3a3a00321c3..61805469bdd7 100644
--- a/drivers/media/platform/s5p-fimc/fimc-core.h
+++ b/drivers/media/platform/s5p-fimc/fimc-core.h
@@ -440,6 +440,7 @@ struct fimc_dev {
440 unsigned long state; 440 unsigned long state;
441 struct vb2_alloc_ctx *alloc_ctx; 441 struct vb2_alloc_ctx *alloc_ctx;
442 struct fimc_pipeline pipeline; 442 struct fimc_pipeline pipeline;
443 const struct fimc_pipeline_ops *pipeline_ops;
443}; 444};
444 445
445/** 446/**
diff --git a/drivers/media/platform/s5p-fimc/fimc-lite.c b/drivers/media/platform/s5p-fimc/fimc-lite.c
index cd4cf12d20e3..bef8d3ef79cc 100644
--- a/drivers/media/platform/s5p-fimc/fimc-lite.c
+++ b/drivers/media/platform/s5p-fimc/fimc-lite.c
@@ -28,9 +28,11 @@
28#include <media/v4l2-mem2mem.h> 28#include <media/v4l2-mem2mem.h>
29#include <media/videobuf2-core.h> 29#include <media/videobuf2-core.h>
30#include <media/videobuf2-dma-contig.h> 30#include <media/videobuf2-dma-contig.h>
31#include <media/s5p_fimc.h>
31 32
32#include "fimc-mdevice.h" 33#include "fimc-mdevice.h"
33#include "fimc-core.h" 34#include "fimc-core.h"
35#include "fimc-lite.h"
34#include "fimc-lite-reg.h" 36#include "fimc-lite-reg.h"
35 37
36static int debug; 38static int debug;
@@ -193,7 +195,7 @@ static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
193 if (!streaming) 195 if (!streaming)
194 return 0; 196 return 0;
195 197
196 return fimc_pipeline_s_stream(&fimc->pipeline, 0); 198 return fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 0);
197} 199}
198 200
199static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend) 201static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
@@ -307,7 +309,8 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
307 flite_hw_capture_start(fimc); 309 flite_hw_capture_start(fimc);
308 310
309 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state)) 311 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
310 fimc_pipeline_s_stream(&fimc->pipeline, 1); 312 fimc_pipeline_call(fimc, set_stream,
313 &fimc->pipeline, 1);
311 } 314 }
312 if (debug > 0) 315 if (debug > 0)
313 flite_hw_dump_regs(fimc, __func__); 316 flite_hw_dump_regs(fimc, __func__);
@@ -411,7 +414,8 @@ static void buffer_queue(struct vb2_buffer *vb)
411 spin_unlock_irqrestore(&fimc->slock, flags); 414 spin_unlock_irqrestore(&fimc->slock, flags);
412 415
413 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state)) 416 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
414 fimc_pipeline_s_stream(&fimc->pipeline, 1); 417 fimc_pipeline_call(fimc, set_stream,
418 &fimc->pipeline, 1);
415 return; 419 return;
416 } 420 }
417 spin_unlock_irqrestore(&fimc->slock, flags); 421 spin_unlock_irqrestore(&fimc->slock, flags);
@@ -466,8 +470,8 @@ static int fimc_lite_open(struct file *file)
466 goto done; 470 goto done;
467 471
468 if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) { 472 if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) {
469 ret = fimc_pipeline_initialize(&fimc->pipeline, 473 ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
470 &fimc->vfd.entity, true); 474 &fimc->vfd.entity, true);
471 if (ret < 0) { 475 if (ret < 0) {
472 pm_runtime_put_sync(&fimc->pdev->dev); 476 pm_runtime_put_sync(&fimc->pdev->dev);
473 fimc->ref_count--; 477 fimc->ref_count--;
@@ -493,7 +497,7 @@ static int fimc_lite_close(struct file *file)
493 if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { 497 if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
494 clear_bit(ST_FLITE_IN_USE, &fimc->state); 498 clear_bit(ST_FLITE_IN_USE, &fimc->state);
495 fimc_lite_stop_capture(fimc, false); 499 fimc_lite_stop_capture(fimc, false);
496 fimc_pipeline_shutdown(&fimc->pipeline); 500 fimc_pipeline_call(fimc, close, &fimc->pipeline);
497 clear_bit(ST_FLITE_SUSPENDED, &fimc->state); 501 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
498 } 502 }
499 503
@@ -1508,7 +1512,8 @@ static int fimc_lite_resume(struct device *dev)
1508 return 0; 1512 return 0;
1509 1513
1510 INIT_LIST_HEAD(&fimc->active_buf_q); 1514 INIT_LIST_HEAD(&fimc->active_buf_q);
1511 fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd.entity, false); 1515 fimc_pipeline_call(fimc, open, &fimc->pipeline,
1516 &fimc->vfd.entity, false);
1512 fimc_lite_hw_init(fimc); 1517 fimc_lite_hw_init(fimc);
1513 clear_bit(ST_FLITE_SUSPENDED, &fimc->state); 1518 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
1514 1519
@@ -1534,7 +1539,7 @@ static int fimc_lite_suspend(struct device *dev)
1534 if (ret < 0 || !fimc_lite_active(fimc)) 1539 if (ret < 0 || !fimc_lite_active(fimc))
1535 return ret; 1540 return ret;
1536 1541
1537 return fimc_pipeline_shutdown(&fimc->pipeline); 1542 return fimc_pipeline_call(fimc, close, &fimc->pipeline);
1538} 1543}
1539#endif /* CONFIG_PM_SLEEP */ 1544#endif /* CONFIG_PM_SLEEP */
1540 1545
diff --git a/drivers/media/platform/s5p-fimc/fimc-lite.h b/drivers/media/platform/s5p-fimc/fimc-lite.h
index 9944dd36ec7c..b04bf3b8369f 100644
--- a/drivers/media/platform/s5p-fimc/fimc-lite.h
+++ b/drivers/media/platform/s5p-fimc/fimc-lite.h
@@ -108,6 +108,7 @@ struct flite_buffer {
108 * @test_pattern: test pattern controls 108 * @test_pattern: test pattern controls
109 * @index: FIMC-LITE platform device index 109 * @index: FIMC-LITE platform device index
110 * @pipeline: video capture pipeline data structure 110 * @pipeline: video capture pipeline data structure
111 * @pipeline_ops: media pipeline ops for the video node driver
111 * @slock: spinlock protecting this data structure and the hw registers 112 * @slock: spinlock protecting this data structure and the hw registers
112 * @lock: mutex serializing video device and the subdev operations 113 * @lock: mutex serializing video device and the subdev operations
113 * @clock: FIMC-LITE gate clock 114 * @clock: FIMC-LITE gate clock
@@ -142,6 +143,7 @@ struct fimc_lite {
142 struct v4l2_ctrl *test_pattern; 143 struct v4l2_ctrl *test_pattern;
143 u32 index; 144 u32 index;
144 struct fimc_pipeline pipeline; 145 struct fimc_pipeline pipeline;
146 const struct fimc_pipeline_ops *pipeline_ops;
145 147
146 struct mutex lock; 148 struct mutex lock;
147 spinlock_t slock; 149 spinlock_t slock;
diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c
index e2aa8d99d858..223fcfe2e1b3 100644
--- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c
+++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <media/v4l2-ctrls.h> 24#include <media/v4l2-ctrls.h>
25#include <media/media-device.h> 25#include <media/media-device.h>
26#include <media/s5p_fimc.h>
26 27
27#include "fimc-core.h" 28#include "fimc-core.h"
28#include "fimc-lite.h" 29#include "fimc-lite.h"
@@ -38,7 +39,8 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
38 * 39 *
39 * Caller holds the graph mutex. 40 * Caller holds the graph mutex.
40 */ 41 */
41void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me) 42static void fimc_pipeline_prepare(struct fimc_pipeline *p,
43 struct media_entity *me)
42{ 44{
43 struct media_pad *pad = &me->pads[0]; 45 struct media_pad *pad = &me->pads[0];
44 struct v4l2_subdev *sd; 46 struct v4l2_subdev *sd;
@@ -114,7 +116,7 @@ static int __subdev_set_power(struct v4l2_subdev *sd, int on)
114 * 116 *
115 * Needs to be called with the graph mutex held. 117 * Needs to be called with the graph mutex held.
116 */ 118 */
117int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state) 119static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
118{ 120{
119 unsigned int i; 121 unsigned int i;
120 int ret; 122 int ret;
@@ -134,15 +136,15 @@ int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
134} 136}
135 137
136/** 138/**
137 * __fimc_pipeline_initialize - update the pipeline information, enable power 139 * __fimc_pipeline_open - update the pipeline information, enable power
138 * of all pipeline subdevs and the sensor clock 140 * of all pipeline subdevs and the sensor clock
139 * @me: media entity to start graph walk with 141 * @me: media entity to start graph walk with
140 * @prep: true to acquire sensor (and csis) subdevs 142 * @prep: true to acquire sensor (and csis) subdevs
141 * 143 *
142 * This function must be called with the graph mutex held. 144 * This function must be called with the graph mutex held.
143 */ 145 */
144static int __fimc_pipeline_initialize(struct fimc_pipeline *p, 146static int __fimc_pipeline_open(struct fimc_pipeline *p,
145 struct media_entity *me, bool prep) 147 struct media_entity *me, bool prep)
146{ 148{
147 int ret; 149 int ret;
148 150
@@ -159,28 +161,27 @@ static int __fimc_pipeline_initialize(struct fimc_pipeline *p,
159 return fimc_pipeline_s_power(p, 1); 161 return fimc_pipeline_s_power(p, 1);
160} 162}
161 163
162int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me, 164static int fimc_pipeline_open(struct fimc_pipeline *p,
163 bool prep) 165 struct media_entity *me, bool prep)
164{ 166{
165 int ret; 167 int ret;
166 168
167 mutex_lock(&me->parent->graph_mutex); 169 mutex_lock(&me->parent->graph_mutex);
168 ret = __fimc_pipeline_initialize(p, me, prep); 170 ret = __fimc_pipeline_open(p, me, prep);
169 mutex_unlock(&me->parent->graph_mutex); 171 mutex_unlock(&me->parent->graph_mutex);
170 172
171 return ret; 173 return ret;
172} 174}
173EXPORT_SYMBOL_GPL(fimc_pipeline_initialize);
174 175
175/** 176/**
176 * __fimc_pipeline_shutdown - disable the sensor clock and pipeline power 177 * __fimc_pipeline_close - disable the sensor clock and pipeline power
177 * @fimc: fimc device terminating the pipeline 178 * @fimc: fimc device terminating the pipeline
178 * 179 *
179 * Disable power of all subdevs in the pipeline and turn off the external 180 * Disable power of all subdevs in the pipeline and turn off the external
180 * sensor clock. 181 * sensor clock.
181 * Called with the graph mutex held. 182 * Called with the graph mutex held.
182 */ 183 */
183static int __fimc_pipeline_shutdown(struct fimc_pipeline *p) 184static int __fimc_pipeline_close(struct fimc_pipeline *p)
184{ 185{
185 int ret = 0; 186 int ret = 0;
186 187
@@ -191,7 +192,7 @@ static int __fimc_pipeline_shutdown(struct fimc_pipeline *p)
191 return ret == -ENXIO ? 0 : ret; 192 return ret == -ENXIO ? 0 : ret;
192} 193}
193 194
194int fimc_pipeline_shutdown(struct fimc_pipeline *p) 195static int fimc_pipeline_close(struct fimc_pipeline *p)
195{ 196{
196 struct media_entity *me; 197 struct media_entity *me;
197 int ret; 198 int ret;
@@ -201,12 +202,11 @@ int fimc_pipeline_shutdown(struct fimc_pipeline *p)
201 202
202 me = &p->subdevs[IDX_SENSOR]->entity; 203 me = &p->subdevs[IDX_SENSOR]->entity;
203 mutex_lock(&me->parent->graph_mutex); 204 mutex_lock(&me->parent->graph_mutex);
204 ret = __fimc_pipeline_shutdown(p); 205 ret = __fimc_pipeline_close(p);
205 mutex_unlock(&me->parent->graph_mutex); 206 mutex_unlock(&me->parent->graph_mutex);
206 207
207 return ret; 208 return ret;
208} 209}
209EXPORT_SYMBOL_GPL(fimc_pipeline_shutdown);
210 210
211/** 211/**
212 * fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs 212 * fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs
@@ -232,7 +232,13 @@ int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
232 return 0; 232 return 0;
233 233
234} 234}
235EXPORT_SYMBOL_GPL(fimc_pipeline_s_stream); 235
236/* Media pipeline operations for the FIMC/FIMC-LITE video device driver */
237static const struct fimc_pipeline_ops fimc_pipeline_ops = {
238 .open = fimc_pipeline_open,
239 .close = fimc_pipeline_close,
240 .set_stream = fimc_pipeline_s_stream,
241};
236 242
237/* 243/*
238 * Sensor subdevice helper functions 244 * Sensor subdevice helper functions
@@ -347,6 +353,7 @@ static int fimc_register_callback(struct device *dev, void *p)
347 if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS) 353 if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
348 return 0; 354 return 0;
349 355
356 fimc->pipeline_ops = &fimc_pipeline_ops;
350 fmd->fimc[fimc->pdev->id] = fimc; 357 fmd->fimc[fimc->pdev->id] = fimc;
351 sd->grp_id = FIMC_GROUP_ID; 358 sd->grp_id = FIMC_GROUP_ID;
352 359
@@ -372,6 +379,7 @@ static int fimc_lite_register_callback(struct device *dev, void *p)
372 if (fimc->index >= FIMC_LITE_MAX_DEVS) 379 if (fimc->index >= FIMC_LITE_MAX_DEVS)
373 return 0; 380 return 0;
374 381
382 fimc->pipeline_ops = &fimc_pipeline_ops;
375 fmd->fimc_lite[fimc->index] = fimc; 383 fmd->fimc_lite[fimc->index] = fimc;
376 sd->grp_id = FLITE_GROUP_ID; 384 sd->grp_id = FLITE_GROUP_ID;
377 385
@@ -473,12 +481,14 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd)
473 if (fmd->fimc[i] == NULL) 481 if (fmd->fimc[i] == NULL)
474 continue; 482 continue;
475 v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev); 483 v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
484 fmd->fimc[i]->pipeline_ops = NULL;
476 fmd->fimc[i] = NULL; 485 fmd->fimc[i] = NULL;
477 } 486 }
478 for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) { 487 for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
479 if (fmd->fimc_lite[i] == NULL) 488 if (fmd->fimc_lite[i] == NULL)
480 continue; 489 continue;
481 v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev); 490 v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
491 fmd->fimc[i]->pipeline_ops = NULL;
482 fmd->fimc_lite[i] = NULL; 492 fmd->fimc_lite[i] = NULL;
483 } 493 }
484 for (i = 0; i < CSIS_MAX_ENTITIES; i++) { 494 for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
@@ -832,7 +842,7 @@ static int fimc_md_link_notify(struct media_pad *source,
832 } 842 }
833 843
834 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 844 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
835 ret = __fimc_pipeline_shutdown(pipeline); 845 ret = __fimc_pipeline_close(pipeline);
836 pipeline->subdevs[IDX_SENSOR] = NULL; 846 pipeline->subdevs[IDX_SENSOR] = NULL;
837 pipeline->subdevs[IDX_CSIS] = NULL; 847 pipeline->subdevs[IDX_CSIS] = NULL;
838 848
@@ -851,8 +861,8 @@ static int fimc_md_link_notify(struct media_pad *source,
851 if (fimc) { 861 if (fimc) {
852 mutex_lock(&fimc->lock); 862 mutex_lock(&fimc->lock);
853 if (fimc->vid_cap.refcnt > 0) { 863 if (fimc->vid_cap.refcnt > 0) {
854 ret = __fimc_pipeline_initialize(pipeline, 864 ret = __fimc_pipeline_open(pipeline,
855 source->entity, true); 865 source->entity, true);
856 if (!ret) 866 if (!ret)
857 ret = fimc_capture_ctrls_create(fimc); 867 ret = fimc_capture_ctrls_create(fimc);
858 } 868 }
@@ -860,8 +870,8 @@ static int fimc_md_link_notify(struct media_pad *source,
860 } else { 870 } else {
861 mutex_lock(&fimc_lite->lock); 871 mutex_lock(&fimc_lite->lock);
862 if (fimc_lite->ref_count > 0) { 872 if (fimc_lite->ref_count > 0) {
863 ret = __fimc_pipeline_initialize(pipeline, 873 ret = __fimc_pipeline_open(pipeline,
864 source->entity, true); 874 source->entity, true);
865 } 875 }
866 mutex_unlock(&fimc_lite->lock); 876 mutex_unlock(&fimc_lite->lock);
867 } 877 }
diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.h b/drivers/media/platform/s5p-fimc/fimc-mdevice.h
index d310d9cc3e1a..0135386457ee 100644
--- a/drivers/media/platform/s5p-fimc/fimc-mdevice.h
+++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.h
@@ -108,11 +108,5 @@ static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
108} 108}
109 109
110int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on); 110int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
111void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me);
112int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
113 bool resume);
114int fimc_pipeline_shutdown(struct fimc_pipeline *p);
115int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state);
116int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool state);
117 111
118#endif 112#endif
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
index 8587aaf73646..09421a611d73 100644
--- a/include/media/s5p_fimc.h
+++ b/include/media/s5p_fimc.h
@@ -12,6 +12,8 @@
12#ifndef S5P_FIMC_H_ 12#ifndef S5P_FIMC_H_
13#define S5P_FIMC_H_ 13#define S5P_FIMC_H_
14 14
15#include <media/media-entity.h>
16
15enum cam_bus_type { 17enum cam_bus_type {
16 FIMC_ITU_601 = 1, 18 FIMC_ITU_601 = 1,
17 FIMC_ITU_656, 19 FIMC_ITU_656,
@@ -80,4 +82,20 @@ struct fimc_pipeline {
80 struct media_pipeline *m_pipeline; 82 struct media_pipeline *m_pipeline;
81}; 83};
82 84
85/*
86 * Media pipeline operations to be called from within the fimc(-lite)
87 * video node when it is the last entity of the pipeline. Implemented
88 * by corresponding media device driver.
89 */
90struct fimc_pipeline_ops {
91 int (*open)(struct fimc_pipeline *p, struct media_entity *me,
92 bool resume);
93 int (*close)(struct fimc_pipeline *p);
94 int (*set_stream)(struct fimc_pipeline *p, bool state);
95};
96
97#define fimc_pipeline_call(f, op, p, args...) \
98 (!(f) ? -ENODEV : (((f)->pipeline_ops && (f)->pipeline_ops->op) ? \
99 (f)->pipeline_ops->op((p), ##args) : -ENOIOCTLCMD))
100
83#endif /* S5P_FIMC_H_ */ 101#endif /* S5P_FIMC_H_ */