Blame view

drivers/media/video/v4l2-dev.c 21.4 KB
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
1
2
3
4
5
6
7
8
9
10
11
  /*
   * Video capture interface for Linux version 2
   *
   *	A generic video device interface for the LINUX operating system
   *	using a set of device structures/vectors for low level operations.
   *
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License
   *	as published by the Free Software Foundation; either version
   *	2 of the License, or (at your option) any later version.
   *
d9b01449e   Alan Cox   V4L/DVB (9491): r...
12
   * Authors:	Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   *              Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
   *
   * Fixes:	20000516  Claudio Matsuoka <claudio@conectiva.com>
   *		- Added procfs support
   */
  
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/mm.h>
  #include <linux/string.h>
  #include <linux/errno.h>
  #include <linux/init.h>
  #include <linux/kmod.h>
  #include <linux/slab.h>
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
28
29
30
31
  #include <asm/uaccess.h>
  #include <asm/system.h>
  
  #include <media/v4l2-common.h>
9bea3514d   Hans Verkuil   V4L/DVB (9974): v...
32
  #include <media/v4l2-device.h>
bec43661b   Hans Verkuil   V4L/DVB (10135): ...
33
  #include <media/v4l2-ioctl.h>
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
34
35
36
37
38
39
40
41
42
43
44
  
  #define VIDEO_NUM_DEVICES	256
  #define VIDEO_NAME              "video4linux"
  
  /*
   *	sysfs stuff
   */
  
  static ssize_t show_index(struct device *cd,
  			 struct device_attribute *attr, char *buf)
  {
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
45
  	struct video_device *vdev = to_video_device(cd);
bfa8a273b   Hans Verkuil   V4L/DVB (8787): v...
46

dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
47
48
  	return sprintf(buf, "%i
  ", vdev->index);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
49
50
51
52
53
  }
  
  static ssize_t show_name(struct device *cd,
  			 struct device_attribute *attr, char *buf)
  {
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
54
  	struct video_device *vdev = to_video_device(cd);
bfa8a273b   Hans Verkuil   V4L/DVB (8787): v...
55

dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
56
57
  	return sprintf(buf, "%.*s
  ", (int)sizeof(vdev->name), vdev->name);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
58
59
60
61
62
63
64
  }
  
  static struct device_attribute video_device_attrs[] = {
  	__ATTR(name, S_IRUGO, show_name, NULL),
  	__ATTR(index, S_IRUGO, show_index, NULL),
  	__ATTR_NULL
  };
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
65
66
67
68
69
  /*
   *	Active devices
   */
  static struct video_device *video_device[VIDEO_NUM_DEVICES];
  static DEFINE_MUTEX(videodev_lock);
22e221258   Hans Verkuil   V4L/DVB (12722): ...
70
  static DECLARE_BITMAP(devnode_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
71

5062cb70c   Hans Verkuil   V4L/DVB (12724): ...
72
73
74
75
76
77
78
79
80
81
82
83
  /* Device node utility functions */
  
  /* Note: these utility functions all assume that vfl_type is in the range
     [0, VFL_TYPE_MAX-1]. */
  
  #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
  /* Return the bitmap corresponding to vfl_type. */
  static inline unsigned long *devnode_bits(int vfl_type)
  {
  	/* Any types not assigned to fixed minor ranges must be mapped to
  	   one single bitmap for the purposes of finding a free node number
  	   since all those unassigned types use the same minor range. */
226c0eeae   Hans Verkuil   V4L/DVB: videotex...
84
  	int idx = (vfl_type > VFL_TYPE_RADIO) ? VFL_TYPE_MAX - 1 : vfl_type;
5062cb70c   Hans Verkuil   V4L/DVB (12724): ...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  
  	return devnode_nums[idx];
  }
  #else
  /* Return the bitmap corresponding to vfl_type. */
  static inline unsigned long *devnode_bits(int vfl_type)
  {
  	return devnode_nums[vfl_type];
  }
  #endif
  
  /* Mark device node number vdev->num as used */
  static inline void devnode_set(struct video_device *vdev)
  {
  	set_bit(vdev->num, devnode_bits(vdev->vfl_type));
  }
  
  /* Mark device node number vdev->num as unused */
  static inline void devnode_clear(struct video_device *vdev)
  {
  	clear_bit(vdev->num, devnode_bits(vdev->vfl_type));
  }
  
  /* Try to find a free device node number in the range [from, to> */
  static inline int devnode_find(struct video_device *vdev, int from, int to)
  {
  	return find_next_zero_bit(devnode_bits(vdev->vfl_type), to, from);
  }
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
113
114
  struct video_device *video_device_alloc(void)
  {
bfa8a273b   Hans Verkuil   V4L/DVB (8787): v...
115
  	return kzalloc(sizeof(struct video_device), GFP_KERNEL);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
116
117
  }
  EXPORT_SYMBOL(video_device_alloc);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
118
  void video_device_release(struct video_device *vdev)
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
119
  {
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
120
  	kfree(vdev);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
121
122
  }
  EXPORT_SYMBOL(video_device_release);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
123
  void video_device_release_empty(struct video_device *vdev)
f9e86b5e9   Hans Verkuil   V4L/DVB (8782): v...
124
125
126
127
128
  {
  	/* Do nothing */
  	/* Only valid when the video_device struct is a static. */
  }
  EXPORT_SYMBOL(video_device_release_empty);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
129
  static inline void video_get(struct video_device *vdev)
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
130
  {
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
131
132
133
134
135
136
137
138
139
140
141
142
  	get_device(&vdev->dev);
  }
  
  static inline void video_put(struct video_device *vdev)
  {
  	put_device(&vdev->dev);
  }
  
  /* Called when the last user of the video device exits. */
  static void v4l2_device_release(struct device *cd)
  {
  	struct video_device *vdev = to_video_device(cd);
bedf8bcf6   Hans Verkuil   [media] v4l2-devi...
143
  	struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
144
145
  
  	mutex_lock(&videodev_lock);
1fc2b5f7f   Guennadi Liakhovetski   [media] V4L: cosm...
146
  	if (WARN_ON(video_device[vdev->minor] != vdev)) {
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
147
  		/* should not happen */
1fc2b5f7f   Guennadi Liakhovetski   [media] V4L: cosm...
148
  		mutex_unlock(&videodev_lock);
6ea9a1829   Hans Verkuil   V4L/DVB (8857): v...
149
150
  		return;
  	}
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
151
152
  
  	/* Free up this device for reuse */
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
153
  	video_device[vdev->minor] = NULL;
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
154

dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
155
156
157
158
159
  	/* Delete the cdev on this minor as well */
  	cdev_del(vdev->cdev);
  	/* Just in case some driver tries to access this from
  	   the release() callback. */
  	vdev->cdev = NULL;
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
160

22e221258   Hans Verkuil   V4L/DVB (12722): ...
161
  	/* Mark device node number as free */
5062cb70c   Hans Verkuil   V4L/DVB (12724): ...
162
  	devnode_clear(vdev);
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
163

dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
164
  	mutex_unlock(&videodev_lock);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
165

c064b8eac   Laurent Pinchart   [media] v4l: Don'...
166
  #if defined(CONFIG_MEDIA_CONTROLLER)
1fc2b5f7f   Guennadi Liakhovetski   [media] V4L: cosm...
167
  	if (v4l2_dev && v4l2_dev->mdev &&
c064b8eac   Laurent Pinchart   [media] v4l: Don'...
168
169
170
  	    vdev->vfl_type != VFL_TYPE_SUBDEV)
  		media_device_unregister_entity(&vdev->entity);
  #endif
8280b662d   Hans Verkuil   [media] v4l: Fix ...
171
172
173
174
175
176
177
178
  	/* Do not call v4l2_device_put if there is no release callback set.
  	 * Drivers that have no v4l2_device release callback might free the
  	 * v4l2_dev instance in the video_device release callback below, so we
  	 * must perform this check here.
  	 *
  	 * TODO: In the long run all drivers that use v4l2_device should use the
  	 * v4l2_device release callback. This check will then be unnecessary.
  	 */
e58fced20   Antonio Ospite   [media] videodev:...
179
  	if (v4l2_dev && v4l2_dev->release == NULL)
8280b662d   Hans Verkuil   [media] v4l: Fix ...
180
  		v4l2_dev = NULL;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
181
182
183
  	/* Release video_device and perform other
  	   cleanups as needed. */
  	vdev->release(vdev);
bedf8bcf6   Hans Verkuil   [media] v4l2-devi...
184
185
186
187
  
  	/* Decrease v4l2_device refcount */
  	if (v4l2_dev)
  		v4l2_device_put(v4l2_dev);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
188
189
190
191
192
  }
  
  static struct class video_class = {
  	.name = VIDEO_NAME,
  	.dev_attrs = video_device_attrs,
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
193
  };
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
194
195
196
197
198
  struct video_device *video_devdata(struct file *file)
  {
  	return video_device[iminor(file->f_path.dentry->d_inode)];
  }
  EXPORT_SYMBOL(video_devdata);
022654930   Hans Verkuil   [media] v4l2_prio...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  
  /* Priority handling */
  
  static inline bool prio_is_valid(enum v4l2_priority prio)
  {
  	return prio == V4L2_PRIORITY_BACKGROUND ||
  	       prio == V4L2_PRIORITY_INTERACTIVE ||
  	       prio == V4L2_PRIORITY_RECORD;
  }
  
  void v4l2_prio_init(struct v4l2_prio_state *global)
  {
  	memset(global, 0, sizeof(*global));
  }
  EXPORT_SYMBOL(v4l2_prio_init);
  
  int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
  		     enum v4l2_priority new)
  {
  	if (!prio_is_valid(new))
  		return -EINVAL;
  	if (*local == new)
  		return 0;
  
  	atomic_inc(&global->prios[new]);
  	if (prio_is_valid(*local))
  		atomic_dec(&global->prios[*local]);
  	*local = new;
  	return 0;
  }
  EXPORT_SYMBOL(v4l2_prio_change);
  
  void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
  {
  	v4l2_prio_change(global, local, V4L2_PRIORITY_DEFAULT);
  }
  EXPORT_SYMBOL(v4l2_prio_open);
  
  void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)
  {
  	if (prio_is_valid(local))
  		atomic_dec(&global->prios[local]);
  }
  EXPORT_SYMBOL(v4l2_prio_close);
  
  enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
  {
  	if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
  		return V4L2_PRIORITY_RECORD;
  	if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
  		return V4L2_PRIORITY_INTERACTIVE;
  	if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
  		return V4L2_PRIORITY_BACKGROUND;
  	return V4L2_PRIORITY_UNSET;
  }
  EXPORT_SYMBOL(v4l2_prio_max);
  
  int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)
  {
  	return (local < v4l2_prio_max(global)) ? -EBUSY : 0;
  }
  EXPORT_SYMBOL(v4l2_prio_check);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
261
262
263
264
  static ssize_t v4l2_read(struct file *filp, char __user *buf,
  		size_t sz, loff_t *off)
  {
  	struct video_device *vdev = video_devdata(filp);
2877842de   Hans Verkuil   [media] v4l2-dev:...
265
  	int ret = -ENODEV;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
266
267
268
  
  	if (!vdev->fops->read)
  		return -EINVAL;
2877842de   Hans Verkuil   [media] v4l2-dev:...
269
270
  	if (vdev->lock && mutex_lock_interruptible(vdev->lock))
  		return -ERESTARTSYS;
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
271
272
273
274
275
  	if (video_is_registered(vdev))
  		ret = vdev->fops->read(filp, buf, sz, off);
  	if (vdev->lock)
  		mutex_unlock(vdev->lock);
  	return ret;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
276
277
278
279
280
281
  }
  
  static ssize_t v4l2_write(struct file *filp, const char __user *buf,
  		size_t sz, loff_t *off)
  {
  	struct video_device *vdev = video_devdata(filp);
2877842de   Hans Verkuil   [media] v4l2-dev:...
282
  	int ret = -ENODEV;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
283
284
285
  
  	if (!vdev->fops->write)
  		return -EINVAL;
2877842de   Hans Verkuil   [media] v4l2-dev:...
286
287
  	if (vdev->lock && mutex_lock_interruptible(vdev->lock))
  		return -ERESTARTSYS;
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
288
289
290
291
292
  	if (video_is_registered(vdev))
  		ret = vdev->fops->write(filp, buf, sz, off);
  	if (vdev->lock)
  		mutex_unlock(vdev->lock);
  	return ret;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
293
294
295
296
297
  }
  
  static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
  {
  	struct video_device *vdev = video_devdata(filp);
2877842de   Hans Verkuil   [media] v4l2-dev:...
298
  	int ret = POLLERR | POLLHUP;
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
299
300
  
  	if (!vdev->fops->poll)
2877842de   Hans Verkuil   [media] v4l2-dev:...
301
  		return DEFAULT_POLLMASK;
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
302
303
304
305
306
307
308
  	if (vdev->lock)
  		mutex_lock(vdev->lock);
  	if (video_is_registered(vdev))
  		ret = vdev->fops->poll(filp, poll);
  	if (vdev->lock)
  		mutex_unlock(vdev->lock);
  	return ret;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
309
  }
86a5ef7d7   Arnd Bergmann   v4l: Convert v4l2...
310
  static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
311
312
  {
  	struct video_device *vdev = video_devdata(filp);
724206301   Mauro Carvalho Chehab   V4L/DVB: Fix a me...
313
  	int ret = -ENODEV;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
314

86a5ef7d7   Arnd Bergmann   v4l: Convert v4l2...
315
  	if (vdev->fops->unlocked_ioctl) {
2877842de   Hans Verkuil   [media] v4l2-dev:...
316
317
  		if (vdev->lock && mutex_lock_interruptible(vdev->lock))
  			return -ERESTARTSYS;
724206301   Mauro Carvalho Chehab   V4L/DVB: Fix a me...
318
319
  		if (video_is_registered(vdev))
  			ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
320
321
  		if (vdev->lock)
  			mutex_unlock(vdev->lock);
86a5ef7d7   Arnd Bergmann   v4l: Convert v4l2...
322
  	} else if (vdev->fops->ioctl) {
879aa24d6   Hans Verkuil   [media] V4L: impr...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
  		/* This code path is a replacement for the BKL. It is a major
  		 * hack but it will have to do for those drivers that are not
  		 * yet converted to use unlocked_ioctl.
  		 *
  		 * There are two options: if the driver implements struct
  		 * v4l2_device, then the lock defined there is used to
  		 * serialize the ioctls. Otherwise the v4l2 core lock defined
  		 * below is used. This lock is really bad since it serializes
  		 * completely independent devices.
  		 *
  		 * Both variants suffer from the same problem: if the driver
  		 * sleeps, then it blocks all ioctls since the lock is still
  		 * held. This is very common for VIDIOC_DQBUF since that
  		 * normally waits for a frame to arrive. As a result any other
  		 * ioctl calls will proceed very, very slowly since each call
  		 * will have to wait for the VIDIOC_QBUF to finish. Things that
  		 * should take 0.01s may now take 10-20 seconds.
  		 *
  		 * The workaround is to *not* take the lock for VIDIOC_DQBUF.
  		 * This actually works OK for videobuf-based drivers, since
  		 * videobuf will take its own internal lock.
  		 */
0edf2e5e2   Arnd Bergmann   [media] v4l: kill...
345
  		static DEFINE_MUTEX(v4l2_ioctl_mutex);
879aa24d6   Hans Verkuil   [media] V4L: impr...
346
347
  		struct mutex *m = vdev->v4l2_dev ?
  			&vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex;
0edf2e5e2   Arnd Bergmann   [media] v4l: kill...
348

879aa24d6   Hans Verkuil   [media] V4L: impr...
349
350
  		if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m))
  			return -ERESTARTSYS;
724206301   Mauro Carvalho Chehab   V4L/DVB: Fix a me...
351
352
  		if (video_is_registered(vdev))
  			ret = vdev->fops->ioctl(filp, cmd, arg);
879aa24d6   Hans Verkuil   [media] V4L: impr...
353
354
  		if (cmd != VIDIOC_DQBUF)
  			mutex_unlock(m);
86a5ef7d7   Arnd Bergmann   v4l: Convert v4l2...
355
356
  	} else
  		ret = -ENOTTY;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
357

86a5ef7d7   Arnd Bergmann   v4l: Convert v4l2...
358
  	return ret;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
359
  }
ecc6517d9   Bob Liu   [media] Revert "V...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  #ifdef CONFIG_MMU
  #define v4l2_get_unmapped_area NULL
  #else
  static unsigned long v4l2_get_unmapped_area(struct file *filp,
  		unsigned long addr, unsigned long len, unsigned long pgoff,
  		unsigned long flags)
  {
  	struct video_device *vdev = video_devdata(filp);
  
  	if (!vdev->fops->get_unmapped_area)
  		return -ENOSYS;
  	if (!video_is_registered(vdev))
  		return -ENODEV;
  	return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
  }
  #endif
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
376
377
378
  static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
  {
  	struct video_device *vdev = video_devdata(filp);
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
379
380
381
382
  	int ret = -ENODEV;
  
  	if (!vdev->fops->mmap)
  		return ret;
2877842de   Hans Verkuil   [media] v4l2-dev:...
383
384
  	if (vdev->lock && mutex_lock_interruptible(vdev->lock))
  		return -ERESTARTSYS;
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
385
386
387
388
389
  	if (video_is_registered(vdev))
  		ret = vdev->fops->mmap(filp, vm);
  	if (vdev->lock)
  		mutex_unlock(vdev->lock);
  	return ret;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
390
391
392
393
394
395
  }
  
  /* Override for the open function */
  static int v4l2_open(struct inode *inode, struct file *filp)
  {
  	struct video_device *vdev;
65d9ff9c8   Hans Verkuil   V4L/DVB (11390): ...
396
  	int ret = 0;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
397
398
399
400
  
  	/* Check if the video device is available */
  	mutex_lock(&videodev_lock);
  	vdev = video_devdata(filp);
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
401
  	/* return ENODEV if the video device has already been removed. */
ca9afe6f8   Hans Verkuil   [media] v4l2-dev:...
402
  	if (vdev == NULL || !video_is_registered(vdev)) {
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
403
404
405
406
407
408
  		mutex_unlock(&videodev_lock);
  		return -ENODEV;
  	}
  	/* and increase the device refcount */
  	video_get(vdev);
  	mutex_unlock(&videodev_lock);
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
409
  	if (vdev->fops->open) {
2877842de   Hans Verkuil   [media] v4l2-dev:...
410
411
412
413
  		if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
  			ret = -ERESTARTSYS;
  			goto err;
  		}
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
414
415
416
417
418
419
420
  		if (video_is_registered(vdev))
  			ret = vdev->fops->open(filp);
  		else
  			ret = -ENODEV;
  		if (vdev->lock)
  			mutex_unlock(vdev->lock);
  	}
65d9ff9c8   Hans Verkuil   V4L/DVB (11390): ...
421

2877842de   Hans Verkuil   [media] v4l2-dev:...
422
  err:
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
423
  	/* decrease the refcount in case of an error */
c064b8eac   Laurent Pinchart   [media] v4l: Don'...
424
  	if (ret)
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
425
426
427
428
429
430
431
432
  		video_put(vdev);
  	return ret;
  }
  
  /* Override for the release function */
  static int v4l2_release(struct inode *inode, struct file *filp)
  {
  	struct video_device *vdev = video_devdata(filp);
65d9ff9c8   Hans Verkuil   V4L/DVB (11390): ...
433
  	int ret = 0;
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
434
435
436
  	if (vdev->fops->release) {
  		if (vdev->lock)
  			mutex_lock(vdev->lock);
65d9ff9c8   Hans Verkuil   V4L/DVB (11390): ...
437
  		vdev->fops->release(filp);
ee6869afc   Hans Verkuil   V4L/DVB: v4l2: ad...
438
439
440
  		if (vdev->lock)
  			mutex_unlock(vdev->lock);
  	}
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
441
442
443
444
445
  	/* decrease the refcount unconditionally since the release()
  	   return value is ignored. */
  	video_put(vdev);
  	return ret;
  }
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
446
447
448
449
450
  static const struct file_operations v4l2_fops = {
  	.owner = THIS_MODULE,
  	.read = v4l2_read,
  	.write = v4l2_write,
  	.open = v4l2_open,
ecc6517d9   Bob Liu   [media] Revert "V...
451
  	.get_unmapped_area = v4l2_get_unmapped_area,
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
452
  	.mmap = v4l2_mmap,
86a5ef7d7   Arnd Bergmann   v4l: Convert v4l2...
453
  	.unlocked_ioctl = v4l2_ioctl,
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
454
  #ifdef CONFIG_COMPAT
9bb7cde79   Hans Verkuil   V4L/DVB (10139): ...
455
  	.compat_ioctl = v4l2_compat_ioctl32,
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
456
457
458
459
460
  #endif
  	.release = v4l2_release,
  	.poll = v4l2_poll,
  	.llseek = no_llseek,
  };
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
461
  /**
7ae0cd9bc   Hans Verkuil   V4L/DVB (12541): ...
462
   * get_index - assign stream index number based on parent device
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
463
   * @vdev: video_device to assign index number to, vdev->parent should be assigned
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
464
   *
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
465
   * Note that when this is called the new device has not yet been registered
7ae0cd9bc   Hans Verkuil   V4L/DVB (12541): ...
466
   * in the video_device array, but it was able to obtain a minor number.
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
467
   *
7ae0cd9bc   Hans Verkuil   V4L/DVB (12541): ...
468
469
470
471
472
   * This means that we can always obtain a free stream index number since
   * the worst case scenario is that there are VIDEO_NUM_DEVICES - 1 slots in
   * use of the video_device array.
   *
   * Returns a free index number.
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
473
   */
7ae0cd9bc   Hans Verkuil   V4L/DVB (12541): ...
474
  static int get_index(struct video_device *vdev)
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
475
  {
775a05dd5   Hans Verkuil   V4L/DVB (10641): ...
476
477
478
  	/* This can be static since this function is called with the global
  	   videodev_lock held. */
  	static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
479
  	int i;
7ae0cd9bc   Hans Verkuil   V4L/DVB (12541): ...
480
  	/* Some drivers do not set the parent. In that case always return 0. */
806e5b7cf   Hans Verkuil   V4L/DVB (9942): v...
481
  	if (vdev->parent == NULL)
7ae0cd9bc   Hans Verkuil   V4L/DVB (12541): ...
482
  		return 0;
775a05dd5   Hans Verkuil   V4L/DVB (10641): ...
483
484
  
  	bitmap_zero(used, VIDEO_NUM_DEVICES);
806e5b7cf   Hans Verkuil   V4L/DVB (9942): v...
485

27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
486
487
  	for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
  		if (video_device[i] != NULL &&
5e85e732f   Hans Verkuil   V4L/DVB (8428): v...
488
  		    video_device[i]->parent == vdev->parent) {
775a05dd5   Hans Verkuil   V4L/DVB (10641): ...
489
  			set_bit(video_device[i]->index, used);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
490
491
  		}
  	}
7ae0cd9bc   Hans Verkuil   V4L/DVB (12541): ...
492
  	return find_first_zero_bit(used, VIDEO_NUM_DEVICES);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
493
  }
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
494
  /**
2096a5dcf   Laurent Pinchart   [media] v4l: subd...
495
   *	__video_register_device - register video4linux devices
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
496
   *	@vdev: video device structure we want to register
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
497
   *	@type: type of device to register
22e221258   Hans Verkuil   V4L/DVB (12722): ...
498
   *	@nr:   which device node number (0 == /dev/video0, 1 == /dev/video1, ...
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
499
   *             -1 == first free)
6b5270d21   Hans Verkuil   V4L/DVB (12725): ...
500
501
   *	@warn_if_nr_in_use: warn if the desired device node number
   *	       was already in use and another number was chosen instead.
2096a5dcf   Laurent Pinchart   [media] v4l: subd...
502
   *	@owner: module that owns the video device node
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
503
   *
22e221258   Hans Verkuil   V4L/DVB (12722): ...
504
505
506
   *	The registration code assigns minor numbers and device node numbers
   *	based on the requested type and registers the new device node with
   *	the kernel.
46b633779   Hans Verkuil   [media] v4l2-dev:...
507
508
509
510
   *
   *	This function assumes that struct video_device was zeroed when it
   *	was allocated and does not contain any stale date.
   *
22e221258   Hans Verkuil   V4L/DVB (12722): ...
511
512
   *	An error is returned if no free minor or device node number could be
   *	found, or if the registration of the device node failed.
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
513
514
515
516
517
518
519
   *
   *	Zero is returned on success.
   *
   *	Valid types are
   *
   *	%VFL_TYPE_GRABBER - A frame grabber
   *
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
520
521
522
   *	%VFL_TYPE_VBI - Vertical blank data (undecoded)
   *
   *	%VFL_TYPE_RADIO - A radio card
2096a5dcf   Laurent Pinchart   [media] v4l: subd...
523
524
   *
   *	%VFL_TYPE_SUBDEV - A subdevice
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
525
   */
2096a5dcf   Laurent Pinchart   [media] v4l: subd...
526
527
  int __video_register_device(struct video_device *vdev, int type, int nr,
  		int warn_if_nr_in_use, struct module *owner)
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
528
529
  {
  	int i = 0;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
530
  	int ret;
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
531
532
533
  	int minor_offset = 0;
  	int minor_cnt = VIDEO_NUM_DEVICES;
  	const char *name_base;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
534

dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
535
536
  	/* A minor value of -1 marks this video device as never
  	   having been registered */
428c8d191   Trent Piepho   V4L/DVB (10791): ...
537
  	vdev->minor = -1;
f3b9f50ef   Henrik Kretzschmar   V4L/DVB (8750): V...
538

dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
539
  	/* the release callback MUST be present */
1fc2b5f7f   Guennadi Liakhovetski   [media] V4L: cosm...
540
  	if (WARN_ON(!vdev->release))
ee7aa9f82   Henrik Kretzschmar   V4L/DVB (8750): V...
541
  		return -EINVAL;
1babcb460   Sakari Ailus   V4L/DVB: V4L: Fil...
542
543
544
  	/* v4l2_fh support */
  	spin_lock_init(&vdev->fh_lock);
  	INIT_LIST_HEAD(&vdev->fh_list);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
545
  	/* Part 1: check device type */
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
546
547
  	switch (type) {
  	case VFL_TYPE_GRABBER:
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
548
549
  		name_base = "video";
  		break;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
550
  	case VFL_TYPE_VBI:
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
551
552
553
  		name_base = "vbi";
  		break;
  	case VFL_TYPE_RADIO:
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
554
555
  		name_base = "radio";
  		break;
2096a5dcf   Laurent Pinchart   [media] v4l: subd...
556
557
558
  	case VFL_TYPE_SUBDEV:
  		name_base = "v4l-subdev";
  		break;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
559
560
561
562
  	default:
  		printk(KERN_ERR "%s called with unknown type: %d
  ",
  		       __func__, type);
46f2c21cf   Henrik Kretzschmar   V4L/DVB (8682): V...
563
  		return -EINVAL;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
564
  	}
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
565
566
  	vdev->vfl_type = type;
  	vdev->cdev = NULL;
11bbc1cad   Hans Verkuil   V4L/DVB: v4l2: ho...
567
568
569
570
571
  	if (vdev->v4l2_dev) {
  		if (vdev->v4l2_dev->dev)
  			vdev->parent = vdev->v4l2_dev->dev;
  		if (vdev->ctrl_handler == NULL)
  			vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
b1a873a37   Hans Verkuil   [media] v4l2: use...
572
573
574
  		/* If the prio state pointer is NULL, then use the v4l2_device
  		   prio state. */
  		if (vdev->prio == NULL)
0f62fd6a2   Hans Verkuil   [media] v4l2: add...
575
  			vdev->prio = &vdev->v4l2_dev->prio;
11bbc1cad   Hans Verkuil   V4L/DVB: v4l2: ho...
576
  	}
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
577

22e221258   Hans Verkuil   V4L/DVB (12722): ...
578
  	/* Part 2: find a free minor, device node number and device index. */
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
  #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
  	/* Keep the ranges for the first four types for historical
  	 * reasons.
  	 * Newer devices (not yet in place) should use the range
  	 * of 128-191 and just pick the first free minor there
  	 * (new style). */
  	switch (type) {
  	case VFL_TYPE_GRABBER:
  		minor_offset = 0;
  		minor_cnt = 64;
  		break;
  	case VFL_TYPE_RADIO:
  		minor_offset = 64;
  		minor_cnt = 64;
  		break;
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
594
595
596
597
598
599
600
601
602
603
  	case VFL_TYPE_VBI:
  		minor_offset = 224;
  		minor_cnt = 32;
  		break;
  	default:
  		minor_offset = 128;
  		minor_cnt = 64;
  		break;
  	}
  #endif
22e221258   Hans Verkuil   V4L/DVB (12722): ...
604
  	/* Pick a device node number */
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
605
  	mutex_lock(&videodev_lock);
5062cb70c   Hans Verkuil   V4L/DVB (12724): ...
606
  	nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
607
  	if (nr == minor_cnt)
5062cb70c   Hans Verkuil   V4L/DVB (12724): ...
608
  		nr = devnode_find(vdev, 0, minor_cnt);
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
609
  	if (nr == minor_cnt) {
22e221258   Hans Verkuil   V4L/DVB (12722): ...
610
611
  		printk(KERN_ERR "could not get a free device node number
  ");
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
612
613
  		mutex_unlock(&videodev_lock);
  		return -ENFILE;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
614
  	}
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
615
  #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
22e221258   Hans Verkuil   V4L/DVB (12722): ...
616
  	/* 1-on-1 mapping of device node number to minor number */
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
617
618
  	i = nr;
  #else
22e221258   Hans Verkuil   V4L/DVB (12722): ...
619
620
  	/* The device node number and minor numbers are independent, so
  	   we just find the first free minor number. */
dd89601d4   Hans Verkuil   V4L/DVB (9133): v...
621
622
623
624
625
626
627
628
629
630
  	for (i = 0; i < VIDEO_NUM_DEVICES; i++)
  		if (video_device[i] == NULL)
  			break;
  	if (i == VIDEO_NUM_DEVICES) {
  		mutex_unlock(&videodev_lock);
  		printk(KERN_ERR "could not get a free minor
  ");
  		return -ENFILE;
  	}
  #endif
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
631
632
  	vdev->minor = i + minor_offset;
  	vdev->num = nr;
5062cb70c   Hans Verkuil   V4L/DVB (12724): ...
633
  	devnode_set(vdev);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
634
635
  	/* Should not happen since we thought this minor was free */
  	WARN_ON(video_device[vdev->minor] != NULL);
7ae0cd9bc   Hans Verkuil   V4L/DVB (12541): ...
636
  	vdev->index = get_index(vdev);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
637
  	mutex_unlock(&videodev_lock);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
638
639
640
641
642
643
  	/* Part 3: Initialize the character device */
  	vdev->cdev = cdev_alloc();
  	if (vdev->cdev == NULL) {
  		ret = -ENOMEM;
  		goto cleanup;
  	}
86a5ef7d7   Arnd Bergmann   v4l: Convert v4l2...
644
  	vdev->cdev->ops = &v4l2_fops;
2096a5dcf   Laurent Pinchart   [media] v4l: subd...
645
  	vdev->cdev->owner = owner;
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
646
  	ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
647
648
649
  	if (ret < 0) {
  		printk(KERN_ERR "%s: cdev_add failed
  ", __func__);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
650
651
652
  		kfree(vdev->cdev);
  		vdev->cdev = NULL;
  		goto cleanup;
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
653
  	}
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
654
655
  
  	/* Part 4: register the device with sysfs */
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
656
657
658
659
  	vdev->dev.class = &video_class;
  	vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
  	if (vdev->parent)
  		vdev->dev.parent = vdev->parent;
22e221258   Hans Verkuil   V4L/DVB (12722): ...
660
  	dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
661
  	ret = device_register(&vdev->dev);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
662
663
664
  	if (ret < 0) {
  		printk(KERN_ERR "%s: device_register failed
  ", __func__);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
665
  		goto cleanup;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
666
  	}
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
667
668
669
  	/* Register the release callback that will be called when the last
  	   reference to the device goes away. */
  	vdev->dev.release = v4l2_device_release;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
670

6b5270d21   Hans Verkuil   V4L/DVB (12725): ...
671
  	if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
eac8ea536   Laurent Pinchart   V4L/DVB (13549): ...
672
673
674
  		printk(KERN_WARNING "%s: requested %s%d, got %s
  ", __func__,
  			name_base, nr, video_device_node_name(vdev));
bedf8bcf6   Hans Verkuil   [media] v4l2-devi...
675
676
677
678
  
  	/* Increase v4l2_device refcount */
  	if (vdev->v4l2_dev)
  		v4l2_device_get(vdev->v4l2_dev);
2c0ab67be   Laurent Pinchart   [media] v4l: Make...
679
680
  #if defined(CONFIG_MEDIA_CONTROLLER)
  	/* Part 5: Register the entity. */
c4f0b78ad   Laurent Pinchart   [media] v4l: Don'...
681
682
  	if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
  	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
2c0ab67be   Laurent Pinchart   [media] v4l: Make...
683
684
  		vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
  		vdev->entity.name = vdev->name;
fa5034c66   Clemens Ladisch   [media] media: fi...
685
686
  		vdev->entity.info.v4l.major = VIDEO_MAJOR;
  		vdev->entity.info.v4l.minor = vdev->minor;
2c0ab67be   Laurent Pinchart   [media] v4l: Make...
687
688
689
690
691
692
693
694
695
696
  		ret = media_device_register_entity(vdev->v4l2_dev->mdev,
  			&vdev->entity);
  		if (ret < 0)
  			printk(KERN_WARNING
  			       "%s: media_device_register_entity failed
  ",
  			       __func__);
  	}
  #endif
  	/* Part 6: Activate this minor. The char device can now be used. */
957b4aa9f   Laurent Pinchart   V4L/DVB (13552): ...
697
  	set_bit(V4L2_FL_REGISTERED, &vdev->flags);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
698
699
700
  	mutex_lock(&videodev_lock);
  	video_device[vdev->minor] = vdev;
  	mutex_unlock(&videodev_lock);
2c0ab67be   Laurent Pinchart   [media] v4l: Make...
701

dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
702
  	return 0;
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
703

dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
704
  cleanup:
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
705
  	mutex_lock(&videodev_lock);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
706
707
  	if (vdev->cdev)
  		cdev_del(vdev->cdev);
5062cb70c   Hans Verkuil   V4L/DVB (12724): ...
708
  	devnode_clear(vdev);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
709
  	mutex_unlock(&videodev_lock);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
710
711
  	/* Mark this video device as never having been registered. */
  	vdev->minor = -1;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
712
713
  	return ret;
  }
2096a5dcf   Laurent Pinchart   [media] v4l: subd...
714
  EXPORT_SYMBOL(__video_register_device);
6b5270d21   Hans Verkuil   V4L/DVB (12725): ...
715

27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
716
717
  /**
   *	video_unregister_device - unregister a video4linux device
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
718
   *	@vdev: the device to unregister
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
719
   *
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
720
721
   *	This unregisters the passed device. Future open calls will
   *	be met with errors.
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
722
   */
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
723
  void video_unregister_device(struct video_device *vdev)
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
724
  {
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
725
  	/* Check if vdev was ever registered at all */
957b4aa9f   Laurent Pinchart   V4L/DVB (13552): ...
726
  	if (!vdev || !video_is_registered(vdev))
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
727
  		return;
ca9afe6f8   Hans Verkuil   [media] v4l2-dev:...
728
729
730
731
  	mutex_lock(&videodev_lock);
  	/* This must be in a critical section to prevent a race with v4l2_open.
  	 * Once this bit has been cleared video_get may never be called again.
  	 */
957b4aa9f   Laurent Pinchart   V4L/DVB (13552): ...
732
  	clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
ca9afe6f8   Hans Verkuil   [media] v4l2-dev:...
733
  	mutex_unlock(&videodev_lock);
dc93a70cc   Hans Verkuil   V4L/DVB (9973): v...
734
  	device_unregister(&vdev->dev);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
735
736
737
738
  }
  EXPORT_SYMBOL(video_unregister_device);
  
  /*
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
739
740
   *	Initialise video for linux
   */
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
741
742
  static int __init videodev_init(void)
  {
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
743
  	dev_t dev = MKDEV(VIDEO_MAJOR, 0);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
744
745
746
747
  	int ret;
  
  	printk(KERN_INFO "Linux video capture interface: v2.00
  ");
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
748
749
750
751
752
753
  	ret = register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME);
  	if (ret < 0) {
  		printk(KERN_WARNING "videodev: unable to get major %d
  ",
  				VIDEO_MAJOR);
  		return ret;
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
754
755
756
757
  	}
  
  	ret = class_register(&video_class);
  	if (ret < 0) {
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
758
  		unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
759
760
761
762
763
764
765
766
767
768
  		printk(KERN_WARNING "video_dev: class_register failed
  ");
  		return -EIO;
  	}
  
  	return 0;
  }
  
  static void __exit videodev_exit(void)
  {
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
769
  	dev_t dev = MKDEV(VIDEO_MAJOR, 0);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
770
  	class_unregister(&video_class);
7f8ecfab7   Hans Verkuil   V4L/DVB (8852): v...
771
  	unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
772
773
774
775
776
777
778
779
  }
  
  module_init(videodev_init)
  module_exit(videodev_exit)
  
  MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
  MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
  MODULE_LICENSE("GPL");
cbb72b0f6   Scott James Remnant   V4L/DVB (10947): ...
780
  MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);
27a5e6d3f   Hans Verkuil   V4L/DVB (8427): v...
781
782
783
784
785
786
787
  
  
  /*
   * Local variables:
   * c-basic-offset: 8
   * End:
   */