diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-12-19 19:28:27 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:39:35 -0500 |
commit | dc93a70cc7f92e1dbaf29fa7dfd914b0f618fb31 (patch) | |
tree | ec14edc6348b80390a1787e70828b5cd3401fe3c /include/media | |
parent | be49e368fb6e20c3a90c566b040ac3d248e2ce29 (diff) |
V4L/DVB (9973): v4l2-dev: use the release callback from device instead of cdev
Instead of relying on the cdev release callback we should rely on the
release callback from the device struct. This requires that we use
get_device/put_device to do proper refcounting. In order to do this
safely v4l2-dev.c now sets up its own file_operations that call
out to the driver's ops.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'include/media')
-rw-r--r-- | include/media/v4l2-dev.h | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index a0a6b41c5e09..e0d72d2c6f0e 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h | |||
@@ -26,6 +26,11 @@ | |||
26 | 26 | ||
27 | struct v4l2_ioctl_callbacks; | 27 | struct v4l2_ioctl_callbacks; |
28 | 28 | ||
29 | /* Flag to mark the video_device struct as unregistered. | ||
30 | Drivers can set this flag if they want to block all future | ||
31 | device access. It is set by video_unregister_device. */ | ||
32 | #define V4L2_FL_UNREGISTERED (0) | ||
33 | |||
29 | /* | 34 | /* |
30 | * Newer version of video_device, handled by videodev2.c | 35 | * Newer version of video_device, handled by videodev2.c |
31 | * This version moves redundant code from video device code to | 36 | * This version moves redundant code from video device code to |
@@ -39,15 +44,17 @@ struct video_device | |||
39 | 44 | ||
40 | /* sysfs */ | 45 | /* sysfs */ |
41 | struct device dev; /* v4l device */ | 46 | struct device dev; /* v4l device */ |
42 | struct cdev cdev; /* character device */ | 47 | struct cdev *cdev; /* character device */ |
43 | void (*cdev_release)(struct kobject *kobj); | ||
44 | struct device *parent; /* device parent */ | 48 | struct device *parent; /* device parent */ |
45 | 49 | ||
46 | /* device info */ | 50 | /* device info */ |
47 | char name[32]; | 51 | char name[32]; |
48 | int vfl_type; | 52 | int vfl_type; |
53 | /* 'minor' is set to -1 if the registration failed */ | ||
49 | int minor; | 54 | int minor; |
50 | u16 num; | 55 | u16 num; |
56 | /* use bitops to set/clear/test flags */ | ||
57 | unsigned long flags; | ||
51 | /* attribute to differentiate multiple indices on one physical device */ | 58 | /* attribute to differentiate multiple indices on one physical device */ |
52 | int index; | 59 | int index; |
53 | 60 | ||
@@ -58,7 +65,7 @@ struct video_device | |||
58 | v4l2_std_id current_norm; /* Current tvnorm */ | 65 | v4l2_std_id current_norm; /* Current tvnorm */ |
59 | 66 | ||
60 | /* callbacks */ | 67 | /* callbacks */ |
61 | void (*release)(struct video_device *vfd); | 68 | void (*release)(struct video_device *vdev); |
62 | 69 | ||
63 | /* ioctl callbacks */ | 70 | /* ioctl callbacks */ |
64 | const struct v4l2_ioctl_ops *ioctl_ops; | 71 | const struct v4l2_ioctl_ops *ioctl_ops; |
@@ -67,36 +74,41 @@ struct video_device | |||
67 | /* dev to video-device */ | 74 | /* dev to video-device */ |
68 | #define to_video_device(cd) container_of(cd, struct video_device, dev) | 75 | #define to_video_device(cd) container_of(cd, struct video_device, dev) |
69 | 76 | ||
70 | /* Register and unregister devices. Note that if video_register_device fails, | 77 | /* Register video devices. Note that if video_register_device fails, |
71 | the release() callback of the video_device structure is *not* called, so | 78 | the release() callback of the video_device structure is *not* called, so |
72 | the caller is responsible for freeing any data. Usually that means that | 79 | the caller is responsible for freeing any data. Usually that means that |
73 | you call video_device_release() on failure. */ | 80 | you call video_device_release() on failure. |
74 | int __must_check video_register_device(struct video_device *vfd, int type, int nr); | 81 | |
75 | int __must_check video_register_device_index(struct video_device *vfd, | 82 | Also note that vdev->minor is set to -1 if the registration failed. */ |
83 | int __must_check video_register_device(struct video_device *vdev, int type, int nr); | ||
84 | int __must_check video_register_device_index(struct video_device *vdev, | ||
76 | int type, int nr, int index); | 85 | int type, int nr, int index); |
77 | void video_unregister_device(struct video_device *vfd); | 86 | |
87 | /* Unregister video devices. Will do nothing if vdev == NULL or | ||
88 | vdev->minor < 0. */ | ||
89 | void video_unregister_device(struct video_device *vdev); | ||
78 | 90 | ||
79 | /* helper functions to alloc/release struct video_device, the | 91 | /* helper functions to alloc/release struct video_device, the |
80 | latter can also be used for video_device->release(). */ | 92 | latter can also be used for video_device->release(). */ |
81 | struct video_device * __must_check video_device_alloc(void); | 93 | struct video_device * __must_check video_device_alloc(void); |
82 | 94 | ||
83 | /* this release function frees the vfd pointer */ | 95 | /* this release function frees the vdev pointer */ |
84 | void video_device_release(struct video_device *vfd); | 96 | void video_device_release(struct video_device *vdev); |
85 | 97 | ||
86 | /* this release function does nothing, use when the video_device is a | 98 | /* this release function does nothing, use when the video_device is a |
87 | static global struct. Note that having a static video_device is | 99 | static global struct. Note that having a static video_device is |
88 | a dubious construction at best. */ | 100 | a dubious construction at best. */ |
89 | void video_device_release_empty(struct video_device *vfd); | 101 | void video_device_release_empty(struct video_device *vdev); |
90 | 102 | ||
91 | /* helper functions to access driver private data. */ | 103 | /* helper functions to access driver private data. */ |
92 | static inline void *video_get_drvdata(struct video_device *dev) | 104 | static inline void *video_get_drvdata(struct video_device *vdev) |
93 | { | 105 | { |
94 | return dev_get_drvdata(&dev->dev); | 106 | return dev_get_drvdata(&vdev->dev); |
95 | } | 107 | } |
96 | 108 | ||
97 | static inline void video_set_drvdata(struct video_device *dev, void *data) | 109 | static inline void video_set_drvdata(struct video_device *vdev, void *data) |
98 | { | 110 | { |
99 | dev_set_drvdata(&dev->dev, data); | 111 | dev_set_drvdata(&vdev->dev, data); |
100 | } | 112 | } |
101 | 113 | ||
102 | struct video_device *video_devdata(struct file *file); | 114 | struct video_device *video_devdata(struct file *file); |
@@ -108,4 +120,9 @@ static inline void *video_drvdata(struct file *file) | |||
108 | return video_get_drvdata(video_devdata(file)); | 120 | return video_get_drvdata(video_devdata(file)); |
109 | } | 121 | } |
110 | 122 | ||
123 | static inline int video_is_unregistered(struct video_device *vdev) | ||
124 | { | ||
125 | return test_bit(V4L2_FL_UNREGISTERED, &vdev->flags); | ||
126 | } | ||
127 | |||
111 | #endif /* _V4L2_DEV_H */ | 128 | #endif /* _V4L2_DEV_H */ |