From patchwork Thu Jul 29 16:06:47 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 115227 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6TG7RKG005382 for ; Thu, 29 Jul 2010 16:07:28 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757970Ab0G2QHP (ORCPT ); Thu, 29 Jul 2010 12:07:15 -0400 Received: from perceval.irobotique.be ([92.243.18.41]:36475 "EHLO perceval.irobotique.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757957Ab0G2QHL (ORCPT ); Thu, 29 Jul 2010 12:07:11 -0400 Received: from localhost.localdomain (unknown [91.178.154.203]) by perceval.irobotique.be (Postfix) with ESMTPSA id ED49A35AD7; Thu, 29 Jul 2010 16:07:05 +0000 (UTC) From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: sakari.ailus@maxwell.research.nokia.com Subject: [SAMPLE v3 03/12] v4l: Create v4l2 subdev file handle structure Date: Thu, 29 Jul 2010 18:06:47 +0200 Message-Id: <1280419616-7658-15-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1280419616-7658-1-git-send-email-laurent.pinchart@ideasonboard.com> References: <1280419616-7658-1-git-send-email-laurent.pinchart@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 29 Jul 2010 16:07:28 +0000 (UTC) diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index 1efa267..2fe3818 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c @@ -28,38 +28,60 @@ #include #include +static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) +{ + fh->probe_fmt = kzalloc(sizeof(*fh->probe_fmt) * + sd->entity.num_pads, GFP_KERNEL); + if (fh->probe_fmt == NULL) + return -ENOMEM; + + return 0; +} + +static void subdev_fh_free(struct v4l2_subdev_fh *fh) +{ + kfree(fh->probe_fmt); + fh->probe_fmt = NULL; +} + static int subdev_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); + struct v4l2_subdev_fh *subdev_fh; struct media_entity *entity; - struct v4l2_fh *vfh = NULL; int ret; if (!sd->initialized) return -EAGAIN; - if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) { - vfh = kzalloc(sizeof(*vfh), GFP_KERNEL); - if (vfh == NULL) - return -ENOMEM; + subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL); + if (subdev_fh == NULL) + return -ENOMEM; - ret = v4l2_fh_init(vfh, vdev); - if (ret) - goto err; + ret = subdev_fh_init(subdev_fh, sd); + if (ret) { + kfree(subdev_fh); + return ret; + } + + ret = v4l2_fh_init(&subdev_fh->vfh, vdev); + if (ret) + goto err; - ret = v4l2_event_init(vfh); + if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) { + ret = v4l2_event_init(&subdev_fh->vfh); if (ret) goto err; - ret = v4l2_event_alloc(vfh, sd->nevents); + ret = v4l2_event_alloc(&subdev_fh->vfh, sd->nevents); if (ret) goto err; - - v4l2_fh_add(vfh); - file->private_data = vfh; } + v4l2_fh_add(&subdev_fh->vfh); + file->private_data = &subdev_fh->vfh; + entity = media_entity_get(&sd->entity); if (!entity) { ret = -EBUSY; @@ -69,11 +91,10 @@ static int subdev_open(struct file *file) return 0; err: - if (vfh != NULL) { - v4l2_fh_del(vfh); - v4l2_fh_exit(vfh); - kfree(vfh); - } + v4l2_fh_del(&subdev_fh->vfh); + v4l2_fh_exit(&subdev_fh->vfh); + subdev_fh_free(subdev_fh); + kfree(subdev_fh); return ret; } @@ -83,14 +104,15 @@ static int subdev_close(struct file *file) struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_fh *vfh = file->private_data; + struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); media_entity_put(&sd->entity); - if (vfh != NULL) { - v4l2_fh_del(vfh); - v4l2_fh_exit(vfh); - kfree(vfh); - } + v4l2_fh_del(vfh); + v4l2_fh_exit(vfh); + subdev_fh_free(subdev_fh); + kfree(subdev_fh); + file->private_data = NULL; return 0; } @@ -99,7 +121,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); - struct v4l2_fh *fh = file->private_data; + struct v4l2_fh *vfh = file->private_data; switch (cmd) { case VIDIOC_QUERYCTRL: @@ -127,13 +149,13 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return -ENOIOCTLCMD; - return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK); + return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); case VIDIOC_SUBSCRIBE_EVENT: - return v4l2_subdev_call(sd, core, subscribe_event, fh, arg); + return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); case VIDIOC_UNSUBSCRIBE_EVENT: - return v4l2_subdev_call(sd, core, unsubscribe_event, fh, arg); + return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); default: return -ENOIOCTLCMD; diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index f9e1897..01b4135 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -24,6 +24,7 @@ #include #include #include +#include #include /* generic v4l2_device notify callback notification values */ @@ -447,6 +448,23 @@ struct v4l2_subdev { #define vdev_to_v4l2_subdev(vdev) \ container_of(vdev, struct v4l2_subdev, devnode) +/* + * Used for storing subdev information per file handle + */ +struct v4l2_subdev_fh { + struct v4l2_fh vfh; + struct v4l2_mbus_framefmt *probe_fmt; +}; + +#define to_v4l2_subdev_fh(fh) \ + container_of(fh, struct v4l2_subdev_fh, vfh) + +static inline struct v4l2_mbus_framefmt * +v4l2_subdev_get_probe_format(struct v4l2_subdev_fh *fh, unsigned int pad) +{ + return &fh->probe_fmt[pad]; +} + extern const struct v4l2_file_operations v4l2_subdev_fops; static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p)