Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: v4l2-async: Add notifier operation to destroy asd instances

Drivers typically extend the v4l2_async_subdev structure by embedding it
in a driver-specific structure, to store per-subdev custom data. The
v4l2_async_subdev instances are freed by the v4l2-async framework, which
makes this mechanism cumbersome to use safely when custom data needs
special treatment to be destroyed (such as freeing additional memory, or
releasing references to kernel objects).

To ease this, add a .destroy() operation to the
v4l2_async_notifier_operations structure. The operation is called right
before the v4l2_async_subdev is freed, giving drivers a chance to
destroy data if needed.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Laurent Pinchart and committed by
Mauro Carvalho Chehab
57cb848f c4d987de

+18
+6
Documentation/driver-api/media/v4l2-subdev.rst
··· 243 243 .complete() callback is called. When a subdevice is removed from the 244 244 system the .unbind() method is called. All three callbacks are optional. 245 245 246 + Drivers can store any type of custom data in their driver-specific 247 + :c:type:`v4l2_async_subdev` wrapper. If any of that data requires special 248 + handling when the structure is freed, drivers must implement the ``.destroy()`` 249 + notifier callback. The framework will call it right before freeing the 250 + :c:type:`v4l2_async_subdev`. 251 + 246 252 Calling subdev operations 247 253 ~~~~~~~~~~~~~~~~~~~~~~~~~ 248 254
+10
drivers/media/v4l2-core/v4l2-async.c
··· 52 52 return n->ops->complete(n); 53 53 } 54 54 55 + static void v4l2_async_nf_call_destroy(struct v4l2_async_notifier *n, 56 + struct v4l2_async_subdev *asd) 57 + { 58 + if (!n->ops || !n->ops->destroy) 59 + return; 60 + 61 + n->ops->destroy(asd); 62 + } 63 + 55 64 static bool match_i2c(struct v4l2_async_notifier *notifier, 56 65 struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) 57 66 { ··· 642 633 } 643 634 644 635 list_del(&asd->asd_list); 636 + v4l2_async_nf_call_destroy(notifier, asd); 645 637 kfree(asd); 646 638 } 647 639 }
+2
include/media/v4l2-async.h
··· 81 81 * @complete: All subdevices have been probed successfully. The complete 82 82 * callback is only executed for the root notifier. 83 83 * @unbind: a subdevice is leaving 84 + * @destroy: the asd is about to be freed 84 85 */ 85 86 struct v4l2_async_notifier_operations { 86 87 int (*bound)(struct v4l2_async_notifier *notifier, ··· 91 90 void (*unbind)(struct v4l2_async_notifier *notifier, 92 91 struct v4l2_subdev *subdev, 93 92 struct v4l2_async_subdev *asd); 93 + void (*destroy)(struct v4l2_async_subdev *asd); 94 94 }; 95 95 96 96 /**