[PATCH 02/10] v4l2-event: Add v4l2_subscribed_event_ops

2012-04-08 Thread Hans de Goede
Just like with ctrl events, drivers may want to get called back on
listener add / remove for other event types too. Rather then special
casing all of this in subscribe / unsubscribe event it is better to
use ops for this.

Signed-off-by: Hans de Goede 
Acked-by: Hans Verkuil 
---
 Documentation/video4linux/v4l2-framework.txt |   28 +
 drivers/media/video/ivtv/ivtv-ioctl.c|2 +-
 drivers/media/video/omap3isp/ispccdc.c   |2 +-
 drivers/media/video/omap3isp/ispstat.c   |2 +-
 drivers/media/video/v4l2-ctrls.c |2 +-
 drivers/media/video/v4l2-event.c |   54 --
 drivers/usb/gadget/uvc_v4l2.c|2 +-
 include/media/v4l2-event.h   |   24 
 8 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/Documentation/video4linux/v4l2-framework.txt 
b/Documentation/video4linux/v4l2-framework.txt
index 659b2ba..b77bb48 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -941,21 +941,35 @@ fast.
 
 Useful functions:
 
-- v4l2_event_queue()
+void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
 
   Queue events to video device. The driver's only responsibility is to fill
   in the type and the data fields. The other fields will be filled in by
   V4L2.
 
-- v4l2_event_subscribe()
+int v4l2_event_subscribe(struct v4l2_fh *fh,
+struct v4l2_event_subscription *sub, unsigned elems,
+const struct v4l2_subscribed_event_ops *ops)
 
   The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
   is able to produce events with specified event id. Then it calls
-  v4l2_event_subscribe() to subscribe the event. The last argument is the
-  size of the event queue for this event. If it is 0, then the framework
-  will fill in a default value (this depends on the event type).
+  v4l2_event_subscribe() to subscribe the event.
 
-- v4l2_event_unsubscribe()
+  The elems argument is the size of the event queue for this event. If it is 0,
+  then the framework will fill in a default value (this depends on the event
+  type).
+
+  The ops argument allows the driver to specify a number of callbacks:
+  * add: called when a new listener gets added (subscribing to the same
+ event twice will only cause this callback to get called once)
+  * del: called when a listener stops listening
+  * replace: replace event 'old' with event 'new'.
+  * merge:   merge event 'old' into event 'new'.
+  All 4 callbacks are optional, if you don't want to specify any callbacks
+  the ops argument itself maybe NULL.
+
+int v4l2_event_unsubscribe(struct v4l2_fh *fh,
+  struct v4l2_event_subscription *sub)
 
   vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
   v4l2_event_unsubscribe() directly unless it wants to be involved in
@@ -964,7 +978,7 @@ Useful functions:
   The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
   drivers may want to handle this in a special way.
 
-- v4l2_event_pending()
+int v4l2_event_pending(struct v4l2_fh *fh)
 
   Returns the number of pending events. Useful when implementing poll.
 
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index 5452bee..5b41e5b 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1469,7 +1469,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
struct v4l2_event_subscripti
case V4L2_EVENT_VSYNC:
case V4L2_EVENT_EOS:
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/omap3isp/ispccdc.c 
b/drivers/media/video/omap3isp/ispccdc.c
index eaabc27..1f3c16d 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1703,7 +1703,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, 
struct v4l2_fh *fh,
if (sub->id != 0)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
 }
 
 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
diff --git a/drivers/media/video/omap3isp/ispstat.c 
b/drivers/media/video/omap3isp/ispstat.c
index 11871ec..b8640be 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1032,7 +1032,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
*subdev,
if (sub->type != stat->event_type)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
 }
 
 int omap3isp_stat_unsubsc

[PATCH 03/10] v4l2-event: Add v4l2_subscribed_event_ops

2012-03-25 Thread Hans de Goede
Just like with ctrl events, drivers may want to get called back on
listener add / remove for other event types too. Rather then special
casing all of this in subscribe / unsubscribe event it is better to
use ops for this.

Signed-off-by: Hans de Goede 
Acked-by: Hans Verkuil 
---
 Documentation/video4linux/v4l2-framework.txt |   28 +
 drivers/media/video/ivtv/ivtv-ioctl.c|2 +-
 drivers/media/video/omap3isp/ispccdc.c   |2 +-
 drivers/media/video/omap3isp/ispstat.c   |2 +-
 drivers/media/video/v4l2-ctrls.c |2 +-
 drivers/media/video/v4l2-event.c |   54 --
 drivers/usb/gadget/uvc_v4l2.c|2 +-
 include/media/v4l2-event.h   |   24 
 8 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/Documentation/video4linux/v4l2-framework.txt 
b/Documentation/video4linux/v4l2-framework.txt
index 659b2ba..b77bb48 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -941,21 +941,35 @@ fast.
 
 Useful functions:
 
-- v4l2_event_queue()
+void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
 
   Queue events to video device. The driver's only responsibility is to fill
   in the type and the data fields. The other fields will be filled in by
   V4L2.
 
-- v4l2_event_subscribe()
+int v4l2_event_subscribe(struct v4l2_fh *fh,
+struct v4l2_event_subscription *sub, unsigned elems,
+const struct v4l2_subscribed_event_ops *ops)
 
   The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
   is able to produce events with specified event id. Then it calls
-  v4l2_event_subscribe() to subscribe the event. The last argument is the
-  size of the event queue for this event. If it is 0, then the framework
-  will fill in a default value (this depends on the event type).
+  v4l2_event_subscribe() to subscribe the event.
 
-- v4l2_event_unsubscribe()
+  The elems argument is the size of the event queue for this event. If it is 0,
+  then the framework will fill in a default value (this depends on the event
+  type).
+
+  The ops argument allows the driver to specify a number of callbacks:
+  * add: called when a new listener gets added (subscribing to the same
+ event twice will only cause this callback to get called once)
+  * del: called when a listener stops listening
+  * replace: replace event 'old' with event 'new'.
+  * merge:   merge event 'old' into event 'new'.
+  All 4 callbacks are optional, if you don't want to specify any callbacks
+  the ops argument itself maybe NULL.
+
+int v4l2_event_unsubscribe(struct v4l2_fh *fh,
+  struct v4l2_event_subscription *sub)
 
   vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
   v4l2_event_unsubscribe() directly unless it wants to be involved in
@@ -964,7 +978,7 @@ Useful functions:
   The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
   drivers may want to handle this in a special way.
 
-- v4l2_event_pending()
+int v4l2_event_pending(struct v4l2_fh *fh)
 
   Returns the number of pending events. Useful when implementing poll.
 
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index 5452bee..5b41e5b 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1469,7 +1469,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
struct v4l2_event_subscripti
case V4L2_EVENT_VSYNC:
case V4L2_EVENT_EOS:
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/omap3isp/ispccdc.c 
b/drivers/media/video/omap3isp/ispccdc.c
index eaabc27..1f3c16d 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1703,7 +1703,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, 
struct v4l2_fh *fh,
if (sub->id != 0)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
 }
 
 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
diff --git a/drivers/media/video/omap3isp/ispstat.c 
b/drivers/media/video/omap3isp/ispstat.c
index 11871ec..b8640be 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1032,7 +1032,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
*subdev,
if (sub->type != stat->event_type)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
 }
 
 int omap3isp_stat_unsubsc

[PATCH 3/6] v4l2-event: Add v4l2_subscribed_event_ops

2012-03-23 Thread Hans de Goede
Just like with ctrl events, drivers may want to get called back on
listener add / remove for other event types too. Rather then special
casing all of this in subscribe / unsubscribe event it is better to
use ops for this.

Signed-off-by: Hans de Goede 
Acked-by: Hans Verkuil 
---
 Documentation/video4linux/v4l2-framework.txt |   28 +
 drivers/media/video/ivtv/ivtv-ioctl.c|2 +-
 drivers/media/video/omap3isp/ispccdc.c   |2 +-
 drivers/media/video/omap3isp/ispstat.c   |2 +-
 drivers/media/video/v4l2-ctrls.c |2 +-
 drivers/media/video/v4l2-event.c |   54 --
 drivers/usb/gadget/uvc_v4l2.c|2 +-
 include/media/v4l2-event.h   |   24 
 8 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/Documentation/video4linux/v4l2-framework.txt 
b/Documentation/video4linux/v4l2-framework.txt
index 659b2ba..b77bb48 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -941,21 +941,35 @@ fast.
 
 Useful functions:
 
-- v4l2_event_queue()
+void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
 
   Queue events to video device. The driver's only responsibility is to fill
   in the type and the data fields. The other fields will be filled in by
   V4L2.
 
-- v4l2_event_subscribe()
+int v4l2_event_subscribe(struct v4l2_fh *fh,
+struct v4l2_event_subscription *sub, unsigned elems,
+const struct v4l2_subscribed_event_ops *ops)
 
   The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
   is able to produce events with specified event id. Then it calls
-  v4l2_event_subscribe() to subscribe the event. The last argument is the
-  size of the event queue for this event. If it is 0, then the framework
-  will fill in a default value (this depends on the event type).
+  v4l2_event_subscribe() to subscribe the event.
 
-- v4l2_event_unsubscribe()
+  The elems argument is the size of the event queue for this event. If it is 0,
+  then the framework will fill in a default value (this depends on the event
+  type).
+
+  The ops argument allows the driver to specify a number of callbacks:
+  * add: called when a new listener gets added (subscribing to the same
+ event twice will only cause this callback to get called once)
+  * del: called when a listener stops listening
+  * replace: replace event 'old' with event 'new'.
+  * merge:   merge event 'old' into event 'new'.
+  All 4 callbacks are optional, if you don't want to specify any callbacks
+  the ops argument itself maybe NULL.
+
+int v4l2_event_unsubscribe(struct v4l2_fh *fh,
+  struct v4l2_event_subscription *sub)
 
   vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
   v4l2_event_unsubscribe() directly unless it wants to be involved in
@@ -964,7 +978,7 @@ Useful functions:
   The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
   drivers may want to handle this in a special way.
 
-- v4l2_event_pending()
+int v4l2_event_pending(struct v4l2_fh *fh)
 
   Returns the number of pending events. Useful when implementing poll.
 
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index 5452bee..5b41e5b 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1469,7 +1469,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
struct v4l2_event_subscripti
case V4L2_EVENT_VSYNC:
case V4L2_EVENT_EOS:
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/omap3isp/ispccdc.c 
b/drivers/media/video/omap3isp/ispccdc.c
index eaabc27..1f3c16d 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1703,7 +1703,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, 
struct v4l2_fh *fh,
if (sub->id != 0)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
 }
 
 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
diff --git a/drivers/media/video/omap3isp/ispstat.c 
b/drivers/media/video/omap3isp/ispstat.c
index 11871ec..b8640be 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1032,7 +1032,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
*subdev,
if (sub->type != stat->event_type)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
 }
 
 int omap3isp_stat_unsubsc

Re: [PATCH 4/5] v4l2-event: Add v4l2_subscribed_event_ops

2011-11-02 Thread Hans Verkuil
On Wednesday 02 November 2011 11:13:24 Hans de Goede wrote:
> Just like with ctrl events, drivers may want to get called back on
> listener add / remove for other event types too. Rather then special
> casing all of this in subscribe / unsubscribe event it is better to
> use ops for this.
> 
> Signed-off-by: Hans de Goede 

Acked-by: Hans Verkuil 

> ---
>  Documentation/video4linux/v4l2-framework.txt |   28 ++---
>  drivers/media/video/ivtv/ivtv-ioctl.c|2 +-
>  drivers/media/video/omap3isp/ispccdc.c   |2 +-
>  drivers/media/video/omap3isp/ispstat.c   |2 +-
>  drivers/media/video/pwc/pwc-v4l.c|2 +-
>  drivers/media/video/v4l2-event.c |   54
> - drivers/media/video/vivi.c   |  
>  2 +-
>  include/media/v4l2-event.h   |   24 ---
>  8 files changed, 86 insertions(+), 30 deletions(-)
> 
> diff --git a/Documentation/video4linux/v4l2-framework.txt
> b/Documentation/video4linux/v4l2-framework.txt index f8dcabf..16eb8af
> 100644
> --- a/Documentation/video4linux/v4l2-framework.txt
> +++ b/Documentation/video4linux/v4l2-framework.txt
> @@ -930,21 +930,35 @@ fast.
> 
>  Useful functions:
> 
> -- v4l2_event_queue()
> +void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event
> *ev)
> 
>Queue events to video device. The driver's only responsibility is to
> fill in the type and the data fields. The other fields will be filled in
> by V4L2.
> 
> -- v4l2_event_subscribe()
> +int v4l2_event_subscribe(struct v4l2_fh *fh,
> +  struct v4l2_event_subscription *sub, unsigned elems,
> +  const struct v4l2_subscribed_event_ops *ops)
> 
>The video_device->ioctl_ops->vidioc_subscribe_event must check the
> driver is able to produce events with specified event id. Then it calls - 
> v4l2_event_subscribe() to subscribe the event. The last argument is the - 
> size of the event queue for this event. If it is 0, then the framework - 
> will fill in a default value (this depends on the event type).
> +  v4l2_event_subscribe() to subscribe the event.
> 
> -- v4l2_event_unsubscribe()
> +  The elems argument is the size of the event queue for this event. If it
> is 0, +  then the framework will fill in a default value (this depends on
> the event +  type).
> +
> +  The ops argument allows the driver to specify a number of callbacks:
> +  * add: called when a new listener gets added (subscribing to the
> same + event twice will only cause this callback to get called
> once) +  * del: called when a listener stops listening
> +  * replace: replace event 'old' with event 'new'.
> +  * merge:   merge event 'old' into event 'new'.
> +  All 4 callbacks are optional, if you don't want to specify any callbacks
> +  the ops argument itself maybe NULL.
> +
> +int v4l2_event_unsubscribe(struct v4l2_fh *fh,
> +struct v4l2_event_subscription *sub)
> 
>vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
>v4l2_event_unsubscribe() directly unless it wants to be involved in
> @@ -953,7 +967,7 @@ Useful functions:
>The special type V4L2_EVENT_ALL may be used to unsubscribe all events.
> The drivers may want to handle this in a special way.
> 
> -- v4l2_event_pending()
> +int v4l2_event_pending(struct v4l2_fh *fh)
> 
>Returns the number of pending events. Useful when implementing poll.
> 
> diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c
> b/drivers/media/video/ivtv/ivtv-ioctl.c index ecafa69..9aec8a0 100644
> --- a/drivers/media/video/ivtv/ivtv-ioctl.c
> +++ b/drivers/media/video/ivtv/ivtv-ioctl.c
> @@ -1456,7 +1456,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh,
> struct v4l2_event_subscripti case V4L2_EVENT_VSYNC:
>   case V4L2_EVENT_EOS:
>   case V4L2_EVENT_CTRL:
> - return v4l2_event_subscribe(fh, sub, 0);
> + return v4l2_event_subscribe(fh, sub, 0, NULL);
>   default:
>   return -EINVAL;
>   }
> diff --git a/drivers/media/video/omap3isp/ispccdc.c
> b/drivers/media/video/omap3isp/ispccdc.c index 40b141c..b6da736 100644
> --- a/drivers/media/video/omap3isp/ispccdc.c
> +++ b/drivers/media/video/omap3isp/ispccdc.c
> @@ -1700,7 +1700,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev
> *sd, struct v4l2_fh *fh, if (sub->id != 0)
>   return -EINVAL;
> 
> - return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
> + return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
>  }
> 
>  static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh
> *fh, diff --git a/drivers/media/video/omap3isp/ispstat.c
> b/drivers/media/video/omap3isp/ispstat.c index 8080659..4f337a2 100644
> --- a/drivers/media/video/omap3isp/ispstat.c
> +++ b/drivers/media/video/omap3isp/ispstat.c
> @@ -1049,7 +1049,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev
> *subdev, if (sub->type != stat->event_type)

[PATCH 4/5] v4l2-event: Add v4l2_subscribed_event_ops

2011-11-02 Thread Hans de Goede
Just like with ctrl events, drivers may want to get called back on
listener add / remove for other event types too. Rather then special
casing all of this in subscribe / unsubscribe event it is better to
use ops for this.

Signed-off-by: Hans de Goede 
---
 Documentation/video4linux/v4l2-framework.txt |   28 ++---
 drivers/media/video/ivtv/ivtv-ioctl.c|2 +-
 drivers/media/video/omap3isp/ispccdc.c   |2 +-
 drivers/media/video/omap3isp/ispstat.c   |2 +-
 drivers/media/video/pwc/pwc-v4l.c|2 +-
 drivers/media/video/v4l2-event.c |   54 -
 drivers/media/video/vivi.c   |2 +-
 include/media/v4l2-event.h   |   24 ---
 8 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/Documentation/video4linux/v4l2-framework.txt 
b/Documentation/video4linux/v4l2-framework.txt
index f8dcabf..16eb8af 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -930,21 +930,35 @@ fast.
 
 Useful functions:
 
-- v4l2_event_queue()
+void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
 
   Queue events to video device. The driver's only responsibility is to fill
   in the type and the data fields. The other fields will be filled in by
   V4L2.
 
-- v4l2_event_subscribe()
+int v4l2_event_subscribe(struct v4l2_fh *fh,
+struct v4l2_event_subscription *sub, unsigned elems,
+const struct v4l2_subscribed_event_ops *ops)
 
   The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
   is able to produce events with specified event id. Then it calls
-  v4l2_event_subscribe() to subscribe the event. The last argument is the
-  size of the event queue for this event. If it is 0, then the framework
-  will fill in a default value (this depends on the event type).
+  v4l2_event_subscribe() to subscribe the event.
 
-- v4l2_event_unsubscribe()
+  The elems argument is the size of the event queue for this event. If it is 0,
+  then the framework will fill in a default value (this depends on the event
+  type).
+
+  The ops argument allows the driver to specify a number of callbacks:
+  * add: called when a new listener gets added (subscribing to the same
+ event twice will only cause this callback to get called once)
+  * del: called when a listener stops listening
+  * replace: replace event 'old' with event 'new'.
+  * merge:   merge event 'old' into event 'new'.
+  All 4 callbacks are optional, if you don't want to specify any callbacks
+  the ops argument itself maybe NULL.
+
+int v4l2_event_unsubscribe(struct v4l2_fh *fh,
+  struct v4l2_event_subscription *sub)
 
   vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
   v4l2_event_unsubscribe() directly unless it wants to be involved in
@@ -953,7 +967,7 @@ Useful functions:
   The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
   drivers may want to handle this in a special way.
 
-- v4l2_event_pending()
+int v4l2_event_pending(struct v4l2_fh *fh)
 
   Returns the number of pending events. Useful when implementing poll.
 
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index ecafa69..9aec8a0 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1456,7 +1456,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
struct v4l2_event_subscripti
case V4L2_EVENT_VSYNC:
case V4L2_EVENT_EOS:
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/omap3isp/ispccdc.c 
b/drivers/media/video/omap3isp/ispccdc.c
index 40b141c..b6da736 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1700,7 +1700,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, 
struct v4l2_fh *fh,
if (sub->id != 0)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
 }
 
 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
diff --git a/drivers/media/video/omap3isp/ispstat.c 
b/drivers/media/video/omap3isp/ispstat.c
index 8080659..4f337a2 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1049,7 +1049,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
*subdev,
if (sub->type != stat->event_type)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
 }
 
 int omap3isp_stat_unsubscribe_event(struct v4l2_sub

Re: [PATCH 5/6] v4l2-event: Add v4l2_subscribed_event_ops

2011-11-02 Thread Hans de Goede

Hi,

hverkuil wrote:

> > + if (sev->ops && sev->ops->add) {
> > + int ret = sev->ops->add(sev);
> > + if (ret) {
> > + sev->ops = NULL;
> > + v4l2_event_unsubscribe(fh, sub);
> > + return ret;
> > + }

The problem here is that the event is basically available for use after the
spin_unlock_irqrestore(), but before the sev->ops->add() call. In the past I
just 'knew' that the event would never be generated by the control framework
until after v4l2_ctrl_add_event was called, but this should be formalized now
that these ops are added.

I see two options:

1) Have some method to mark the sev as being 'invalid' so functions sending
events can skip it (needed as well for your patch 4/6).

2) Document that drivers should never be able to send an event until after
the add() callback has succeeded.

I am leaning towards option 1 myself.

How about leaving sev->elems at 0 until after the add() op succeeds?

That's easy to test against and easy to implement.


I agree that option 1 is the best and that leaving sev->elems 0 is a good
way to do this. This will be in my next revision of this patch set.

Thanks & Regards,

Hans

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/6] v4l2-event: Add v4l2_subscribed_event_ops

2011-10-31 Thread Hans de Goede
Just like with ctrl events, drivers may want to get called back on
listener add / remove for other event types too. Rather then special
casing all of this in subscribe / unsubscribe event it is better to
use ops for this.

Signed-off-by: Hans de Goede 
---
 Documentation/video4linux/v4l2-framework.txt |   28 +
 drivers/media/video/ivtv/ivtv-ioctl.c|2 +-
 drivers/media/video/omap3isp/ispccdc.c   |2 +-
 drivers/media/video/omap3isp/ispstat.c   |2 +-
 drivers/media/video/pwc/pwc-v4l.c|2 +-
 drivers/media/video/v4l2-event.c |   42 +++--
 drivers/media/video/vivi.c   |2 +-
 include/media/v4l2-event.h   |   24 ++
 8 files changed, 75 insertions(+), 29 deletions(-)

diff --git a/Documentation/video4linux/v4l2-framework.txt 
b/Documentation/video4linux/v4l2-framework.txt
index f8dcabf..16eb8af 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -930,21 +930,35 @@ fast.
 
 Useful functions:
 
-- v4l2_event_queue()
+void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
 
   Queue events to video device. The driver's only responsibility is to fill
   in the type and the data fields. The other fields will be filled in by
   V4L2.
 
-- v4l2_event_subscribe()
+int v4l2_event_subscribe(struct v4l2_fh *fh,
+struct v4l2_event_subscription *sub, unsigned elems,
+const struct v4l2_subscribed_event_ops *ops)
 
   The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
   is able to produce events with specified event id. Then it calls
-  v4l2_event_subscribe() to subscribe the event. The last argument is the
-  size of the event queue for this event. If it is 0, then the framework
-  will fill in a default value (this depends on the event type).
+  v4l2_event_subscribe() to subscribe the event.
 
-- v4l2_event_unsubscribe()
+  The elems argument is the size of the event queue for this event. If it is 0,
+  then the framework will fill in a default value (this depends on the event
+  type).
+
+  The ops argument allows the driver to specify a number of callbacks:
+  * add: called when a new listener gets added (subscribing to the same
+ event twice will only cause this callback to get called once)
+  * del: called when a listener stops listening
+  * replace: replace event 'old' with event 'new'.
+  * merge:   merge event 'old' into event 'new'.
+  All 4 callbacks are optional, if you don't want to specify any callbacks
+  the ops argument itself maybe NULL.
+
+int v4l2_event_unsubscribe(struct v4l2_fh *fh,
+  struct v4l2_event_subscription *sub)
 
   vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
   v4l2_event_unsubscribe() directly unless it wants to be involved in
@@ -953,7 +967,7 @@ Useful functions:
   The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
   drivers may want to handle this in a special way.
 
-- v4l2_event_pending()
+int v4l2_event_pending(struct v4l2_fh *fh)
 
   Returns the number of pending events. Useful when implementing poll.
 
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index ecafa69..9aec8a0 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1456,7 +1456,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
struct v4l2_event_subscripti
case V4L2_EVENT_VSYNC:
case V4L2_EVENT_EOS:
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/omap3isp/ispccdc.c 
b/drivers/media/video/omap3isp/ispccdc.c
index 40b141c..b6da736 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1700,7 +1700,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, 
struct v4l2_fh *fh,
if (sub->id != 0)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
 }
 
 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
diff --git a/drivers/media/video/omap3isp/ispstat.c 
b/drivers/media/video/omap3isp/ispstat.c
index 8080659..4f337a2 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1049,7 +1049,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
*subdev,
if (sub->type != stat->event_type)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
 }
 
 int omap3isp_stat_unsubscribe_event(struct v

Re: [PATCH 5/6] v4l2-event: Add v4l2_subscribed_event_ops

2011-10-30 Thread Hans Verkuil
On Sunday, October 30, 2011 12:17:28 Hans Verkuil wrote:
> On Thursday, October 27, 2011 13:18:02 Hans de Goede wrote:
> > Just like with ctrl events, drivers may want to get called back on
> > listener add / remove for other event types too. Rather then special
> > casing all of this in subscribe / unsubscribe event it is better to
> > use ops for this.
> > 
> > Signed-off-by: Hans de Goede 
> 
> Acked-by: Hans Verkuil 

Scratch this ack. I've found a race condition, see below...

> 
> Regards,
> 
>   Hans
> 
> > ---
> >  drivers/media/video/ivtv/ivtv-ioctl.c  |2 +-
> >  drivers/media/video/omap3isp/ispccdc.c |2 +-
> >  drivers/media/video/omap3isp/ispstat.c |2 +-
> >  drivers/media/video/pwc/pwc-v4l.c  |2 +-
> >  drivers/media/video/v4l2-event.c   |   42 
> > ---
> >  drivers/media/video/vivi.c |2 +-
> >  include/media/v4l2-event.h |   24 +-
> >  7 files changed, 54 insertions(+), 22 deletions(-)
> > 
> > diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
> > b/drivers/media/video/ivtv/ivtv-ioctl.c
> > index ecafa69..9aec8a0 100644
> > --- a/drivers/media/video/ivtv/ivtv-ioctl.c
> > +++ b/drivers/media/video/ivtv/ivtv-ioctl.c
> > @@ -1456,7 +1456,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
> > struct v4l2_event_subscripti
> > case V4L2_EVENT_VSYNC:
> > case V4L2_EVENT_EOS:
> > case V4L2_EVENT_CTRL:
> > -   return v4l2_event_subscribe(fh, sub, 0);
> > +   return v4l2_event_subscribe(fh, sub, 0, NULL);
> > default:
> > return -EINVAL;
> > }
> > diff --git a/drivers/media/video/omap3isp/ispccdc.c 
> > b/drivers/media/video/omap3isp/ispccdc.c
> > index 40b141c..b6da736 100644
> > --- a/drivers/media/video/omap3isp/ispccdc.c
> > +++ b/drivers/media/video/omap3isp/ispccdc.c
> > @@ -1700,7 +1700,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev 
> > *sd, struct v4l2_fh *fh,
> > if (sub->id != 0)
> > return -EINVAL;
> >  
> > -   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
> > +   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
> >  }
> >  
> >  static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh 
> > *fh,
> > diff --git a/drivers/media/video/omap3isp/ispstat.c 
> > b/drivers/media/video/omap3isp/ispstat.c
> > index 8080659..4f337a2 100644
> > --- a/drivers/media/video/omap3isp/ispstat.c
> > +++ b/drivers/media/video/omap3isp/ispstat.c
> > @@ -1049,7 +1049,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
> > *subdev,
> > if (sub->type != stat->event_type)
> > return -EINVAL;
> >  
> > -   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
> > +   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
> >  }
> >  
> >  int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
> > diff --git a/drivers/media/video/pwc/pwc-v4l.c 
> > b/drivers/media/video/pwc/pwc-v4l.c
> > index 68e1323..7f159bf 100644
> > --- a/drivers/media/video/pwc/pwc-v4l.c
> > +++ b/drivers/media/video/pwc/pwc-v4l.c
> > @@ -1138,7 +1138,7 @@ static int pwc_subscribe_event(struct v4l2_fh *fh,
> >  {
> > switch (sub->type) {
> > case V4L2_EVENT_CTRL:
> > -   return v4l2_event_subscribe(fh, sub, 0);
> > +   return v4l2_event_subscribe(fh, sub, 0, NULL);
> > default:
> > return -EINVAL;
> > }
> > diff --git a/drivers/media/video/v4l2-event.c 
> > b/drivers/media/video/v4l2-event.c
> > index 3d27300..2dd9252 100644
> > --- a/drivers/media/video/v4l2-event.c
> > +++ b/drivers/media/video/v4l2-event.c
> > @@ -131,14 +131,14 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, 
> > const struct v4l2_event *e
> > sev->first = sev_pos(sev, 1);
> > fh->navailable--;
> > if (sev->elems == 1) {
> > -   if (sev->replace) {
> > -   sev->replace(&kev->event, ev);
> > +   if (sev->ops && sev->ops->replace) {
> > +   sev->ops->replace(&kev->event, ev);
> > copy_payload = false;
> > }
> > -   } else if (sev->merge) {
> > +   } else if (sev->ops && sev->ops->merge) {
> > struct v4l2_kevent *second_oldest =
> > sev->events + sev_pos(sev, 0);
> > -   sev->merge(&kev->event, &second_oldest->event);
> > +   sev->ops->merge(&kev->event, &second_oldest->event);
> > }
> > }
> >  
> > @@ -207,8 +207,14 @@ static void ctrls_merge(const struct v4l2_event *old, 
> > struct v4l2_event *new)
> > new->u.ctrl.changes |= old->u.ctrl.changes;
> >  }
> >  
> > +const struct v4l2_subscribed_event_ops ctrl_ops = {
> > +   .replace = ctrls_replace,
> > +   .merge = ctrls_merge,
> > +};
> > +
> >  int v4l2_event_subscribe(struct v4l2_fh *fh,
> > -struct v4l2_event_subscr

Re: [PATCH 5/6] v4l2-event: Add v4l2_subscribed_event_ops

2011-10-30 Thread Hans Verkuil
On Thursday, October 27, 2011 13:18:02 Hans de Goede wrote:
> Just like with ctrl events, drivers may want to get called back on
> listener add / remove for other event types too. Rather then special
> casing all of this in subscribe / unsubscribe event it is better to
> use ops for this.
> 
> Signed-off-by: Hans de Goede 

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/media/video/ivtv/ivtv-ioctl.c  |2 +-
>  drivers/media/video/omap3isp/ispccdc.c |2 +-
>  drivers/media/video/omap3isp/ispstat.c |2 +-
>  drivers/media/video/pwc/pwc-v4l.c  |2 +-
>  drivers/media/video/v4l2-event.c   |   42 ---
>  drivers/media/video/vivi.c |2 +-
>  include/media/v4l2-event.h |   24 +-
>  7 files changed, 54 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
> b/drivers/media/video/ivtv/ivtv-ioctl.c
> index ecafa69..9aec8a0 100644
> --- a/drivers/media/video/ivtv/ivtv-ioctl.c
> +++ b/drivers/media/video/ivtv/ivtv-ioctl.c
> @@ -1456,7 +1456,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
> struct v4l2_event_subscripti
>   case V4L2_EVENT_VSYNC:
>   case V4L2_EVENT_EOS:
>   case V4L2_EVENT_CTRL:
> - return v4l2_event_subscribe(fh, sub, 0);
> + return v4l2_event_subscribe(fh, sub, 0, NULL);
>   default:
>   return -EINVAL;
>   }
> diff --git a/drivers/media/video/omap3isp/ispccdc.c 
> b/drivers/media/video/omap3isp/ispccdc.c
> index 40b141c..b6da736 100644
> --- a/drivers/media/video/omap3isp/ispccdc.c
> +++ b/drivers/media/video/omap3isp/ispccdc.c
> @@ -1700,7 +1700,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, 
> struct v4l2_fh *fh,
>   if (sub->id != 0)
>   return -EINVAL;
>  
> - return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
> + return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
>  }
>  
>  static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
> diff --git a/drivers/media/video/omap3isp/ispstat.c 
> b/drivers/media/video/omap3isp/ispstat.c
> index 8080659..4f337a2 100644
> --- a/drivers/media/video/omap3isp/ispstat.c
> +++ b/drivers/media/video/omap3isp/ispstat.c
> @@ -1049,7 +1049,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
> *subdev,
>   if (sub->type != stat->event_type)
>   return -EINVAL;
>  
> - return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
> + return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
>  }
>  
>  int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
> diff --git a/drivers/media/video/pwc/pwc-v4l.c 
> b/drivers/media/video/pwc/pwc-v4l.c
> index 68e1323..7f159bf 100644
> --- a/drivers/media/video/pwc/pwc-v4l.c
> +++ b/drivers/media/video/pwc/pwc-v4l.c
> @@ -1138,7 +1138,7 @@ static int pwc_subscribe_event(struct v4l2_fh *fh,
>  {
>   switch (sub->type) {
>   case V4L2_EVENT_CTRL:
> - return v4l2_event_subscribe(fh, sub, 0);
> + return v4l2_event_subscribe(fh, sub, 0, NULL);
>   default:
>   return -EINVAL;
>   }
> diff --git a/drivers/media/video/v4l2-event.c 
> b/drivers/media/video/v4l2-event.c
> index 3d27300..2dd9252 100644
> --- a/drivers/media/video/v4l2-event.c
> +++ b/drivers/media/video/v4l2-event.c
> @@ -131,14 +131,14 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, 
> const struct v4l2_event *e
>   sev->first = sev_pos(sev, 1);
>   fh->navailable--;
>   if (sev->elems == 1) {
> - if (sev->replace) {
> - sev->replace(&kev->event, ev);
> + if (sev->ops && sev->ops->replace) {
> + sev->ops->replace(&kev->event, ev);
>   copy_payload = false;
>   }
> - } else if (sev->merge) {
> + } else if (sev->ops && sev->ops->merge) {
>   struct v4l2_kevent *second_oldest =
>   sev->events + sev_pos(sev, 0);
> - sev->merge(&kev->event, &second_oldest->event);
> + sev->ops->merge(&kev->event, &second_oldest->event);
>   }
>   }
>  
> @@ -207,8 +207,14 @@ static void ctrls_merge(const struct v4l2_event *old, 
> struct v4l2_event *new)
>   new->u.ctrl.changes |= old->u.ctrl.changes;
>  }
>  
> +const struct v4l2_subscribed_event_ops ctrl_ops = {
> + .replace = ctrls_replace,
> + .merge = ctrls_merge,
> +};
> +
>  int v4l2_event_subscribe(struct v4l2_fh *fh,
> -  struct v4l2_event_subscription *sub, unsigned elems)
> +  struct v4l2_event_subscription *sub, unsigned elems,
> +  const struct v4l2_subscribed_event_ops *ops)
>  {
>   struct v4l2_subscribed_event *sev, *found_ev;
>   struct v4l2_ctrl *ctrl = NULL;
> @@

Re: [PATCH 5/6] v4l2-event: Add v4l2_subscribed_event_ops

2011-10-28 Thread Hans de Goede

Hi,

On 10/27/2011 02:30 PM, Laurent Pinchart wrote:

Hi Hans,

On Thursday 27 October 2011 13:18:02 Hans de Goede wrote:

Just like with ctrl events, drivers may want to get called back on
listener add / remove for other event types too. Rather then special
casing all of this in subscribe / unsubscribe event it is better to
use ops for this.

Signed-off-by: Hans de Goede
---
  drivers/media/video/ivtv/ivtv-ioctl.c  |2 +-
  drivers/media/video/omap3isp/ispccdc.c |2 +-
  drivers/media/video/omap3isp/ispstat.c |2 +-
  drivers/media/video/pwc/pwc-v4l.c  |2 +-
  drivers/media/video/v4l2-event.c   |   42 ++---
  drivers/media/video/vivi.c |2 +-
  include/media/v4l2-event.h |   24 +-


Haven't you forgotten to update Documentation/video4linux/v4l2-framework.txt ?



I think I have, I'll go and do another revision fixing this.


  7 files changed, 54 insertions(+), 22 deletions(-)


[snip]


diff --git a/drivers/media/video/v4l2-event.c
b/drivers/media/video/v4l2-event.c index 3d27300..2dd9252 100644
--- a/drivers/media/video/v4l2-event.c
+++ b/drivers/media/video/v4l2-event.c
@@ -131,14 +131,14 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh,
const struct v4l2_event *e sev->first = sev_pos(sev, 1);
fh->navailable--;
if (sev->elems == 1) {
-   if (sev->replace) {
-   sev->replace(&kev->event, ev);
+   if (sev->ops&&  sev->ops->replace) {
+   sev->ops->replace(&kev->event, ev);
copy_payload = false;
}
-   } else if (sev->merge) {
+   } else if (sev->ops&&  sev->ops->merge) {
struct v4l2_kevent *second_oldest =
sev->events + sev_pos(sev, 0);
-   sev->merge(&kev->event,&second_oldest->event);
+   sev->ops->merge(&kev->event,&second_oldest->event);
}
}

@@ -207,8 +207,14 @@ static void ctrls_merge(const struct v4l2_event *old,
struct v4l2_event *new) new->u.ctrl.changes |= old->u.ctrl.changes;
  }

+const struct v4l2_subscribed_event_ops ctrl_ops = {


Shouldn't this be static const ?



You're right I will fix this in the next iteration.


+   .replace = ctrls_replace,
+   .merge = ctrls_merge,
+};
+
  int v4l2_event_subscribe(struct v4l2_fh *fh,
-struct v4l2_event_subscription *sub, unsigned elems)
+struct v4l2_event_subscription *sub, unsigned elems,
+const struct v4l2_subscribed_event_ops *ops)
  {
struct v4l2_subscribed_event *sev, *found_ev;
struct v4l2_ctrl *ctrl = NULL;
@@ -236,9 +242,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
sev->flags = sub->flags;
sev->fh = fh;
sev->elems = elems;
+   sev->ops = ops;
if (ctrl) {
-   sev->replace = ctrls_replace;
-   sev->merge = ctrls_merge;
+   sev->ops =&ctrl_ops;
}


You can remove the brackets here.



I was aiming for minimal diff size here, since this bit will go away in the
next patch in the series anyways.



spin_lock_irqsave(&fh->vdev->fh_lock, flags);
@@ -247,10 +253,22 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
list_add(&sev->list,&fh->subscribed);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);

-   /* v4l2_ctrl_add_event uses a mutex, so do this outside the spin lock */
-   if (found_ev)
+   if (found_ev) {
kfree(sev);
-   else if (ctrl)
+   return 0; /* Already listening */
+   }
+
+   if (sev->ops&&  sev->ops->add) {
+   int ret = sev->ops->add(sev);
+   if (ret) {
+   sev->ops = NULL;
+   v4l2_event_unsubscribe(fh, sub);
+   return ret;
+   }
+   }
+
+   /* v4l2_ctrl_add_event uses a mutex, so do this outside the spin lock */
+   if (ctrl)
v4l2_ctrl_add_event(ctrl, sev);

return 0;
@@ -307,6 +325,10 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
}

spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
+
+   if (sev&&  sev->ops&&  sev->ops->del)
+   sev->ops->del(sev);
+
if (sev&&  sev->type == V4L2_EVENT_CTRL) {
struct v4l2_ctrl *ctrl = v4l2_ctrl_find(fh->ctrl_handler, 
sev->id);





Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/6] v4l2-event: Add v4l2_subscribed_event_ops

2011-10-27 Thread Laurent Pinchart
Hi Hans,

On Thursday 27 October 2011 13:18:02 Hans de Goede wrote:
> Just like with ctrl events, drivers may want to get called back on
> listener add / remove for other event types too. Rather then special
> casing all of this in subscribe / unsubscribe event it is better to
> use ops for this.
> 
> Signed-off-by: Hans de Goede 
> ---
>  drivers/media/video/ivtv/ivtv-ioctl.c  |2 +-
>  drivers/media/video/omap3isp/ispccdc.c |2 +-
>  drivers/media/video/omap3isp/ispstat.c |2 +-
>  drivers/media/video/pwc/pwc-v4l.c  |2 +-
>  drivers/media/video/v4l2-event.c   |   42 ++---
>  drivers/media/video/vivi.c |2 +-
>  include/media/v4l2-event.h |   24 +-

Haven't you forgotten to update Documentation/video4linux/v4l2-framework.txt ?

>  7 files changed, 54 insertions(+), 22 deletions(-)

[snip]

> diff --git a/drivers/media/video/v4l2-event.c
> b/drivers/media/video/v4l2-event.c index 3d27300..2dd9252 100644
> --- a/drivers/media/video/v4l2-event.c
> +++ b/drivers/media/video/v4l2-event.c
> @@ -131,14 +131,14 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh,
> const struct v4l2_event *e sev->first = sev_pos(sev, 1);
>   fh->navailable--;
>   if (sev->elems == 1) {
> - if (sev->replace) {
> - sev->replace(&kev->event, ev);
> + if (sev->ops && sev->ops->replace) {
> + sev->ops->replace(&kev->event, ev);
>   copy_payload = false;
>   }
> - } else if (sev->merge) {
> + } else if (sev->ops && sev->ops->merge) {
>   struct v4l2_kevent *second_oldest =
>   sev->events + sev_pos(sev, 0);
> - sev->merge(&kev->event, &second_oldest->event);
> + sev->ops->merge(&kev->event, &second_oldest->event);
>   }
>   }
> 
> @@ -207,8 +207,14 @@ static void ctrls_merge(const struct v4l2_event *old,
> struct v4l2_event *new) new->u.ctrl.changes |= old->u.ctrl.changes;
>  }
> 
> +const struct v4l2_subscribed_event_ops ctrl_ops = {

Shouldn't this be static const ?

> + .replace = ctrls_replace,
> + .merge = ctrls_merge,
> +};
> +
>  int v4l2_event_subscribe(struct v4l2_fh *fh,
> -  struct v4l2_event_subscription *sub, unsigned elems)
> +  struct v4l2_event_subscription *sub, unsigned elems,
> +  const struct v4l2_subscribed_event_ops *ops)
>  {
>   struct v4l2_subscribed_event *sev, *found_ev;
>   struct v4l2_ctrl *ctrl = NULL;
> @@ -236,9 +242,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
>   sev->flags = sub->flags;
>   sev->fh = fh;
>   sev->elems = elems;
> + sev->ops = ops;
>   if (ctrl) {
> - sev->replace = ctrls_replace;
> - sev->merge = ctrls_merge;
> + sev->ops = &ctrl_ops;
>   }

You can remove the brackets here.

> 
>   spin_lock_irqsave(&fh->vdev->fh_lock, flags);
> @@ -247,10 +253,22 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
>   list_add(&sev->list, &fh->subscribed);
>   spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
> 
> - /* v4l2_ctrl_add_event uses a mutex, so do this outside the spin lock */
> - if (found_ev)
> + if (found_ev) {
>   kfree(sev);
> - else if (ctrl)
> + return 0; /* Already listening */
> + }
> +
> + if (sev->ops && sev->ops->add) {
> + int ret = sev->ops->add(sev);
> + if (ret) {
> + sev->ops = NULL;
> + v4l2_event_unsubscribe(fh, sub);
> + return ret;
> + }
> + }
> +
> + /* v4l2_ctrl_add_event uses a mutex, so do this outside the spin lock */
> + if (ctrl)
>   v4l2_ctrl_add_event(ctrl, sev);
> 
>   return 0;
> @@ -307,6 +325,10 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
>   }
> 
>   spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
> +
> + if (sev && sev->ops && sev->ops->del)
> + sev->ops->del(sev);
> +
>   if (sev && sev->type == V4L2_EVENT_CTRL) {
>   struct v4l2_ctrl *ctrl = v4l2_ctrl_find(fh->ctrl_handler, 
> sev->id);
> 

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/6] v4l2-event: Add v4l2_subscribed_event_ops

2011-10-27 Thread Hans de Goede
Just like with ctrl events, drivers may want to get called back on
listener add / remove for other event types too. Rather then special
casing all of this in subscribe / unsubscribe event it is better to
use ops for this.

Signed-off-by: Hans de Goede 
---
 drivers/media/video/ivtv/ivtv-ioctl.c  |2 +-
 drivers/media/video/omap3isp/ispccdc.c |2 +-
 drivers/media/video/omap3isp/ispstat.c |2 +-
 drivers/media/video/pwc/pwc-v4l.c  |2 +-
 drivers/media/video/v4l2-event.c   |   42 ---
 drivers/media/video/vivi.c |2 +-
 include/media/v4l2-event.h |   24 +-
 7 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index ecafa69..9aec8a0 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1456,7 +1456,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
struct v4l2_event_subscripti
case V4L2_EVENT_VSYNC:
case V4L2_EVENT_EOS:
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/omap3isp/ispccdc.c 
b/drivers/media/video/omap3isp/ispccdc.c
index 40b141c..b6da736 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1700,7 +1700,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, 
struct v4l2_fh *fh,
if (sub->id != 0)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
 }
 
 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
diff --git a/drivers/media/video/omap3isp/ispstat.c 
b/drivers/media/video/omap3isp/ispstat.c
index 8080659..4f337a2 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1049,7 +1049,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
*subdev,
if (sub->type != stat->event_type)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
 }
 
 int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
diff --git a/drivers/media/video/pwc/pwc-v4l.c 
b/drivers/media/video/pwc/pwc-v4l.c
index 68e1323..7f159bf 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1138,7 +1138,7 @@ static int pwc_subscribe_event(struct v4l2_fh *fh,
 {
switch (sub->type) {
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
index 3d27300..2dd9252 100644
--- a/drivers/media/video/v4l2-event.c
+++ b/drivers/media/video/v4l2-event.c
@@ -131,14 +131,14 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, 
const struct v4l2_event *e
sev->first = sev_pos(sev, 1);
fh->navailable--;
if (sev->elems == 1) {
-   if (sev->replace) {
-   sev->replace(&kev->event, ev);
+   if (sev->ops && sev->ops->replace) {
+   sev->ops->replace(&kev->event, ev);
copy_payload = false;
}
-   } else if (sev->merge) {
+   } else if (sev->ops && sev->ops->merge) {
struct v4l2_kevent *second_oldest =
sev->events + sev_pos(sev, 0);
-   sev->merge(&kev->event, &second_oldest->event);
+   sev->ops->merge(&kev->event, &second_oldest->event);
}
}
 
@@ -207,8 +207,14 @@ static void ctrls_merge(const struct v4l2_event *old, 
struct v4l2_event *new)
new->u.ctrl.changes |= old->u.ctrl.changes;
 }
 
+const struct v4l2_subscribed_event_ops ctrl_ops = {
+   .replace = ctrls_replace,
+   .merge = ctrls_merge,
+};
+
 int v4l2_event_subscribe(struct v4l2_fh *fh,
-struct v4l2_event_subscription *sub, unsigned elems)
+struct v4l2_event_subscription *sub, unsigned elems,
+const struct v4l2_subscribed_event_ops *ops)
 {
struct v4l2_subscribed_event *sev, *found_ev;
struct v4l2_ctrl *ctrl = NULL;
@@ -236,9 +242,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
sev->flags = sub->flags;
sev->fh = fh;
sev->elems = elems;
+   sev->ops = ops;
if (ctrl) {
-   sev->replace = ctrls_replace;
-  

[PATCH 2/3] v4l2-event: Add v4l2_subscribed_event_ops

2011-10-24 Thread Hans de Goede
Just like with ctrl events, drivers may want to get called back on
listener add / remove for other event types too. Rather then special
casing all of this in subscribe / unsubscribe event it is better to
use ops for this.

Signed-off-by: Hans de Goede 
---
 drivers/media/video/ivtv/ivtv-ioctl.c  |2 +-
 drivers/media/video/omap3isp/ispccdc.c |2 +-
 drivers/media/video/omap3isp/ispstat.c |2 +-
 drivers/media/video/pwc/pwc-v4l.c  |2 +-
 drivers/media/video/v4l2-event.c   |   42 ---
 drivers/media/video/vivi.c |2 +-
 include/media/v4l2-event.h |   24 +-
 7 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index ecafa69..9aec8a0 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1456,7 +1456,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, 
struct v4l2_event_subscripti
case V4L2_EVENT_VSYNC:
case V4L2_EVENT_EOS:
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/omap3isp/ispccdc.c 
b/drivers/media/video/omap3isp/ispccdc.c
index 40b141c..b6da736 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1700,7 +1700,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, 
struct v4l2_fh *fh,
if (sub->id != 0)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
 }
 
 static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
diff --git a/drivers/media/video/omap3isp/ispstat.c 
b/drivers/media/video/omap3isp/ispstat.c
index 8080659..4f337a2 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1049,7 +1049,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev 
*subdev,
if (sub->type != stat->event_type)
return -EINVAL;
 
-   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS);
+   return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
 }
 
 int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
diff --git a/drivers/media/video/pwc/pwc-v4l.c 
b/drivers/media/video/pwc/pwc-v4l.c
index 68e1323..7f159bf 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1138,7 +1138,7 @@ static int pwc_subscribe_event(struct v4l2_fh *fh,
 {
switch (sub->type) {
case V4L2_EVENT_CTRL:
-   return v4l2_event_subscribe(fh, sub, 0);
+   return v4l2_event_subscribe(fh, sub, 0, NULL);
default:
return -EINVAL;
}
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
index 9f56f18..7190c2b 100644
--- a/drivers/media/video/v4l2-event.c
+++ b/drivers/media/video/v4l2-event.c
@@ -131,14 +131,14 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, 
const struct v4l2_event *e
sev->first = sev_pos(sev, 1);
fh->navailable--;
if (sev->elems == 1) {
-   if (sev->replace) {
-   sev->replace(&kev->event, ev);
+   if (sev->ops && sev->ops->replace) {
+   sev->ops->replace(&kev->event, ev);
copy_payload = false;
}
-   } else if (sev->merge) {
+   } else if (sev->ops && sev->ops->merge) {
struct v4l2_kevent *second_oldest =
sev->events + sev_pos(sev, 0);
-   sev->merge(&kev->event, &second_oldest->event);
+   sev->ops->merge(&kev->event, &second_oldest->event);
}
}
 
@@ -207,8 +207,14 @@ static void ctrls_merge(const struct v4l2_event *old, 
struct v4l2_event *new)
new->u.ctrl.changes |= old->u.ctrl.changes;
 }
 
+const struct v4l2_subscribed_event_ops ctrl_ops = {
+   .replace = ctrls_replace,
+   .merge = ctrls_merge,
+};
+
 int v4l2_event_subscribe(struct v4l2_fh *fh,
-struct v4l2_event_subscription *sub, unsigned elems)
+struct v4l2_event_subscription *sub, unsigned elems,
+const struct v4l2_subscribed_event_ops *ops)
 {
struct v4l2_subscribed_event *sev, *found_ev;
struct v4l2_ctrl *ctrl = NULL;
@@ -236,9 +242,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
sev->flags = sub->flags;
sev->fh = fh;
sev->elems = elems;
+   sev->ops = ops;
if (ctrl) {
-   sev->replace = ctrls_replace;
-  

Add v4l2_subscribed_event_ops

2011-10-24 Thread Hans de Goede
Hi Hans et all,

As discussed at the kernel summit. Note I have only compile tested this
as I've no control event capable hardware with me (until I'm done with
adding support for ctrl events to the UVC driver).

Regards,

Hans

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html