aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2019-03-05 03:36:20 -0500
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-03-19 13:34:16 -0400
commit2b177f2849d23061508bb13594cc1bff1ccb46c9 (patch)
treeaf17f637006d58cec9319e6ae442816d37124294
parent3650a23eda89f99b964fbd63a20320fafaa73e33 (diff)
media: vimc: use new release op
Use the new v4l2_subdev_internal_ops release op to free the subdev memory only when the last user closed the file handle. Move v4l2_device_unregister_subdev() to the end of the vimc_ent_sd_unregister() function since now the unregister_subdev() call may free the vimc_ent_device struct which is used after the unregister_subdev() call. So this now has to be done last. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r--drivers/media/platform/vimc/vimc-common.c4
-rw-r--r--drivers/media/platform/vimc/vimc-common.h2
-rw-r--r--drivers/media/platform/vimc/vimc-debayer.c15
-rw-r--r--drivers/media/platform/vimc/vimc-scaler.c15
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c19
5 files changed, 46 insertions, 9 deletions
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
index c1a74bb2df58..e8e6c6b95db9 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -380,6 +380,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
380 u32 function, 380 u32 function,
381 u16 num_pads, 381 u16 num_pads,
382 const unsigned long *pads_flag, 382 const unsigned long *pads_flag,
383 const struct v4l2_subdev_internal_ops *sd_int_ops,
383 const struct v4l2_subdev_ops *sd_ops) 384 const struct v4l2_subdev_ops *sd_ops)
384{ 385{
385 int ret; 386 int ret;
@@ -394,6 +395,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
394 395
395 /* Initialize the subdev */ 396 /* Initialize the subdev */
396 v4l2_subdev_init(sd, sd_ops); 397 v4l2_subdev_init(sd, sd_ops);
398 sd->internal_ops = sd_int_ops;
397 sd->entity.function = function; 399 sd->entity.function = function;
398 sd->entity.ops = &vimc_ent_sd_mops; 400 sd->entity.ops = &vimc_ent_sd_mops;
399 sd->owner = THIS_MODULE; 401 sd->owner = THIS_MODULE;
@@ -431,9 +433,9 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
431 433
432void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd) 434void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd)
433{ 435{
434 v4l2_device_unregister_subdev(sd);
435 media_entity_cleanup(ved->ent); 436 media_entity_cleanup(ved->ent);
436 vimc_pads_cleanup(ved->pads); 437 vimc_pads_cleanup(ved->pads);
438 v4l2_device_unregister_subdev(sd);
437} 439}
438EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister); 440EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
439 441
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
index 84539430b5e7..c439cbf2f030 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -187,6 +187,7 @@ const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
187 * @function: media entity function defined by MEDIA_ENT_F_* macros 187 * @function: media entity function defined by MEDIA_ENT_F_* macros
188 * @num_pads: number of pads to initialize 188 * @num_pads: number of pads to initialize
189 * @pads_flag: flags to use in each pad 189 * @pads_flag: flags to use in each pad
190 * @sd_int_ops: pointer to &struct v4l2_subdev_internal_ops
190 * @sd_ops: pointer to &struct v4l2_subdev_ops. 191 * @sd_ops: pointer to &struct v4l2_subdev_ops.
191 * 192 *
192 * Helper function initialize and register the struct vimc_ent_device and struct 193 * Helper function initialize and register the struct vimc_ent_device and struct
@@ -199,6 +200,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
199 u32 function, 200 u32 function,
200 u16 num_pads, 201 u16 num_pads,
201 const unsigned long *pads_flag, 202 const unsigned long *pads_flag,
203 const struct v4l2_subdev_internal_ops *sd_int_ops,
202 const struct v4l2_subdev_ops *sd_ops); 204 const struct v4l2_subdev_ops *sd_ops);
203 205
204/** 206/**
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
index 7d77c63b99d2..eaed4233ad1b 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -489,6 +489,18 @@ static void *vimc_deb_process_frame(struct vimc_ent_device *ved,
489 489
490} 490}
491 491
492static void vimc_deb_release(struct v4l2_subdev *sd)
493{
494 struct vimc_deb_device *vdeb =
495 container_of(sd, struct vimc_deb_device, sd);
496
497 kfree(vdeb);
498}
499
500static const struct v4l2_subdev_internal_ops vimc_deb_int_ops = {
501 .release = vimc_deb_release,
502};
503
492static void vimc_deb_comp_unbind(struct device *comp, struct device *master, 504static void vimc_deb_comp_unbind(struct device *comp, struct device *master,
493 void *master_data) 505 void *master_data)
494{ 506{
@@ -497,7 +509,6 @@ static void vimc_deb_comp_unbind(struct device *comp, struct device *master,
497 ved); 509 ved);
498 510
499 vimc_ent_sd_unregister(ved, &vdeb->sd); 511 vimc_ent_sd_unregister(ved, &vdeb->sd);
500 kfree(vdeb);
501} 512}
502 513
503static int vimc_deb_comp_bind(struct device *comp, struct device *master, 514static int vimc_deb_comp_bind(struct device *comp, struct device *master,
@@ -519,7 +530,7 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master,
519 MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2, 530 MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
520 (const unsigned long[2]) {MEDIA_PAD_FL_SINK, 531 (const unsigned long[2]) {MEDIA_PAD_FL_SINK,
521 MEDIA_PAD_FL_SOURCE}, 532 MEDIA_PAD_FL_SOURCE},
522 &vimc_deb_ops); 533 &vimc_deb_int_ops, &vimc_deb_ops);
523 if (ret) { 534 if (ret) {
524 kfree(vdeb); 535 kfree(vdeb);
525 return ret; 536 return ret;
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
index 39b2a73dfcc1..2028afa4ef7a 100644
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ b/drivers/media/platform/vimc/vimc-scaler.c
@@ -348,6 +348,18 @@ static void *vimc_sca_process_frame(struct vimc_ent_device *ved,
348 return vsca->src_frame; 348 return vsca->src_frame;
349}; 349};
350 350
351static void vimc_sca_release(struct v4l2_subdev *sd)
352{
353 struct vimc_sca_device *vsca =
354 container_of(sd, struct vimc_sca_device, sd);
355
356 kfree(vsca);
357}
358
359static const struct v4l2_subdev_internal_ops vimc_sca_int_ops = {
360 .release = vimc_sca_release,
361};
362
351static void vimc_sca_comp_unbind(struct device *comp, struct device *master, 363static void vimc_sca_comp_unbind(struct device *comp, struct device *master,
352 void *master_data) 364 void *master_data)
353{ 365{
@@ -356,7 +368,6 @@ static void vimc_sca_comp_unbind(struct device *comp, struct device *master,
356 ved); 368 ved);
357 369
358 vimc_ent_sd_unregister(ved, &vsca->sd); 370 vimc_ent_sd_unregister(ved, &vsca->sd);
359 kfree(vsca);
360} 371}
361 372
362 373
@@ -379,7 +390,7 @@ static int vimc_sca_comp_bind(struct device *comp, struct device *master,
379 MEDIA_ENT_F_PROC_VIDEO_SCALER, 2, 390 MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
380 (const unsigned long[2]) {MEDIA_PAD_FL_SINK, 391 (const unsigned long[2]) {MEDIA_PAD_FL_SINK,
381 MEDIA_PAD_FL_SOURCE}, 392 MEDIA_PAD_FL_SOURCE},
382 &vimc_sca_ops); 393 &vimc_sca_int_ops, &vimc_sca_ops);
383 if (ret) { 394 if (ret) {
384 kfree(vsca); 395 kfree(vsca);
385 return ret; 396 return ret;
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index 59195f262623..d7891d3bbeaa 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -301,6 +301,20 @@ static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = {
301 .s_ctrl = vimc_sen_s_ctrl, 301 .s_ctrl = vimc_sen_s_ctrl,
302}; 302};
303 303
304static void vimc_sen_release(struct v4l2_subdev *sd)
305{
306 struct vimc_sen_device *vsen =
307 container_of(sd, struct vimc_sen_device, sd);
308
309 v4l2_ctrl_handler_free(&vsen->hdl);
310 tpg_free(&vsen->tpg);
311 kfree(vsen);
312}
313
314static const struct v4l2_subdev_internal_ops vimc_sen_int_ops = {
315 .release = vimc_sen_release,
316};
317
304static void vimc_sen_comp_unbind(struct device *comp, struct device *master, 318static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
305 void *master_data) 319 void *master_data)
306{ 320{
@@ -309,9 +323,6 @@ static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
309 container_of(ved, struct vimc_sen_device, ved); 323 container_of(ved, struct vimc_sen_device, ved);
310 324
311 vimc_ent_sd_unregister(ved, &vsen->sd); 325 vimc_ent_sd_unregister(ved, &vsen->sd);
312 v4l2_ctrl_handler_free(&vsen->hdl);
313 tpg_free(&vsen->tpg);
314 kfree(vsen);
315} 326}
316 327
317/* Image Processing Controls */ 328/* Image Processing Controls */
@@ -371,7 +382,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
371 pdata->entity_name, 382 pdata->entity_name,
372 MEDIA_ENT_F_CAM_SENSOR, 1, 383 MEDIA_ENT_F_CAM_SENSOR, 1,
373 (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, 384 (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
374 &vimc_sen_ops); 385 &vimc_sen_int_ops, &vimc_sen_ops);
375 if (ret) 386 if (ret)
376 goto err_free_hdl; 387 goto err_free_hdl;
377 388