aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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_ */