summaryrefslogtreecommitdiff
path: root/drivers/media/platform/vimc/vimc-sensor.c
diff options
context:
space:
mode:
authorLucas A. M. Magalhães <lucmaga@gmail.com>2019-01-21 20:05:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-03-23 14:35:30 +0100
commit77fbb561bb09f56877dd84318212da393909975f (patch)
tree32a80b24c1e29d30e848a154c3b30bcb9cb34b84 /drivers/media/platform/vimc/vimc-sensor.c
parentc1ce0ea53e5bc2ea4b4d918d8fb0fac3e46b8c46 (diff)
media: vimc: Add vimc-streamer for stream control
commit adc589d2a20808fb99d46a78175cd023f2040338 upstream. Add a linear pipeline logic for the stream control. It's created by walking backwards on the entity graph. When the stream starts it will simply loop through the pipeline calling the respective process_frame function of each entity. Fixes: f2fe89061d797 ("vimc: Virtual Media Controller core, capture and sensor") Cc: stable@vger.kernel.org # for v4.20 Signed-off-by: Lucas A. M. Magalhães <lucmaga@gmail.com> Acked-by: Helen Koike <helen.koike@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> [hverkuil-cisco@xs4all.nl: fixed small space-after-tab issue in the patch] Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/media/platform/vimc/vimc-sensor.c')
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c56
1 files changed, 13 insertions, 43 deletions
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index 02e68c8fc02b..70cee5c0c89a 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -16,8 +16,6 @@
*/
#include <linux/component.h>
-#include <linux/freezer.h>
-#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/v4l2-mediabus.h>
@@ -197,38 +195,27 @@ static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
.set_fmt = vimc_sen_set_fmt,
};
-static int vimc_sen_tpg_thread(void *data)
+static void *vimc_sen_process_frame(struct vimc_ent_device *ved,
+ const void *sink_frame)
{
- struct vimc_sen_device *vsen = data;
- unsigned int i;
-
- set_freezable();
- set_current_state(TASK_UNINTERRUPTIBLE);
-
- for (;;) {
- try_to_freeze();
- if (kthread_should_stop())
- break;
-
- tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
+ struct vimc_sen_device *vsen = container_of(ved, struct vimc_sen_device,
+ ved);
+ const struct vimc_pix_map *vpix;
+ unsigned int frame_size;
- /* Send the frame to all source pads */
- for (i = 0; i < vsen->sd.entity.num_pads; i++)
- vimc_propagate_frame(&vsen->sd.entity.pads[i],
- vsen->frame);
+ /* Calculate the frame size */
+ vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
+ frame_size = vsen->mbus_format.width * vpix->bpp *
+ vsen->mbus_format.height;
- /* 60 frames per second */
- schedule_timeout(HZ/60);
- }
-
- return 0;
+ tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
+ return vsen->frame;
}
static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
{
struct vimc_sen_device *vsen =
container_of(sd, struct vimc_sen_device, sd);
- int ret;
if (enable) {
const struct vimc_pix_map *vpix;
@@ -254,26 +241,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
/* configure the test pattern generator */
vimc_sen_tpg_s_format(vsen);
- /* Initialize the image generator thread */
- vsen->kthread_sen = kthread_run(vimc_sen_tpg_thread, vsen,
- "%s-sen", vsen->sd.v4l2_dev->name);
- if (IS_ERR(vsen->kthread_sen)) {
- dev_err(vsen->dev, "%s: kernel_thread() failed\n",
- vsen->sd.name);
- vfree(vsen->frame);
- vsen->frame = NULL;
- return PTR_ERR(vsen->kthread_sen);
- }
} else {
- if (!vsen->kthread_sen)
- return 0;
-
- /* Stop image generator */
- ret = kthread_stop(vsen->kthread_sen);
- if (ret)
- return ret;
- vsen->kthread_sen = NULL;
vfree(vsen->frame);
vsen->frame = NULL;
return 0;
@@ -325,6 +294,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
if (ret)
goto err_free_vsen;
+ vsen->ved.process_frame = vimc_sen_process_frame;
dev_set_drvdata(comp, &vsen->ved);
vsen->dev = comp;