Skip to contentSkip to conversation

V4L cleanups and documentation improvements

PATCH In review Mauro Carvalho Chehab 8 participants 56 messages Sep 27, 2017 – Dec 18, 2017

Subsystems (18)
lore
Share & tools
lore
#0 lore raw

v2 cover V4L cleanups and documentation improvements

This patch series is meant to improve V4L documentation. It touches some files at the tree doing some cleanup, in order to simplify the source code.

Mauro Carvalho Chehab (17):
media: tuner-types: add kernel-doc markups for struct tunertype
media: v4l2-common: get rid of v4l2_routing dead struct
media: v4l2-common: get rid of struct v4l2_discrete_probe
media: v4l2-common.h: document ancillary functions
media: v4l2-device.h: document ancillary macros
media: v4l2-dv-timings.h: convert comment into kernel-doc markup
media: v4l2-event.rst: improve events description
media: v4l2-ioctl.h: convert debug macros into enum and document
media: cec-pin.h: convert comments for cec_pin_state into kernel-doc
media: rc-core.rst: add an introduction for RC core
media: rc-core.h: minor adjustments at rc_driver_type doc
media: v4l2-fwnode.h: better describe bus union at fwnode endpoint
struct
media: v4l2-async: simplify v4l2_async_subdev structure
media: v4l2-async: better describe match union at async match struct
media: v4l2-ctrls: document nested members of structs
media: videobuf2-core: improve kernel-doc markups
media: media-entity.h: add kernel-doc markups for nested structs

 Documentation/media/kapi/rc-core.rst           |  77 ++++++++
 Documentation/media/kapi/v4l2-event.rst        |  64 +++++--
 drivers/media/platform/am437x/am437x-vpfe.c    |   6 +-
 drivers/media/platform/atmel/atmel-isc.c       |   2 +-
 drivers/media/platform/atmel/atmel-isi.c       |   2 +-
 drivers/media/platform/davinci/vpif_capture.c  |   4 +-
 drivers/media/platform/exynos4-is/media-dev.c  |   4 +-
 drivers/media/platform/omap3isp/isp.c          |   4 +-
 drivers/media/platform/pxa_camera.c            |   2 +-
 drivers/media/platform/qcom/camss-8x16/camss.c |   2 +-
 drivers/media/platform/rcar-vin/rcar-core.c    |   8 +-
 drivers/media/platform/rcar_drif.c             |   4 +-
 drivers/media/platform/soc_camera/soc_camera.c |   2 +-
 drivers/media/platform/stm32/stm32-dcmi.c      |   2 +-
 drivers/media/platform/ti-vpe/cal.c            |   2 +-
 drivers/media/platform/vivid/vivid-vid-cap.c   |   9 +-
 drivers/media/platform/xilinx/xilinx-vipp.c    |   2 +-
 drivers/media/v4l2-core/v4l2-async.c           |   4 +-
 drivers/media/v4l2-core/v4l2-common.c          |  27 +--
 drivers/staging/media/imx/imx-media-dev.c      |   8 +-
 include/media/cec-pin.h                        |  81 ++++++---
 include/media/media-entity.h                   |   5 +
 include/media/rc-core.h                        |   4 +-
 include/media/tuner-types.h                    |  15 ++
 include/media/v4l2-async.h                     |  43 ++++-
 include/media/v4l2-common.h                    | 130 +++++++++++---
 include/media/v4l2-ctrls.h                     |  11 +-
 include/media/v4l2-device.h                    | 238 +++++++++++++++++++++----
 include/media/v4l2-dv-timings.h                |  14 +-
 include/media/v4l2-event.h                     |  34 ----
 include/media/v4l2-fwnode.h                    |  13 +-
 include/media/v4l2-ioctl.h                     |  33 ++--
 include/media/videobuf2-core.h                 |  59 +++---
 33 files changed, 660 insertions(+), 255 deletions(-)
Signature · 1 line
2.13.5
#1 lore raw

PATCH v2 1/17 media: tuner-types: add kernel-doc markups for struct tunertype

This struct is lacking documentation. Add it.

---
 include/media/tuner-types.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
include/media/tuner-types.h +15 -0
index aed539068d2d..55bc14093c0f 100644
@@ -170,6 +170,21 @@ struct tuner_params {
 	struct tuner_range *ranges;
 };
 
+/**
+ * struct tunertype - describes the known tuners.
+ *
+ * @name:	string with the tuner's name.
+ * @count:	size of &struct tuner_params array.
+ * @params:	pointer to &struct tuner_params array.
+ *
+ * @min:	minimal tuner frequency, in 62.5 kHz step.
+ *		should be multiplied to 16 to convert to MHz.
+ * @max:	minimal tuner frequency, in 62.5 kHz step.
+ *		Should be multiplied to 16 to convert to MHz.
+ * @stepsize:	frequency step, in Hz.
+ * @initdata:	optional byte sequence to initialize the tuner.
+ * @sleepdata:	optional byte sequence to power down the tuner.
+ */
 struct tunertype {
 	char *name;
 	unsigned int count;
Signature · 1 line
2.13.5
#2 lore raw

PATCH v2 2/17 media: v4l2-common: get rid of v4l2_routing dead struct

In reply to Mauro Carvalho Chehab

This struct is not used anymore. Get rid of it and update the documentation about what should still be converted.

---
 include/media/v4l2-common.h | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)
include/media/v4l2-common.h +5 -9
index aac8b7b6e691..7dbecbe3009c 100644
@@ -224,10 +224,11 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
 
 /* ------------------------------------------------------------------------- */
 
-/* Note: these remaining ioctls/structs should be removed as well, but they are
-   still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and
-   v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup
-   is needed in those modules. */
+/*
+ * FIXME: these remaining ioctls/structs should be removed as well, but they
+ * are still used in tuner-simple.c (TUNER_SET_CONFIG) and cx18/ivtv (RESET).
+ * To remove these ioctls some more cleanup is needed in those modules.
+ */
 
 /* s_config */
 struct v4l2_priv_tun_config {
@@ -238,11 +239,6 @@ struct v4l2_priv_tun_config {
 
 #define VIDIOC_INT_RESET            	_IOW ('d', 102, u32)
 
-struct v4l2_routing {
-	u32 input;
-	u32 output;
-};
-
 /* ------------------------------------------------------------------------- */
 
 /* Miscellaneous helper functions */
Signature · 1 line
2.13.5
maintainer Acked-by on v2 2/17
#3 lore raw

Re: [PATCH v2 02/17] media: v4l2-common: get rid of v4l2_routing dead struct

Hi Mauro,

Thank you for the patch.

Quoted 4 lines · On Thursday, 28 September 2017 00:46:45 EEST Mauro Carvalho Chehab wrote:

This struct is not used anymore. Get rid of it and update the documentation about what should still be converted.

Quoted 41 lines
---
 include/media/v4l2-common.h | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)
include/media/v4l2-common.h +0 -2
index aac8b7b6e691..7dbecbe3009c 100644
@@ -224,10 +224,11 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd,
 struct spi_device *spi,
 
 /*
-------------------------------------------------------------------------
 */
 
-/* Note: these remaining ioctls/structs should be removed as well, but they
 are -   still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET)

and - v4l2-int-device.h (v4l2_routing). To remove these ioctls some more
cleanup - is needed in those modules. */
+/*
+ * FIXME: these remaining ioctls/structs should be removed as well, but they + * are still used in tuner-simple.c (TUNER_SET_CONFIG) and cx18/ivtv (RESET). + * To remove these ioctls some more cleanup is needed in those modules. + */

/* s_config */
struct v4l2_priv_tun_config {

include/media/v4l2-common.h +0 -6
@@ -238,11 +239,6 @@ struct v4l2_priv_tun_config {
 
 #define VIDIOC_INT_RESET            	_IOW ('d', 102, u32)
 
-struct v4l2_routing {
-	u32 input;
-	u32 output;
-};
-
 /*
-------------------------------------------------------------------------
 */
 
 /* Miscellaneous helper functions */
Signature · 3 lines
Regards,

Laurent Pinchart
Acked-by on v2 2/17
#4 lore raw

Re: [PATCH v2 02/17] media: v4l2-common: get rid of v4l2_routing dead struct

In reply to Mauro Carvalho Chehab
Quoted 4 lines · Mauro Carvalho Chehab

This struct is not used anymore. Get rid of it and update the documentation about what should still be converted.

Quoted 25 lines
---
 include/media/v4l2-common.h | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)
include/media/v4l2-common.h +5 -4
index aac8b7b6e691..7dbecbe3009c 100644
@@ -224,10 +224,11 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
 
 /* ------------------------------------------------------------------------- */
 
-/* Note: these remaining ioctls/structs should be removed as well, but they are
-   still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and
-   v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup
-   is needed in those modules. */
+/*
+ * FIXME: these remaining ioctls/structs should be removed as well, but they
+ * are still used in tuner-simple.c (TUNER_SET_CONFIG) and cx18/ivtv (RESET).
+ * To remove these ioctls some more cleanup is needed in those modules.
+ */
 
 /* s_config */
 struct v4l2_priv_tun_config {

include/media/v4l2-common.h struct v4l2_priv_tun_config { · line 240

Quoted 2 lines
include/media/v4l2-common.h +0 -0
@@ -238,11 +239,6 @@ struct v4l2_priv_tun_config {
 
 #define VIDIOC_INT_RESET            	_IOW ('d', 102, u32)

Regarding this one: I *think* (long time ago) that the main reason for this was to reset a locked up IR blaster. I wonder if this is still needed after Sean's rework of this. Once that's all done and merged this would probably merit another look to see if it can be removed.

Regards,

Hans

Quoted 10 lines
include/media/v4l2-common.h +0 -5
-struct v4l2_routing {
-	u32 input;
-	u32 output;
-};
-
 /* ------------------------------------------------------------------------- */
 
 /* Miscellaneous helper functions */
 
#5 lore raw

Re: [PATCH v2 02/17] media: v4l2-common: get rid of v4l2_routing dead struct

Em Fri, 13 Oct 2017 15:24:34 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 7 lines
Quoted 7 lines
---
 include/media/v4l2-common.h | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)
include/media/v4l2-common.h +0 -0
@@ -238,11 +239,6 @@ struct v4l2_priv_tun_config {
 
Quoted 7 lines

include/media/v4l2-common.h struct v4l2_priv_tun_config { · line 240

Quoted 1 line
include/media/v4l2-common.h +0 -0
 #define VIDIOC_INT_RESET            	_IOW ('d', 102, u32)  

Regarding this one: I *think* (long time ago) that the main reason for this was to reset a locked up IR blaster. I wonder if this is still needed after Sean's rework of this. Once that's all done and merged this would probably merit another look to see if it can be removed.

Sean,

Could you please double-check if this is still required on RC?

Thanks,
Mauro

maintainer
#6 lore raw

Re: [PATCH v2 02/17] media: v4l2-common: get rid of v4l2_routing dead struct

Quoted 18 lines · Mauro Carvalho Chehab

Em Fri, 13 Oct 2017 15:24:34 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 7 lines
Quoted 7 lines
---
 include/media/v4l2-common.h | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)
include/media/v4l2-common.h +0 -0
@@ -238,11 +239,6 @@ struct v4l2_priv_tun_config {
 
Quoted 7 lines

include/media/v4l2-common.h struct v4l2_priv_tun_config { · line 240

Quoted 1 line
include/media/v4l2-common.h +0 -0
 #define VIDIOC_INT_RESET            	_IOW ('d', 102, u32)  

Regarding this one: I *think* (long time ago) that the main reason for this was to reset a locked up IR blaster. I wonder if this is still needed after Sean's rework of this. Once that's all done and merged this would probably merit another look to see if it can be removed.

Quoted 3 lines

Sean,

Could you please double-check if this is still required on RC?

The ioctl can also reset the digitizer in ivtv, I don't know anything about that.

As far the IR receiver/blaster is concerned:

This ioctl does exactly as it says and it works. There are a few ways that the zilog microcontroller can be crashed, but I don't know of any that exist in the current code base.

I seem to recall that the microcontroller could get stuck due particular i2c states, which was fixed with patches to ivtv-i2c.c. That does not mean there aren't any others though.

What would be nicer if the ir driver got no response, it would reset it automatically. I'm not sure how to wire up ir-kbd-i2c with the ir reset function of ivtv and cx18 though.

Then again with no known use cases it seems superfluous. How about removing the ioctl and then hooking up the IR driver to the reset, should it be necessary?

Sean

#7 lore raw

PATCH v2 3/17 media: v4l2-common: get rid of struct v4l2_discrete_probe

In reply to Mauro Carvalho Chehab

This struct is there just two store two arguments of v4l2_find_nearest_format(). The other two arguments are passed as parameter.

IMHO, there isn't much sense on doing that, and that will just add one more struct to document ;)

So, let's get rid of the struct, passing the parameters directly.

---
 drivers/media/platform/vivid/vivid-vid-cap.c |  9 +++------
 drivers/media/v4l2-core/v4l2-common.c        | 13 +++++++------
 include/media/v4l2-common.h                  | 12 ++++--------
 3 files changed, 14 insertions(+), 20 deletions(-)
drivers/media/platform/vivid/vivid-vid-cap.c +3 -6
index 01419455e545..0fbbcde19f0d 100644
@@ -93,11 +93,6 @@ static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = {
 	{  1, 60 },
 };
 
-static const struct v4l2_discrete_probe webcam_probe = {
-	webcam_sizes,
-	VIVID_WEBCAM_SIZES
-};
-
 static int vid_cap_queue_setup(struct vb2_queue *vq,
 		       unsigned *nbuffers, unsigned *nplanes,
 		       unsigned sizes[], struct device *alloc_devs[])
@@ -578,7 +573,9 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
 	mp->field = vivid_field_cap(dev, mp->field);
 	if (vivid_is_webcam(dev)) {
 		const struct v4l2_frmsize_discrete *sz =
-			v4l2_find_nearest_format(&webcam_probe, mp->width, mp->height);
+			v4l2_find_nearest_format(webcam_sizes,
+						 VIVID_WEBCAM_SIZES,
+						 mp->width, mp->height);
 
 		w = sz->width;
 		h = sz->height;
drivers/media/v4l2-core/v4l2-common.c +7 -6
index a5ea1f517291..fb9a2a3c1072 100644
@@ -371,18 +371,19 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 }
 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
 
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
-		const struct v4l2_discrete_probe *probe,
-		s32 width, s32 height)
+const struct v4l2_frmsize_discrete
+*v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
+			  const size_t num_sizes,
+			  s32 width, s32 height)
 {
 	int i;
 	u32 error, min_error = UINT_MAX;
 	const struct v4l2_frmsize_discrete *size, *best = NULL;
 
-	if (!probe)
-		return best;
+	if (!sizes)
+		return NULL;
 
-	for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) {
+	for (i = 0, size = sizes; i < num_sizes; i++, size++) {
 		error = abs(size->width - width) + abs(size->height - height);
 		if (error < min_error) {
 			min_error = error;
include/media/v4l2-common.h +4 -8
index 7dbecbe3009c..7ae7840df068 100644
@@ -249,14 +249,10 @@ void v4l_bound_align_image(unsigned int *w, unsigned int wmin,
 			   unsigned int hmax, unsigned int halign,
 			   unsigned int salign);
 
-struct v4l2_discrete_probe {
-	const struct v4l2_frmsize_discrete	*sizes;
-	int					num_sizes;
-};
-
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
-		const struct v4l2_discrete_probe *probe,
-		s32 width, s32 height);
+const struct v4l2_frmsize_discrete
+*v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
+			  const size_t num_sizes,
+			  s32 width, s32 height);
 
 void v4l2_get_timestamp(struct timeval *tv);
 
Signature · 1 line
2.13.5
maintainer
#8 lore raw

Re: [PATCH v2 03/17] media: v4l2-common: get rid of struct v4l2_discrete_probe

Hi Mauro,

Thank you for the patch.

Quoted 84 lines · On Thursday, 28 September 2017 00:46:46 EEST Mauro Carvalho Chehab wrote:

This struct is there just two store two arguments of v4l2_find_nearest_format(). The other two arguments are passed as parameter.

IMHO, there isn't much sense on doing that, and that will just add one more struct to document ;)

So, let's get rid of the struct, passing the parameters directly.

---
 drivers/media/platform/vivid/vivid-vid-cap.c |  9 +++------
 drivers/media/v4l2-core/v4l2-common.c        | 13 +++++++------
 include/media/v4l2-common.h                  | 12 ++++--------
 3 files changed, 14 insertions(+), 20 deletions(-)
(quoted diff) +0 -0

b/drivers/media/platform/vivid/vivid-vid-cap.c index 01419455e545..0fbbcde19f0d 100644

drivers/media/platform/vivid/vivid-vid-cap.c +3 -6
@@ -93,11 +93,6 @@ static const struct v4l2_fract
 webcam_intervals[VIVID_WEBCAM_IVALS] = { {  1, 60 },
 };
 
-static const struct v4l2_discrete_probe webcam_probe = {
-	webcam_sizes,
-	VIVID_WEBCAM_SIZES
-};
-
 static int vid_cap_queue_setup(struct vb2_queue *vq,
 		       unsigned *nbuffers, unsigned *nplanes,
 		       unsigned sizes[], struct device *alloc_devs[])
@@ -578,7 +573,9 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
 mp->field = vivid_field_cap(dev, mp->field);
 	if (vivid_is_webcam(dev)) {
 		const struct v4l2_frmsize_discrete *sz =
-			v4l2_find_nearest_format(&webcam_probe, mp->width, mp->height);
+			v4l2_find_nearest_format(webcam_sizes,
+						 VIVID_WEBCAM_SIZES,
+						 mp->width, mp->height);
 
 		w = sz->width;
 		h = sz->height;
(quoted diff) +0 -0

b/drivers/media/v4l2-core/v4l2-common.c index a5ea1f517291..fb9a2a3c1072 100644

drivers/media/v4l2-core/v4l2-common.c +7 -6
@@ -371,18 +371,19 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin,
 unsigned int wmax, }
 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
 
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
-		const struct v4l2_discrete_probe *probe,
-		s32 width, s32 height)
+const struct v4l2_frmsize_discrete
+*v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
+			  const size_t num_sizes,
+			  s32 width, s32 height)
 {
 	int i;
 	u32 error, min_error = UINT_MAX;
 	const struct v4l2_frmsize_discrete *size, *best = NULL;
 
-	if (!probe)
-		return best;
+	if (!sizes)
+		return NULL;
 
-	for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) {
+	for (i = 0, size = sizes; i < num_sizes; i++, size++) {
 		error = abs(size->width - width) + abs(size->height - height);
 		if (error < min_error) {
 			min_error = error;
include/media/v4l2-common.h +0 -1
index 7dbecbe3009c..7ae7840df068 100644
@@ -249,14 +249,10 @@ void v4l_bound_align_image(unsigned int *w, unsigned
 int wmin, unsigned int hmax, unsigned int halign,
 			   unsigned int salign);
 
-struct v4l2_discrete_probe {

include/media/v4l2-common.h void v4l_bound_align_image(unsigned int *w, unsigned · line 254

Quoted 10 lines
include/media/v4l2-common.h +3 -7
-	const struct v4l2_frmsize_discrete	*sizes;
-	int					num_sizes;
-};
-
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
-		const struct v4l2_discrete_probe *probe,
-		s32 width, s32 height);
+const struct v4l2_frmsize_discrete
+*v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
+			  const size_t num_sizes,

No need for a const keyword.

Quoted 3 lines
include/media/v4l2-common.h +1 -0
+			  s32 width, s32 height);
 
 void v4l2_get_timestamp(struct timeval *tv);
Signature · 3 lines
Regards,

Laurent Pinchart
Acked-by on v2 3/17
#9 lore raw

Re: [PATCH v2 03/17] media: v4l2-common: get rid of struct v4l2_discrete_probe

In reply to Mauro Carvalho Chehab
Quoted 48 lines · Mauro Carvalho Chehab

This struct is there just two store two arguments of v4l2_find_nearest_format(). The other two arguments are passed as parameter.

IMHO, there isn't much sense on doing that, and that will just add one more struct to document ;)

So, let's get rid of the struct, passing the parameters directly.

---
 drivers/media/platform/vivid/vivid-vid-cap.c |  9 +++------
 drivers/media/v4l2-core/v4l2-common.c        | 13 +++++++------
 include/media/v4l2-common.h                  | 12 ++++--------
 3 files changed, 14 insertions(+), 20 deletions(-)
drivers/media/platform/vivid/vivid-vid-cap.c +3 -6
index 01419455e545..0fbbcde19f0d 100644
@@ -93,11 +93,6 @@ static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = {
 	{  1, 60 },
 };
 
-static const struct v4l2_discrete_probe webcam_probe = {
-	webcam_sizes,
-	VIVID_WEBCAM_SIZES
-};
-
 static int vid_cap_queue_setup(struct vb2_queue *vq,
 		       unsigned *nbuffers, unsigned *nplanes,
 		       unsigned sizes[], struct device *alloc_devs[])
@@ -578,7 +573,9 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
 	mp->field = vivid_field_cap(dev, mp->field);
 	if (vivid_is_webcam(dev)) {
 		const struct v4l2_frmsize_discrete *sz =
-			v4l2_find_nearest_format(&webcam_probe, mp->width, mp->height);
+			v4l2_find_nearest_format(webcam_sizes,
+						 VIVID_WEBCAM_SIZES,
+						 mp->width, mp->height);
 
 		w = sz->width;
 		h = sz->height;
drivers/media/v4l2-core/v4l2-common.c +0 -0
index a5ea1f517291..fb9a2a3c1072 100644

drivers/media/v4l2-core/v4l2-common.c void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, · line 375

Quoted 8 lines
drivers/media/v4l2-core/v4l2-common.c +2 -3
@@ -371,18 +371,19 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 }
 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
 
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
-		const struct v4l2_discrete_probe *probe,
-		s32 width, s32 height)
+const struct v4l2_frmsize_discrete
+*v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,

Please move the initial '*' to the end of the first line. Otherwise it is very hard to see that this function returns a pointer.

Quoted 25 lines
drivers/media/v4l2-core/v4l2-common.c +5 -3
+			  const size_t num_sizes,
+			  s32 width, s32 height)
 {
 	int i;
 	u32 error, min_error = UINT_MAX;
 	const struct v4l2_frmsize_discrete *size, *best = NULL;
 
-	if (!probe)
-		return best;
+	if (!sizes)
+		return NULL;
 
-	for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) {
+	for (i = 0, size = sizes; i < num_sizes; i++, size++) {
 		error = abs(size->width - width) + abs(size->height - height);
 		if (error < min_error) {
 			min_error = error;
include/media/v4l2-common.h +0 -0
index 7dbecbe3009c..7ae7840df068 100644
@@ -249,14 +249,10 @@ void v4l_bound_align_image(unsigned int *w, unsigned int wmin,
 			   unsigned int hmax, unsigned int halign,
 			   unsigned int salign);
 

include/media/v4l2-common.h void v4l_bound_align_image(unsigned int *w, unsigned int wmin, · line 253

Quoted 10 lines
include/media/v4l2-common.h +2 -8
-struct v4l2_discrete_probe {
-	const struct v4l2_frmsize_discrete	*sizes;
-	int					num_sizes;
-};
-
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
-		const struct v4l2_discrete_probe *probe,
-		s32 width, s32 height);
+const struct v4l2_frmsize_discrete
+*v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,

Same here.

include/media/v4l2-common.h void v4l_bound_align_image(unsigned int *w, unsigned int wmin, · line 258

Quoted 6 lines
include/media/v4l2-common.h +2 -0
+			  const size_t num_sizes,
+			  s32 width, s32 height);
 
 void v4l2_get_timestamp(struct timeval *tv);
 

After changing that you can add my:

Regards,

Hans

#10 lore raw

PATCH v2 4/17 media: v4l2-common.h: document ancillary functions

In reply to Mauro Carvalho Chehab

There are several ancillary functions that aren't documented.

Document them.

---
 drivers/media/v4l2-core/v4l2-common.c |  14 -----
 include/media/v4l2-common.h           | 104 ++++++++++++++++++++++++++++++----
 2 files changed, 94 insertions(+), 24 deletions(-)
drivers/media/v4l2-core/v4l2-common.c +0 -14
index fb9a2a3c1072..ac404d5083e0 100644
@@ -320,20 +320,6 @@ static unsigned int clamp_align(unsigned int x, unsigned int min,
 	return x;
 }
 
-/* Bound an image to have a width between wmin and wmax, and height between
- * hmin and hmax, inclusive.  Additionally, the width will be a multiple of
- * 2^walign, the height will be a multiple of 2^halign, and the overall size
- * (width*height) will be a multiple of 2^salign.  The image may be shrunk
- * or enlarged to fit the alignment constraints.
- *
- * The width or height maximum must not be smaller than the corresponding
- * minimum.  The alignments must not be so high there are no possible image
- * sizes within the allowed bounds.  wmin and hmin must be at least 1
- * (don't use 0).  If you don't care about a certain alignment, specify 0,
- * as 2^0 is 1 and one byte alignment is equivalent to no alignment.  If
- * you only want to adjust downward, specify a maximum that's the same as
- * the initial value.
- */
 void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 			   unsigned int walign,
 			   u32 *h, unsigned int hmin, unsigned int hmax,
include/media/v4l2-common.h +94 -10

134 lines not on this page · raw message

Signature · 1 line
2.13.5
maintainer
#11 lore raw

Re: [PATCH v2 04/17] media: v4l2-common.h: document ancillary functions

Hi Mauro,

Thank you for the patch.

Quoted 25 lines · On Thursday, 28 September 2017 00:46:47 EEST Mauro Carvalho Chehab wrote:

There are several ancillary functions that aren't documented.

Document them.

---
 drivers/media/v4l2-core/v4l2-common.c |  14 -----
 include/media/v4l2-common.h           | 104 +++++++++++++++++++++++++++----
 2 files changed, 94 insertions(+), 24 deletions(-)
(quoted diff) +0 -0

b/drivers/media/v4l2-core/v4l2-common.c index fb9a2a3c1072..ac404d5083e0 100644

drivers/media/v4l2-core/v4l2-common.c +0 -2
@@ -320,20 +320,6 @@ static unsigned int clamp_align(unsigned int x,
 unsigned int min, return x;
 }
 
-/* Bound an image to have a width between wmin and wmax, and height between
- * hmin and hmax, inclusive.  Additionally, the width will be a multiple

of - * 2^walign, the height will be a multiple of 2^halign, and the overall size - * (width*height) will be a multiple of 2^salign. The image may be shrunk - * or enlarged to fit the alignment constraints.
- *

Quoted 8 lines

- * The width or height maximum must not be smaller than the corresponding
- * minimum. The alignments must not be so high there are no possible image
- * sizes within the allowed bounds. wmin and hmin must be at least 1 - * (don't use 0). If you don't care about a certain alignment, specify 0, - * as 2^0 is 1 and one byte alignment is equivalent to no alignment. If - * you only want to adjust downward, specify a maximum that's the same as - * the initial value.
- */

I still think documentation would be much better placed in C files than header files. Maybe we could quickly discuss this during the media summit at ELCE.

Quoted 42 lines

void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,

drivers/media/v4l2-core/v4l2-common.c +0 -0
 			   unsigned int walign,
 			   u32 *h, unsigned int hmin, unsigned int hmax,
include/media/v4l2-common.h +0 -0
index 7ae7840df068..d3f5f907d566 100644
@@ -174,17 +174,43 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd,

struct i2c_client *client, */
unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd);

include/media/v4l2-common.h +24 -6
+/**
+ * enum v4l2_i2c_tuner_type - specifies the range of tuner address that
+ *	should be used when seeking for I2C devices.
+ *
+ * @ADDRS_RADIO:		Radio tuner addresses.
+ * 				Represent the following I2C addresses:
+ * 				0x10 (if compiled with tea5761 support)
+ *				and 0x60.
+ * @ADDRS_DEMOD:		Demod tuner addresses.
+ * 				Represent the following I2C addresses:
+ * 				0x42, 0x43, 0x4a and 0x4b.
+ * @ADDRS_TV:			TV tuner addresses.
+ * 				Represent the following I2C addresses:
+ * 				0x42, 0x43, 0x4a, 0x4b, 0x60, 0x61, 0x62,
+ *				0x63 and 0x64.
+ * @ADDRS_TV_WITH_DEMOD:	TV tuner addresses if demod is present, this
+ *				excludes addresses used by the demodulator
+ *				from the list of candidates.
+ * 				Represent the following I2C addresses:
+ * 				0x60, 0x61, 0x62, 0x63 and 0x64.
+ *
+ * NOTE: All I2C addresses above use the 7-bit notation.
+ */
 enum v4l2_i2c_tuner_type {
-	ADDRS_RADIO,	/* Radio tuner addresses */
-	ADDRS_DEMOD,	/* Demod tuner addresses */
-	ADDRS_TV,	/* TV tuner addresses */
-	/* TV tuner addresses if demod is present, this excludes
-	   addresses used by the demodulator from the list of
-	   candidates. */
+	ADDRS_RADIO,

include/media/v4l2-common.h void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, · line 209

Quoted 10 lines
include/media/v4l2-common.h +6 -2
+	ADDRS_DEMOD,
+	ADDRS_TV,
 	ADDRS_TV_WITH_DEMOD,
 };
-/* Return a list of I2C tuner addresses to probe. Use only if the tuner
-   addresses are unknown. */
+/**
+ * v4l2_i2c_tuner_addrs - Return a list of I2C tuner addresses to probe.
+ *
+ * @type: type of the tuner type to seek, as defined by

s/tuner type/tuner/

Quoted 22 lines

+ * &enum v4l2_i2c_tuner_type.
+ *
+ * NOTE: Use only if the tuner addresses are unknown.
+ */
const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);

/* --------------------------------------------------------------------- */ @@ -228,6 +254,9 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd,
struct spi_device *spi,
* FIXME: these remaining ioctls/structs should be removed as well, but they
* are still used in tuner-simple.c (TUNER_SET_CONFIG) and cx18/ivtv (RESET).
* To remove these ioctls some more cleanup is needed in those modules.
+ *
+ * It doesn't make much sense on documenting them, as what we really want is
+ * to get rid of them.
*/

/* s_config */

include/media/v4l2-common.h struct v4l2_priv_tun_config { · line 277

Quoted 7 lines
include/media/v4l2-common.h +3 -1
@@ -243,17 +272,72 @@ struct v4l2_priv_tun_config {
 
 /* Miscellaneous helper functions */
 
-void v4l_bound_align_image(unsigned int *w, unsigned int wmin,
+/**
+ * v4l_bound_align_image - adjust video dimensions according to
+ * 	a given criteria.

s/a given criteria/the given constraints/

Quoted 13 lines
include/media/v4l2-common.h +13 -0
+ *
+ * @width:	pointer to width that will be adjusted if needed.
+ * @wmin:	minimum width.
+ * @wmax:	maximum width.
+ * @walign:	least significant bit on width.
+ * @height:	pointer to height that will be adjusted if needed.
+ * @hmin:	minimum height.
+ * @hmax:	maximum height.
+ * @halign:	least significant bit on width.
+ * @salign:	least significant bit for the image size (e. g.
+ *		:math:`width * height`).
+ *
+ * Bound an image to have @width between @wmin and @wmax, and @height
Quoted 2 lines

between
+ * @hmin and @hmax, inclusive.

s/Bound/Bind/ ? I think "Clip" would be better actually.

Quoted 9 lines

+ *
+ * Additionally, the @width will be a multiple of :math:2^{walign},
+ * the @height will be a multiple of :math:2^{halign}, and the overall
+ * size :math:width * height will be a multiple of :math:2^{salign}.
+ *
+ * .. note::
+ *
+ * #. The image may be shrunk or enlarged to fit the alignment
constraints.

It's not the image that will be shrunk or enlarged, but the clipping rectangle.

Quoted 25 lines
+ *    #. @wmax must not be smaller than @wmin.
+ *    #. @hmax must not be smaller than @hmin.
+ *    #. The alignments must not be so high there are no possible image

+ * sizes within the allowed bounds.
+ * #. @wmin and @hmin must be at least 1 (don't use 0).
+ * #. For @walign, @halign and @salign, if you don't care about a
certain
+ * alignment, specify ``0``, as :math:2^0 = 1 and one byte
alignment
+ * is equivalent to no alignment.
+ * #. If you only want to adjust downward, specify a maximum that's the
+ * same as the initial value.
+ */

include/media/v4l2-common.h +7 -1
+void v4l_bound_align_image(unsigned int *width, unsigned int wmin,
 			   unsigned int wmax, unsigned int walign,
-			   unsigned int *h, unsigned int hmin,
+			   unsigned int *height, unsigned int hmin,
 			   unsigned int hmax, unsigned int halign,
 			   unsigned int salign);
 
+/**
+ * v4l2_find_nearest_format - find the nearest format size among a discrete
+ *	set of resolutions.
+ *
+ * @sizes: array with a pointer to & struct v4l2_frmsize_discrete image
Quoted 2 lines

sizes.
+ * @num_sizes: size of @sizes array.

I'd say "length" instead of "size", or "number of elements in the @sizes array". Size could be interpreted as the array size in bytes.

Quoted 6 lines

+ * @width: desired width.
+ * @height: desired heigth.
+ *
+ * Finds the closest resolution to minimize the width and height differences
+ * between what userspace requested and the supported resolutions.

This function isn't restricted to be used to handle userspace sizes, I wouldn't mention userspace here.

Quoted 11 lines

+ */
const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,

include/media/v4l2-common.h +2 -0
 			  const size_t num_sizes,
 			  s32 width, s32 height);
 
+/**
+ * v4l2_get_timestamp - ancillary routine to get a timestamp to be used

when
+ * filling streaming metadata. Internally, it uses ktime_get_ts(), +
* with is the recommended way to get it.

s/with/which/

Quoted 6 lines

+ *
+ * @tv: pointer to &stuct timeval to be filled.
+ */
void v4l2_get_timestamp(struct timeval *tv);

#endif /* V4L2_COMMON_H_ */

Signature · 3 lines
Regards,

Laurent Pinchart
#12 lore raw

Re: [PATCH v2 04/17] media: v4l2-common.h: document ancillary functions

In reply to Mauro Carvalho Chehab
Quoted 1 line · Mauro Carvalho Chehab

There are several ancillary functions that aren't documented.

s/ancillary/helper/g

Quoted 143 lines

Document them.

---
 drivers/media/v4l2-core/v4l2-common.c |  14 -----
 include/media/v4l2-common.h           | 104 ++++++++++++++++++++++++++++++----
 2 files changed, 94 insertions(+), 24 deletions(-)
drivers/media/v4l2-core/v4l2-common.c +0 -14
index fb9a2a3c1072..ac404d5083e0 100644
@@ -320,20 +320,6 @@ static unsigned int clamp_align(unsigned int x, unsigned int min,
 	return x;
 }
 
-/* Bound an image to have a width between wmin and wmax, and height between
- * hmin and hmax, inclusive.  Additionally, the width will be a multiple of
- * 2^walign, the height will be a multiple of 2^halign, and the overall size
- * (width*height) will be a multiple of 2^salign.  The image may be shrunk
- * or enlarged to fit the alignment constraints.
- *
- * The width or height maximum must not be smaller than the corresponding
- * minimum.  The alignments must not be so high there are no possible image
- * sizes within the allowed bounds.  wmin and hmin must be at least 1
- * (don't use 0).  If you don't care about a certain alignment, specify 0,
- * as 2^0 is 1 and one byte alignment is equivalent to no alignment.  If
- * you only want to adjust downward, specify a maximum that's the same as
- * the initial value.
- */
 void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 			   unsigned int walign,
 			   u32 *h, unsigned int hmin, unsigned int hmax,
include/media/v4l2-common.h +74 -9
index 7ae7840df068..d3f5f907d566 100644
@@ -174,17 +174,43 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
  */
 unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd);
 
+/**
+ * enum v4l2_i2c_tuner_type - specifies the range of tuner address that
+ *	should be used when seeking for I2C devices.
+ *
+ * @ADDRS_RADIO:		Radio tuner addresses.
+ * 				Represent the following I2C addresses:
+ * 				0x10 (if compiled with tea5761 support)
+ *				and 0x60.
+ * @ADDRS_DEMOD:		Demod tuner addresses.
+ * 				Represent the following I2C addresses:
+ * 				0x42, 0x43, 0x4a and 0x4b.
+ * @ADDRS_TV:			TV tuner addresses.
+ * 				Represent the following I2C addresses:
+ * 				0x42, 0x43, 0x4a, 0x4b, 0x60, 0x61, 0x62,
+ *				0x63 and 0x64.
+ * @ADDRS_TV_WITH_DEMOD:	TV tuner addresses if demod is present, this
+ *				excludes addresses used by the demodulator
+ *				from the list of candidates.
+ * 				Represent the following I2C addresses:
+ * 				0x60, 0x61, 0x62, 0x63 and 0x64.
+ *
+ * NOTE: All I2C addresses above use the 7-bit notation.
+ */
 enum v4l2_i2c_tuner_type {
-	ADDRS_RADIO,	/* Radio tuner addresses */
-	ADDRS_DEMOD,	/* Demod tuner addresses */
-	ADDRS_TV,	/* TV tuner addresses */
-	/* TV tuner addresses if demod is present, this excludes
-	   addresses used by the demodulator from the list of
-	   candidates. */
+	ADDRS_RADIO,
+	ADDRS_DEMOD,
+	ADDRS_TV,
 	ADDRS_TV_WITH_DEMOD,
 };
-/* Return a list of I2C tuner addresses to probe. Use only if the tuner
-   addresses are unknown. */
+/**
+ * v4l2_i2c_tuner_addrs - Return a list of I2C tuner addresses to probe.
+ *
+ * @type: type of the tuner type to seek, as defined by
+ *	  &enum v4l2_i2c_tuner_type.
+ *
+ * NOTE: Use only if the tuner addresses are unknown.
+ */
 const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
 
 /* ------------------------------------------------------------------------- */
@@ -228,6 +254,9 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
  * FIXME: these remaining ioctls/structs should be removed as well, but they
  * are still used in tuner-simple.c (TUNER_SET_CONFIG) and cx18/ivtv (RESET).
  * To remove these ioctls some more cleanup is needed in those modules.
+ *
+ * It doesn't make much sense on documenting them, as what we really want is
+ * to get rid of them.
  */
 
 /* s_config */
@@ -243,17 +272,72 @@ struct v4l2_priv_tun_config {
 
 /* Miscellaneous helper functions */
 
-void v4l_bound_align_image(unsigned int *w, unsigned int wmin,
+/**
+ * v4l_bound_align_image - adjust video dimensions according to
+ * 	a given criteria.
+ *
+ * @width:	pointer to width that will be adjusted if needed.
+ * @wmin:	minimum width.
+ * @wmax:	maximum width.
+ * @walign:	least significant bit on width.
+ * @height:	pointer to height that will be adjusted if needed.
+ * @hmin:	minimum height.
+ * @hmax:	maximum height.
+ * @halign:	least significant bit on width.
+ * @salign:	least significant bit for the image size (e. g.
+ *		:math:`width * height`).
+ *
+ * Bound an image to have @width between @wmin and @wmax, and @height between
+ * @hmin and @hmax, inclusive.
+ *
+ * Additionally, the @width will be a multiple of :math:`2^{walign}`,
+ * the @height will be a multiple of :math:`2^{halign}`, and the overall
+ * size :math:`width * height` will be a multiple of :math:`2^{salign}`.
+ *
+ * .. note::
+ *
+ *    #. The image may be shrunk or enlarged to fit the alignment constraints.
+ *    #. @wmax must not be smaller than @wmin.
+ *    #. @hmax must not be smaller than @hmin.
+ *    #. The alignments must not be so high there are no possible image
+ *       sizes within the allowed bounds.
+ *    #. @wmin and @hmin must be at least 1 (don't use 0).
+ *    #. For @walign, @halign and @salign, if you don't care about a certain
+ *       alignment, specify ``0``, as :math:`2^0 = 1` and one byte alignment
+ *       is equivalent to no alignment.
+ *    #. If you only want to adjust downward, specify a maximum that's the
+ *       same as the initial value.
+ */
+void v4l_bound_align_image(unsigned int *width, unsigned int wmin,
 			   unsigned int wmax, unsigned int walign,

include/media/v4l2-common.h struct v4l2_priv_tun_config { · line 321

Quoted 10 lines
include/media/v4l2-common.h +6 -1
-			   unsigned int *h, unsigned int hmin,
+			   unsigned int *height, unsigned int hmin,
 			   unsigned int hmax, unsigned int halign,
 			   unsigned int salign);
 
+/**
+ * v4l2_find_nearest_format - find the nearest format size among a discrete
+ *	set of resolutions.
+ *
+ * @sizes: array with a pointer to & struct v4l2_frmsize_discrete image sizes.

Just say: array of struct v4l2_frmsize_discrete image sizes.

include/media/v4l2-common.h struct v4l2_priv_tun_config { · line 324

Quoted 3 lines
include/media/v4l2-common.h +3 -0
+ * @num_sizes: size of @sizes array.
+ * @width: desired width.
+ * @height: desired heigth.

heigth -> height

Quoted 5 lines
include/media/v4l2-common.h +4 -0
+ *
+ * Finds the closest resolution to minimize the width and height differences
+ * between what userspace requested and the supported resolutions.
+ */
 const struct v4l2_frmsize_discrete

include/media/v4l2-common.h struct v4l2_priv_tun_config { · line 339

Quoted 10 lines
include/media/v4l2-common.h +6 -0
 *v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
 			  const size_t num_sizes,
 			  s32 width, s32 height);
 
+/**
+ * v4l2_get_timestamp - ancillary routine to get a timestamp to be used when
+ *	filling streaming metadata. Internally, it uses ktime_get_ts(),
+ *	with is the recommended way to get it.
+ *
+ * @tv: pointer to &stuct timeval to be filled.

stuct -> struct

include/media/v4l2-common.h struct v4l2_priv_tun_config { · line 343

Quoted 5 lines
include/media/v4l2-common.h +1 -0
+ */
 void v4l2_get_timestamp(struct timeval *tv);
 
 #endif /* V4L2_COMMON_H_ */

Regards,

Hans

#13 lore raw

PATCH v2 5/17 media: v4l2-device.h: document ancillary macros

In reply to Mauro Carvalho Chehab

There are several widely macros that aren't documented using kernel-docs markups.

Add it.

---
 include/media/v4l2-device.h | 238 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 204 insertions(+), 34 deletions(-)
include/media/v4l2-device.h +204 -34
index 8ffa94009d1a..d6d1c4f7d42c 100644
@@ -56,7 +56,6 @@ struct v4l2_ctrl_handler;
  *    #) @dev->driver_data points to this struct.
  *    #) @dev might be %NULL if there is no parent device
  */
-
 struct v4l2_device {
 	struct device *dev;
 #if defined(CONFIG_MEDIA_CONTROLLER)
@@ -166,7 +165,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
  * v4l2_device_register_subdev - Registers a subdev with a v4l2 device.
  *
  * @v4l2_dev: pointer to struct &v4l2_device
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  *
  * While registered, the subdev module is marked as in-use.
  *
@@ -179,7 +178,7 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
 /**
  * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  *
  * .. note ::
  *
@@ -201,7 +200,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
 /**
  * v4l2_subdev_notify - Sends a notification to v4l2_device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  * @notification: type of notification. Please notice that the notification
  *	type is driver-specific.
  * @arg: arguments for the notification. Those are specific to each
@@ -214,13 +213,43 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 		sd->v4l2_dev->notify(sd, notification, arg);
 }
 
-/* Iterate over all subdevs. */
+/* Ancillary macros to iterate over all subdevs. */
+
+/**
+ * v4l2_device_for_each_subdev - Ancillary macro that interates over all
+ *	sub-devices
+ *
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @v4l2_dev: pointer to &struct v4l2_device
+ *
+ * Sometimes, a driver may need to broadcast a command to all subdevices.
+ * This ancillary macro allows interacting to all sub-devices associated
+ * to a device.
+ */
 #define v4l2_device_for_each_subdev(sd, v4l2_dev)			\
 	list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
 
-/* Call the specified callback for all subdevs matching the condition.
-   Ignore any errors. Note that you cannot add or delete a subdev
-   while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_p - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...)	\
 	do {								\
 		list_for_each_entry((sd), &(v4l2_dev)->subdevs, list)	\
@@ -228,6 +257,24 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 				(sd)->ops->o->f((sd) , ##args);		\
 	} while (0)
 
+/**
+ * __v4l2_device_call_subdevs - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...)	\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -236,10 +283,29 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 						f , ##args);		\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching the condition.
-   If the callback returns an error other than 0 or -ENOIOCTLCMD, then
-   return with that error code. Note that you cannot add or delete a
-   subdev while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_until_err_p - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
 ({									\
 	long __err = 0;							\
@@ -253,6 +319,27 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 	(__err == -ENOIOCTLCMD) ? 0 : __err;				\
 })
 
+/**
+ * __v4l2_device_call_subdevs_until_err - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -260,9 +347,25 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 						f , ##args);		\
 })
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). Ignore any errors. Note that you cannot add or delete
-   a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_all - Calls the specified callback for
+ *	all subdevs matching a device-specific group ID.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)		\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -272,10 +375,28 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). If the callback returns an error other than 0 or
-   -ENOIOCTLCMD, then return with that error code. Note that you cannot
-   add or delete a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_until_err - Calls the specified callback for
+ *	all subdevs matching a device-specific group ID.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...)	\
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -284,10 +405,24 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 })
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == `0, then match them all). Ignore any errors. Note that you
- * cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_all - Calls the specified callback for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...)	\
 	do {								\
@@ -298,11 +433,27 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 	} while (0)
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == 0, then match them all). If the callback returns an error
- * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note that
- * you cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_until_err - Calls the specified callback for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
 ({									\
@@ -312,9 +463,19 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 })
 
-/*
- * Does any subdev with matching grpid (or all if grpid == 0) has the given
- * op?
+
+/**
+ * v4l2_device_has_op - checks if any subdev with matching grpid has a
+ * 	given ops.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_has_op(v4l2_dev, grpid, o, f)			\
 ({									\
@@ -331,9 +492,18 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 	__result;							\
 })
 
-/*
- * Does any subdev with matching grpmsk (or all if grpmsk == 0) has the given
- * op?
+/**
+ * v4l2_device_mask_has_op - checks if any subdev with matching group
+ *	mask has a given ops.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f)			\
 ({									\
Signature · 1 line
2.13.5
maintainer
#14 lore raw

Re: [PATCH v2 05/17] media: v4l2-device.h: document ancillary macros

Hi Mauro,

Thank you for the patch.

Quoted 1 line · On Thursday, 28 September 2017 00:46:48 EEST Mauro Carvalho Chehab wrote:

There are several widely macros that aren't documented using kernel-docs

What's a widely macro ? :-)

Quoted 3 lines

markups.

Add it.

Did you mean "Add documentation." ? "Document them." is also an option.

Quoted 37 lines
---
 include/media/v4l2-device.h | 238 +++++++++++++++++++++++++++++++++-------
 1 file changed, 204 insertions(+), 34 deletions(-)
include/media/v4l2-device.h +0 -1
index 8ffa94009d1a..d6d1c4f7d42c 100644
@@ -56,7 +56,6 @@ struct v4l2_ctrl_handler;
  *    #) @dev->driver_data points to this struct.
  *    #) @dev might be %NULL if there is no parent device
  */
-
 struct v4l2_device {
 	struct device *dev;
 #if defined(CONFIG_MEDIA_CONTROLLER)
@@ -166,7 +165,7 @@ void v4l2_device_unregister(struct v4l2_device
 *v4l2_dev); * v4l2_device_register_subdev - Registers a subdev with a v4l2

device. *
* @v4l2_dev: pointer to struct &v4l2_device
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
*
* While registered, the subdev module is marked as in-use. *

include/media/v4l2-device.h +0 -0
@@ -179,7 +178,7 @@ int __must_check v4l2_device_register_subdev(struct

v4l2_device *v4l2_dev, /**
* v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
*
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
*
* .. note ::
*

include/media/v4l2-device.h v4l2_device_register_subdev_nodes(struct v4l2_device · line 206

Quoted 8 lines
include/media/v4l2-device.h +1 -1
@@ -201,7 +200,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device
 *v4l2_dev); /**
  * v4l2_subdev_notify - Sends a notification to v4l2_device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  * @notification: type of notification. Please notice that the notification
  *	type is driver-specific.
  * @arg: arguments for the notification. Those are specific to each

While all this makes sense, it's not related to $SUBJECT.

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct · line 216

Quoted 6 lines
include/media/v4l2-device.h +1 -1
@@ -214,13 +213,43 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, sd->v4l2_dev->notify(sd, notification, arg);
 }
 
-/* Iterate over all subdevs. */
+/* Ancillary macros to iterate over all subdevs. */

Ancillary means supplemental and non-essential. I wouldn't call the macros below ancillary.

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, · line 220

Quoted 3 lines
include/media/v4l2-device.h +3 -0
+/**
+ * v4l2_device_for_each_subdev - Ancillary macro that interates over all
+ *	sub-devices

All sub-devices of a given v4l2_device. Otherwise it could be understood as all sub-devices in the system.

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct · line 221

Quoted 2 lines
include/media/v4l2-device.h +2 -0
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.

How about "&struct v4l2_subdev pointer used as an iterator by the loop" ?

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct · line 222

Quoted 1 line
include/media/v4l2-device.h +1 -0
+ * @v4l2_dev: pointer to &struct v4l2_device

And "&struct v4l2_device owning the sub-devices to iterate over" or something similar ?

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, · line 228

Quoted 4 lines
include/media/v4l2-device.h +4 -0
+ *
+ * Sometimes, a driver may need to broadcast a command to all subdevices.
+ * This ancillary macro allows interacting to all sub-devices associated
+ * to a device.

That's just one possible use of this macro. I wouldn't make it the only documented on. Maybe something as the following ?

"This macro iterates over all sub-devices owned by the @v4l2_dev device. It acts as a for loop iterator and executes the next statement with the @sd variable pointing to each sub-device in turn".

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, · line 234

Quoted 9 lines
include/media/v4l2-device.h +3 -3
+ */
 #define v4l2_device_for_each_subdev(sd, v4l2_dev)			\
 	list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
 
-/* Call the specified callback for all subdevs matching the condition.
-   Ignore any errors. Note that you cannot add or delete a subdev
-   while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_p - Calls the specified callback for

All the __v4l2_device_* macros are internal, I don't think there's a need to document them just for the sake of it.

Quoted 110 lines
include/media/v4l2-device.h +38 -4
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...)	\
 	do {								\
 		list_for_each_entry((sd), &(v4l2_dev)->subdevs, list)	\
@@ -228,6 +257,24 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, (sd)->ops->o->f((sd) , ##args);		\
 	} while (0)
 
+/**
+ * __v4l2_device_call_subdevs - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...)	\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -236,10 +283,29 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, f , ##args);		\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching the condition.
-   If the callback returns an error other than 0 or -ENOIOCTLCMD, then
-   return with that error code. Note that you cannot add or delete a
-   subdev while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_until_err_p - Calls the specified callback

for
+ * all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @sd: pointer that will be filled by the macro with all
+ * &struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * The callback functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
#define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f,
args...) \ ({ \

include/media/v4l2-device.h +21 -0
 	long __err = 0;							\
@@ -253,6 +319,27 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, (__err == -ENOIOCTLCMD) ? 0 : __err;				\
 })
 
+/**
+ * __v4l2_device_call_subdevs_until_err - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...)
 \ ({									\
 	struct v4l2_subdev *__sd;					\

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct · line 351

Quoted 8 lines
include/media/v4l2-device.h +2 -3
@@ -260,9 +347,25 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, f , ##args);		\
 })
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). Ignore any errors. Note that you cannot add or delete
-   a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_all - Calls the specified callback for

The word "operation" would be better than the word "callback".

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct · line 352

Quoted 1 line
include/media/v4l2-device.h +1 -0
+ *	all subdevs matching a device-specific group ID.

How exactly is the group ID device-specific ?

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, · line 361

Quoted 8 lines
include/media/v4l2-device.h +8 -0
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.

Using the word "group" here makes it very confusing. You could use "operation class" instead. Another option would be to document @o.@f of Sphinx doesn't complain/

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, · line 250

Quoted 5 lines
include/media/v4l2-device.h +5 -0
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at

s/walking at/walking/

All these comments apply for the macros below.

Quoted 21 lines
include/media/v4l2-device.h +10 -4
+ * the subdevs list.
+ */
 #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)		\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -272,10 +375,28 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, ##args);					\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). If the callback returns an error other than 0 or
-   -ENOIOCTLCMD, then return with that error code. Note that you cannot
-   add or delete a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_until_err - Calls the specified callback for
+ *	all subdevs matching a device-specific group ID.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.

include/media/v4l2-device.h static inline void v4l2_subdev_notify(struct · line 395

Quoted 10 lines
include/media/v4l2-device.h +10 -0
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.

Otherwise ?

Quoted 115 lines
include/media/v4l2-device.h +21 -8
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...)	\
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -284,10 +405,24 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, ##args);					\
 })
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == `0, then match them all). Ignore any errors. Note that you
- * cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_all - Calls the specified callback for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...)	\
 	do {								\
@@ -298,11 +433,27 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, ##args);					\
 	} while (0)
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == 0, then match them all). If the callback returns an error
- * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note

that
- * you cannot add or delete a subdev while walking the subdevs list.

include/media/v4l2-device.h +34 -5
+/**
+ * v4l2_device_mask_call_until_err - Calls the specified callback for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
 ({									\
@@ -312,9 +463,19 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, ##args);					\
 })
 
-/*
- * Does any subdev with matching grpid (or all if grpid == 0) has the given
- * op?
+
+/**
+ * v4l2_device_has_op - checks if any subdev with matching grpid has a
+ * 	given ops.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_has_op(v4l2_dev, grpid, o, f)			\
 ({									\
@@ -331,9 +492,18 @@ static inline void v4l2_subdev_notify(struct
 v4l2_subdev *sd, __result;							\
 })
 
-/*
- * Does any subdev with matching grpmsk (or all if grpmsk == 0) has the

given
- * op?
+/**
+ * v4l2_device_mask_has_op - checks if any subdev with matching group
+ * mask has a given ops.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ * group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * The callback functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
*/
#define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f) \
({ \

Signature · 3 lines
Regards,

Laurent Pinchart
author Acked-by Sakari Ailus
#15 lore raw

Re: [PATCH v2 05/17] media: v4l2-device.h: document ancillary macros

Em Fri, 13 Oct 2017 15:33:01 +0300
Laurent Pinchart <[email protected]> escreveu:

Quoted 7 lines

Hi Mauro,

Thank you for the patch.

Quoted 1 line · On Thursday, 28 September 2017 00:46:48 EEST Mauro Carvalho Chehab wrote:

There are several widely macros that aren't documented using kernel-docs

Quoted 10 lines

What's a widely macro ? :-)

Quoted 3 lines

markups.

Add it.

Did you mean "Add documentation." ? "Document them." is also an option.

Quoted 2 lines

I attended most of the points you pointed. I'll comment just the ones that I have a different opinion, or require further discussions.

Quoted 8 lines

Review

Quoted 5 lines
(quoted diff) +2 -3
-/* Call the specified callback for all subdevs matching the condition.
-   Ignore any errors. Note that you cannot add or delete a subdev
-   while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_p - Calls the specified callback for  

All the __v4l2_device_* macros are internal, I don't think there's a need to document them just for the sake of it.

Yeah, they're meant to be used only internally, but there are lot of tricks on those macros. So, I prefer to keep them documented.

Quoted 4 lines
Quoted 2 lines

+ * all subdevs matching a device-specific group ID.

How exactly is the group ID device-specific ?

This "group" is really device-specific: each device may define its own private set of device groups. I guess only one or two drivers actually use it, like this one:

drivers/media/platform/davinci/vpif_display.c

See calls for v4l2_device_call_until_err() there.

The group ID is filled on this logic, inside vpif_probe():

			if (vpif_obj.sd[i])
				vpif_obj.sd[i]->grp_id = 1 << i;

Maybe it could say, instead:

"all subdevs matching the &v4l2_subdev.grp_id, as
assigned by the bridge driver."

Quoted 11 lines
Quoted 8 lines

+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * The callback functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.

Using the word "group" here makes it very confusing. You could use "operation class" instead.

It isn't an operation class. It is a group of sub-devices, defined by the bridge driver.

Quoted 2 lines

Another option would be to document @o.@f of Sphinx doesn't complain/

It will complain.

I'm enclosing a new version of this patch with the requested changes.

Thanks,
Mauro

[PATCH v3 05/17] media: v4l2-device.h: document helper macros

There are several macros that aren't documented using kernel-docs markups.

Document them.

While here, add cross-references to structs on this file.

---
 include/media/v4l2-device.h |  246 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 211 insertions(+), 35 deletions(-)
include/media/v4l2-device.h +211 -35
@@ -38,7 +38,7 @@ struct v4l2_ctrl_handler;
  * @lock: lock this struct; can be used by the driver as well
  *	if this struct is embedded into a larger struct.
  * @name: unique device name, by default the driver name + bus ID
- * @notify: notify callback called by some sub-devices.
+ * @notify: notify operation called by some sub-devices.
  * @ctrl_handler: The control handler. May be %NULL.
  * @prio: Device's priority state
  * @ref: Keep track of the references to this struct.
@@ -56,7 +56,6 @@ struct v4l2_ctrl_handler;
  *    #) @dev->driver_data points to this struct.
  *    #) @dev might be %NULL if there is no parent device
  */
-
 struct v4l2_device {
 	struct device *dev;
 #if defined(CONFIG_MEDIA_CONTROLLER)
@@ -166,7 +165,7 @@ void v4l2_device_unregister(struct v4l2_
  * v4l2_device_register_subdev - Registers a subdev with a v4l2 device.
  *
  * @v4l2_dev: pointer to struct &v4l2_device
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  *
  * While registered, the subdev module is marked as in-use.
  *
@@ -179,7 +178,7 @@ int __must_check v4l2_device_register_su
 /**
  * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  *
  * .. note ::
  *
@@ -201,7 +200,7 @@ v4l2_device_register_subdev_nodes(struct
 /**
  * v4l2_subdev_notify - Sends a notification to v4l2_device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  * @notification: type of notification. Please notice that the notification
  *	type is driver-specific.
  * @arg: arguments for the notification. Those are specific to each
@@ -214,13 +213,43 @@ static inline void v4l2_subdev_notify(st
 		sd->v4l2_dev->notify(sd, notification, arg);
 }
 
-/* Iterate over all subdevs. */
+/* Helper macros to iterate over all subdevs. */
+
+/**
+ * v4l2_device_for_each_subdev - Helper macro that interates over all
+ *	sub-devices of a given &v4l2_device.
+ *
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev pointer used as an iterator by the loop.
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ *
+ * This macro iterates over all sub-devices owned by the @v4l2_dev device.
+ * It acts as a for loop iterator and executes the next statement with
+ * the @sd variable pointing to each sub-device in turn.
+ */
 #define v4l2_device_for_each_subdev(sd, v4l2_dev)			\
 	list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
 
-/* Call the specified callback for all subdevs matching the condition.
-   Ignore any errors. Note that you cannot add or delete a subdev
-   while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_p - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev pointer used as an iterator by the loop.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...)	\
 	do {								\
 		list_for_each_entry((sd), &(v4l2_dev)->subdevs, list)	\
@@ -228,6 +257,24 @@ static inline void v4l2_subdev_notify(st
 				(sd)->ops->o->f((sd) , ##args);		\
 	} while (0)
 
+/**
+ * __v4l2_device_call_subdevs - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...)	\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -236,10 +283,30 @@ static inline void v4l2_subdev_notify(st
 						f , ##args);		\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching the condition.
-   If the callback returns an error other than 0 or -ENOIOCTLCMD, then
-   return with that error code. Note that you cannot add or delete a
-   subdev while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_until_err_p - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code, zero
+ * otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
 ({									\
 	long __err = 0;							\
@@ -253,6 +320,28 @@ static inline void v4l2_subdev_notify(st
 	(__err == -ENOIOCTLCMD) ? 0 : __err;				\
 })
 
+/**
+ * __v4l2_device_call_subdevs_until_err - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -260,9 +349,26 @@ static inline void v4l2_subdev_notify(st
 						f , ##args);		\
 })
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). Ignore any errors. Note that you cannot add or delete
-   a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_all - Calls the specified operation for
+ *	all subdevs matching the &v4l2_subdev.grp_id, as assigned
+ *	by the bridge driver.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)		\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -272,10 +378,30 @@ static inline void v4l2_subdev_notify(st
 			##args);					\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). If the callback returns an error other than 0 or
-   -ENOIOCTLCMD, then return with that error code. Note that you cannot
-   add or delete a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_until_err - Calls the specified operation for
+ *	all subdevs matching the &v4l2_subdev.grp_id, as assigned
+ *	by the bridge driver, until an error occurs.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...)	\
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -284,10 +410,24 @@ static inline void v4l2_subdev_notify(st
 			##args);					\
 })
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == `0, then match them all). Ignore any errors. Note that you
- * cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_all - Calls the specified operation for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...)	\
 	do {								\
@@ -298,11 +438,28 @@ static inline void v4l2_subdev_notify(st
 			##args);					\
 	} while (0)
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == 0, then match them all). If the callback returns an error
- * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note that
- * you cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_until_err - Calls the specified operation for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
 ({									\
@@ -312,9 +469,19 @@ static inline void v4l2_subdev_notify(st
 			##args);					\
 })
 
-/*
- * Does any subdev with matching grpid (or all if grpid == 0) has the given
- * op?
+
+/**
+ * v4l2_device_has_op - checks if any subdev with matching grpid has a
+ * 	given ops.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_has_op(v4l2_dev, grpid, o, f)			\
 ({									\
@@ -331,9 +498,18 @@ static inline void v4l2_subdev_notify(st
 	__result;							\
 })
 
-/*
- * Does any subdev with matching grpmsk (or all if grpmsk == 0) has the given
- * op?
+/**
+ * v4l2_device_mask_has_op - checks if any subdev with matching group
+ *	mask has a given ops.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * 	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f)			\
 ({									\
Acked-by on v2 5/17
#16 lore raw

Re: [PATCH v2 05/17] media: v4l2-device.h: document ancillary macros

In reply to Mauro Carvalho Chehab
Quoted 6 lines · Mauro Carvalho Chehab

There are several widely macros that aren't documented using kernel-docs markups.

Add it.

Regards,

Hans

Quoted 348 lines
---
 include/media/v4l2-device.h | 238 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 204 insertions(+), 34 deletions(-)
include/media/v4l2-device.h +204 -34
index 8ffa94009d1a..d6d1c4f7d42c 100644
@@ -56,7 +56,6 @@ struct v4l2_ctrl_handler;
  *    #) @dev->driver_data points to this struct.
  *    #) @dev might be %NULL if there is no parent device
  */
-
 struct v4l2_device {
 	struct device *dev;
 #if defined(CONFIG_MEDIA_CONTROLLER)
@@ -166,7 +165,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
  * v4l2_device_register_subdev - Registers a subdev with a v4l2 device.
  *
  * @v4l2_dev: pointer to struct &v4l2_device
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  *
  * While registered, the subdev module is marked as in-use.
  *
@@ -179,7 +178,7 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
 /**
  * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  *
  * .. note ::
  *
@@ -201,7 +200,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
 /**
  * v4l2_subdev_notify - Sends a notification to v4l2_device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  * @notification: type of notification. Please notice that the notification
  *	type is driver-specific.
  * @arg: arguments for the notification. Those are specific to each
@@ -214,13 +213,43 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 		sd->v4l2_dev->notify(sd, notification, arg);
 }
 
-/* Iterate over all subdevs. */
+/* Ancillary macros to iterate over all subdevs. */
+
+/**
+ * v4l2_device_for_each_subdev - Ancillary macro that interates over all
+ *	sub-devices
+ *
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @v4l2_dev: pointer to &struct v4l2_device
+ *
+ * Sometimes, a driver may need to broadcast a command to all subdevices.
+ * This ancillary macro allows interacting to all sub-devices associated
+ * to a device.
+ */
 #define v4l2_device_for_each_subdev(sd, v4l2_dev)			\
 	list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
 
-/* Call the specified callback for all subdevs matching the condition.
-   Ignore any errors. Note that you cannot add or delete a subdev
-   while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_p - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...)	\
 	do {								\
 		list_for_each_entry((sd), &(v4l2_dev)->subdevs, list)	\
@@ -228,6 +257,24 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 				(sd)->ops->o->f((sd) , ##args);		\
 	} while (0)
 
+/**
+ * __v4l2_device_call_subdevs - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...)	\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -236,10 +283,29 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 						f , ##args);		\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching the condition.
-   If the callback returns an error other than 0 or -ENOIOCTLCMD, then
-   return with that error code. Note that you cannot add or delete a
-   subdev while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_until_err_p - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
 ({									\
 	long __err = 0;							\
@@ -253,6 +319,27 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 	(__err == -ENOIOCTLCMD) ? 0 : __err;				\
 })
 
+/**
+ * __v4l2_device_call_subdevs_until_err - Calls the specified callback for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -260,9 +347,25 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 						f , ##args);		\
 })
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). Ignore any errors. Note that you cannot add or delete
-   a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_all - Calls the specified callback for
+ *	all subdevs matching a device-specific group ID.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)		\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -272,10 +375,28 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). If the callback returns an error other than 0 or
-   -ENOIOCTLCMD, then return with that error code. Note that you cannot
-   add or delete a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_until_err - Calls the specified callback for
+ *	all subdevs matching a device-specific group ID.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
+ */
 #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...)	\
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -284,10 +405,24 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 })
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == `0, then match them all). Ignore any errors. Note that you
- * cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_all - Calls the specified callback for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...)	\
 	do {								\
@@ -298,11 +433,27 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 	} while (0)
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == 0, then match them all). If the callback returns an error
- * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note that
- * you cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_until_err - Calls the specified callback for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the callback returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code.
+ *
+ * Note: subdevs cannot be added or deleted while walking at
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
 ({									\
@@ -312,9 +463,19 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 })
 
-/*
- * Does any subdev with matching grpid (or all if grpid == 0) has the given
- * op?
+
+/**
+ * v4l2_device_has_op - checks if any subdev with matching grpid has a
+ * 	given ops.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * 	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_has_op(v4l2_dev, grpid, o, f)			\
 ({									\
@@ -331,9 +492,18 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 	__result;							\
 })
 
-/*
- * Does any subdev with matching grpmsk (or all if grpmsk == 0) has the given
- * op?
+/**
+ * v4l2_device_mask_has_op - checks if any subdev with matching group
+ *	mask has a given ops.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ * 	The callback functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f)			\
 ({									\
#17 lore raw

PATCH v2 6/17 media: v4l2-dv-timings.h: convert comment into kernel-doc markup

In reply to Mauro Carvalho Chehab

The can_reduce_fps() is already documented, but it is not using the kernel-doc markup. Convert it, in order to generate documentation from it.

---
 include/media/v4l2-dv-timings.h | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
include/media/v4l2-dv-timings.h +8 -6
index 61a18893e004..c0855887ad87 100644
@@ -203,13 +203,15 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait);
  */
 struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t);
 
-/*
- * reduce_fps - check if conditions for reduced fps are true.
- * bt - v4l2 timing structure
+/**
+ * can_reduce_fps - check if conditions for reduced fps are true.
+ * @bt: v4l2 timing structure
+ *
  * For different timings reduced fps is allowed if following conditions
- * are met -
- * For CVT timings: if reduced blanking v2 (vsync == 8) is true.
- * For CEA861 timings: if V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
+ * are met:
+ *
+ *   - For CVT timings: if reduced blanking v2 (vsync == 8) is true.
+ *   - For CEA861 timings: if %V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
  */
 static inline  bool can_reduce_fps(struct v4l2_bt_timings *bt)
 {
Signature · 1 line
2.13.5
maintainer
#18 lore raw

Re: [PATCH v2 06/17] media: v4l2-dv-timings.h: convert comment into kernel-doc markup

Hi Mauro,

Thank you for the patch.

Quoted 18 lines · On Thursday, 28 September 2017 00:46:49 EEST Mauro Carvalho Chehab wrote:

The can_reduce_fps() is already documented, but it is not using the kernel-doc markup. Convert it, in order to generate documentation from it.

---
 include/media/v4l2-dv-timings.h | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
(quoted diff) +0 -0

b/include/media/v4l2-dv-timings.h index 61a18893e004..c0855887ad87 100644

include/media/v4l2-dv-timings.h +0 -0
@@ -203,13 +203,15 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8

hor_landscape, u8 vert_portrait); */
struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings
*t);

include/media/v4l2-dv-timings.h struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait); · line 210

Quoted 8 lines
include/media/v4l2-dv-timings.h +4 -3
-/*
- * reduce_fps - check if conditions for reduced fps are true.
- * bt - v4l2 timing structure
+/**
+ * can_reduce_fps - check if conditions for reduced fps are true.
+ * @bt: v4l2 timing structure
+ *
  * For different timings reduced fps is allowed if following conditions

While at it, s/following conditions/the following conditions/

Quoted 10 lines

- * are met -
- * For CVT timings: if reduced blanking v2 (vsync == 8) is true.
- * For CEA861 timings: if V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
+ * are met:
+ *
+ * - For CVT timings: if reduced blanking v2 (vsync == 8) is true.
+ * - For CEA861 timings: if %V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
*/
static inline bool can_reduce_fps(struct v4l2_bt_timings *bt) {

Signature · 3 lines
Regards,

Laurent Pinchart
Acked-by on v2 6/17
#19 lore raw

Re: [PATCH v2 06/17] media: v4l2-dv-timings.h: convert comment into kernel-doc markup

In reply to Mauro Carvalho Chehab
Quoted 5 lines · Mauro Carvalho Chehab

The can_reduce_fps() is already documented, but it is not using the kernel-doc markup. Convert it, in order to generate documentation from it.

Quoted 31 lines
---
 include/media/v4l2-dv-timings.h | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
include/media/v4l2-dv-timings.h +8 -6
index 61a18893e004..c0855887ad87 100644
@@ -203,13 +203,15 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait);
  */
 struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t);
 
-/*
- * reduce_fps - check if conditions for reduced fps are true.
- * bt - v4l2 timing structure
+/**
+ * can_reduce_fps - check if conditions for reduced fps are true.
+ * @bt: v4l2 timing structure
+ *
  * For different timings reduced fps is allowed if following conditions
- * are met -
- * For CVT timings: if reduced blanking v2 (vsync == 8) is true.
- * For CEA861 timings: if V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
+ * are met:
+ *
+ *   - For CVT timings: if reduced blanking v2 (vsync == 8) is true.
+ *   - For CEA861 timings: if %V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
  */
 static inline  bool can_reduce_fps(struct v4l2_bt_timings *bt)
 {
#20 lore raw

PATCH v2 7/17 media: v4l2-event.rst: improve events description

In reply to Mauro Carvalho Chehab

Both v4l2-event.rst and v4l2-event.h have an overview of events, but there are some inconsistencies there:

- at v4l2-event, the event's ringbuffer is called kevent. Its name is, instead, v4l2_kevent;

- Some things are mentioned on both places (with different words), others are either on one of the files.

In order to cleanup this mess, put everything at v4l2-event.rst and improve it to be a little more coherent and to have cross references.

---
 Documentation/media/kapi/v4l2-event.rst | 64 ++++++++++++++++++++++++++-------
 include/media/v4l2-event.h              | 34 ------------------
 2 files changed, 52 insertions(+), 46 deletions(-)
Documentation/media/kapi/v4l2-event.rst +52 -12
index 9938d21ef4d1..7831a503e2aa 100644
@@ -5,27 +5,67 @@ V4L2 events
 The V4L2 events provide a generic way to pass events to user space.
 The driver must use :c:type:`v4l2_fh` to be able to support V4L2 events.
 
-Events are defined by a type and an optional ID. The ID may refer to a V4L2
-object such as a control ID. If unused, then the ID is 0.
+Events are subscribed per-filehandle. An event specification consists of a
+``type`` and is optionally associated with an object identified through the
+``id`` field. If unused, then the ``id`` is 0. So an event is uniquely
+identified by the ``(type, id)`` tuple.
 
-When the user subscribes to an event the driver will allocate a number of
-kevent structs for that event. So every (type, ID) event tuple will have
-its own set of kevent structs. This guarantees that if a driver is generating
-lots of events of one type in a short time, then that will not overwrite
-events of another type.
+The :c:type:`v4l2_fh` struct has a list of subscribed events on its
+``subscribed`` field.
 
-But if you get more events of one type than the number of kevents that were
-reserved, then the oldest event will be dropped and the new one added.
+When the user subscribes to an event, a :c:type:`v4l2_subscribed_event`
+struct is added to :c:type:`v4l2_fh`\ ``.subscribed``, one for every
+subscribed event.
+
+Each :c:type:`v4l2_subscribed_event` struct ends with a
+:c:type:`v4l2_kevent` ringbuffer, with the size given by the caller
+of :c:func:`v4l2_event_subscribe`. Such ringbuffer is used to store any events
+raised by the driver.
+
+So every ``(type, ID)`` event tuple will have its own set of
+:c:type:`v4l2_kevent` ringbuffer. This guarantees that if a driver is
+generating lots of events of one type in a short time, then that will
+not overwrite events of another type.
+
+But if you get more events of one type than the size of the
+:c:type:`v4l2_kevent` ringbuffer, then the oldest event will be dropped
+and the new one added.
+
+The :c:type:`v4l2_kevent` struct links into the ``available``
+list of the :c:type:`v4l2_fh` struct so :ref:`VIDIOC_DQEVENT` will
+know which event to dequeue first.
+
+Finally, if the event subscription is associated with a particular object
+such as a V4L2 control, then that object needs to know about that as well
+so that an event can be raised by that object. So the ``node`` field can
+be used to link the :c:type:`v4l2_subscribed_event` struct into a list of
+such object.
+
+So to summarize:
+
+- struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events,
+  and one of the ``available`` events.
+
+- struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised
+  (pending) events of that particular type.
+
+- If struct :c:type:`v4l2_subscribed_event` is associated with a specific
+  object, then that object will have an internal list of
+  struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an
+  event to that object.
 
 Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has
 ``merge()`` and ``replace()`` callbacks which drivers can set. These
 callbacks are called when a new event is raised and there is no more room.
+
 The ``replace()`` callback allows you to replace the payload of the old event
 with that of the new event, merging any relevant data from the old payload
 into the new payload that replaces it. It is called when this event type has
-only one kevent struct allocated. The ``merge()`` callback allows you to merge
-the oldest event payload into that of the second-oldest event payload. It is
-called when there are two or more kevent structs allocated.
+only one :c:type:`v4l2_kevent` struct allocated.
+
+The ``merge()`` callback allows you to merge the oldest event payload into
+that of the second-oldest event payload. It is called when there are two
+or more :c:type:`v4l2_kevent` structs allocated.
 
 This way no status information is lost, just the intermediate steps leading
 up to that state.
include/media/v4l2-event.h +0 -34
index 6741910c3a18..4e83529117f7 100644
@@ -24,40 +24,6 @@
 #include <linux/videodev2.h>
 #include <linux/wait.h>
 
-/*
- * Overview:
- *
- * Events are subscribed per-filehandle. An event specification consists of a
- * type and is optionally associated with an object identified through the
- * 'id' field. So an event is uniquely identified by the (type, id) tuple.
- *
- * The v4l2-fh struct has a list of subscribed events. The v4l2_subscribed_event
- * struct is added to that list, one for every subscribed event.
- *
- * Each v4l2_subscribed_event struct ends with an array of v4l2_kevent structs.
- * This array (ringbuffer, really) is used to store any events raised by the
- * driver. The v4l2_kevent struct links into the 'available' list of the
- * v4l2_fh struct so VIDIOC_DQEVENT will know which event to dequeue first.
- *
- * Finally, if the event subscription is associated with a particular object
- * such as a V4L2 control, then that object needs to know about that as well
- * so that an event can be raised by that object. So the 'node' field can
- * be used to link the v4l2_subscribed_event struct into a list of that
- * object.
- *
- * So to summarize:
- *
- * struct v4l2_fh has two lists: one of the subscribed events, and one of the
- * pending events.
- *
- * struct v4l2_subscribed_event has a ringbuffer of raised (pending) events of
- * that particular type.
- *
- * If struct v4l2_subscribed_event is associated with a specific object, then
- * that object will have an internal list of struct v4l2_subscribed_event so
- * it knows who subscribed an event to that object.
- */
-
 struct v4l2_fh;
 struct v4l2_subdev;
 struct v4l2_subscribed_event;
Signature · 1 line
2.13.5
Acked-by on v2 7/17
#21 lore raw

Re: [PATCH v2 07/17] media: v4l2-event.rst: improve events description

Hi Mauro,

Quoted 4 lines · Mauro Carvalho Chehab

Both v4l2-event.rst and v4l2-event.h have an overview of events, but there are some inconsistencies there:

- at v4l2-event, the event's ringbuffer is called kevent. Its

s/ringbuffer/ring buffer/g

With that,

Quoted 147 lines

name is, instead, v4l2_kevent;

- Some things are mentioned on both places (with different words), others are either on one of the files.

In order to cleanup this mess, put everything at v4l2-event.rst and improve it to be a little more coherent and to have cross references.

---
 Documentation/media/kapi/v4l2-event.rst | 64 ++++++++++++++++++++++++++-------
 include/media/v4l2-event.h              | 34 ------------------
 2 files changed, 52 insertions(+), 46 deletions(-)
Documentation/media/kapi/v4l2-event.rst +52 -12
index 9938d21ef4d1..7831a503e2aa 100644
@@ -5,27 +5,67 @@ V4L2 events
 The V4L2 events provide a generic way to pass events to user space.
 The driver must use :c:type:`v4l2_fh` to be able to support V4L2 events.
 
-Events are defined by a type and an optional ID. The ID may refer to a V4L2
-object such as a control ID. If unused, then the ID is 0.
+Events are subscribed per-filehandle. An event specification consists of a
+``type`` and is optionally associated with an object identified through the
+``id`` field. If unused, then the ``id`` is 0. So an event is uniquely
+identified by the ``(type, id)`` tuple.
 
-When the user subscribes to an event the driver will allocate a number of
-kevent structs for that event. So every (type, ID) event tuple will have
-its own set of kevent structs. This guarantees that if a driver is generating
-lots of events of one type in a short time, then that will not overwrite
-events of another type.
+The :c:type:`v4l2_fh` struct has a list of subscribed events on its
+``subscribed`` field.
 
-But if you get more events of one type than the number of kevents that were
-reserved, then the oldest event will be dropped and the new one added.
+When the user subscribes to an event, a :c:type:`v4l2_subscribed_event`
+struct is added to :c:type:`v4l2_fh`\ ``.subscribed``, one for every
+subscribed event.
+
+Each :c:type:`v4l2_subscribed_event` struct ends with a
+:c:type:`v4l2_kevent` ringbuffer, with the size given by the caller
+of :c:func:`v4l2_event_subscribe`. Such ringbuffer is used to store any events
+raised by the driver.
+
+So every ``(type, ID)`` event tuple will have its own set of
+:c:type:`v4l2_kevent` ringbuffer. This guarantees that if a driver is
+generating lots of events of one type in a short time, then that will
+not overwrite events of another type.
+
+But if you get more events of one type than the size of the
+:c:type:`v4l2_kevent` ringbuffer, then the oldest event will be dropped
+and the new one added.
+
+The :c:type:`v4l2_kevent` struct links into the ``available``
+list of the :c:type:`v4l2_fh` struct so :ref:`VIDIOC_DQEVENT` will
+know which event to dequeue first.
+
+Finally, if the event subscription is associated with a particular object
+such as a V4L2 control, then that object needs to know about that as well
+so that an event can be raised by that object. So the ``node`` field can
+be used to link the :c:type:`v4l2_subscribed_event` struct into a list of
+such object.
+
+So to summarize:
+
+- struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events,
+  and one of the ``available`` events.
+
+- struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised
+  (pending) events of that particular type.
+
+- If struct :c:type:`v4l2_subscribed_event` is associated with a specific
+  object, then that object will have an internal list of
+  struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an
+  event to that object.
 
 Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has
 ``merge()`` and ``replace()`` callbacks which drivers can set. These
 callbacks are called when a new event is raised and there is no more room.
+
 The ``replace()`` callback allows you to replace the payload of the old event
 with that of the new event, merging any relevant data from the old payload
 into the new payload that replaces it. It is called when this event type has
-only one kevent struct allocated. The ``merge()`` callback allows you to merge
-the oldest event payload into that of the second-oldest event payload. It is
-called when there are two or more kevent structs allocated.
+only one :c:type:`v4l2_kevent` struct allocated.
+
+The ``merge()`` callback allows you to merge the oldest event payload into
+that of the second-oldest event payload. It is called when there are two
+or more :c:type:`v4l2_kevent` structs allocated.
 
 This way no status information is lost, just the intermediate steps leading
 up to that state.
include/media/v4l2-event.h +0 -34
index 6741910c3a18..4e83529117f7 100644
@@ -24,40 +24,6 @@
 #include <linux/videodev2.h>
 #include <linux/wait.h>
 
-/*
- * Overview:
- *
- * Events are subscribed per-filehandle. An event specification consists of a
- * type and is optionally associated with an object identified through the
- * 'id' field. So an event is uniquely identified by the (type, id) tuple.
- *
- * The v4l2-fh struct has a list of subscribed events. The v4l2_subscribed_event
- * struct is added to that list, one for every subscribed event.
- *
- * Each v4l2_subscribed_event struct ends with an array of v4l2_kevent structs.
- * This array (ringbuffer, really) is used to store any events raised by the
- * driver. The v4l2_kevent struct links into the 'available' list of the
- * v4l2_fh struct so VIDIOC_DQEVENT will know which event to dequeue first.
- *
- * Finally, if the event subscription is associated with a particular object
- * such as a V4L2 control, then that object needs to know about that as well
- * so that an event can be raised by that object. So the 'node' field can
- * be used to link the v4l2_subscribed_event struct into a list of that
- * object.
- *
- * So to summarize:
- *
- * struct v4l2_fh has two lists: one of the subscribed events, and one of the
- * pending events.
- *
- * struct v4l2_subscribed_event has a ringbuffer of raised (pending) events of
- * that particular type.
- *
- * If struct v4l2_subscribed_event is associated with a specific object, then
- * that object will have an internal list of struct v4l2_subscribed_event so
- * it knows who subscribed an event to that object.
- */
-
 struct v4l2_fh;
 struct v4l2_subdev;
 struct v4l2_subscribed_event;
Signature · 1 line
2.13.5
Signature · 2 lines
Sakari Ailus
e-mail: [email protected]
#22 lore raw

Re: [PATCH v2 07/17] media: v4l2-event.rst: improve events description

In reply to Mauro Carvalho Chehab

Nice! I have some small fixes and one little rewrite for the replace/merge documentation:

Quoted 30 lines · Mauro Carvalho Chehab

Both v4l2-event.rst and v4l2-event.h have an overview of events, but there are some inconsistencies there:

- at v4l2-event, the event's ringbuffer is called kevent. Its name is, instead, v4l2_kevent;

- Some things are mentioned on both places (with different words), others are either on one of the files.

In order to cleanup this mess, put everything at v4l2-event.rst and improve it to be a little more coherent and to have cross references.

---
 Documentation/media/kapi/v4l2-event.rst | 64 ++++++++++++++++++++++++++-------
 include/media/v4l2-event.h              | 34 ------------------
 2 files changed, 52 insertions(+), 46 deletions(-)
Documentation/media/kapi/v4l2-event.rst +1 -2
index 9938d21ef4d1..7831a503e2aa 100644
@@ -5,27 +5,67 @@ V4L2 events
 The V4L2 events provide a generic way to pass events to user space.
 The driver must use :c:type:`v4l2_fh` to be able to support V4L2 events.
 
-Events are defined by a type and an optional ID. The ID may refer to a V4L2
-object such as a control ID. If unused, then the ID is 0.
+Events are subscribed per-filehandle. An event specification consists of a

Documentation/media/kapi/v4l2-event.rst V4L2 events · line 13

Quoted 10 lines
Documentation/media/kapi/v4l2-event.rst +4 -5
+``type`` and is optionally associated with an object identified through the
+``id`` field. If unused, then the ``id`` is 0. So an event is uniquely
+identified by the ``(type, id)`` tuple.
 
-When the user subscribes to an event the driver will allocate a number of
-kevent structs for that event. So every (type, ID) event tuple will have
-its own set of kevent structs. This guarantees that if a driver is generating
-lots of events of one type in a short time, then that will not overwrite
-events of another type.
+The :c:type:`v4l2_fh` struct has a list of subscribed events on its

on -> at

Documentation/media/kapi/v4l2-event.rst V4L2 events · line 22

Quoted 11 lines
Documentation/media/kapi/v4l2-event.rst +8 -2
+``subscribed`` field.
 
-But if you get more events of one type than the number of kevents that were
-reserved, then the oldest event will be dropped and the new one added.
+When the user subscribes to an event, a :c:type:`v4l2_subscribed_event`
+struct is added to :c:type:`v4l2_fh`\ ``.subscribed``, one for every
+subscribed event.
+
+Each :c:type:`v4l2_subscribed_event` struct ends with a
+:c:type:`v4l2_kevent` ringbuffer, with the size given by the caller
+of :c:func:`v4l2_event_subscribe`. Such ringbuffer is used to store any events

Such -> This

Documentation/media/kapi/v4l2-event.rst V4L2 events · line 25

Quoted 3 lines
Documentation/media/kapi/v4l2-event.rst +3 -0
+raised by the driver.
+
+So every ``(type, ID)`` event tuple will have its own set of

Drop 'set of'.

Quoted 7 lines
Documentation/media/kapi/v4l2-event.rst +7 -0
+:c:type:`v4l2_kevent` ringbuffer. This guarantees that if a driver is
+generating lots of events of one type in a short time, then that will
+not overwrite events of another type.
+
+But if you get more events of one type than the size of the
+:c:type:`v4l2_kevent` ringbuffer, then the oldest event will be dropped
+and the new one added.

Documentation/media/kapi/v4l2-event.rst V4L2 events · line 42

Quoted 10 lines
Documentation/media/kapi/v4l2-event.rst +10 -0
+
+The :c:type:`v4l2_kevent` struct links into the ``available``
+list of the :c:type:`v4l2_fh` struct so :ref:`VIDIOC_DQEVENT` will
+know which event to dequeue first.
+
+Finally, if the event subscription is associated with a particular object
+such as a V4L2 control, then that object needs to know about that as well
+so that an event can be raised by that object. So the ``node`` field can
+be used to link the :c:type:`v4l2_subscribed_event` struct into a list of
+such object.

objects

Quoted 15 lines
Documentation/media/kapi/v4l2-event.rst +13 -0
+
+So to summarize:
+
+- struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events,
+  and one of the ``available`` events.
+
+- struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised
+  (pending) events of that particular type.
+
+- If struct :c:type:`v4l2_subscribed_event` is associated with a specific
+  object, then that object will have an internal list of
+  struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an
+  event to that object.
 
 Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has

Documentation/media/kapi/v4l2-event.rst V4L2 events · line 64

Quoted 10 lines
Documentation/media/kapi/v4l2-event.rst +2 -3
 ``merge()`` and ``replace()`` callbacks which drivers can set. These
 callbacks are called when a new event is raised and there is no more room.
+
 The ``replace()`` callback allows you to replace the payload of the old event
 with that of the new event, merging any relevant data from the old payload
 into the new payload that replaces it. It is called when this event type has
-only one kevent struct allocated. The ``merge()`` callback allows you to merge
-the oldest event payload into that of the second-oldest event payload. It is
-called when there are two or more kevent structs allocated.
+only one :c:type:`v4l2_kevent` struct allocated.

I'd say: "a ringbuffer with size 1, i.e. only one event can be stored in the ringbuffer."

Documentation/media/kapi/v4l2-event.rst V4L2 events · line 68

Quoted 4 lines
Documentation/media/kapi/v4l2-event.rst +4 -0
+
+The ``merge()`` callback allows you to merge the oldest event payload into
+that of the second-oldest event payload. It is called when there are two
+or more :c:type:`v4l2_kevent` structs allocated.

"It is called when the ringbuffer has size > 1."

Quoted 39 lines
Documentation/media/kapi/v4l2-event.rst +0 -0
 This way no status information is lost, just the intermediate steps leading
 up to that state.
include/media/v4l2-event.h +0 -27
index 6741910c3a18..4e83529117f7 100644
@@ -24,40 +24,6 @@
 #include <linux/videodev2.h>
 #include <linux/wait.h>
 
-/*
- * Overview:
- *
- * Events are subscribed per-filehandle. An event specification consists of a
- * type and is optionally associated with an object identified through the
- * 'id' field. So an event is uniquely identified by the (type, id) tuple.
- *
- * The v4l2-fh struct has a list of subscribed events. The v4l2_subscribed_event
- * struct is added to that list, one for every subscribed event.
- *
- * Each v4l2_subscribed_event struct ends with an array of v4l2_kevent structs.
- * This array (ringbuffer, really) is used to store any events raised by the
- * driver. The v4l2_kevent struct links into the 'available' list of the
- * v4l2_fh struct so VIDIOC_DQEVENT will know which event to dequeue first.
- *
- * Finally, if the event subscription is associated with a particular object
- * such as a V4L2 control, then that object needs to know about that as well
- * so that an event can be raised by that object. So the 'node' field can
- * be used to link the v4l2_subscribed_event struct into a list of that
- * object.
- *
- * So to summarize:
- *
- * struct v4l2_fh has two lists: one of the subscribed events, and one of the
- * pending events.
- *
- * struct v4l2_subscribed_event has a ringbuffer of raised (pending) events of

include/media/v4l2-event.h line 29

Quoted 10 lines
include/media/v4l2-event.h +0 -7
- * that particular type.
- *
- * If struct v4l2_subscribed_event is associated with a specific object, then
- * that object will have an internal list of struct v4l2_subscribed_event so
- * it knows who subscribed an event to that object.
- */
-
 struct v4l2_fh;
 struct v4l2_subdev;
 struct v4l2_subscribed_event;

Regards,

Hans

#23 lore raw

PATCH v2 8/17 media: v4l2-ioctl.h: convert debug macros into enum and document

In reply to Mauro Carvalho Chehab

Currently, there's no way to document #define foo <value> with kernel-doc. So, convert it to an enum, and document.

---
 include/media/v4l2-ioctl.h | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)
include/media/v4l2-ioctl.h +19 -14
index bd5312118013..136e2cffcf9e 100644
@@ -588,20 +588,25 @@ struct v4l2_ioctl_ops {
 };
 
 
-/* v4l debugging and diagnostics */
-
-/* Device debug flags to be used with the video device debug attribute */
-
-/* Just log the ioctl name + error code */
-#define V4L2_DEV_DEBUG_IOCTL		0x01
-/* Log the ioctl name arguments + error code */
-#define V4L2_DEV_DEBUG_IOCTL_ARG	0x02
-/* Log the file operations open, release, mmap and get_unmapped_area */
-#define V4L2_DEV_DEBUG_FOP		0x04
-/* Log the read and write file operations and the VIDIOC_(D)QBUF ioctls */
-#define V4L2_DEV_DEBUG_STREAMING	0x08
-/* Log poll() */
-#define V4L2_DEV_DEBUG_POLL		0x10
+/**
+ * enum v4l2_debug_flags - Device debug flags to be used with the video
+ *	device debug attribute
+ *
+ * @V4L2_DEV_DEBUG_IOCTL:	Just log the ioctl name + error code.
+ * @V4L2_DEV_DEBUG_IOCTL_ARG:	Log the ioctl name arguments + error code.
+ * @V4L2_DEV_DEBUG_FOP:		Log the file operations and open, release,
+ *				mmap and get_unmapped_area syscalls.
+ * @V4L2_DEV_DEBUG_STREAMING:	Log the read and write syscalls and
+ *				:c:ref:`VIDIOC_[Q|DQ]BUFF <VIDIOC_QBUF>` ioctls.
+ * @V4L2_DEV_DEBUG_POLL:	Log poll syscalls.
+ */
+enum v4l2_debug_flags {
+	V4L2_DEV_DEBUG_IOCTL		= 0x01,
+	V4L2_DEV_DEBUG_IOCTL_ARG	= 0x02,
+	V4L2_DEV_DEBUG_FOP		= 0x04,
+	V4L2_DEV_DEBUG_STREAMING	= 0x08,
+	V4L2_DEV_DEBUG_POLL		= 0x10,
+};
 
 /*  Video standard functions  */
 
Signature · 1 line
2.13.5
maintainer
#24 lore raw

Re: [PATCH v2 08/17] media: v4l2-ioctl.h: convert debug macros into enum and document

Hi Mauro,

Thank you for the patch.

Quoted 2 lines · On Thursday, 28 September 2017 00:46:51 EEST Mauro Carvalho Chehab wrote:

Currently, there's no way to document #define foo <value> with kernel-doc. So, convert it to an enum, and document.

The documentation seems fine to me (except for one comment below). However, converting macros to an enum just to work around a defect of the documentation system doesn't seem like a good idea to me. I'd rather find a way to document macros.

Quoted 27 lines
---
 include/media/v4l2-ioctl.h | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)
include/media/v4l2-ioctl.h +0 -14
index bd5312118013..136e2cffcf9e 100644
@@ -588,20 +588,25 @@ struct v4l2_ioctl_ops {
 };
 
 
-/* v4l debugging and diagnostics */
-
-/* Device debug flags to be used with the video device debug attribute */
-
-/* Just log the ioctl name + error code */
-#define V4L2_DEV_DEBUG_IOCTL		0x01
-/* Log the ioctl name arguments + error code */
-#define V4L2_DEV_DEBUG_IOCTL_ARG	0x02
-/* Log the file operations open, release, mmap and get_unmapped_area */
-#define V4L2_DEV_DEBUG_FOP		0x04
-/* Log the read and write file operations and the VIDIOC_(D)QBUF ioctls */
-#define V4L2_DEV_DEBUG_STREAMING	0x08
-/* Log poll() */
-#define V4L2_DEV_DEBUG_POLL		0x10

include/media/v4l2-ioctl.h struct v4l2_ioctl_ops { · line 600

Quoted 10 lines
include/media/v4l2-ioctl.h +10 -0
+/**
+ * enum v4l2_debug_flags - Device debug flags to be used with the video
+ *	device debug attribute
+ *
+ * @V4L2_DEV_DEBUG_IOCTL:	Just log the ioctl name + error code.
+ * @V4L2_DEV_DEBUG_IOCTL_ARG:	Log the ioctl name arguments + error code.
+ * @V4L2_DEV_DEBUG_FOP:		Log the file operations and open, release,
+ *				mmap and get_unmapped_area syscalls.
+ * @V4L2_DEV_DEBUG_STREAMING:	Log the read and write syscalls and
+ *				:c:ref:`VIDIOC_[Q|DQ]BUFF <VIDIOC_QBUF>` ioctls.

s/BUFF/BUF.

A regexp would use VIDIOC_(Q|DQ)BUF. You can also write VIDIOC_{QBUF,DQBUF} which seems clearer to me.

Quoted 11 lines
include/media/v4l2-ioctl.h +9 -0
+ * @V4L2_DEV_DEBUG_POLL:	Log poll syscalls.
+ */
+enum v4l2_debug_flags {
+	V4L2_DEV_DEBUG_IOCTL		= 0x01,
+	V4L2_DEV_DEBUG_IOCTL_ARG	= 0x02,
+	V4L2_DEV_DEBUG_FOP		= 0x04,
+	V4L2_DEV_DEBUG_STREAMING	= 0x08,
+	V4L2_DEV_DEBUG_POLL		= 0x10,
+};
 
 /*  Video standard functions  */
Signature · 3 lines
Regards,

Laurent Pinchart
#25 lore raw

Re: [PATCH v2 08/17] media: v4l2-ioctl.h: convert debug macros into enum and document

Em Fri, 13 Oct 2017 15:38:11 +0300
Laurent Pinchart <[email protected]> escreveu:

Quoted 4 lines

Hi Mauro,

Thank you for the patch.

Quoted 8 lines
Quoted 2 lines · On Thursday, 28 September 2017 00:46:51 EEST Mauro Carvalho Chehab wrote:

Currently, there's no way to document #define foo <value> with kernel-doc. So, convert it to an enum, and document.

The documentation seems fine to me (except for one comment below). However, converting macros to an enum just to work around a defect of the documentation system doesn't seem like a good idea to me. I'd rather find a way to document macros.

I agree that this limitation should be fixed.

Yet, in this specific case where we have an "array" of defines, all associated to the same field (even being a bitmask), and assuming that we would add a way for kernel-doc to parse this kind of defines (not sure how easy/doable would be), then, in order to respect the way kernel-doc markup is, the documentation for those macros would be:

/**
* define: Just log the ioctl name + error code
*/
#define V4L2_DEV_DEBUG_IOCTL 0x01
/**
* define: Log the ioctl name arguments + error code
*/
#define V4L2_DEV_DEBUG_IOCTL_ARG 0x02
/**
* define: Log the file operations open, release, mmap and get_unmapped_area */
#define V4L2_DEV_DEBUG_FOP 0x04
/**
* define: Log the read and write file operations and the VIDIOC_(D)QBUF ioctls */
#define V4L2_DEV_DEBUG_STREAMING 0x08

IMHO, this is a way easier to read/understand by humans, and a way more coincise:

/**
* enum v4l2_debug_flags - Device debug flags to be used with the video
* device debug attribute
*
* @V4L2_DEV_DEBUG_IOCTL: Just log the ioctl name + error code.
* @V4L2_DEV_DEBUG_IOCTL_ARG: Log the ioctl name arguments + error code.
* @V4L2_DEV_DEBUG_FOP: Log the file operations and open, release,
* mmap and get_unmapped_area syscalls.
* @V4L2_DEV_DEBUG_STREAMING: Log the read and write syscalls and
* :c:ref:VIDIOC_[Q|DQ]BUFF <VIDIOC_QBUF> ioctls.
*/

It also underlines the aspect that those names are grouped altogether.

So, IMHO, the main reason to place them inside an enum and document as such is that it looks a way better for humans to read.

Thanks,
Mauro

maintainer
#26 lore raw

Re: [PATCH v2 08/17] media: v4l2-ioctl.h: convert debug macros into enum and document

Hi Mauro,

Quoted 51 lines · On Monday, 18 December 2017 17:13:26 EET Mauro Carvalho Chehab wrote:

Em Fri, 13 Oct 2017 15:38:11 +0300 Laurent Pinchart escreveu:

Quoted 8 lines · On Thursday, 28 September 2017 00:46:51 EEST Mauro Carvalho Chehab wrote:
Quoted 2 lines

Currently, there's no way to document #define foo <value> with kernel-doc. So, convert it to an enum, and document.

The documentation seems fine to me (except for one comment below). However, converting macros to an enum just to work around a defect of the documentation system doesn't seem like a good idea to me. I'd rather find a way to document macros.

I agree that this limitation should be fixed.

Yet, in this specific case where we have an "array" of defines, all associated to the same field (even being a bitmask), and assuming that we would add a way for kernel-doc to parse this kind of defines (not sure how easy/doable would be), then, in order to respect the way kernel-doc markup is, the documentation for those macros would be:

/**
* define: Just log the ioctl name + error code
*/
#define V4L2_DEV_DEBUG_IOCTL 0x01
/**
* define: Log the ioctl name arguments + error code
*/
#define V4L2_DEV_DEBUG_IOCTL_ARG 0x02
/**
* define: Log the file operations open, release, mmap and get_unmapped_area
*/
#define V4L2_DEV_DEBUG_FOP 0x04
/**
* define: Log the read and write file operations and the VIDIOC_(D)QBUF
ioctls */
#define V4L2_DEV_DEBUG_STREAMING 0x08

IMHO, this is a way easier to read/understand by humans, and a way more coincise:

/**
* enum v4l2_debug_flags - Device debug flags to be used with the video
* device debug attribute
*
* @V4L2_DEV_DEBUG_IOCTL: Just log the ioctl name + error code.
* @V4L2_DEV_DEBUG_IOCTL_ARG: Log the ioctl name arguments + error code.
* @V4L2_DEV_DEBUG_FOP: Log the file operations and open, release,
* mmap and get_unmapped_area syscalls.
* @V4L2_DEV_DEBUG_STREAMING: Log the read and write syscalls and
* :c:ref:VIDIOC_[Q|DQ]BUFF <VIDIOC_QBUF> ioctls.
*/

Quoted 4 lines

It also underlines the aspect that those names are grouped altogether.

So, IMHO, the main reason to place them inside an enum and document as such is that it looks a way better for humans to read.

As we're talking about extending kerneldoc to document macros, we're free to decide on a format that would make it easy and clear. Based on your above example, we could write it

/**
* define v4l2_debug_flags - Device debug flags to be used with the video
* device debug attribute
*
* @V4L2_DEV_DEBUG_IOCTL: Just log the ioctl name + error code.
* @V4L2_DEV_DEBUG_IOCTL_ARG: Log the ioctl name arguments + error code.
* @V4L2_DEV_DEBUG_FOP: Log the file operations and open, release,
* mmap and get_unmapped_area syscalls.
* @V4L2_DEV_DEBUG_STREAMING: Log the read and write syscalls and
* :c:ref:VIDIOC_[Q|DQ]BUFF <VIDIOC_QBUF> ioctls.
*/

That would be simple, clear, and wouldn't require a code change to workaround a limitation of the documentation system.

Signature · 3 lines
Regards,

Laurent Pinchart
#27 lore raw

Re: [PATCH v2 08/17] media: v4l2-ioctl.h: convert debug macros into enum and document

Em Mon, 18 Dec 2017 17:32:11 +0200
Laurent Pinchart <[email protected]> escreveu:

Quoted 75 lines

Hi Mauro,

Quoted 51 lines · On Monday, 18 December 2017 17:13:26 EET Mauro Carvalho Chehab wrote:

Em Fri, 13 Oct 2017 15:38:11 +0300 Laurent Pinchart escreveu:

Quoted 8 lines · On Thursday, 28 September 2017 00:46:51 EEST Mauro Carvalho Chehab wrote:
Quoted 2 lines

Currently, there's no way to document #define foo <value> with kernel-doc. So, convert it to an enum, and document.

The documentation seems fine to me (except for one comment below). However, converting macros to an enum just to work around a defect of the documentation system doesn't seem like a good idea to me. I'd rather find a way to document macros.

I agree that this limitation should be fixed.

Yet, in this specific case where we have an "array" of defines, all associated to the same field (even being a bitmask), and assuming that we would add a way for kernel-doc to parse this kind of defines (not sure how easy/doable would be), then, in order to respect the way kernel-doc markup is, the documentation for those macros would be:

/**
* define: Just log the ioctl name + error code
*/
#define V4L2_DEV_DEBUG_IOCTL 0x01
/**
* define: Log the ioctl name arguments + error code
*/
#define V4L2_DEV_DEBUG_IOCTL_ARG 0x02
/**
* define: Log the file operations open, release, mmap and get_unmapped_area
*/
#define V4L2_DEV_DEBUG_FOP 0x04
/**
* define: Log the read and write file operations and the VIDIOC_(D)QBUF
ioctls */
#define V4L2_DEV_DEBUG_STREAMING 0x08

IMHO, this is a way easier to read/understand by humans, and a way more coincise:

/**
* enum v4l2_debug_flags - Device debug flags to be used with the video
* device debug attribute
*
* @V4L2_DEV_DEBUG_IOCTL: Just log the ioctl name + error code.
* @V4L2_DEV_DEBUG_IOCTL_ARG: Log the ioctl name arguments + error code.
* @V4L2_DEV_DEBUG_FOP: Log the file operations and open, release,
* mmap and get_unmapped_area syscalls.
* @V4L2_DEV_DEBUG_STREAMING: Log the read and write syscalls and
* :c:ref:VIDIOC_[Q|DQ]BUFF <VIDIOC_QBUF> ioctls.
*/

Quoted 4 lines

It also underlines the aspect that those names are grouped altogether.

So, IMHO, the main reason to place them inside an enum and document as such is that it looks a way better for humans to read.

As we're talking about extending kerneldoc to document macros, we're free to decide on a format that would make it easy and clear. Based on your above example, we could write it

/**
* define v4l2_debug_flags - Device debug flags to be used with the video
* device debug attribute
*
* @V4L2_DEV_DEBUG_IOCTL: Just log the ioctl name + error code.
* @V4L2_DEV_DEBUG_IOCTL_ARG: Log the ioctl name arguments + error code.
* @V4L2_DEV_DEBUG_FOP: Log the file operations and open, release,
* mmap and get_unmapped_area syscalls.
* @V4L2_DEV_DEBUG_STREAMING: Log the read and write syscalls and
* :c:ref:VIDIOC_[Q|DQ]BUFF <VIDIOC_QBUF> ioctls.
*/

Quoted 2 lines

That would be simple, clear, and wouldn't require a code change to workaround a limitation of the documentation system.

That works for me but that would be against the way other things are parsed by kernel-doc.

Besides that, I suspect that a patchset adding support for it at kernel-doc will be painful, as it currently assumes that a

	 /**
	  * ...
	  */

markup refers just to the first non-blank line just below it. So, such patch will likely need to add a hack in order to support it, but I may be wrong.

I guess we'll end by needing support for #define foo bar type of defines some day.

Anyway, I suspect that, for those debug macros, the best is to change it to an enum of bits. I sent a proposal with such approach:

	https://patchwork.linuxtv.org/patch/46092/

Thanks,
Mauro

Acked-by on v2 8/17
#28 lore raw

Re: [PATCH v2 08/17] media: v4l2-ioctl.h: convert debug macros into enum and document

In reply to Mauro Carvalho Chehab
Quoted 4 lines · Mauro Carvalho Chehab

Currently, there's no way to document #define foo <value> with kernel-doc. So, convert it to an enum, and document.

Thanks,

Hans

Quoted 49 lines
---
 include/media/v4l2-ioctl.h | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)
include/media/v4l2-ioctl.h +19 -14
index bd5312118013..136e2cffcf9e 100644
@@ -588,20 +588,25 @@ struct v4l2_ioctl_ops {
 };
 
 
-/* v4l debugging and diagnostics */
-
-/* Device debug flags to be used with the video device debug attribute */
-
-/* Just log the ioctl name + error code */
-#define V4L2_DEV_DEBUG_IOCTL		0x01
-/* Log the ioctl name arguments + error code */
-#define V4L2_DEV_DEBUG_IOCTL_ARG	0x02
-/* Log the file operations open, release, mmap and get_unmapped_area */
-#define V4L2_DEV_DEBUG_FOP		0x04
-/* Log the read and write file operations and the VIDIOC_(D)QBUF ioctls */
-#define V4L2_DEV_DEBUG_STREAMING	0x08
-/* Log poll() */
-#define V4L2_DEV_DEBUG_POLL		0x10
+/**
+ * enum v4l2_debug_flags - Device debug flags to be used with the video
+ *	device debug attribute
+ *
+ * @V4L2_DEV_DEBUG_IOCTL:	Just log the ioctl name + error code.
+ * @V4L2_DEV_DEBUG_IOCTL_ARG:	Log the ioctl name arguments + error code.
+ * @V4L2_DEV_DEBUG_FOP:		Log the file operations and open, release,
+ *				mmap and get_unmapped_area syscalls.
+ * @V4L2_DEV_DEBUG_STREAMING:	Log the read and write syscalls and
+ *				:c:ref:`VIDIOC_[Q|DQ]BUFF <VIDIOC_QBUF>` ioctls.
+ * @V4L2_DEV_DEBUG_POLL:	Log poll syscalls.
+ */
+enum v4l2_debug_flags {
+	V4L2_DEV_DEBUG_IOCTL		= 0x01,
+	V4L2_DEV_DEBUG_IOCTL_ARG	= 0x02,
+	V4L2_DEV_DEBUG_FOP		= 0x04,
+	V4L2_DEV_DEBUG_STREAMING	= 0x08,
+	V4L2_DEV_DEBUG_POLL		= 0x10,
+};
 
 /*  Video standard functions  */
 
#29 lore raw

PATCH v2 9/17 media: cec-pin.h: convert comments for cec_pin_state into kernel-doc

In reply to Mauro Carvalho Chehab

This enum is already documented, but it is not using a kernel-doc format. Convert its format, in order to produce documentation.

---
 include/media/cec-pin.h | 81 +++++++++++++++++++++++++++++++------------------
 1 file changed, 52 insertions(+), 29 deletions(-)
include/media/cec-pin.h +52 -29
index f09cc9579d53..fbe8c256820e 100644
@@ -24,65 +24,88 @@
 #include <linux/atomic.h>
 #include <media/cec.h>
 
+/**
+ * enum cec_pin_state - state of CEC pins
+ * @CEC_ST_OFF:
+ *	CEC is off
+ * @CEC_ST_IDLE:
+ *	CEC is idle, waiting for Rx or Tx
+ * @CEC_ST_TX_WAIT:
+ *	Pending Tx, waiting for Signal Free Time to expire
+ * @CEC_ST_TX_WAIT_FOR_HIGH:
+ *	Low-drive was detected, wait for bus to go high
+ * @CEC_ST_TX_START_BIT_LOW:
+ *	Drive CEC low for the start bit
+ * @CEC_ST_TX_START_BIT_HIGH:
+ *	Drive CEC high for the start bit
+ * @CEC_ST_TX_DATA_BIT_0_LOW:
+ *	Drive CEC low for the 0 bit
+ * @CEC_ST_TX_DATA_BIT_0_HIGH:
+ *	Drive CEC high for the 0 bit
+ * @CEC_ST_TX_DATA_BIT_1_LOW:
+ *	Drive CEC low for the 1 bit
+ * @CEC_ST_TX_DATA_BIT_1_HIGH:
+ *	Drive CEC high for the 1 bit
+ * @CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE:
+ *	Wait for start of sample time to check for Ack bit or first
+ *	four initiator bits to check for Arbitration Lost.
+ * @CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE:
+ *	Wait for end of bit period after sampling
+ * @CEC_ST_RX_START_BIT_LOW:
+ *	Start bit low detected
+ * @CEC_ST_RX_START_BIT_HIGH:
+ *	Start bit high detected
+ * @CEC_ST_RX_DATA_SAMPLE:
+ *	Wait for bit sample time
+ * @CEC_ST_RX_DATA_POST_SAMPLE:
+ *	Wait for earliest end of bit period after sampling
+ * @CEC_ST_RX_DATA_HIGH:
+ *	Wait for CEC to go high (i.e. end of bit period
+ * @CEC_ST_RX_ACK_LOW:
+ *	Drive CEC low to send 0 Ack bit
+ * @CEC_ST_RX_ACK_LOW_POST:
+ *	End of 0 Ack time, wait for earliest end of bit period
+ * @CEC_ST_RX_ACK_HIGH_POST:
+ *	Wait for CEC to go high (i.e. end of bit period
+ * @CEC_ST_RX_ACK_FINISH:
+ *	Wait for earliest end of bit period and end of message
+ * @CEC_ST_LOW_DRIVE:
+ *	Start low drive
+ * @CEC_ST_RX_IRQ:
+ *	Monitor pin using interrupts
+ * @CEC_PIN_STATES:
+ *	Total number of pin states
+ */
 enum cec_pin_state {
-	/* CEC is off */
 	CEC_ST_OFF,
-	/* CEC is idle, waiting for Rx or Tx */
 	CEC_ST_IDLE,
 
 	/* Tx states */
-
-	/* Pending Tx, waiting for Signal Free Time to expire */
 	CEC_ST_TX_WAIT,
-	/* Low-drive was detected, wait for bus to go high */
 	CEC_ST_TX_WAIT_FOR_HIGH,
-	/* Drive CEC low for the start bit */
 	CEC_ST_TX_START_BIT_LOW,
-	/* Drive CEC high for the start bit */
 	CEC_ST_TX_START_BIT_HIGH,
-	/* Drive CEC low for the 0 bit */
 	CEC_ST_TX_DATA_BIT_0_LOW,
-	/* Drive CEC high for the 0 bit */
 	CEC_ST_TX_DATA_BIT_0_HIGH,
-	/* Drive CEC low for the 1 bit */
 	CEC_ST_TX_DATA_BIT_1_LOW,
-	/* Drive CEC high for the 1 bit */
 	CEC_ST_TX_DATA_BIT_1_HIGH,
-	/*
-	 * Wait for start of sample time to check for Ack bit or first
-	 * four initiator bits to check for Arbitration Lost.
-	 */
 	CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
-	/* Wait for end of bit period after sampling */
 	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
 
 	/* Rx states */
-
-	/* Start bit low detected */
 	CEC_ST_RX_START_BIT_LOW,
-	/* Start bit high detected */
 	CEC_ST_RX_START_BIT_HIGH,
-	/* Wait for bit sample time */
 	CEC_ST_RX_DATA_SAMPLE,
-	/* Wait for earliest end of bit period after sampling */
 	CEC_ST_RX_DATA_POST_SAMPLE,
-	/* Wait for CEC to go high (i.e. end of bit period */
 	CEC_ST_RX_DATA_HIGH,
-	/* Drive CEC low to send 0 Ack bit */
 	CEC_ST_RX_ACK_LOW,
-	/* End of 0 Ack time, wait for earliest end of bit period */
 	CEC_ST_RX_ACK_LOW_POST,
-	/* Wait for CEC to go high (i.e. end of bit period */
 	CEC_ST_RX_ACK_HIGH_POST,
-	/* Wait for earliest end of bit period and end of message */
 	CEC_ST_RX_ACK_FINISH,
 
-	/* Start low drive */
 	CEC_ST_LOW_DRIVE,
-	/* Monitor pin using interrupts */
 	CEC_ST_RX_IRQ,
 
-	/* Total number of pin states */
 	CEC_PIN_STATES
 };
 
Signature · 1 line
2.13.5
#30 lore raw

Re: [PATCH v2 09/17] media: cec-pin.h: convert comments for cec_pin_state into kernel-doc

Quoted 4 lines · Mauro Carvalho Chehab

This enum is already documented, but it is not using a kernel-doc format. Convert its format, in order to produce documentation.

No, this does not belong in the kernel API doc. It is really just an internal API.

The only things that belong in this header are the two function prototypes and struct cec-pin_ops. Everything else should be moved to a cec-pin-priv.h header inside drivers/media/cec.

If it is OK with you, then I'll take care of that.

Regards,

Hans

Quoted 127 lines
---
 include/media/cec-pin.h | 81 +++++++++++++++++++++++++++++++------------------
 1 file changed, 52 insertions(+), 29 deletions(-)
include/media/cec-pin.h +52 -29
index f09cc9579d53..fbe8c256820e 100644
@@ -24,65 +24,88 @@
 #include <linux/atomic.h>
 #include <media/cec.h>
 
+/**
+ * enum cec_pin_state - state of CEC pins
+ * @CEC_ST_OFF:
+ *	CEC is off
+ * @CEC_ST_IDLE:
+ *	CEC is idle, waiting for Rx or Tx
+ * @CEC_ST_TX_WAIT:
+ *	Pending Tx, waiting for Signal Free Time to expire
+ * @CEC_ST_TX_WAIT_FOR_HIGH:
+ *	Low-drive was detected, wait for bus to go high
+ * @CEC_ST_TX_START_BIT_LOW:
+ *	Drive CEC low for the start bit
+ * @CEC_ST_TX_START_BIT_HIGH:
+ *	Drive CEC high for the start bit
+ * @CEC_ST_TX_DATA_BIT_0_LOW:
+ *	Drive CEC low for the 0 bit
+ * @CEC_ST_TX_DATA_BIT_0_HIGH:
+ *	Drive CEC high for the 0 bit
+ * @CEC_ST_TX_DATA_BIT_1_LOW:
+ *	Drive CEC low for the 1 bit
+ * @CEC_ST_TX_DATA_BIT_1_HIGH:
+ *	Drive CEC high for the 1 bit
+ * @CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE:
+ *	Wait for start of sample time to check for Ack bit or first
+ *	four initiator bits to check for Arbitration Lost.
+ * @CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE:
+ *	Wait for end of bit period after sampling
+ * @CEC_ST_RX_START_BIT_LOW:
+ *	Start bit low detected
+ * @CEC_ST_RX_START_BIT_HIGH:
+ *	Start bit high detected
+ * @CEC_ST_RX_DATA_SAMPLE:
+ *	Wait for bit sample time
+ * @CEC_ST_RX_DATA_POST_SAMPLE:
+ *	Wait for earliest end of bit period after sampling
+ * @CEC_ST_RX_DATA_HIGH:
+ *	Wait for CEC to go high (i.e. end of bit period
+ * @CEC_ST_RX_ACK_LOW:
+ *	Drive CEC low to send 0 Ack bit
+ * @CEC_ST_RX_ACK_LOW_POST:
+ *	End of 0 Ack time, wait for earliest end of bit period
+ * @CEC_ST_RX_ACK_HIGH_POST:
+ *	Wait for CEC to go high (i.e. end of bit period
+ * @CEC_ST_RX_ACK_FINISH:
+ *	Wait for earliest end of bit period and end of message
+ * @CEC_ST_LOW_DRIVE:
+ *	Start low drive
+ * @CEC_ST_RX_IRQ:
+ *	Monitor pin using interrupts
+ * @CEC_PIN_STATES:
+ *	Total number of pin states
+ */
 enum cec_pin_state {
-	/* CEC is off */
 	CEC_ST_OFF,
-	/* CEC is idle, waiting for Rx or Tx */
 	CEC_ST_IDLE,
 
 	/* Tx states */
-
-	/* Pending Tx, waiting for Signal Free Time to expire */
 	CEC_ST_TX_WAIT,
-	/* Low-drive was detected, wait for bus to go high */
 	CEC_ST_TX_WAIT_FOR_HIGH,
-	/* Drive CEC low for the start bit */
 	CEC_ST_TX_START_BIT_LOW,
-	/* Drive CEC high for the start bit */
 	CEC_ST_TX_START_BIT_HIGH,
-	/* Drive CEC low for the 0 bit */
 	CEC_ST_TX_DATA_BIT_0_LOW,
-	/* Drive CEC high for the 0 bit */
 	CEC_ST_TX_DATA_BIT_0_HIGH,
-	/* Drive CEC low for the 1 bit */
 	CEC_ST_TX_DATA_BIT_1_LOW,
-	/* Drive CEC high for the 1 bit */
 	CEC_ST_TX_DATA_BIT_1_HIGH,
-	/*
-	 * Wait for start of sample time to check for Ack bit or first
-	 * four initiator bits to check for Arbitration Lost.
-	 */
 	CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
-	/* Wait for end of bit period after sampling */
 	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
 
 	/* Rx states */
-
-	/* Start bit low detected */
 	CEC_ST_RX_START_BIT_LOW,
-	/* Start bit high detected */
 	CEC_ST_RX_START_BIT_HIGH,
-	/* Wait for bit sample time */
 	CEC_ST_RX_DATA_SAMPLE,
-	/* Wait for earliest end of bit period after sampling */
 	CEC_ST_RX_DATA_POST_SAMPLE,
-	/* Wait for CEC to go high (i.e. end of bit period */
 	CEC_ST_RX_DATA_HIGH,
-	/* Drive CEC low to send 0 Ack bit */
 	CEC_ST_RX_ACK_LOW,
-	/* End of 0 Ack time, wait for earliest end of bit period */
 	CEC_ST_RX_ACK_LOW_POST,
-	/* Wait for CEC to go high (i.e. end of bit period */
 	CEC_ST_RX_ACK_HIGH_POST,
-	/* Wait for earliest end of bit period and end of message */
 	CEC_ST_RX_ACK_FINISH,
 
-	/* Start low drive */
 	CEC_ST_LOW_DRIVE,
-	/* Monitor pin using interrupts */
 	CEC_ST_RX_IRQ,
 
-	/* Total number of pin states */
 	CEC_PIN_STATES
 };
 
#31 lore raw

Re: [PATCH v2 09/17] media: cec-pin.h: convert comments for cec_pin_state into kernel-doc

Em Fri, 13 Oct 2017 17:48:21 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 12 lines · Mauro Carvalho Chehab
Quoted 4 lines

This enum is already documented, but it is not using a kernel-doc format. Convert its format, in order to produce documentation.

No, this does not belong in the kernel API doc. It is really just an internal API.

The only things that belong in this header are the two function prototypes and struct cec-pin_ops. Everything else should be moved to a cec-pin-priv.h header inside drivers/media/cec.

Ok. So, let's move the remaining stuff to cec-pin-priv.h.

Quoted 2 lines

If it is OK with you, then I'll take care of that.

Yeah, sure!

Regards,
Mauro

#32 lore raw

PATCH v2 10/17 media: rc-core.rst: add an introduction for RC core

In reply to Mauro Carvalho Chehab

The RC core does several assumptions, but those aren't documented anywhere, with could make harder for ones that want to understand what's there.

So, add an introduction explaining the basic concepts of RC and how they're related to the RC core implementation.

---
 Documentation/media/kapi/rc-core.rst | 77 ++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)
Documentation/media/kapi/rc-core.rst +77 -0
index a45895886257..355c8ea3ad9f 100644
@@ -4,6 +4,83 @@ Remote Controller devices
 Remote Controller core
 ~~~~~~~~~~~~~~~~~~~~~~
 
+The remote controller core implements infrastructure to receive and send
+remote controller keyboard keystrokes and mouse events.
+
+Every time a key is pressed on a remote controller, a scan code is produced.
+Also, on most hardware, keeping a key pressed for more than a few dozens of
+milliseconds produce a repeat key event. That's somewhat similar to what
+a normal keyboard or mouse is handled internally on Linux\ [#f1]_. So, the
+remote controller core is implemented on the top of the linux input/evdev
+interface.
+
+.. [#f1]
+
+   The main difference is that, on keyboard events, the keyboard controller
+   produces one event for a key press and another one for key release. On
+   infrared-based remote controllers, there's no key release event. Instead,
+   an extra code is produced to indicate key repeats.
+
+However, most of the remote controllers use infrared (IR) to transmit signals.
+As there are several protocols used to modulate infrared signals, one
+important part of the core is dedicated to adjust the driver and the core
+system to support the infrared protocol used by the emitter.
+
+The infrared transmission is done by blinking a infrared emitter using a
+carrier. The carrier can be switched on or off by the IR transmitter
+hardware. When the carrier is switched on, it is called *PULSE*.
+When the carrier is switched off, it is called *SPACE*.
+
+In other words, a typical IR transmission can be thinking on a sequence of
+*PULSE* and *SPACE* events, each with a given duration.
+
+The carrier parameters (frequency, duty cycle) and the intervals for
+*PULSE* and *SPACE* events depend on the protocol.
+For example, the NEC protocol uses a carrier of 38kHz, and transmissions
+start with a 9ms *PULSE* and a 4.5ms SPACE. It then transmits 16 bits of
+scan code, being 8 bits for address (usually it is a fixed number for a
+given remote controller), followed by 8 bits of code. A bit "1" is modulated
+with 560µs *PULSE* followed by 1690µs *SPACE* and a bit "0"  is modulated
+with 560µs *PULSE* followed by 560µs *SPACE*.
+
+At receiver, a simple low-pass filter can be used to convert the received
+signal in a sequence of *PULSE/SPACE* events, filtering out the carrier
+frequency. Due to that, the receiver doesn't care about the carrier's
+actual frequency parameters: all it has to do is to measure the amount
+of time it receives *PULSE/SPACE* events.
+So, a simple IR receiver hardware will just provide a sequence of timings
+for those events to the Kernel. The drivers for hardware with such kind of
+receivers are identified by  ``RC_DRIVER_IR_RAW``, as defined by
+:c:type:`rc_driver_type`\ [#f2]_. Other hardware come with a
+microcontroller that decode the *PULSE/SPACE* sequence and return scan
+codes to the Kernel. Such kind of receivers are identified
+by ``RC_DRIVER_SCANCODE``.
+
+.. [#f2]
+
+   The RC core also supports devices that have just IR emitters,
+   without any receivers. Right now, all such devices work only in
+   raw TX mode. Such kind of hardware is identified as
+   ``RC_DRIVER_IR_RAW_TX``.
+
+When the RC core receives events produced by ``RC_DRIVER_IR_RAW`` IR
+receivers, it needs to decode the IR protocol, in order to obtain the
+corresponding scan code. The protocols supported by the RC core are
+defined at enum :c:type:`rc_proto`.
+
+When the RC code receives a scan code (either directly, by a driver
+of the type ``RC_DRIVER_SCANCODE``, or via its IR decoders), it needs
+to convert into a Linux input event code. This is done via a mapping
+table.
+
+The Kernel has support for mapping tables available on most media
+devices. It also supports loading a table in runtime, via some
+sysfs nodes. See the :ref:`RC userspace API <Remote_controllers_Intro>`
+for more details.
+
+Remote controller data structures and functions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 .. kernel-doc:: include/media/rc-core.h
 
 .. kernel-doc:: include/media/rc-map.h
Signature · 1 line
2.13.5
#33 lore raw

PATCH v2 11/17 media: rc-core.h: minor adjustments at rc_driver_type doc

In reply to Mauro Carvalho Chehab

The description of this enum doesn't match what it actually represents. Adjust it.

---
 include/media/rc-core.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/media/rc-core.h +2 -2
index 314a1edb6189..a381abe9186e 100644
@@ -30,9 +30,9 @@ do {								\
 } while (0)
 
 /**
- * enum rc_driver_type - type of the RC output
+ * enum rc_driver_type - type of the RC driver.
  *
- * @RC_DRIVER_SCANCODE:	 Driver or hardware generates a scancode
+ * @RC_DRIVER_SCANCODE:	 Driver or hardware generates a scancode.
  * @RC_DRIVER_IR_RAW:	 Driver or hardware generates pulse/space sequences.
  *			 It needs a Infra-Red pulse/space decoder
  * @RC_DRIVER_IR_RAW_TX: Device transmitter only,
Signature · 1 line
2.13.5
#34 lore raw

PATCH v2 12/17 media: v4l2-fwnode.h: better describe bus union at fwnode endpoint struct

In reply to Mauro Carvalho Chehab

Now that kernel-doc handles nested unions, better document the bus union at struct v4l2_fwnode_endpoint.

---
 include/media/v4l2-fwnode.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
include/media/v4l2-fwnode.h +12 -1
index 7adec9851d9e..5f4716f967d0 100644
@@ -79,7 +79,18 @@ struct v4l2_fwnode_bus_mipi_csi1 {
  * struct v4l2_fwnode_endpoint - the endpoint data structure
  * @base: fwnode endpoint of the v4l2_fwnode
  * @bus_type: bus type
- * @bus: bus configuration data structure
+ * @bus: union with bus configuration data structure
+ * @bus.parallel: pointer for &struct v4l2_fwnode_bus_parallel.
+ *		  Used if the bus is parallel.
+ * @bus.mipi_csi1: pointer for &struct v4l2_fwnode_bus_mipi_csi1.
+ *		   Used if the bus is Mobile Industry Processor
+ * 		   Interface's Camera Serial Interface version 1
+ * 		   (MIPI CSI1) or Standard Mobile Imaging Architecture's
+ *		   Compact Camera Port 2 (SMIA CCP2).
+ * @bus.mipi_csi2: pointer for &struct v4l2_fwnode_bus_mipi_csi2.
+ *		   Used if the bus is Mobile Industry Processor
+ * 		   Interface's Camera Serial Interface version 2
+ *		   (MIPI CSI2).
  * @link_frequencies: array of supported link frequencies
  * @nr_of_link_frequencies: number of elements in link_frequenccies array
  */
Signature · 1 line
2.13.5
Acked-by on v2 12/17
#35 lore raw

Re: [PATCH v2 12/17] media: v4l2-fwnode.h: better describe bus union at fwnode endpoint struct

Hi Mauro,

Thanks for the patch.

Quoted 13 lines · Mauro Carvalho Chehab

Now that kernel-doc handles nested unions, better document the bus union at struct v4l2_fwnode_endpoint.

---
 include/media/v4l2-fwnode.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
include/media/v4l2-fwnode.h +0 -0
index 7adec9851d9e..5f4716f967d0 100644

include/media/v4l2-fwnode.h struct v4l2_fwnode_bus_mipi_csi1 { · line 86

Quoted 9 lines
include/media/v4l2-fwnode.h +5 -1
@@ -79,7 +79,18 @@ struct v4l2_fwnode_bus_mipi_csi1 {
  * struct v4l2_fwnode_endpoint - the endpoint data structure
  * @base: fwnode endpoint of the v4l2_fwnode
  * @bus_type: bus type
- * @bus: bus configuration data structure
+ * @bus: union with bus configuration data structure
+ * @bus.parallel: pointer for &struct v4l2_fwnode_bus_parallel.
+ *		  Used if the bus is parallel.
+ * @bus.mipi_csi1: pointer for &struct v4l2_fwnode_bus_mipi_csi1.
+ *		   Used if the bus is Mobile Industry Processor

s/Mobile.*Interface/MIPI Alliance/

Same below.

Please see:

<URL:https://mipi.org/content/what-does-mipi-stand>

With that,

Quoted 10 lines
include/media/v4l2-fwnode.h +7 -0
+ * 		   Interface's Camera Serial Interface version 1
+ * 		   (MIPI CSI1) or Standard Mobile Imaging Architecture's
+ *		   Compact Camera Port 2 (SMIA CCP2).
+ * @bus.mipi_csi2: pointer for &struct v4l2_fwnode_bus_mipi_csi2.
+ *		   Used if the bus is Mobile Industry Processor
+ * 		   Interface's Camera Serial Interface version 2
+ *		   (MIPI CSI2).
  * @link_frequencies: array of supported link frequencies
  * @nr_of_link_frequencies: number of elements in link_frequenccies array
  */
Signature · 4 lines
Regards,

Sakari Ailus
e-mail: [email protected]
maintainer
#36 lore raw

Re: [PATCH v2 12/17] media: v4l2-fwnode.h: better describe bus union at fwnode endpoint struct

In reply to Mauro Carvalho Chehab

Hi Mauro,

Thank you for the patch.

Quoted 19 lines · On Thursday, 28 September 2017 00:46:55 EEST Mauro Carvalho Chehab wrote:

Now that kernel-doc handles nested unions, better document the bus union at struct v4l2_fwnode_endpoint.

---
 include/media/v4l2-fwnode.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
include/media/v4l2-fwnode.h +2 -1
index 7adec9851d9e..5f4716f967d0 100644
@@ -79,7 +79,18 @@ struct v4l2_fwnode_bus_mipi_csi1 {
  * struct v4l2_fwnode_endpoint - the endpoint data structure
  * @base: fwnode endpoint of the v4l2_fwnode
  * @bus_type: bus type
- * @bus: bus configuration data structure
+ * @bus: union with bus configuration data structure
+ * @bus.parallel: pointer for &struct v4l2_fwnode_bus_parallel.

include/media/v4l2-fwnode.h struct v4l2_fwnode_bus_mipi_csi1 { · line 93

Quoted 10 lines
include/media/v4l2-fwnode.h +10 -0
+ *		  Used if the bus is parallel.
+ * @bus.mipi_csi1: pointer for &struct v4l2_fwnode_bus_mipi_csi1.
+ *		   Used if the bus is Mobile Industry Processor
+ * 		   Interface's Camera Serial Interface version 1
+ * 		   (MIPI CSI1) or Standard Mobile Imaging Architecture's
+ *		   Compact Camera Port 2 (SMIA CCP2).
+ * @bus.mipi_csi2: pointer for &struct v4l2_fwnode_bus_mipi_csi2.
+ *		   Used if the bus is Mobile Industry Processor
+ * 		   Interface's Camera Serial Interface version 2
+ *		   (MIPI CSI2).

These are not pointers.

Quoted 3 lines
include/media/v4l2-fwnode.h +0 -0
  * @link_frequencies: array of supported link frequencies
  * @nr_of_link_frequencies: number of elements in link_frequenccies array
  */
Signature · 3 lines
Regards,

Laurent Pinchart
#37 lore raw

PATCH v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

In reply to Mauro Carvalho Chehab

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

That makes easier to document it, as we don't need to document weird senseless structs.

At drivers, this makes even clearer about the match criteria.

---
 drivers/media/platform/am437x/am437x-vpfe.c    | 6 +++---
 drivers/media/platform/atmel/atmel-isc.c       | 2 +-
 drivers/media/platform/atmel/atmel-isi.c       | 2 +-
 drivers/media/platform/davinci/vpif_capture.c  | 4 ++--
 drivers/media/platform/exynos4-is/media-dev.c  | 4 ++--
 drivers/media/platform/omap3isp/isp.c          | 4 ++--
 drivers/media/platform/pxa_camera.c            | 2 +-
 drivers/media/platform/qcom/camss-8x16/camss.c | 2 +-
 drivers/media/platform/rcar-vin/rcar-core.c    | 8 ++++----
 drivers/media/platform/rcar_drif.c             | 4 ++--
 drivers/media/platform/soc_camera/soc_camera.c | 2 +-
 drivers/media/platform/stm32/stm32-dcmi.c      | 2 +-
 drivers/media/platform/ti-vpe/cal.c            | 2 +-
 drivers/media/platform/xilinx/xilinx-vipp.c    | 2 +-
 drivers/media/v4l2-core/v4l2-async.c           | 4 ++--
 drivers/staging/media/imx/imx-media-dev.c      | 8 ++++----
 include/media/v4l2-async.h                     | 8 ++------
 17 files changed, 31 insertions(+), 35 deletions(-)
drivers/media/platform/am437x/am437x-vpfe.c +3 -3
index dfcc484cab89..f87e8f9467e9 100644
@@ -2304,8 +2304,8 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
 	vpfe_dbg(1, vpfe, "vpfe_async_bound\n");
 
 	for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) {
-		if (vpfe->cfg->asd[i]->match.fwnode.fwnode ==
-		    asd[i].match.fwnode.fwnode) {
+		if (vpfe->cfg->asd[i]->match.fwnode ==
+		    asd[i].match.fwnode) {
 			sdinfo = &vpfe->cfg->sub_devs[i];
 			vpfe->sd[i] = subdev;
 			vpfe->sd[i]->grp_id = sdinfo->grp_id;
@@ -2505,7 +2505,7 @@ vpfe_get_pdata(struct platform_device *pdev)
 		}
 
 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);
+		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
 		of_node_put(rem);
 	}
 
drivers/media/platform/atmel/atmel-isc.c +1 -1
index d7103c5f92c3..c04d9a4dbfac 100644
@@ -1742,7 +1742,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 			subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW;
 
 		subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		subdev_entity->asd->match.fwnode.fwnode =
+		subdev_entity->asd->match.fwnode =
 			of_fwnode_handle(rem);
 		list_add_tail(&subdev_entity->list, &isc->subdev_entities);
 	}
drivers/media/platform/atmel/atmel-isi.c +1 -1
index 891fa2505efa..8c52f9f5f2db 100644
@@ -1124,7 +1124,7 @@ static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
 		/* Remote node to connect */
 		isi->entity.node = remote;
 		isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		isi->entity.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
 		return 0;
 	}
 }
drivers/media/platform/davinci/vpif_capture.c +2 -2
index 0ef36cec21d1..0cf141635cbc 100644
@@ -1390,7 +1390,7 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
 
 	for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
 		struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
-		const struct fwnode_handle *fwnode = _asd->match.fwnode.fwnode;
+		const struct fwnode_handle *fwnode = _asd->match.fwnode;
 
 		if (fwnode == subdev->fwnode) {
 			vpif_obj.sd[i] = subdev;
@@ -1588,7 +1588,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
 		}
 
 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);
+		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
 		of_node_put(rem);
 	}
 
drivers/media/platform/exynos4-is/media-dev.c +2 -2
index d4656d5175d7..d4d97d7e9684 100644
@@ -454,7 +454,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
 	}
 
 	fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-	fmd->sensor[index].asd.match.fwnode.fwnode = of_fwnode_handle(rem);
+	fmd->sensor[index].asd.match.fwnode = of_fwnode_handle(rem);
 	fmd->async_subdevs[index] = &fmd->sensor[index].asd;
 
 	fmd->num_sensors++;
@@ -1361,7 +1361,7 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
 
 	/* Find platform data for this sensor subdev */
 	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
-		if (fmd->sensor[i].asd.match.fwnode.fwnode ==
+		if (fmd->sensor[i].asd.match.fwnode ==
 		    of_fwnode_handle(subdev->dev->of_node))
 			si = &fmd->sensor[i];
 
drivers/media/platform/omap3isp/isp.c +2 -2
index 1a428fe9f070..bbb402a5fcf0 100644
@@ -2170,9 +2170,9 @@ static int isp_fwnodes_parse(struct device *dev,
 
 		notifier->subdevs[notifier->num_subdevs] = &isd->asd;
 
-		isd->asd.match.fwnode.fwnode =
+		isd->asd.match.fwnode =
 			fwnode_graph_get_remote_port_parent(fwnode);
-		if (!isd->asd.match.fwnode.fwnode) {
+		if (!isd->asd.match.fwnode) {
 			dev_warn(dev, "bad remote port parent\n");
 			goto error;
 		}
drivers/media/platform/pxa_camera.c +1 -1
index edca993c2b1f..4a23a60f3418 100644
@@ -2328,7 +2328,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
 	remote = of_graph_get_remote_port(np);
 	if (remote) {
-		asd->match.fwnode.fwnode = of_fwnode_handle(remote);
+		asd->match.fwnode = of_fwnode_handle(remote);
 		of_node_put(remote);
 	} else {
 		dev_notice(dev, "no remote for %pOF\n", np);
drivers/media/platform/qcom/camss-8x16/camss.c +1 -1
index a3760b5dd1d1..7d7bca09473a 100644
@@ -341,7 +341,7 @@ static int camss_of_parse_ports(struct device *dev,
 		}
 
 		csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		csd->asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		csd->asd.match.fwnode = of_fwnode_handle(remote);
 	}
 
 	return notifier->num_subdevs;
drivers/media/platform/rcar-vin/rcar-core.c +4 -4
index 142de447aaaa..3835a2fa0cb7 100644
@@ -171,7 +171,7 @@ static int rvin_digital_graph_parse(struct rvin_dev *vin)
 	struct device_node *ep, *np;
 	int ret;
 
-	vin->digital.asd.match.fwnode.fwnode = NULL;
+	vin->digital.asd.match.fwnode = NULL;
 	vin->digital.subdev = NULL;
 
 	/*
@@ -195,7 +195,7 @@ static int rvin_digital_graph_parse(struct rvin_dev *vin)
 	if (ret)
 		return ret;
 
-	vin->digital.asd.match.fwnode.fwnode = of_fwnode_handle(np);
+	vin->digital.asd.match.fwnode = of_fwnode_handle(np);
 	vin->digital.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 
 	return 0;
@@ -210,7 +210,7 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 	if (ret)
 		return ret;
 
-	if (!vin->digital.asd.match.fwnode.fwnode) {
+	if (!vin->digital.asd.match.fwnode) {
 		vin_dbg(vin, "No digital subdevice found\n");
 		return -ENODEV;
 	}
@@ -223,7 +223,7 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 	subdevs[0] = &vin->digital.asd;
 
 	vin_dbg(vin, "Found digital subdevice %pOF\n",
-		to_of_node(subdevs[0]->match.fwnode.fwnode));
+		to_of_node(subdevs[0]->match.fwnode));
 
 	vin->notifier.num_subdevs = 1;
 	vin->notifier.subdevs = subdevs;
drivers/media/platform/rcar_drif.c +2 -2
index 522364ff0d5d..ae7927305231 100644
@@ -1107,7 +1107,7 @@ static int rcar_drif_notify_bound(struct v4l2_async_notifier *notifier,
 	struct rcar_drif_sdr *sdr =
 		container_of(notifier, struct rcar_drif_sdr, notifier);
 
-	if (sdr->ep.asd.match.fwnode.fwnode !=
+	if (sdr->ep.asd.match.fwnode !=
 	    of_fwnode_handle(subdev->dev->of_node)) {
 		rdrif_err(sdr, "subdev %s cannot bind\n", subdev->name);
 		return -EINVAL;
@@ -1229,7 +1229,7 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
 		return -EINVAL;
 	}
 
-	sdr->ep.asd.match.fwnode.fwnode = fwnode;
+	sdr->ep.asd.match.fwnode = fwnode;
 	sdr->ep.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 	notifier->num_subdevs++;
 
drivers/media/platform/soc_camera/soc_camera.c +1 -1
index 1f3c450c7a69..1bef3ebb49ee 100644
@@ -1513,7 +1513,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
 	if (!info)
 		return -ENOMEM;
 
-	info->sasd.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+	info->sasd.asd.match.fwnode = of_fwnode_handle(remote);
 	info->sasd.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 	info->subdev = &info->sasd.asd;
 
drivers/media/platform/stm32/stm32-dcmi.c +1 -1
index 35ba6f211b79..4c8bd77842f6 100644
@@ -1514,7 +1514,7 @@ static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node)
 		/* Remote node to connect */
 		dcmi->entity.node = remote;
 		dcmi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		dcmi->entity.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		dcmi->entity.asd.match.fwnode = of_fwnode_handle(remote);
 		return 0;
 	}
 }
drivers/media/platform/ti-vpe/cal.c +1 -1
index 42e383a48ffe..7491425eed77 100644
@@ -1700,7 +1700,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
 		goto cleanup_exit;
 	}
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-	asd->match.fwnode.fwnode = of_fwnode_handle(sensor_node);
+	asd->match.fwnode = of_fwnode_handle(sensor_node);
 
 	remote_ep = of_graph_get_remote_endpoint(ep_node);
 	if (!remote_ep) {
drivers/media/platform/xilinx/xilinx-vipp.c +1 -1
index ebfdf334d99c..3fdb0f365538 100644
@@ -390,7 +390,7 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
 
 		entity->node = remote;
 		entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		entity->asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		entity->asd.match.fwnode = of_fwnode_handle(remote);
 		list_add_tail(&entity->list, &xdev->entities);
 		xdev->num_subdevs++;
 	}
drivers/media/v4l2-core/v4l2-async.c +2 -2
index d741a8e0fdac..e087857d02d6 100644
@@ -39,12 +39,12 @@ static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 static bool match_devname(struct v4l2_subdev *sd,
 			  struct v4l2_async_subdev *asd)
 {
-	return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
+	return !strcmp(asd->match.device_name, dev_name(sd->dev));
 }
 
 static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
-	return sd->fwnode == asd->match.fwnode.fwnode;
+	return sd->fwnode == asd->match.fwnode;
 }
 
 static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
drivers/staging/media/imx/imx-media-dev.c +4 -4
index d96f4512224f..858088570684 100644
@@ -48,12 +48,12 @@ imx_media_find_async_subdev(struct imx_media_dev *imxmd,
 		imxsd = &imxmd->subdev[i];
 		switch (imxsd->asd.match_type) {
 		case V4L2_ASYNC_MATCH_FWNODE:
-			if (fwnode && imxsd->asd.match.fwnode.fwnode == fwnode)
+			if (fwnode && imxsd->asd.match.fwnode == fwnode)
 				return imxsd;
 			break;
 		case V4L2_ASYNC_MATCH_DEVNAME:
 			if (devname &&
-			    !strcmp(imxsd->asd.match.device_name.name, devname))
+			    !strcmp(imxsd->asd.match.device_name, devname))
 				return imxsd;
 			break;
 		default:
@@ -108,11 +108,11 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd,
 	asd = &imxsd->asd;
 	if (np) {
 		asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		asd->match.fwnode.fwnode = of_fwnode_handle(np);
+		asd->match.fwnode = of_fwnode_handle(np);
 	} else {
 		asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
 		strncpy(imxsd->devname, devname, sizeof(imxsd->devname));
-		asd->match.device_name.name = imxsd->devname;
+		asd->match.device_name = imxsd->devname;
 		imxsd->pdev = pdev;
 	}
 
include/media/v4l2-async.h +2 -6
index c69d8c8a66d0..e66a3521596f 100644
@@ -54,12 +54,8 @@ enum v4l2_async_match_type {
 struct v4l2_async_subdev {
 	enum v4l2_async_match_type match_type;
 	union {
-		struct {
-			struct fwnode_handle *fwnode;
-		} fwnode;
-		struct {
-			const char *name;
-		} device_name;
+		struct fwnode_handle *fwnode;
+		const char *device_name;
 		struct {
 			int adapter_id;
 			unsigned short address;
Signature · 1 line
2.13.5
Acked-by on v2 13/17
#38 lore raw

Re: [PATCH v2 13/17] media: v4l2-async: simplify v4l2_async_subdev structure

Quoted 7 lines · Mauro Carvalho Chehab

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

Quoted 6 lines

That makes easier to document it, as we don't need to document weird senseless structs.

At drivers, this makes even clearer about the match criteria.

#39 lore raw

PATCH v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

In reply to Mauro Carvalho Chehab

Hi Mauro,

Quoted 9 lines · Mauro Carvalho Chehab

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

That makes easier to document it, as we don't need to document weird senseless structs.

The idea is that in the union, there's a struct which is specific to the match_type field. I wouldn't call it senseless.

In the two cases there's just a single field in the containing struct. You could remove the struct in that case as you do in this patch, and just use the field. But I think the result is less clean and so I wouldn't make this change.

The confusion comes possibly from the fact that the struct is named the same as the field in the struct. These used to be called of and node, but with the fwnode property framework the references to the fwnode are, well, typically similarly called "fwnode". There's no underlying firmware interface with that name, fwnode property API is just an API.

Signature · 4 lines
Kind regards,

Sakari Ailus
e-mail: sakari.ailus at iki.fi
#40 lore raw

PATCH v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

Em Thu, 28 Sep 2017 15:09:21 +0300
Sakari Ailus <[email protected]> escreveu:

Quoted 7 lines

Hi Mauro,

Quoted 4 lines · Mauro Carvalho Chehab

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

Quoted 8 lines
Quoted 5 lines

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

That makes easier to document it, as we don't need to document weird senseless structs.

The idea is that in the union, there's a struct which is specific to the match_type field. I wouldn't call it senseless.

Why a struct for each specific match_type is **needed**? It it is not needed, then it is senseless per definition :-)

In the specific case of fwnode, there's already a named struct for fwnode_handle. The only thing is that it is declared outside enum v4l2_async_match_type. So, I don't see any reason to do things like:

		struct {
			struct fwnode_handle *fwnode;
		} fwnode;

If you're in doubt about that, think on how would you document both fwnode structs. Both fwnode structs specify the match criteria if %V4L2_ASYNC_MATCH_FWNODE.

The same applies to this:

		struct {
			const char *name;
		} device_name;

Both device_name and name specifies the match criteria if %V4L2_ASYNC_MATCH_DEVNAME.

Quoted 5 lines

In the two cases there's just a single field in the containing struct. You could remove the struct in that case as you do in this patch, and just use the field. But I think the result is less clean and so I wouldn't make this change.

It is actually cleaner without the stucts.

Without the useless struct, if one wants to match a firmware node, it should be doing:

 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);

And that' it. For anyone that reads the above code, even not knowing all details of "match", is clear that the match criteria is whatever of_fwnode_handle() returns.

Now, on this:

 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
		pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);

It sounds that something is missing, as only one field of match.fwnode was specified. Anyone not familiar with that non-conventional usage of a struct with just one struct field inside would need to seek for the header file declaring the struct. That would consume a lot of time for code reviewers for no good reason.

The same apply for devname search:

In this case:

		asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
		asd->match.device_name.name = imxsd->devname;

I would be expecting something else to be filled at device_name's struct, for example to specify a case sensitive or case insensitive match criteria, to allow seeking for a device's substring, or to allow using other struct device fields to narrow the seek.

With this:

		asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
		asd->match.device_name = imxsd->devname;

It is clear that the match criteria is fully specified.

Quoted 5 lines

The confusion comes possibly from the fact that the struct is named the same as the field in the struct. These used to be called of and node, but with the fwnode property framework the references to the fwnode are, well, typically similarly called "fwnode". There's no underlying firmware interface with that name, fwnode property API is just an API.

The duplicated "fwnode" name only made it more evident that we don't need to enclose a single match criteria field inside a struct.

Thanks,
Mauro

#41 lore raw

PATCH v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

Hi Mauro,

(Removing the non-list recipients.)

Quoted 50 lines · Mauro Carvalho Chehab

Em Thu, 28 Sep 2017 15:09:21 +0300
Sakari Ailus <[email protected]> escreveu:

Quoted 7 lines

Hi Mauro,

Quoted 4 lines · Mauro Carvalho Chehab

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

Quoted 8 lines
Quoted 5 lines

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

That makes easier to document it, as we don't need to document weird senseless structs.

The idea is that in the union, there's a struct which is specific to the match_type field. I wouldn't call it senseless.

Why a struct for each specific match_type is **needed**? It it is not needed, then it is senseless per definition :-)

In the specific case of fwnode, there's already a named struct for fwnode_handle. The only thing is that it is declared outside enum v4l2_async_match_type. So, I don't see any reason to do things like:

		struct {
			struct fwnode_handle *fwnode;
		} fwnode;

If you're in doubt about that, think on how would you document both fwnode structs. Both fwnode structs specify the match criteria if %V4L2_ASYNC_MATCH_FWNODE.

The same applies to this:

		struct {
			const char *name;
		} device_name;

Both device_name and name specifies the match criteria if %V4L2_ASYNC_MATCH_DEVNAME.

Quoted 5 lines

In the two cases there's just a single field in the containing struct. You could remove the struct in that case as you do in this patch, and just use the field. But I think the result is less clean and so I wouldn't make this change.

Quoted 7 lines

It is actually cleaner without the stucts.

Without the useless struct, if one wants to match a firmware node, it should be doing:

 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);

This code should be and will be moved out of drivers. See:

<URL:http://www.spinics.net/lists/linux-media/msg122688.html>

So there are going to be quite a bit fewer instances of it, and none should remain in drivers. I frankly don't have a strong opinion on this; there are arguments for and against. I just don't see a reason to change it.

It'd be nice to have Hans's and Laurent's opinion though.

Quoted 42 lines

And that' it. For anyone that reads the above code, even not knowing all details of "match", is clear that the match criteria is whatever of_fwnode_handle() returns.

Now, on this:

 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
		pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);

It sounds that something is missing, as only one field of match.fwnode was specified. Anyone not familiar with that non-conventional usage of a struct with just one struct field inside would need to seek for the header file declaring the struct. That would consume a lot of time for code reviewers for no good reason.

The same apply for devname search:

In this case:

		asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
		asd->match.device_name.name = imxsd->devname;

I would be expecting something else to be filled at device_name's struct, for example to specify a case sensitive or case insensitive match criteria, to allow seeking for a device's substring, or to allow using other struct device fields to narrow the seek.

With this:

		asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
		asd->match.device_name = imxsd->devname;

It is clear that the match criteria is fully specified.

Quoted 5 lines

The confusion comes possibly from the fact that the struct is named the same as the field in the struct. These used to be called of and node, but with the fwnode property framework the references to the fwnode are, well, typically similarly called "fwnode". There's no underlying firmware interface with that name, fwnode property API is just an API.

The duplicated "fwnode" name only made it more evident that we don't need to enclose a single match criteria field inside a struct.

Signature · 4 lines
Kind regards,

Sakari Ailus
e-mail: sakari.ailus at iki.fi
#42 lore raw

PATCH v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

Em Sat, 30 Sep 2017 01:05:24 +0300
Sakari Ailus <[email protected]> escreveu:

Quoted 63 lines

Hi Mauro,

(Removing the non-list recipients.)

Quoted 50 lines · Mauro Carvalho Chehab

Em Thu, 28 Sep 2017 15:09:21 +0300
Sakari Ailus <[email protected]> escreveu:

Quoted 7 lines

Hi Mauro,

Quoted 4 lines · Mauro Carvalho Chehab

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

Quoted 8 lines
Quoted 5 lines

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

That makes easier to document it, as we don't need to document weird senseless structs.

The idea is that in the union, there's a struct which is specific to the match_type field. I wouldn't call it senseless.

Why a struct for each specific match_type is **needed**? It it is not needed, then it is senseless per definition :-)

In the specific case of fwnode, there's already a named struct for fwnode_handle. The only thing is that it is declared outside enum v4l2_async_match_type. So, I don't see any reason to do things like:

		struct {
			struct fwnode_handle *fwnode;
		} fwnode;

If you're in doubt about that, think on how would you document both fwnode structs. Both fwnode structs specify the match criteria if %V4L2_ASYNC_MATCH_FWNODE.

The same applies to this:

		struct {
			const char *name;
		} device_name;

Both device_name and name specifies the match criteria if %V4L2_ASYNC_MATCH_DEVNAME.

Quoted 5 lines

In the two cases there's just a single field in the containing struct. You could remove the struct in that case as you do in this patch, and just use the field. But I think the result is less clean and so I wouldn't make this change.

Quoted 7 lines

It is actually cleaner without the stucts.

Without the useless struct, if one wants to match a firmware node, it should be doing:

 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);  
Quoted 7 lines

This code should be and will be moved out of drivers. See:

<URL:http://www.spinics.net/lists/linux-media/msg122688.html>

So there are going to be quite a bit fewer instances of it, and none should remain in drivers. I frankly don't have a strong opinion on this; there are arguments for and against. I just don't see a reason to change it.

There are still a few occurrences on drivers. Just rebased it. I'll post it in a few, inside a new patch series.

Simplifying the name of the match rules makes easier to understand what's going on.

Thanks,
Mauro

#43 lore raw

PATCH RESEND v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

In reply to Mauro Carvalho Chehab

Hi Mauro,

Quoted 9 lines · Mauro Carvalho Chehab

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

That makes easier to document it, as we don't need to document weird senseless structs.

The idea is that in the union, there's a struct which is specific to the match_type field. I wouldn't call it senseless.

In the two cases there's just a single field in the containing struct. You could remove the struct in that case as you do in this patch, and just use the field. But I think the result is less clean and so I wouldn't make this change.

The confusion comes possibly from the fact that the struct is named the same as the field in the struct. These used to be called of and node, but with the fwnode property framework the references to the fwnode are, well, typically similarly called "fwnode". There's no underlying firmware interface with that name, fwnode property API is just an API.

Signature · 4 lines
Kind regards,

Sakari Ailus
e-mail: sakari.ailus at iki.fi
#44 lore raw

PATCH RESEND v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

In reply to Mauro Carvalho Chehab

(Resending for Mauro, while dropping the non-list recipients. The original likely had too many recipients.)

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

That makes easier to document it, as we don't need to document weird senseless structs.

At drivers, this makes even clearer about the match criteria.

---
 drivers/media/platform/am437x/am437x-vpfe.c    | 6 +++---
 drivers/media/platform/atmel/atmel-isc.c       | 2 +-
 drivers/media/platform/atmel/atmel-isi.c       | 2 +-
 drivers/media/platform/davinci/vpif_capture.c  | 4 ++--
 drivers/media/platform/exynos4-is/media-dev.c  | 4 ++--
 drivers/media/platform/omap3isp/isp.c          | 4 ++--
 drivers/media/platform/pxa_camera.c            | 2 +-
 drivers/media/platform/qcom/camss-8x16/camss.c | 2 +-
 drivers/media/platform/rcar-vin/rcar-core.c    | 8 ++++----
 drivers/media/platform/rcar_drif.c             | 4 ++--
 drivers/media/platform/soc_camera/soc_camera.c | 2 +-
 drivers/media/platform/stm32/stm32-dcmi.c      | 2 +-
 drivers/media/platform/ti-vpe/cal.c            | 2 +-
 drivers/media/platform/xilinx/xilinx-vipp.c    | 2 +-
 drivers/media/v4l2-core/v4l2-async.c           | 4 ++--
 drivers/staging/media/imx/imx-media-dev.c      | 8 ++++----
 include/media/v4l2-async.h                     | 8 ++------
 17 files changed, 31 insertions(+), 35 deletions(-)
drivers/media/platform/am437x/am437x-vpfe.c +3 -3
index dfcc484cab89..f87e8f9467e9 100644
@@ -2304,8 +2304,8 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
 	vpfe_dbg(1, vpfe, "vpfe_async_bound\n");
 
 	for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) {
-		if (vpfe->cfg->asd[i]->match.fwnode.fwnode ==
-		    asd[i].match.fwnode.fwnode) {
+		if (vpfe->cfg->asd[i]->match.fwnode ==
+		    asd[i].match.fwnode) {
 			sdinfo = &vpfe->cfg->sub_devs[i];
 			vpfe->sd[i] = subdev;
 			vpfe->sd[i]->grp_id = sdinfo->grp_id;
@@ -2505,7 +2505,7 @@ vpfe_get_pdata(struct platform_device *pdev)
 		}
 
 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);
+		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
 		of_node_put(rem);
 	}
 
drivers/media/platform/atmel/atmel-isc.c +1 -1
index d7103c5f92c3..c04d9a4dbfac 100644
@@ -1742,7 +1742,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 			subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW;
 
 		subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		subdev_entity->asd->match.fwnode.fwnode =
+		subdev_entity->asd->match.fwnode =
 			of_fwnode_handle(rem);
 		list_add_tail(&subdev_entity->list, &isc->subdev_entities);
 	}
drivers/media/platform/atmel/atmel-isi.c +1 -1
index 891fa2505efa..8c52f9f5f2db 100644
@@ -1124,7 +1124,7 @@ static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
 		/* Remote node to connect */
 		isi->entity.node = remote;
 		isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		isi->entity.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
 		return 0;
 	}
 }
drivers/media/platform/davinci/vpif_capture.c +2 -2
index 0ef36cec21d1..0cf141635cbc 100644
@@ -1390,7 +1390,7 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
 
 	for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
 		struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
-		const struct fwnode_handle *fwnode = _asd->match.fwnode.fwnode;
+		const struct fwnode_handle *fwnode = _asd->match.fwnode;
 
 		if (fwnode == subdev->fwnode) {
 			vpif_obj.sd[i] = subdev;
@@ -1588,7 +1588,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
 		}
 
 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);
+		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
 		of_node_put(rem);
 	}
 
drivers/media/platform/exynos4-is/media-dev.c +2 -2
index d4656d5175d7..d4d97d7e9684 100644
@@ -454,7 +454,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
 	}
 
 	fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-	fmd->sensor[index].asd.match.fwnode.fwnode = of_fwnode_handle(rem);
+	fmd->sensor[index].asd.match.fwnode = of_fwnode_handle(rem);
 	fmd->async_subdevs[index] = &fmd->sensor[index].asd;
 
 	fmd->num_sensors++;
@@ -1361,7 +1361,7 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
 
 	/* Find platform data for this sensor subdev */
 	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
-		if (fmd->sensor[i].asd.match.fwnode.fwnode ==
+		if (fmd->sensor[i].asd.match.fwnode ==
 		    of_fwnode_handle(subdev->dev->of_node))
 			si = &fmd->sensor[i];
 
drivers/media/platform/omap3isp/isp.c +2 -2
index 1a428fe9f070..bbb402a5fcf0 100644
@@ -2170,9 +2170,9 @@ static int isp_fwnodes_parse(struct device *dev,
 
 		notifier->subdevs[notifier->num_subdevs] = &isd->asd;
 
-		isd->asd.match.fwnode.fwnode =
+		isd->asd.match.fwnode =
 			fwnode_graph_get_remote_port_parent(fwnode);
-		if (!isd->asd.match.fwnode.fwnode) {
+		if (!isd->asd.match.fwnode) {
 			dev_warn(dev, "bad remote port parent\n");
 			goto error;
 		}
drivers/media/platform/pxa_camera.c +1 -1
index edca993c2b1f..4a23a60f3418 100644
@@ -2328,7 +2328,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
 	remote = of_graph_get_remote_port(np);
 	if (remote) {
-		asd->match.fwnode.fwnode = of_fwnode_handle(remote);
+		asd->match.fwnode = of_fwnode_handle(remote);
 		of_node_put(remote);
 	} else {
 		dev_notice(dev, "no remote for %pOF\n", np);
drivers/media/platform/qcom/camss-8x16/camss.c +1 -1
index a3760b5dd1d1..7d7bca09473a 100644
@@ -341,7 +341,7 @@ static int camss_of_parse_ports(struct device *dev,
 		}
 
 		csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		csd->asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		csd->asd.match.fwnode = of_fwnode_handle(remote);
 	}
 
 	return notifier->num_subdevs;
drivers/media/platform/rcar-vin/rcar-core.c +4 -4
index 142de447aaaa..3835a2fa0cb7 100644
@@ -171,7 +171,7 @@ static int rvin_digital_graph_parse(struct rvin_dev *vin)
 	struct device_node *ep, *np;
 	int ret;
 
-	vin->digital.asd.match.fwnode.fwnode = NULL;
+	vin->digital.asd.match.fwnode = NULL;
 	vin->digital.subdev = NULL;
 
 	/*
@@ -195,7 +195,7 @@ static int rvin_digital_graph_parse(struct rvin_dev *vin)
 	if (ret)
 		return ret;
 
-	vin->digital.asd.match.fwnode.fwnode = of_fwnode_handle(np);
+	vin->digital.asd.match.fwnode = of_fwnode_handle(np);
 	vin->digital.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 
 	return 0;
@@ -210,7 +210,7 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 	if (ret)
 		return ret;
 
-	if (!vin->digital.asd.match.fwnode.fwnode) {
+	if (!vin->digital.asd.match.fwnode) {
 		vin_dbg(vin, "No digital subdevice found\n");
 		return -ENODEV;
 	}
@@ -223,7 +223,7 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 	subdevs[0] = &vin->digital.asd;
 
 	vin_dbg(vin, "Found digital subdevice %pOF\n",
-		to_of_node(subdevs[0]->match.fwnode.fwnode));
+		to_of_node(subdevs[0]->match.fwnode));
 
 	vin->notifier.num_subdevs = 1;
 	vin->notifier.subdevs = subdevs;
drivers/media/platform/rcar_drif.c +2 -2
index 522364ff0d5d..ae7927305231 100644
@@ -1107,7 +1107,7 @@ static int rcar_drif_notify_bound(struct v4l2_async_notifier *notifier,
 	struct rcar_drif_sdr *sdr =
 		container_of(notifier, struct rcar_drif_sdr, notifier);
 
-	if (sdr->ep.asd.match.fwnode.fwnode !=
+	if (sdr->ep.asd.match.fwnode !=
 	    of_fwnode_handle(subdev->dev->of_node)) {
 		rdrif_err(sdr, "subdev %s cannot bind\n", subdev->name);
 		return -EINVAL;
@@ -1229,7 +1229,7 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
 		return -EINVAL;
 	}
 
-	sdr->ep.asd.match.fwnode.fwnode = fwnode;
+	sdr->ep.asd.match.fwnode = fwnode;
 	sdr->ep.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 	notifier->num_subdevs++;
 
drivers/media/platform/soc_camera/soc_camera.c +1 -1
index 1f3c450c7a69..1bef3ebb49ee 100644
@@ -1513,7 +1513,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
 	if (!info)
 		return -ENOMEM;
 
-	info->sasd.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+	info->sasd.asd.match.fwnode = of_fwnode_handle(remote);
 	info->sasd.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 	info->subdev = &info->sasd.asd;
 
drivers/media/platform/stm32/stm32-dcmi.c +1 -1
index 35ba6f211b79..4c8bd77842f6 100644
@@ -1514,7 +1514,7 @@ static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node)
 		/* Remote node to connect */
 		dcmi->entity.node = remote;
 		dcmi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		dcmi->entity.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		dcmi->entity.asd.match.fwnode = of_fwnode_handle(remote);
 		return 0;
 	}
 }
drivers/media/platform/ti-vpe/cal.c +1 -1
index 42e383a48ffe..7491425eed77 100644
@@ -1700,7 +1700,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
 		goto cleanup_exit;
 	}
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-	asd->match.fwnode.fwnode = of_fwnode_handle(sensor_node);
+	asd->match.fwnode = of_fwnode_handle(sensor_node);
 
 	remote_ep = of_graph_get_remote_endpoint(ep_node);
 	if (!remote_ep) {
drivers/media/platform/xilinx/xilinx-vipp.c +1 -1
index ebfdf334d99c..3fdb0f365538 100644
@@ -390,7 +390,7 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
 
 		entity->node = remote;
 		entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		entity->asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		entity->asd.match.fwnode = of_fwnode_handle(remote);
 		list_add_tail(&entity->list, &xdev->entities);
 		xdev->num_subdevs++;
 	}
drivers/media/v4l2-core/v4l2-async.c +2 -2
index d741a8e0fdac..e087857d02d6 100644
@@ -39,12 +39,12 @@ static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 static bool match_devname(struct v4l2_subdev *sd,
 			  struct v4l2_async_subdev *asd)
 {
-	return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
+	return !strcmp(asd->match.device_name, dev_name(sd->dev));
 }
 
 static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
-	return sd->fwnode == asd->match.fwnode.fwnode;
+	return sd->fwnode == asd->match.fwnode;
 }
 
 static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
drivers/staging/media/imx/imx-media-dev.c +4 -4
index d96f4512224f..858088570684 100644
@@ -48,12 +48,12 @@ imx_media_find_async_subdev(struct imx_media_dev *imxmd,
 		imxsd = &imxmd->subdev[i];
 		switch (imxsd->asd.match_type) {
 		case V4L2_ASYNC_MATCH_FWNODE:
-			if (fwnode && imxsd->asd.match.fwnode.fwnode == fwnode)
+			if (fwnode && imxsd->asd.match.fwnode == fwnode)
 				return imxsd;
 			break;
 		case V4L2_ASYNC_MATCH_DEVNAME:
 			if (devname &&
-			    !strcmp(imxsd->asd.match.device_name.name, devname))
+			    !strcmp(imxsd->asd.match.device_name, devname))
 				return imxsd;
 			break;
 		default:
@@ -108,11 +108,11 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd,
 	asd = &imxsd->asd;
 	if (np) {
 		asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		asd->match.fwnode.fwnode = of_fwnode_handle(np);
+		asd->match.fwnode = of_fwnode_handle(np);
 	} else {
 		asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
 		strncpy(imxsd->devname, devname, sizeof(imxsd->devname));
-		asd->match.device_name.name = imxsd->devname;
+		asd->match.device_name = imxsd->devname;
 		imxsd->pdev = pdev;
 	}
 
include/media/v4l2-async.h +2 -6
index c69d8c8a66d0..e66a3521596f 100644
@@ -54,12 +54,8 @@ enum v4l2_async_match_type {
 struct v4l2_async_subdev {
 	enum v4l2_async_match_type match_type;
 	union {
-		struct {
-			struct fwnode_handle *fwnode;
-		} fwnode;
-		struct {
-			const char *name;
-		} device_name;
+		struct fwnode_handle *fwnode;
+		const char *device_name;
 		struct {
 			int adapter_id;
 			unsigned short address;
Signature · 1 line
2.13.5
#45 lore raw

PATCH RESEND v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

Quoted 10 lines · Mauro Carvalho Chehab

(Resending for Mauro, while dropping the non-list recipients. The original likely had too many recipients.)

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

Quoted 6 lines

That makes easier to document it, as we don't need to document weird senseless structs.

At drivers, this makes even clearer about the match criteria.

#46 lore raw

PATCH RESEND v2 13/17 media: v4l2-async: simplify v4l2_async_subdev structure

In reply to Mauro Carvalho Chehab

Hi Mauro,

Quoted 9 lines · Mauro Carvalho Chehab

The V4L2_ASYNC_MATCH_FWNODE match criteria requires just one struct to be filled (struct fwnode_handle). The V4L2_ASYNC_MATCH_DEVNAME match criteria requires just a device name.

So, it doesn't make sense to enclose those into structs, as the criteria can go directly into the union.

That makes easier to document it, as we don't need to document weird senseless structs.

The idea is that in the union, there's a struct which is specific to the match_type field. I wouldn't call it senseless.

In the two cases there's just a single field in the containing struct. You could remove the struct in that case as you do in this patch, and just use the field. But I think the result is less clean and so I wouldn't make this change.

The confusion comes possibly from the fact that the struct is named the same as the field in the struct. These used to be called of and node, but with the fwnode property framework the references to the fwnode are, well, typically similarly called "fwnode". There's no underlying firmware interface with that name, fwnode property API is just an API.

Signature · 4 lines
Kind regards,

Sakari Ailus
e-mail: sakari.ailus at iki.fi
#47 lore raw

PATCH v2 14/17 media: v4l2-async: better describe match union at async match struct

In reply to Mauro Carvalho Chehab

Now that kernel-doc handles nested unions, better document the match union at struct v4l2_async_subdev.

---
 include/media/v4l2-async.h | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)
include/media/v4l2-async.h +32 -3
index e66a3521596f..62c2d572ec23 100644
@@ -46,10 +46,39 @@ enum v4l2_async_match_type {
 /**
  * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
  *
- * @match_type:	type of match that will be used
- * @match:	union of per-bus type matching data sets
+ * @match_type:
+ *	type of match that will be used
+ * @match:
+ *	union of per-bus type matching data sets
+ * @match.fwnode:
+ *		pointer to &struct fwnode_handle to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE.
+ * @match.device_name:
+ *		string containing the device name to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_DEVNAME.
+ * @match.i2c:
+ *		embedded struct with I2C parameters to be matched.
+ * 		Both @match.i2c.adapter_id and @match.i2c.address
+ *		should be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.adapter_id:
+ *		I2C adapter ID to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.address:
+ *		I2C address to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.custom:
+ *		Driver-specific match criteria.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.match:
+ *		Driver-specific match function to be used if
+ *		%V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.priv:
+ *		Driver-specific private struct with match parameters
+ *		to be used if %V4L2_ASYNC_MATCH_CUSTOM.
  * @list:	used to link struct v4l2_async_subdev objects, waiting to be
- *		probed, to a notifier->waiting list
+ *		probed, to a notifier->waiting list.
+ *		Not to be used by drivers.
  */
 struct v4l2_async_subdev {
 	enum v4l2_async_match_type match_type;
Signature · 1 line
2.13.5
maintainer
#48 lore raw

Re: [PATCH v2 14/17] media: v4l2-async: better describe match union at async match struct

Hi Mauro,

Thank you for the patch.

Quoted 13 lines · On Thursday, 28 September 2017 00:46:57 EEST Mauro Carvalho Chehab wrote:

Now that kernel-doc handles nested unions, better document the match union at struct v4l2_async_subdev.

---
 include/media/v4l2-async.h | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)
include/media/v4l2-async.h +0 -0
index e66a3521596f..62c2d572ec23 100644

include/media/v4l2-async.h enum v4l2_async_match_type { · line 52

Quoted 9 lines
include/media/v4l2-async.h +4 -2
@@ -46,10 +46,39 @@ enum v4l2_async_match_type {
 /**
  * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
  *
- * @match_type:	type of match that will be used
- * @match:	union of per-bus type matching data sets
+ * @match_type:
+ *	type of match that will be used
+ * @match:
+ *	union of per-bus type matching data sets

The lines don't exceed the 80 columnes limit, you can keep them as-is.

include/media/v4l2-async.h enum v4l2_async_match_type { · line 63

Quoted 11 lines
include/media/v4l2-async.h +11 -0
+ * @match.fwnode:
+ *		pointer to &struct fwnode_handle to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE.
+ * @match.device_name:
+ *		string containing the device name to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_DEVNAME.
+ * @match.i2c:
+ *		embedded struct with I2C parameters to be matched.
+ * 		Both @match.i2c.adapter_id and @match.i2c.address
+ *		should be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.

Do you really need to document this ? Isn't it enough to document @match.i2c.adapter_id and @match.i2c.address ?

include/media/v4l2-async.h enum v4l2_async_match_type { · line 72

Quoted 9 lines
include/media/v4l2-async.h +9 -0
+ * @match.i2c.adapter_id:
+ *		I2C adapter ID to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.address:
+ *		I2C address to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.custom:
+ *		Driver-specific match criteria.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_CUSTOM.

Same here.

Quoted 13 lines
include/media/v4l2-async.h +8 -1
+ * @match.custom.match:
+ *		Driver-specific match function to be used if
+ *		%V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.priv:
+ *		Driver-specific private struct with match parameters
+ *		to be used if %V4L2_ASYNC_MATCH_CUSTOM.
  * @list:	used to link struct v4l2_async_subdev objects, waiting to be
- *		probed, to a notifier->waiting list
+ *		probed, to a notifier->waiting list.
+ *		Not to be used by drivers.
  */
 struct v4l2_async_subdev {
 	enum v4l2_async_match_type match_type;
Signature · 3 lines
Regards,

Laurent Pinchart
#49 lore raw

Re: [PATCH v2 14/17] media: v4l2-async: better describe match union at async match struct

Em Fri, 13 Oct 2017 15:49:25 +0300
Laurent Pinchart <[email protected]> escreveu:

Quoted 13 lines

Hi Mauro,

Thank you for the patch.

Quoted 8 lines · On Thursday, 28 September 2017 00:46:57 EEST Mauro Carvalho Chehab wrote:

Now that kernel-doc handles nested unions, better document the match union at struct v4l2_async_subdev.

---
 include/media/v4l2-async.h | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)
Quoted 16 lines
Quoted 5 lines
include/media/v4l2-async.h +0 -0
index e66a3521596f..62c2d572ec23 100644

include/media/v4l2-async.h enum v4l2_async_match_type { · line 52

Quoted 9 lines
include/media/v4l2-async.h +4 -2
@@ -46,10 +46,39 @@ enum v4l2_async_match_type {
 /**
  * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
  *
- * @match_type:	type of match that will be used
- * @match:	union of per-bus type matching data sets
+ * @match_type:
+ *	type of match that will be used
+ * @match:
+ *	union of per-bus type matching data sets  

The lines don't exceed the 80 columnes limit, you can keep them as-is.

OK.

Quoted 13 lines

include/media/v4l2-async.h enum v4l2_async_match_type { · line 63

Quoted 12 lines
include/media/v4l2-async.h +11 -0
+ * @match.fwnode:
+ *		pointer to &struct fwnode_handle to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE.
+ * @match.device_name:
+ *		string containing the device name to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_DEVNAME.
+ * @match.i2c:
+ *		embedded struct with I2C parameters to be matched.
+ * 		Both @match.i2c.adapter_id and @match.i2c.address
+ *		should be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.  
Quoted 2 lines

Do you really need to document this ? Isn't it enough to document @match.i2c.adapter_id and @match.i2c.address ?

No. If we don't document a non-anonymous struct, kernel-doc will complain that a field description is missed. Same applies to the custom field below.

There's a way to get rid of it: converting it to an anonymous struct, but I guess that will make the usage of the match rule harder to understand.

Quoted 11 lines

include/media/v4l2-async.h enum v4l2_async_match_type { · line 72

Quoted 10 lines
include/media/v4l2-async.h +9 -0
+ * @match.i2c.adapter_id:
+ *		I2C adapter ID to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.address:
+ *		I2C address to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.custom:
+ *		Driver-specific match criteria.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_CUSTOM.  
Quoted 16 lines

Same here.

Quoted 13 lines
include/media/v4l2-async.h +8 -1
+ * @match.custom.match:
+ *		Driver-specific match function to be used if
+ *		%V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.priv:
+ *		Driver-specific private struct with match parameters
+ *		to be used if %V4L2_ASYNC_MATCH_CUSTOM.
  * @list:	used to link struct v4l2_async_subdev objects, waiting to be
- *		probed, to a notifier->waiting list
+ *		probed, to a notifier->waiting list.
+ *		Not to be used by drivers.
  */
 struct v4l2_async_subdev {
 	enum v4l2_async_match_type match_type;  

Thanks,
Mauro

#50 lore raw

PATCH v2 15/17 media: v4l2-ctrls: document nested members of structs

In reply to Mauro Carvalho Chehab

There are a few nested members at v4l2-ctrls.h. Now that kernel-doc supports, document them.

---
 include/media/v4l2-ctrls.h | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
include/media/v4l2-ctrls.h +9 -2
index dacfe54057f8..ca05f0f49bc5 100644
@@ -147,7 +147,7 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
  * @type_ops:	The control type ops.
  * @id:	The control ID.
  * @name:	The control name.
- * @type:	The control type.
+ * @type:	The control type, as defined by &enum v4l2_ctrl_type.
  * @minimum:	The control's minimum value.
  * @maximum:	The control's maximum value.
  * @default_value: The control's default value.
@@ -166,8 +166,15 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
  *		empty strings ("") correspond to non-existing menu items (this
  *		is in addition to the menu_skip_mask above). The last entry
  *		must be NULL.
+ *		Used only if the @type is %V4L2_CTRL_TYPE_MENU.
+ * @qmenu_int:	A 64-bit integer array for with integer menu items.
+ *		The size of array must be equal to the menu size, e. g.:
+ *		:math:`ceil(\frac{maximum - minimum}{step}) + 1`.
+ *		Used only if the @type is %V4L2_CTRL_TYPE_INTEGER_MENU.
  * @flags:	The control's flags.
- * @cur:	The control's current value.
+ * @cur:	Struct to store data about the current value.
+ * @cur.val:	The control's current value, if the @type is represented via
+ *		a u32 integer (see &enum v4l2_ctrl_type).
  * @val:	The control's new s32 value.
  * @priv:	The control's private pointer. For use by the driver. It is
  *		untouched by the control framework. Note that this pointer is
Signature · 1 line
2.13.5
maintainer
#51 lore raw

Re: [PATCH v2 15/17] media: v4l2-ctrls: document nested members of structs

Hi Mauro,

Thank you for the patch.

Quoted 13 lines · On Thursday, 28 September 2017 00:46:58 EEST Mauro Carvalho Chehab wrote:

There are a few nested members at v4l2-ctrls.h. Now that kernel-doc supports, document them.

---
 include/media/v4l2-ctrls.h | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
include/media/v4l2-ctrls.h +0 -0
index dacfe54057f8..ca05f0f49bc5 100644

include/media/v4l2-ctrls.h typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl · line 150

Quoted 5 lines
include/media/v4l2-ctrls.h +1 -1
@@ -147,7 +147,7 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl
 *ctrl, void *priv); * @type_ops:	The control type ops.
  * @id:	The control ID.
  * @name:	The control name.
- * @type:	The control type.
+ * @type:	The control type, as defined by &enum v4l2_ctrl_type.

Why do you need this ? The field is an enum v4l2_ctrl_type, Sphinx should generate the proper link already.

Quoted 6 lines
include/media/v4l2-ctrls.h +0 -0
  * @minimum:	The control's minimum value.
  * @maximum:	The control's maximum value.
  * @default_value: The control's default value.
@@ -166,8 +166,15 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl
 *ctrl, void *priv);
  *		empty strings ("") correspond to non-existing menu items (this

include/media/v4l2-ctrls.h typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl · line 176

Quoted 10 lines
include/media/v4l2-ctrls.h +6 -1
  *		is in addition to the menu_skip_mask above). The last entry
  *		must be NULL.
+ *		Used only if the @type is %V4L2_CTRL_TYPE_MENU.
+ * @qmenu_int:	A 64-bit integer array for with integer menu items.
+ *		The size of array must be equal to the menu size, e. g.:
+ *		:math:`ceil(\frac{maximum - minimum}{step}) + 1`.
+ *		Used only if the @type is %V4L2_CTRL_TYPE_INTEGER_MENU.
  * @flags:	The control's flags.
- * @cur:	The control's current value.
+ * @cur:	Struct to store data about the current value.

s/Struct/Structure/
s/data about the current value/the current value/

Quoted 5 lines
include/media/v4l2-ctrls.h +2 -0
+ * @cur.val:	The control's current value, if the @type is represented via
+ *		a u32 integer (see &enum v4l2_ctrl_type).
  * @val:	The control's new s32 value.
  * @priv:	The control's private pointer. For use by the driver. It is

* untouched by the control framework. Note that this pointer is

Signature · 3 lines
Regards,

Laurent Pinchart
#52 lore raw

PATCH v2 16/17 media: videobuf2-core: improve kernel-doc markups

In reply to Mauro Carvalho Chehab

Now that nested structs are supported, change the documentation to use it. While here, add cross-references where pertinent and use monotonic fonts where pertinent, using the right markup tags.

---
 include/media/videobuf2-core.h | 59 +++++++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 30 deletions(-)
include/media/videobuf2-core.h +29 -30
index ef9b64398c8c..5f4df060affb 100644
@@ -69,7 +69,7 @@ struct vb2_threadio_data;
  *		 argument to other ops in this structure.
  * @put_userptr: inform the allocator that a USERPTR buffer will no longer
  *		 be used.
- * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation;
+ * @attach_dmabuf: attach a shared &struct dma_buf for a hardware operation;
  *		   used for DMABUF memory types; dev is the alloc device
  *		   dbuf is the shared dma_buf; returns ERR_PTR() on failure;
  *		   allocator private per-buffer structure on success;
@@ -153,20 +153,19 @@ struct vb2_mem_ops {
  * @length:	size of this plane (NOT the payload) in bytes
  * @min_length:	minimum required size of this plane (NOT the payload) in bytes.
  *		@length is always greater or equal to @min_length.
- * @offset:	when memory in the associated struct vb2_buffer is
- *		VB2_MEMORY_MMAP, equals the offset from the start of
+ * @m:		Union with memtype-specific data
+ * @m.offset:	when memory in the associated struct vb2_buffer is
+ *		%VB2_MEMORY_MMAP, equals the offset from the start of
  *		the device memory for this plane (or is a "cookie" that
  *		should be passed to mmap() called on the video node)
- * @userptr:	when memory is VB2_MEMORY_USERPTR, a userspace pointer
+ * @m.userptr:	when memory is %VB2_MEMORY_USERPTR, a userspace pointer
  *		pointing to this plane
- * @fd:		when memory is VB2_MEMORY_DMABUF, a userspace file
+ * @m.fd:	when memory is %VB2_MEMORY_DMABUF, a userspace file
  *		descriptor associated with this plane
- * @m:		Union with memtype-specific data (@offset, @userptr or
- *		@fd).
  * @data_offset:	offset in the plane to the start of data; usually 0,
  *		unless there is a header in front of the data
  * Should contain enough information to be able to cover all the fields
- * of struct v4l2_plane at videodev2.h
+ * of &struct v4l2_plane at videodev2.h
  */
 struct vb2_plane {
 	void			*mem_priv;
@@ -356,7 +355,7 @@ struct vb2_buffer {
  *			driver can return an error if hardware fails, in that
  *			case all buffers that have been already given by
  *			the @buf_queue callback are to be returned by the driver
- *			by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED.
+ *			by calling vb2_buffer_done() with %%VB2_BUF_STATE_QUEUED.
  *			If you need a minimum number of buffers before you can
  *			start streaming, then set @min_buffers_needed in the
  *			vb2_queue structure. If that is non-zero then
@@ -366,7 +365,7 @@ struct vb2_buffer {
  *			should stop any DMA transactions or wait until they
  *			finish and give back all buffers it got from &buf_queue
  *			callback by calling vb2_buffer_done() with either
- *			%VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use
+ *			%VB2_BUF_STATE_DONE or %%VB2_BUF_STATE_ERROR; may use
  *			vb2_wait_for_all_buffers() function
  * @buf_queue:		passes buffer vb to the driver; driver may start
  *			hardware operation on this buffer; driver should give
@@ -401,13 +400,13 @@ struct vb2_ops {
  * @verify_planes_array: Verify that a given user space structure contains
  *			enough planes for the buffer. This is called
  *			for each dequeued buffer.
- * @fill_user_buffer:	given a vb2_buffer fill in the userspace structure.
+ * @fill_user_buffer:	given a &vb2_buffer fill in the userspace structure.
  *			For V4L2 this is a struct v4l2_buffer.
- * @fill_vb2_buffer:	given a userspace structure, fill in the vb2_buffer.
+ * @fill_vb2_buffer:	given a userspace structure, fill in the &vb2_buffer.
  *			If the userspace structure is invalid, then this op
  *			will return an error.
  * @copy_timestamp:	copy the timestamp from a userspace structure to
- *			the vb2_buffer struct.
+ *			the &vb2_buffer struct.
  */
 struct vb2_buf_ops {
 	int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb);
@@ -428,10 +427,10 @@ struct vb2_buf_ops {
  *		doesn't fill in the @alloc_devs array.
  * @dma_attrs:	DMA attributes to use for the DMA.
  * @bidirectional: when this flag is set the DMA direction for the buffers of
- *		this queue will be overridden with DMA_BIDIRECTIONAL direction.
+ *		this queue will be overridden with %DMA_BIDIRECTIONAL direction.
  *		This is useful in cases where the hardware (firmware) writes to
- *		a buffer which is mapped as read (DMA_TO_DEVICE), or reads from
- *		buffer which is mapped for write (DMA_FROM_DEVICE) in order
+ *		a buffer which is mapped as read (%DMA_TO_DEVICE), or reads from
+ *		buffer which is mapped for write (%DMA_FROM_DEVICE) in order
  *		to satisfy some internal hardware restrictions or adds a padding
  *		needed by the processing algorithm. In case the DMA mapping is
  *		not bidirectional but the hardware (firmware) trying to access
@@ -440,10 +439,10 @@ struct vb2_buf_ops {
  * @fileio_read_once:		report EOF after reading the first buffer
  * @fileio_write_immediately:	queue buffer after each write() call
  * @allow_zero_bytesused:	allow bytesused == 0 to be passed to the driver
- * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
+ * @quirk_poll_must_check_waiting_for_buffers: Return %POLLERR at poll when QBUF
  *              has not been called. This is a vb1 idiom that has been adopted
  *              also by vb2.
- * @lock:	pointer to a mutex that protects the vb2_queue struct. The
+ * @lock:	pointer to a mutex that protects the &vb2_queue struct. The
  *		driver can set this to a mutex to let the v4l2 core serialize
  *		the queuing ioctls. If the driver wants to handle locking
  *		itself, then this should be set to NULL. This lock is not used
@@ -464,7 +463,7 @@ struct vb2_buf_ops {
  * @timestamp_flags: Timestamp flags; V4L2_BUF_FLAG_TIMESTAMP_* and
  *		V4L2_BUF_FLAG_TSTAMP_SRC_*
  * @gfp_flags:	additional gfp flags used when allocating the buffers.
- *		Typically this is 0, but it may be e.g. GFP_DMA or __GFP_DMA32
+ *		Typically this is 0, but it may be e.g. %GFP_DMA or %__GFP_DMA32
  *		to force the buffer allocation to a specific memory zone.
  * @min_buffers_needed: the minimum number of buffers needed before
  *		@start_streaming can be called. Used when a DMA engine
@@ -491,13 +490,13 @@ struct vb2_buf_ops {
  * @error:	a fatal error occurred on the queue
  * @waiting_for_buffers: used in poll() to check if vb2 is still waiting for
  *		buffers. Only set for capture queues if qbuf has not yet been
- *		called since poll() needs to return POLLERR in that situation.
+ *		called since poll() needs to return %POLLERR in that situation.
  * @is_multiplanar: set if buffer type is multiplanar
  * @is_output:	set if buffer type is output
  * @copy_timestamp: set if vb2-core should set timestamps
  * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the
  *		last decoded buffer was already dequeued. Set for capture queues
- *		when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
+ *		when a buffer with the %V4L2_BUF_FLAG_LAST is dequeued.
  * @fileio:	file io emulator internal data, used only if emulator is active
  * @threadio:	thread io internal data, used only if thread is active
  */
@@ -569,7 +568,7 @@ struct vb2_queue {
 
 /**
  * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
- * @vb:		vb2_buffer to which the plane in question belongs to
+ * @vb:		&vb2_buffer to which the plane in question belongs to
  * @plane_no:	plane number for which the address is to be returned
  *
  * This function returns a kernel virtual address of a given plane if
@@ -579,7 +578,7 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
 
 /**
  * vb2_plane_cookie() - Return allocator specific cookie for the given plane
- * @vb:		vb2_buffer to which the plane in question belongs to
+ * @vb:		&vb2_buffer to which the plane in question belongs to
  * @plane_no:	plane number for which the cookie is to be returned
  *
  * This function returns an allocator specific cookie for a given plane if
@@ -644,7 +643,7 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q);
  * @index:	id number of the buffer
  * @pb:		buffer struct passed from userspace
  *
- * Should be called from vidioc_querybuf ioctl handler in driver.
+ * Should be called from &vidioc_querybuf ioctl handler in driver.
  * The passed buffer should have been verified.
  * This function fills the relevant information for the userspace.
  */
@@ -656,7 +655,7 @@ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb);
  * @memory: memory type
  * @count: requested buffer count
  *
- * Should be called from vidioc_reqbufs ioctl handler of a driver.
+ * Should be called from &vidioc_reqbufs ioctl handler of a driver.
  *
  * This function:
  *
@@ -664,7 +663,7 @@ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb);
  * #) sets up the queue,
  * #) negotiates number of buffers and planes per buffer with the driver
  *    to be used during streaming,
- * #) allocates internal buffer structures (struct vb2_buffer), according to
+ * #) allocates internal buffer structures (&struct vb2_buffer), according to
  *    the agreed parameters,
  * #) for MMAP memory type, allocates actual video memory, using the
  *    memory handling/allocation routines provided during queue initialization
@@ -779,7 +778,7 @@ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type);
  * @type:	buffer type
  * @index:	id number of the buffer
  * @plane:	index of the plane to be exported, 0 for single plane queues
- * @flags:	flags for newly created file, currently only O_CLOEXEC is
+ * @flags:	flags for newly created file, currently only %O_CLOEXEC is
  *		supported, refer to manual of open syscall for more details
  *
  * The return values from this function are intended to be directly returned
@@ -792,7 +791,7 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
  * vb2_core_queue_init() - initialize a videobuf2 queue
  * @q:		videobuf2 queue; this structure should be allocated in driver
  *
- * The vb2_queue structure should be allocated by the driver. The driver is
+ * The &vb2_queue structure should be allocated by the driver. The driver is
  * responsible of clearing it's content and setting initial values for some
  * required entries before calling this function.
  * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer
@@ -819,8 +818,8 @@ void vb2_core_queue_release(struct vb2_queue *q);
  * waiting on the queue. Polling will now set POLLERR and queuing and dequeuing
  * buffers will return -EIO.
  *
- * The error flag will be cleared when cancelling the queue, either from
- * vb2_streamoff or vb2_queue_release. Drivers should thus not call this
+ * The error flag will be cleared when canceling the queue, either from
+ * vb2_streamoff() or vb2_queue_release(). Drivers should thus not call this
  * function before starting the stream, otherwise the error flag will remain set
  * until the queue is released when closing the device node.
  */
Signature · 1 line
2.13.5
maintainer Acked-by on v2 16/17
#53 lore raw

Re: [PATCH v2 16/17] media: videobuf2-core: improve kernel-doc markups

Hi,

Quoted 6 lines · Mauro Carvalho Chehab

Now that nested structs are supported, change the documentation to use it. While here, add cross-references where pertinent and use monotonic fonts where pertinent, using the right markup tags.

Quoted 195 lines
---
  include/media/videobuf2-core.h | 59 +++++++++++++++++++++---------------------
  1 file changed, 29 insertions(+), 30 deletions(-)
include/media/videobuf2-core.h +27 -28
index ef9b64398c8c..5f4df060affb 100644
@@ -69,7 +69,7 @@ struct vb2_threadio_data;
   *		 argument to other ops in this structure.
   * @put_userptr: inform the allocator that a USERPTR buffer will no longer
   *		 be used.
- * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation;
+ * @attach_dmabuf: attach a shared &struct dma_buf for a hardware operation;
   *		   used for DMABUF memory types; dev is the alloc device
   *		   dbuf is the shared dma_buf; returns ERR_PTR() on failure;
   *		   allocator private per-buffer structure on success;
@@ -153,20 +153,19 @@ struct vb2_mem_ops {
   * @length:	size of this plane (NOT the payload) in bytes
   * @min_length:	minimum required size of this plane (NOT the payload) in bytes.
   *		@length is always greater or equal to @min_length.
- * @offset:	when memory in the associated struct vb2_buffer is
- *		VB2_MEMORY_MMAP, equals the offset from the start of
+ * @m:		Union with memtype-specific data
+ * @m.offset:	when memory in the associated struct vb2_buffer is
+ *		%VB2_MEMORY_MMAP, equals the offset from the start of
   *		the device memory for this plane (or is a "cookie" that
   *		should be passed to mmap() called on the video node)
- * @userptr:	when memory is VB2_MEMORY_USERPTR, a userspace pointer
+ * @m.userptr:	when memory is %VB2_MEMORY_USERPTR, a userspace pointer
   *		pointing to this plane
- * @fd:		when memory is VB2_MEMORY_DMABUF, a userspace file
+ * @m.fd:	when memory is %VB2_MEMORY_DMABUF, a userspace file
   *		descriptor associated with this plane
- * @m:		Union with memtype-specific data (@offset, @userptr or
- *		@fd).
   * @data_offset:	offset in the plane to the start of data; usually 0,
   *		unless there is a header in front of the data
   * Should contain enough information to be able to cover all the fields
- * of struct v4l2_plane at videodev2.h
+ * of &struct v4l2_plane at videodev2.h
   */
  struct vb2_plane {
  	void			*mem_priv;
@@ -356,7 +355,7 @@ struct vb2_buffer {
   *			driver can return an error if hardware fails, in that
   *			case all buffers that have been already given by
   *			the @buf_queue callback are to be returned by the driver
- *			by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED.
+ *			by calling vb2_buffer_done() with %%VB2_BUF_STATE_QUEUED.
   *			If you need a minimum number of buffers before you can
   *			start streaming, then set @min_buffers_needed in the
   *			vb2_queue structure. If that is non-zero then
@@ -366,7 +365,7 @@ struct vb2_buffer {
   *			should stop any DMA transactions or wait until they
   *			finish and give back all buffers it got from &buf_queue
   *			callback by calling vb2_buffer_done() with either
- *			%VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use
+ *			%VB2_BUF_STATE_DONE or %%VB2_BUF_STATE_ERROR; may use
   *			vb2_wait_for_all_buffers() function
   * @buf_queue:		passes buffer vb to the driver; driver may start
   *			hardware operation on this buffer; driver should give
@@ -401,13 +400,13 @@ struct vb2_ops {
   * @verify_planes_array: Verify that a given user space structure contains
   *			enough planes for the buffer. This is called
   *			for each dequeued buffer.
- * @fill_user_buffer:	given a vb2_buffer fill in the userspace structure.
+ * @fill_user_buffer:	given a &vb2_buffer fill in the userspace structure.
   *			For V4L2 this is a struct v4l2_buffer.
- * @fill_vb2_buffer:	given a userspace structure, fill in the vb2_buffer.
+ * @fill_vb2_buffer:	given a userspace structure, fill in the &vb2_buffer.
   *			If the userspace structure is invalid, then this op
   *			will return an error.
   * @copy_timestamp:	copy the timestamp from a userspace structure to
- *			the vb2_buffer struct.
+ *			the &vb2_buffer struct.
   */
  struct vb2_buf_ops {
  	int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb);
@@ -428,10 +427,10 @@ struct vb2_buf_ops {
   *		doesn't fill in the @alloc_devs array.
   * @dma_attrs:	DMA attributes to use for the DMA.
   * @bidirectional: when this flag is set the DMA direction for the buffers of
- *		this queue will be overridden with DMA_BIDIRECTIONAL direction.
+ *		this queue will be overridden with %DMA_BIDIRECTIONAL direction.
   *		This is useful in cases where the hardware (firmware) writes to
- *		a buffer which is mapped as read (DMA_TO_DEVICE), or reads from
- *		buffer which is mapped for write (DMA_FROM_DEVICE) in order
+ *		a buffer which is mapped as read (%DMA_TO_DEVICE), or reads from
+ *		buffer which is mapped for write (%DMA_FROM_DEVICE) in order
   *		to satisfy some internal hardware restrictions or adds a padding
   *		needed by the processing algorithm. In case the DMA mapping is
   *		not bidirectional but the hardware (firmware) trying to access
@@ -440,10 +439,10 @@ struct vb2_buf_ops {
   * @fileio_read_once:		report EOF after reading the first buffer
   * @fileio_write_immediately:	queue buffer after each write() call
   * @allow_zero_bytesused:	allow bytesused == 0 to be passed to the driver
- * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
+ * @quirk_poll_must_check_waiting_for_buffers: Return %POLLERR at poll when QBUF
   *              has not been called. This is a vb1 idiom that has been adopted
   *              also by vb2.
- * @lock:	pointer to a mutex that protects the vb2_queue struct. The
+ * @lock:	pointer to a mutex that protects the &vb2_queue struct. The
   *		driver can set this to a mutex to let the v4l2 core serialize
   *		the queuing ioctls. If the driver wants to handle locking
   *		itself, then this should be set to NULL. This lock is not used
@@ -464,7 +463,7 @@ struct vb2_buf_ops {
   * @timestamp_flags: Timestamp flags; V4L2_BUF_FLAG_TIMESTAMP_* and
   *		V4L2_BUF_FLAG_TSTAMP_SRC_*
   * @gfp_flags:	additional gfp flags used when allocating the buffers.
- *		Typically this is 0, but it may be e.g. GFP_DMA or __GFP_DMA32
+ *		Typically this is 0, but it may be e.g. %GFP_DMA or %__GFP_DMA32
   *		to force the buffer allocation to a specific memory zone.
   * @min_buffers_needed: the minimum number of buffers needed before
   *		@start_streaming can be called. Used when a DMA engine
@@ -491,13 +490,13 @@ struct vb2_buf_ops {
   * @error:	a fatal error occurred on the queue
   * @waiting_for_buffers: used in poll() to check if vb2 is still waiting for
   *		buffers. Only set for capture queues if qbuf has not yet been
- *		called since poll() needs to return POLLERR in that situation.
+ *		called since poll() needs to return %POLLERR in that situation.
   * @is_multiplanar: set if buffer type is multiplanar
   * @is_output:	set if buffer type is output
   * @copy_timestamp: set if vb2-core should set timestamps
   * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the
   *		last decoded buffer was already dequeued. Set for capture queues
- *		when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
+ *		when a buffer with the %V4L2_BUF_FLAG_LAST is dequeued.
   * @fileio:	file io emulator internal data, used only if emulator is active
   * @threadio:	thread io internal data, used only if thread is active
   */
@@ -569,7 +568,7 @@ struct vb2_queue {
 
  /**
   * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
- * @vb:		vb2_buffer to which the plane in question belongs to
+ * @vb:		&vb2_buffer to which the plane in question belongs to
   * @plane_no:	plane number for which the address is to be returned
   *
   * This function returns a kernel virtual address of a given plane if
@@ -579,7 +578,7 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
 
  /**
   * vb2_plane_cookie() - Return allocator specific cookie for the given plane
- * @vb:		vb2_buffer to which the plane in question belongs to
+ * @vb:		&vb2_buffer to which the plane in question belongs to
   * @plane_no:	plane number for which the cookie is to be returned
   *
   * This function returns an allocator specific cookie for a given plane if
@@ -644,7 +643,7 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q);
   * @index:	id number of the buffer
   * @pb:		buffer struct passed from userspace
   *
- * Should be called from vidioc_querybuf ioctl handler in driver.
+ * Should be called from &vidioc_querybuf ioctl handler in driver.
   * The passed buffer should have been verified.
   * This function fills the relevant information for the userspace.
   */
@@ -656,7 +655,7 @@ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb);
   * @memory: memory type
   * @count: requested buffer count
   *
- * Should be called from vidioc_reqbufs ioctl handler of a driver.
+ * Should be called from &vidioc_reqbufs ioctl handler of a driver.
   *
   * This function:
   *
@@ -664,7 +663,7 @@ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb);
   * #) sets up the queue,
   * #) negotiates number of buffers and planes per buffer with the driver
   *    to be used during streaming,
- * #) allocates internal buffer structures (struct vb2_buffer), according to
+ * #) allocates internal buffer structures (&struct vb2_buffer), according to
   *    the agreed parameters,
   * #) for MMAP memory type, allocates actual video memory, using the
   *    memory handling/allocation routines provided during queue initialization
@@ -779,7 +778,7 @@ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type);
   * @type:	buffer type
   * @index:	id number of the buffer
   * @plane:	index of the plane to be exported, 0 for single plane queues
- * @flags:	flags for newly created file, currently only O_CLOEXEC is
+ * @flags:	flags for newly created file, currently only %O_CLOEXEC is
   *		supported, refer to manual of open syscall for more details
   *
   * The return values from this function are intended to be directly returned
@@ -792,7 +791,7 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
   * vb2_core_queue_init() - initialize a videobuf2 queue
   * @q:		videobuf2 queue; this structure should be allocated in driver
   *
- * The vb2_queue structure should be allocated by the driver. The driver is
+ * The &vb2_queue structure should be allocated by the driver. The driver is
   * responsible of clearing it's content and setting initial values for some
   * required entries before calling this function.
   * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer

include/media/videobuf2-core.h void vb2_core_queue_release(struct vb2_queue *q); · line 825

Quoted 10 lines
include/media/videobuf2-core.h +2 -2
@@ -819,8 +818,8 @@ void vb2_core_queue_release(struct vb2_queue *q);
   * waiting on the queue. Polling will now set POLLERR and queuing and dequeuing
   * buffers will return -EIO.
   *
- * The error flag will be cleared when cancelling the queue, either from
- * vb2_streamoff or vb2_queue_release. Drivers should thus not call this
+ * The error flag will be cleared when canceling the queue, either from
+ * vb2_streamoff() or vb2_queue_release(). Drivers should thus not call this
   * function before starting the stream, otherwise the error flag will remain set
   * until the queue is released when closing the device node.
   */

Best regards

Signature · 2 lines
Marek Szyprowski, PhD
Samsung R&D Institute Poland
Acked-by on the v2 series
#54 lore raw
In reply to Mauro Carvalho Chehab

Hi Mauro,

Quoted 15 lines · Mauro Carvalho Chehab

This patch series is meant to improve V4L documentation. It touches some files at the tree doing some cleanup, in order to simplify the source code.

Mauro Carvalho Chehab (17):
media: tuner-types: add kernel-doc markups for struct tunertype
media: v4l2-common: get rid of v4l2_routing dead struct
media: v4l2-common: get rid of struct v4l2_discrete_probe
media: v4l2-common.h: document ancillary functions
media: v4l2-device.h: document ancillary macros
media: v4l2-dv-timings.h: convert comment into kernel-doc markup
media: v4l2-event.rst: improve events description
media: v4l2-ioctl.h: convert debug macros into enum and document
media: cec-pin.h: convert comments for cec_pin_state into kernel-doc
media: rc-core.rst: add an introduction for RC core

Quoted 8 lines

media: rc-core.h: minor adjustments at rc_driver_type doc
media: v4l2-fwnode.h: better describe bus union at fwnode endpoint
struct
media: v4l2-async: simplify v4l2_async_subdev structure
media: v4l2-async: better describe match union at async match struct
media: v4l2-ctrls: document nested members of structs
media: videobuf2-core: improve kernel-doc markups
media: media-entity.h: add kernel-doc markups for nested structs

For patches apart form 7 and 13 (see my comments to them):

Signature · 4 lines
Regards,

Sakari Ailus
e-mail: [email protected]
#55 lore raw

PATCH v2 17/17 media: media-entity.h: add kernel-doc markups for nested structs

In reply to Mauro Carvalho Chehab

Now that nested structs are parsed by kernel-doc, add markups to them.

---
 include/media/media-entity.h | 5 +++++
 1 file changed, 5 insertions(+)
include/media/media-entity.h +5 -0
index 222d379960b7..d7a669058b5e 100644
@@ -88,6 +88,8 @@ struct media_entity_enum {
  * @stack:		Graph traversal stack; the stack contains information
  *			on the path the media entities to be walked and the
  *			links through which they were reached.
+ * @stack.entity:	pointer to &struct media_entity at the graph.
+ * @stack.link:		pointer to &struct list_head.
  * @ent_enum:		Visited entities
  * @top:		The top of the stack
  */
@@ -247,6 +249,9 @@ enum media_entity_type {
  * @pipe:	Pipeline this entity belongs to.
  * @info:	Union with devnode information.  Kept just for backward
  *		compatibility.
+ * @info.dev:	Contains device major and minor info.
+ * @info.dev.major: device node major, if the device is a devnode.
+ * @info.dev.minor: device node minor, if the device is a devnode.
  * @major:	Devnode major number (zero if not applicable). Kept just
  *		for backward compatibility.
  * @minor:	Devnode minor number (zero if not applicable). Kept just
Signature · 1 line
2.13.5