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>
This commit is contained in:
Родитель
3650a23eda
Коммит
2b177f2849
|
@ -380,6 +380,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|||
u32 function,
|
||||
u16 num_pads,
|
||||
const unsigned long *pads_flag,
|
||||
const struct v4l2_subdev_internal_ops *sd_int_ops,
|
||||
const struct v4l2_subdev_ops *sd_ops)
|
||||
{
|
||||
int ret;
|
||||
|
@ -394,6 +395,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|||
|
||||
/* Initialize the subdev */
|
||||
v4l2_subdev_init(sd, sd_ops);
|
||||
sd->internal_ops = sd_int_ops;
|
||||
sd->entity.function = function;
|
||||
sd->entity.ops = &vimc_ent_sd_mops;
|
||||
sd->owner = THIS_MODULE;
|
||||
|
@ -431,9 +433,9 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
|
|||
|
||||
void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd)
|
||||
{
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
media_entity_cleanup(ved->ent);
|
||||
vimc_pads_cleanup(ved->pads);
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
|
|||
* @function: media entity function defined by MEDIA_ENT_F_* macros
|
||||
* @num_pads: number of pads to initialize
|
||||
* @pads_flag: flags to use in each pad
|
||||
* @sd_int_ops: pointer to &struct v4l2_subdev_internal_ops
|
||||
* @sd_ops: pointer to &struct v4l2_subdev_ops.
|
||||
*
|
||||
* 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,
|
|||
u32 function,
|
||||
u16 num_pads,
|
||||
const unsigned long *pads_flag,
|
||||
const struct v4l2_subdev_internal_ops *sd_int_ops,
|
||||
const struct v4l2_subdev_ops *sd_ops);
|
||||
|
||||
/**
|
||||
|
|
|
@ -489,6 +489,18 @@ static void *vimc_deb_process_frame(struct vimc_ent_device *ved,
|
|||
|
||||
}
|
||||
|
||||
static void vimc_deb_release(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct vimc_deb_device *vdeb =
|
||||
container_of(sd, struct vimc_deb_device, sd);
|
||||
|
||||
kfree(vdeb);
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops vimc_deb_int_ops = {
|
||||
.release = vimc_deb_release,
|
||||
};
|
||||
|
||||
static void vimc_deb_comp_unbind(struct device *comp, struct device *master,
|
||||
void *master_data)
|
||||
{
|
||||
|
@ -497,7 +509,6 @@ static void vimc_deb_comp_unbind(struct device *comp, struct device *master,
|
|||
ved);
|
||||
|
||||
vimc_ent_sd_unregister(ved, &vdeb->sd);
|
||||
kfree(vdeb);
|
||||
}
|
||||
|
||||
static 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,
|
|||
MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
|
||||
(const unsigned long[2]) {MEDIA_PAD_FL_SINK,
|
||||
MEDIA_PAD_FL_SOURCE},
|
||||
&vimc_deb_ops);
|
||||
&vimc_deb_int_ops, &vimc_deb_ops);
|
||||
if (ret) {
|
||||
kfree(vdeb);
|
||||
return ret;
|
||||
|
|
|
@ -348,6 +348,18 @@ static void *vimc_sca_process_frame(struct vimc_ent_device *ved,
|
|||
return vsca->src_frame;
|
||||
};
|
||||
|
||||
static void vimc_sca_release(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct vimc_sca_device *vsca =
|
||||
container_of(sd, struct vimc_sca_device, sd);
|
||||
|
||||
kfree(vsca);
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops vimc_sca_int_ops = {
|
||||
.release = vimc_sca_release,
|
||||
};
|
||||
|
||||
static void vimc_sca_comp_unbind(struct device *comp, struct device *master,
|
||||
void *master_data)
|
||||
{
|
||||
|
@ -356,7 +368,6 @@ static void vimc_sca_comp_unbind(struct device *comp, struct device *master,
|
|||
ved);
|
||||
|
||||
vimc_ent_sd_unregister(ved, &vsca->sd);
|
||||
kfree(vsca);
|
||||
}
|
||||
|
||||
|
||||
|
@ -379,7 +390,7 @@ static int vimc_sca_comp_bind(struct device *comp, struct device *master,
|
|||
MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
|
||||
(const unsigned long[2]) {MEDIA_PAD_FL_SINK,
|
||||
MEDIA_PAD_FL_SOURCE},
|
||||
&vimc_sca_ops);
|
||||
&vimc_sca_int_ops, &vimc_sca_ops);
|
||||
if (ret) {
|
||||
kfree(vsca);
|
||||
return ret;
|
||||
|
|
|
@ -301,6 +301,20 @@ static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = {
|
|||
.s_ctrl = vimc_sen_s_ctrl,
|
||||
};
|
||||
|
||||
static void vimc_sen_release(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct vimc_sen_device *vsen =
|
||||
container_of(sd, struct vimc_sen_device, sd);
|
||||
|
||||
v4l2_ctrl_handler_free(&vsen->hdl);
|
||||
tpg_free(&vsen->tpg);
|
||||
kfree(vsen);
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops vimc_sen_int_ops = {
|
||||
.release = vimc_sen_release,
|
||||
};
|
||||
|
||||
static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
|
||||
void *master_data)
|
||||
{
|
||||
|
@ -309,9 +323,6 @@ static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
|
|||
container_of(ved, struct vimc_sen_device, ved);
|
||||
|
||||
vimc_ent_sd_unregister(ved, &vsen->sd);
|
||||
v4l2_ctrl_handler_free(&vsen->hdl);
|
||||
tpg_free(&vsen->tpg);
|
||||
kfree(vsen);
|
||||
}
|
||||
|
||||
/* Image Processing Controls */
|
||||
|
@ -371,7 +382,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
|
|||
pdata->entity_name,
|
||||
MEDIA_ENT_F_CAM_SENSOR, 1,
|
||||
(const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
|
||||
&vimc_sen_ops);
|
||||
&vimc_sen_int_ops, &vimc_sen_ops);
|
||||
if (ret)
|
||||
goto err_free_hdl;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче