diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-24 10:25:10 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-24 10:25:10 -0400 |
commit | 79e8c7bebb467bbc3f2514d75bba669a3f354324 (patch) | |
tree | 5a07985daff3e50751ec40c51c4536d8f2284031 /drivers/media | |
parent | a47b6118e134b51562de520d644d3979b3d99e44 (diff) | |
parent | fea7a08acb13524b47711625eebea40a0ede69a0 (diff) |
Merge tag 'v3.6-rc3' into staging/for_v3.7
Linux 3.6-rc3
* tag 'v3.6-rc3': (764 commits)
Linux 3.6-rc3
task_work: add a scheduling point in task_work_run()
fs: fix fs/namei.c kernel-doc warnings
eventpoll: use-after-possible-free in epoll_create1()
vfio: grab vfio_device reference *before* exposing the sucker via fd_install()
vfio: get rid of vfio_device_put()/vfio_group_get_device* races
vfio: get rid of open-coding kref_put_mutex
introduce kref_put_mutex()
vfio: don't dereference after kfree...
fbcon: fix race condition between console lock and cursor timer (v1.1)
mm: compaction: Abort async compaction if locks are contended or taking too long
mm: have order > 0 compaction start near a pageblock with free pages
rapidio/tsi721: fix unused variable compiler warning
rapidio/tsi721: fix inbound doorbell interrupt handling
drivers/rtc/rtc-rs5c348.c: fix hour decoding in 12-hour mode
mm: correct page->pfmemalloc to fix deactivate_slab regression
drivers/rtc/rtc-pcf2123.c: initialize dynamic sysfs attributes
mm/compaction.c: fix deferring compaction mistake
drivers/misc/sgi-xp/xpc_uv.c: SGI XPC fails to load when cpu 0 is out of IRQ resources
string: do not export memweight() to userspace
...
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/platform/mem2mem_testdev.c | 2 | ||||
-rw-r--r-- | drivers/media/radio/radio-shark.c | 151 | ||||
-rw-r--r-- | drivers/media/radio/radio-shark2.c | 137 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-common.c | 3 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-i2c.c | 5 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-usb.c | 2 | ||||
-rw-r--r-- | drivers/media/rc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/usb/gspca/jl2005bcd.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/gspca/spca506.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/siano/smsusb.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_queue.c | 1 | ||||
-rw-r--r-- | drivers/media/v4l2-core/v4l2-ioctl.c | 10 |
12 files changed, 171 insertions, 147 deletions
diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c index 51b6dd4ddbf..0b496f39a65 100644 --- a/drivers/media/platform/mem2mem_testdev.c +++ b/drivers/media/platform/mem2mem_testdev.c | |||
@@ -431,7 +431,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
431 | strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); | 431 | strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); |
432 | strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); | 432 | strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); |
433 | strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info)); | 433 | strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info)); |
434 | cap->capabilities = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; | 434 | cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; |
435 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | 435 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
436 | return 0; | 436 | return 0; |
437 | } | 437 | } |
diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c index d0b6bb50763..72ded29728b 100644 --- a/drivers/media/radio/radio-shark.c +++ b/drivers/media/radio/radio-shark.c | |||
@@ -35,6 +35,11 @@ | |||
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <sound/tea575x-tuner.h> | 36 | #include <sound/tea575x-tuner.h> |
37 | 37 | ||
38 | #if defined(CONFIG_LEDS_CLASS) || \ | ||
39 | (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK_MODULE)) | ||
40 | #define SHARK_USE_LEDS 1 | ||
41 | #endif | ||
42 | |||
38 | /* | 43 | /* |
39 | * Version Information | 44 | * Version Information |
40 | */ | 45 | */ |
@@ -56,44 +61,18 @@ MODULE_LICENSE("GPL"); | |||
56 | 61 | ||
57 | enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; | 62 | enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; |
58 | 63 | ||
59 | static void shark_led_set_blue(struct led_classdev *led_cdev, | ||
60 | enum led_brightness value); | ||
61 | static void shark_led_set_blue_pulse(struct led_classdev *led_cdev, | ||
62 | enum led_brightness value); | ||
63 | static void shark_led_set_red(struct led_classdev *led_cdev, | ||
64 | enum led_brightness value); | ||
65 | |||
66 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
67 | [BLUE_LED] = { | ||
68 | .name = "%s:blue:", | ||
69 | .brightness = LED_OFF, | ||
70 | .max_brightness = 127, | ||
71 | .brightness_set = shark_led_set_blue, | ||
72 | }, | ||
73 | [BLUE_PULSE_LED] = { | ||
74 | .name = "%s:blue-pulse:", | ||
75 | .brightness = LED_OFF, | ||
76 | .max_brightness = 255, | ||
77 | .brightness_set = shark_led_set_blue_pulse, | ||
78 | }, | ||
79 | [RED_LED] = { | ||
80 | .name = "%s:red:", | ||
81 | .brightness = LED_OFF, | ||
82 | .max_brightness = 1, | ||
83 | .brightness_set = shark_led_set_red, | ||
84 | }, | ||
85 | }; | ||
86 | |||
87 | struct shark_device { | 64 | struct shark_device { |
88 | struct usb_device *usbdev; | 65 | struct usb_device *usbdev; |
89 | struct v4l2_device v4l2_dev; | 66 | struct v4l2_device v4l2_dev; |
90 | struct snd_tea575x tea; | 67 | struct snd_tea575x tea; |
91 | 68 | ||
69 | #ifdef SHARK_USE_LEDS | ||
92 | struct work_struct led_work; | 70 | struct work_struct led_work; |
93 | struct led_classdev leds[NO_LEDS]; | 71 | struct led_classdev leds[NO_LEDS]; |
94 | char led_names[NO_LEDS][32]; | 72 | char led_names[NO_LEDS][32]; |
95 | atomic_t brightness[NO_LEDS]; | 73 | atomic_t brightness[NO_LEDS]; |
96 | unsigned long brightness_new; | 74 | unsigned long brightness_new; |
75 | #endif | ||
97 | 76 | ||
98 | u8 *transfer_buffer; | 77 | u8 *transfer_buffer; |
99 | u32 last_val; | 78 | u32 last_val; |
@@ -175,20 +154,13 @@ static struct snd_tea575x_ops shark_tea_ops = { | |||
175 | .read_val = shark_read_val, | 154 | .read_val = shark_read_val, |
176 | }; | 155 | }; |
177 | 156 | ||
157 | #ifdef SHARK_USE_LEDS | ||
178 | static void shark_led_work(struct work_struct *work) | 158 | static void shark_led_work(struct work_struct *work) |
179 | { | 159 | { |
180 | struct shark_device *shark = | 160 | struct shark_device *shark = |
181 | container_of(work, struct shark_device, led_work); | 161 | container_of(work, struct shark_device, led_work); |
182 | int i, res, brightness, actual_len; | 162 | int i, res, brightness, actual_len; |
183 | 163 | ||
184 | /* | ||
185 | * We use the v4l2_dev lock and registered bit to ensure the device | ||
186 | * does not get unplugged and unreffed while we're running. | ||
187 | */ | ||
188 | mutex_lock(&shark->tea.mutex); | ||
189 | if (!video_is_registered(&shark->tea.vd)) | ||
190 | goto leave; | ||
191 | |||
192 | for (i = 0; i < 3; i++) { | 164 | for (i = 0; i < 3; i++) { |
193 | if (!test_and_clear_bit(i, &shark->brightness_new)) | 165 | if (!test_and_clear_bit(i, &shark->brightness_new)) |
194 | continue; | 166 | continue; |
@@ -208,8 +180,6 @@ static void shark_led_work(struct work_struct *work) | |||
208 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", | 180 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", |
209 | shark->led_names[i], res); | 181 | shark->led_names[i], res); |
210 | } | 182 | } |
211 | leave: | ||
212 | mutex_unlock(&shark->tea.mutex); | ||
213 | } | 183 | } |
214 | 184 | ||
215 | static void shark_led_set_blue(struct led_classdev *led_cdev, | 185 | static void shark_led_set_blue(struct led_classdev *led_cdev, |
@@ -245,19 +215,78 @@ static void shark_led_set_red(struct led_classdev *led_cdev, | |||
245 | schedule_work(&shark->led_work); | 215 | schedule_work(&shark->led_work); |
246 | } | 216 | } |
247 | 217 | ||
218 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
219 | [BLUE_LED] = { | ||
220 | .name = "%s:blue:", | ||
221 | .brightness = LED_OFF, | ||
222 | .max_brightness = 127, | ||
223 | .brightness_set = shark_led_set_blue, | ||
224 | }, | ||
225 | [BLUE_PULSE_LED] = { | ||
226 | .name = "%s:blue-pulse:", | ||
227 | .brightness = LED_OFF, | ||
228 | .max_brightness = 255, | ||
229 | .brightness_set = shark_led_set_blue_pulse, | ||
230 | }, | ||
231 | [RED_LED] = { | ||
232 | .name = "%s:red:", | ||
233 | .brightness = LED_OFF, | ||
234 | .max_brightness = 1, | ||
235 | .brightness_set = shark_led_set_red, | ||
236 | }, | ||
237 | }; | ||
238 | |||
239 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
240 | { | ||
241 | int i, retval; | ||
242 | |||
243 | INIT_WORK(&shark->led_work, shark_led_work); | ||
244 | for (i = 0; i < NO_LEDS; i++) { | ||
245 | shark->leds[i] = shark_led_templates[i]; | ||
246 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
247 | shark->leds[i].name, shark->v4l2_dev.name); | ||
248 | shark->leds[i].name = shark->led_names[i]; | ||
249 | retval = led_classdev_register(dev, &shark->leds[i]); | ||
250 | if (retval) { | ||
251 | v4l2_err(&shark->v4l2_dev, | ||
252 | "couldn't register led: %s\n", | ||
253 | shark->led_names[i]); | ||
254 | return retval; | ||
255 | } | ||
256 | } | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static void shark_unregister_leds(struct shark_device *shark) | ||
261 | { | ||
262 | int i; | ||
263 | |||
264 | for (i = 0; i < NO_LEDS; i++) | ||
265 | led_classdev_unregister(&shark->leds[i]); | ||
266 | |||
267 | cancel_work_sync(&shark->led_work); | ||
268 | } | ||
269 | #else | ||
270 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
271 | { | ||
272 | v4l2_warn(&shark->v4l2_dev, | ||
273 | "CONFIG_LED_CLASS not enabled, LED support disabled\n"); | ||
274 | return 0; | ||
275 | } | ||
276 | static inline void shark_unregister_leds(struct shark_device *shark) { } | ||
277 | #endif | ||
278 | |||
248 | static void usb_shark_disconnect(struct usb_interface *intf) | 279 | static void usb_shark_disconnect(struct usb_interface *intf) |
249 | { | 280 | { |
250 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); | 281 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); |
251 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 282 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
252 | int i; | ||
253 | 283 | ||
254 | mutex_lock(&shark->tea.mutex); | 284 | mutex_lock(&shark->tea.mutex); |
255 | v4l2_device_disconnect(&shark->v4l2_dev); | 285 | v4l2_device_disconnect(&shark->v4l2_dev); |
256 | snd_tea575x_exit(&shark->tea); | 286 | snd_tea575x_exit(&shark->tea); |
257 | mutex_unlock(&shark->tea.mutex); | 287 | mutex_unlock(&shark->tea.mutex); |
258 | 288 | ||
259 | for (i = 0; i < NO_LEDS; i++) | 289 | shark_unregister_leds(shark); |
260 | led_classdev_unregister(&shark->leds[i]); | ||
261 | 290 | ||
262 | v4l2_device_put(&shark->v4l2_dev); | 291 | v4l2_device_put(&shark->v4l2_dev); |
263 | } | 292 | } |
@@ -266,7 +295,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev) | |||
266 | { | 295 | { |
267 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 296 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
268 | 297 | ||
269 | cancel_work_sync(&shark->led_work); | ||
270 | v4l2_device_unregister(&shark->v4l2_dev); | 298 | v4l2_device_unregister(&shark->v4l2_dev); |
271 | kfree(shark->transfer_buffer); | 299 | kfree(shark->transfer_buffer); |
272 | kfree(shark); | 300 | kfree(shark); |
@@ -276,7 +304,7 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
276 | const struct usb_device_id *id) | 304 | const struct usb_device_id *id) |
277 | { | 305 | { |
278 | struct shark_device *shark; | 306 | struct shark_device *shark; |
279 | int i, retval = -ENOMEM; | 307 | int retval = -ENOMEM; |
280 | 308 | ||
281 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); | 309 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); |
282 | if (!shark) | 310 | if (!shark) |
@@ -286,17 +314,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
286 | if (!shark->transfer_buffer) | 314 | if (!shark->transfer_buffer) |
287 | goto err_alloc_buffer; | 315 | goto err_alloc_buffer; |
288 | 316 | ||
289 | /* | 317 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); |
290 | * Work around a bug in usbhid/hid-core.c, where it leaves a dangling | 318 | |
291 | * pointer in intfdata causing v4l2-device.c to not set it. Which | 319 | retval = shark_register_leds(shark, &intf->dev); |
292 | * results in usb_shark_disconnect() referencing the dangling pointer | 320 | if (retval) |
293 | * | 321 | goto err_reg_leds; |
294 | * REMOVE (as soon as the above bug is fixed, patch submitted) | ||
295 | */ | ||
296 | usb_set_intfdata(intf, NULL); | ||
297 | 322 | ||
298 | shark->v4l2_dev.release = usb_shark_release; | 323 | shark->v4l2_dev.release = usb_shark_release; |
299 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); | ||
300 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); | 324 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); |
301 | if (retval) { | 325 | if (retval) { |
302 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); | 326 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); |
@@ -320,32 +344,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
320 | goto err_init_tea; | 344 | goto err_init_tea; |
321 | } | 345 | } |
322 | 346 | ||
323 | INIT_WORK(&shark->led_work, shark_led_work); | ||
324 | for (i = 0; i < NO_LEDS; i++) { | ||
325 | shark->leds[i] = shark_led_templates[i]; | ||
326 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
327 | shark->leds[i].name, shark->v4l2_dev.name); | ||
328 | shark->leds[i].name = shark->led_names[i]; | ||
329 | /* | ||
330 | * We don't fail the probe if we fail to register the leds, | ||
331 | * because once we've called snd_tea575x_init, the /dev/radio0 | ||
332 | * node may be opened from userspace holding a reference to us! | ||
333 | * | ||
334 | * Note we cannot register the leds first instead as | ||
335 | * shark_led_work depends on the v4l2 mutex and registered bit. | ||
336 | */ | ||
337 | retval = led_classdev_register(&intf->dev, &shark->leds[i]); | ||
338 | if (retval) | ||
339 | v4l2_err(&shark->v4l2_dev, | ||
340 | "couldn't register led: %s\n", | ||
341 | shark->led_names[i]); | ||
342 | } | ||
343 | |||
344 | return 0; | 347 | return 0; |
345 | 348 | ||
346 | err_init_tea: | 349 | err_init_tea: |
347 | v4l2_device_unregister(&shark->v4l2_dev); | 350 | v4l2_device_unregister(&shark->v4l2_dev); |
348 | err_reg_dev: | 351 | err_reg_dev: |
352 | shark_unregister_leds(shark); | ||
353 | err_reg_leds: | ||
349 | kfree(shark->transfer_buffer); | 354 | kfree(shark->transfer_buffer); |
350 | err_alloc_buffer: | 355 | err_alloc_buffer: |
351 | kfree(shark); | 356 | kfree(shark); |
diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c index 90aecfb0ff9..7c730a0277a 100644 --- a/drivers/media/radio/radio-shark2.c +++ b/drivers/media/radio/radio-shark2.c | |||
@@ -35,6 +35,11 @@ | |||
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include "radio-tea5777.h" | 36 | #include "radio-tea5777.h" |
37 | 37 | ||
38 | #if defined(CONFIG_LEDS_CLASS) || \ | ||
39 | (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK2_MODULE)) | ||
40 | #define SHARK_USE_LEDS 1 | ||
41 | #endif | ||
42 | |||
38 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | 43 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
39 | MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver"); | 44 | MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver"); |
40 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
@@ -43,7 +48,6 @@ static int debug; | |||
43 | module_param(debug, int, 0); | 48 | module_param(debug, int, 0); |
44 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 49 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
45 | 50 | ||
46 | |||
47 | #define SHARK_IN_EP 0x83 | 51 | #define SHARK_IN_EP 0x83 |
48 | #define SHARK_OUT_EP 0x05 | 52 | #define SHARK_OUT_EP 0x05 |
49 | 53 | ||
@@ -54,36 +58,18 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
54 | 58 | ||
55 | enum { BLUE_LED, RED_LED, NO_LEDS }; | 59 | enum { BLUE_LED, RED_LED, NO_LEDS }; |
56 | 60 | ||
57 | static void shark_led_set_blue(struct led_classdev *led_cdev, | ||
58 | enum led_brightness value); | ||
59 | static void shark_led_set_red(struct led_classdev *led_cdev, | ||
60 | enum led_brightness value); | ||
61 | |||
62 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
63 | [BLUE_LED] = { | ||
64 | .name = "%s:blue:", | ||
65 | .brightness = LED_OFF, | ||
66 | .max_brightness = 127, | ||
67 | .brightness_set = shark_led_set_blue, | ||
68 | }, | ||
69 | [RED_LED] = { | ||
70 | .name = "%s:red:", | ||
71 | .brightness = LED_OFF, | ||
72 | .max_brightness = 1, | ||
73 | .brightness_set = shark_led_set_red, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | struct shark_device { | 61 | struct shark_device { |
78 | struct usb_device *usbdev; | 62 | struct usb_device *usbdev; |
79 | struct v4l2_device v4l2_dev; | 63 | struct v4l2_device v4l2_dev; |
80 | struct radio_tea5777 tea; | 64 | struct radio_tea5777 tea; |
81 | 65 | ||
66 | #ifdef SHARK_USE_LEDS | ||
82 | struct work_struct led_work; | 67 | struct work_struct led_work; |
83 | struct led_classdev leds[NO_LEDS]; | 68 | struct led_classdev leds[NO_LEDS]; |
84 | char led_names[NO_LEDS][32]; | 69 | char led_names[NO_LEDS][32]; |
85 | atomic_t brightness[NO_LEDS]; | 70 | atomic_t brightness[NO_LEDS]; |
86 | unsigned long brightness_new; | 71 | unsigned long brightness_new; |
72 | #endif | ||
87 | 73 | ||
88 | u8 *transfer_buffer; | 74 | u8 *transfer_buffer; |
89 | }; | 75 | }; |
@@ -156,18 +142,12 @@ static struct radio_tea5777_ops shark_tea_ops = { | |||
156 | .read_reg = shark_read_reg, | 142 | .read_reg = shark_read_reg, |
157 | }; | 143 | }; |
158 | 144 | ||
145 | #ifdef SHARK_USE_LEDS | ||
159 | static void shark_led_work(struct work_struct *work) | 146 | static void shark_led_work(struct work_struct *work) |
160 | { | 147 | { |
161 | struct shark_device *shark = | 148 | struct shark_device *shark = |
162 | container_of(work, struct shark_device, led_work); | 149 | container_of(work, struct shark_device, led_work); |
163 | int i, res, brightness, actual_len; | 150 | int i, res, brightness, actual_len; |
164 | /* | ||
165 | * We use the v4l2_dev lock and registered bit to ensure the device | ||
166 | * does not get unplugged and unreffed while we're running. | ||
167 | */ | ||
168 | mutex_lock(&shark->tea.mutex); | ||
169 | if (!video_is_registered(&shark->tea.vd)) | ||
170 | goto leave; | ||
171 | 151 | ||
172 | for (i = 0; i < 2; i++) { | 152 | for (i = 0; i < 2; i++) { |
173 | if (!test_and_clear_bit(i, &shark->brightness_new)) | 153 | if (!test_and_clear_bit(i, &shark->brightness_new)) |
@@ -186,8 +166,6 @@ static void shark_led_work(struct work_struct *work) | |||
186 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", | 166 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", |
187 | shark->led_names[i], res); | 167 | shark->led_names[i], res); |
188 | } | 168 | } |
189 | leave: | ||
190 | mutex_unlock(&shark->tea.mutex); | ||
191 | } | 169 | } |
192 | 170 | ||
193 | static void shark_led_set_blue(struct led_classdev *led_cdev, | 171 | static void shark_led_set_blue(struct led_classdev *led_cdev, |
@@ -212,19 +190,72 @@ static void shark_led_set_red(struct led_classdev *led_cdev, | |||
212 | schedule_work(&shark->led_work); | 190 | schedule_work(&shark->led_work); |
213 | } | 191 | } |
214 | 192 | ||
193 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
194 | [BLUE_LED] = { | ||
195 | .name = "%s:blue:", | ||
196 | .brightness = LED_OFF, | ||
197 | .max_brightness = 127, | ||
198 | .brightness_set = shark_led_set_blue, | ||
199 | }, | ||
200 | [RED_LED] = { | ||
201 | .name = "%s:red:", | ||
202 | .brightness = LED_OFF, | ||
203 | .max_brightness = 1, | ||
204 | .brightness_set = shark_led_set_red, | ||
205 | }, | ||
206 | }; | ||
207 | |||
208 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
209 | { | ||
210 | int i, retval; | ||
211 | |||
212 | INIT_WORK(&shark->led_work, shark_led_work); | ||
213 | for (i = 0; i < NO_LEDS; i++) { | ||
214 | shark->leds[i] = shark_led_templates[i]; | ||
215 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
216 | shark->leds[i].name, shark->v4l2_dev.name); | ||
217 | shark->leds[i].name = shark->led_names[i]; | ||
218 | retval = led_classdev_register(dev, &shark->leds[i]); | ||
219 | if (retval) { | ||
220 | v4l2_err(&shark->v4l2_dev, | ||
221 | "couldn't register led: %s\n", | ||
222 | shark->led_names[i]); | ||
223 | return retval; | ||
224 | } | ||
225 | } | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static void shark_unregister_leds(struct shark_device *shark) | ||
230 | { | ||
231 | int i; | ||
232 | |||
233 | for (i = 0; i < NO_LEDS; i++) | ||
234 | led_classdev_unregister(&shark->leds[i]); | ||
235 | |||
236 | cancel_work_sync(&shark->led_work); | ||
237 | } | ||
238 | #else | ||
239 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
240 | { | ||
241 | v4l2_warn(&shark->v4l2_dev, | ||
242 | "CONFIG_LED_CLASS not enabled, LED support disabled\n"); | ||
243 | return 0; | ||
244 | } | ||
245 | static inline void shark_unregister_leds(struct shark_device *shark) { } | ||
246 | #endif | ||
247 | |||
215 | static void usb_shark_disconnect(struct usb_interface *intf) | 248 | static void usb_shark_disconnect(struct usb_interface *intf) |
216 | { | 249 | { |
217 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); | 250 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); |
218 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 251 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
219 | int i; | ||
220 | 252 | ||
221 | mutex_lock(&shark->tea.mutex); | 253 | mutex_lock(&shark->tea.mutex); |
222 | v4l2_device_disconnect(&shark->v4l2_dev); | 254 | v4l2_device_disconnect(&shark->v4l2_dev); |
223 | radio_tea5777_exit(&shark->tea); | 255 | radio_tea5777_exit(&shark->tea); |
224 | mutex_unlock(&shark->tea.mutex); | 256 | mutex_unlock(&shark->tea.mutex); |
225 | 257 | ||
226 | for (i = 0; i < NO_LEDS; i++) | 258 | shark_unregister_leds(shark); |
227 | led_classdev_unregister(&shark->leds[i]); | ||
228 | 259 | ||
229 | v4l2_device_put(&shark->v4l2_dev); | 260 | v4l2_device_put(&shark->v4l2_dev); |
230 | } | 261 | } |
@@ -233,7 +264,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev) | |||
233 | { | 264 | { |
234 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 265 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
235 | 266 | ||
236 | cancel_work_sync(&shark->led_work); | ||
237 | v4l2_device_unregister(&shark->v4l2_dev); | 267 | v4l2_device_unregister(&shark->v4l2_dev); |
238 | kfree(shark->transfer_buffer); | 268 | kfree(shark->transfer_buffer); |
239 | kfree(shark); | 269 | kfree(shark); |
@@ -243,7 +273,7 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
243 | const struct usb_device_id *id) | 273 | const struct usb_device_id *id) |
244 | { | 274 | { |
245 | struct shark_device *shark; | 275 | struct shark_device *shark; |
246 | int i, retval = -ENOMEM; | 276 | int retval = -ENOMEM; |
247 | 277 | ||
248 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); | 278 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); |
249 | if (!shark) | 279 | if (!shark) |
@@ -253,17 +283,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
253 | if (!shark->transfer_buffer) | 283 | if (!shark->transfer_buffer) |
254 | goto err_alloc_buffer; | 284 | goto err_alloc_buffer; |
255 | 285 | ||
256 | /* | 286 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); |
257 | * Work around a bug in usbhid/hid-core.c, where it leaves a dangling | 287 | |
258 | * pointer in intfdata causing v4l2-device.c to not set it. Which | 288 | retval = shark_register_leds(shark, &intf->dev); |
259 | * results in usb_shark_disconnect() referencing the dangling pointer | 289 | if (retval) |
260 | * | 290 | goto err_reg_leds; |
261 | * REMOVE (as soon as the above bug is fixed, patch submitted) | ||
262 | */ | ||
263 | usb_set_intfdata(intf, NULL); | ||
264 | 291 | ||
265 | shark->v4l2_dev.release = usb_shark_release; | 292 | shark->v4l2_dev.release = usb_shark_release; |
266 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); | ||
267 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); | 293 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); |
268 | if (retval) { | 294 | if (retval) { |
269 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); | 295 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); |
@@ -287,32 +313,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
287 | goto err_init_tea; | 313 | goto err_init_tea; |
288 | } | 314 | } |
289 | 315 | ||
290 | INIT_WORK(&shark->led_work, shark_led_work); | ||
291 | for (i = 0; i < NO_LEDS; i++) { | ||
292 | shark->leds[i] = shark_led_templates[i]; | ||
293 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
294 | shark->leds[i].name, shark->v4l2_dev.name); | ||
295 | shark->leds[i].name = shark->led_names[i]; | ||
296 | /* | ||
297 | * We don't fail the probe if we fail to register the leds, | ||
298 | * because once we've called radio_tea5777_init, the /dev/radio0 | ||
299 | * node may be opened from userspace holding a reference to us! | ||
300 | * | ||
301 | * Note we cannot register the leds first instead as | ||
302 | * shark_led_work depends on the v4l2 mutex and registered bit. | ||
303 | */ | ||
304 | retval = led_classdev_register(&intf->dev, &shark->leds[i]); | ||
305 | if (retval) | ||
306 | v4l2_err(&shark->v4l2_dev, | ||
307 | "couldn't register led: %s\n", | ||
308 | shark->led_names[i]); | ||
309 | } | ||
310 | |||
311 | return 0; | 316 | return 0; |
312 | 317 | ||
313 | err_init_tea: | 318 | err_init_tea: |
314 | v4l2_device_unregister(&shark->v4l2_dev); | 319 | v4l2_device_unregister(&shark->v4l2_dev); |
315 | err_reg_dev: | 320 | err_reg_dev: |
321 | shark_unregister_leds(shark); | ||
322 | err_reg_leds: | ||
316 | kfree(shark->transfer_buffer); | 323 | kfree(shark->transfer_buffer); |
317 | err_alloc_buffer: | 324 | err_alloc_buffer: |
318 | kfree(shark); | 325 | kfree(shark); |
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 9e38132afec..9bb65e170d9 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -151,6 +151,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
151 | .index = 0, | 151 | .index = 0, |
152 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 152 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
153 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 153 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
154 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
154 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 155 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
155 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 156 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
156 | .rangelow = 87500 * 16, | 157 | .rangelow = 87500 * 16, |
@@ -162,6 +163,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
162 | .index = 1, | 163 | .index = 1, |
163 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 164 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
164 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 165 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
166 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
165 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 167 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
166 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 168 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
167 | .rangelow = 76000 * 16, | 169 | .rangelow = 76000 * 16, |
@@ -173,6 +175,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
173 | .index = 2, | 175 | .index = 2, |
174 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 176 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
175 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 177 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
178 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
176 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 179 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
177 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 180 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
178 | .rangelow = 76000 * 16, | 181 | .rangelow = 76000 * 16, |
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 643a6ff7c5d..f867f04cccc 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c | |||
@@ -225,8 +225,9 @@ int si470x_vidioc_querycap(struct file *file, void *priv, | |||
225 | { | 225 | { |
226 | strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); | 226 | strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); |
227 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); | 227 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); |
228 | capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | | 228 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | |
229 | V4L2_CAP_TUNER | V4L2_CAP_RADIO; | 229 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; |
230 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
230 | 231 | ||
231 | return 0; | 232 | return 0; |
232 | } | 233 | } |
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 146be4263ea..be076f7181e 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c | |||
@@ -531,7 +531,7 @@ int si470x_vidioc_querycap(struct file *file, void *priv, | |||
531 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); | 531 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); |
532 | usb_make_path(radio->usbdev, capability->bus_info, | 532 | usb_make_path(radio->usbdev, capability->bus_info, |
533 | sizeof(capability->bus_info)); | 533 | sizeof(capability->bus_info)); |
534 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | | 534 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | |
535 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; | 535 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; |
536 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; | 536 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; |
537 | return 0; | 537 | return 0; |
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 4682a5a3c3e..02ce43c7914 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig | |||
@@ -261,6 +261,7 @@ config IR_WINBOND_CIR | |||
261 | 261 | ||
262 | config IR_IGUANA | 262 | config IR_IGUANA |
263 | tristate "IguanaWorks USB IR Transceiver" | 263 | tristate "IguanaWorks USB IR Transceiver" |
264 | depends on USB_ARCH_HAS_HCD | ||
264 | depends on RC_CORE | 265 | depends on RC_CORE |
265 | select USB | 266 | select USB |
266 | ---help--- | 267 | ---help--- |
diff --git a/drivers/media/usb/gspca/jl2005bcd.c b/drivers/media/usb/gspca/jl2005bcd.c index cf9d9fca5b8..234777116e5 100644 --- a/drivers/media/usb/gspca/jl2005bcd.c +++ b/drivers/media/usb/gspca/jl2005bcd.c | |||
@@ -512,7 +512,7 @@ static const struct sd_desc sd_desc = { | |||
512 | }; | 512 | }; |
513 | 513 | ||
514 | /* -- module initialisation -- */ | 514 | /* -- module initialisation -- */ |
515 | static const __devinitdata struct usb_device_id device_table[] = { | 515 | static const struct usb_device_id device_table[] = { |
516 | {USB_DEVICE(0x0979, 0x0227)}, | 516 | {USB_DEVICE(0x0979, 0x0227)}, |
517 | {} | 517 | {} |
518 | }; | 518 | }; |
diff --git a/drivers/media/usb/gspca/spca506.c b/drivers/media/usb/gspca/spca506.c index 969bb5a4cd9..bab01c86c31 100644 --- a/drivers/media/usb/gspca/spca506.c +++ b/drivers/media/usb/gspca/spca506.c | |||
@@ -579,7 +579,7 @@ static const struct sd_desc sd_desc = { | |||
579 | }; | 579 | }; |
580 | 580 | ||
581 | /* -- module initialisation -- */ | 581 | /* -- module initialisation -- */ |
582 | static const struct usb_device_id device_table[] __devinitconst = { | 582 | static const struct usb_device_id device_table[] = { |
583 | {USB_DEVICE(0x06e1, 0xa190)}, | 583 | {USB_DEVICE(0x06e1, 0xa190)}, |
584 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 | 584 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 |
585 | {USB_DEVICE(0x0733, 0x0430)}, */ | 585 | {USB_DEVICE(0x0733, 0x0430)}, */ |
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 664e460f247..aac622200e9 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c | |||
@@ -481,7 +481,7 @@ static int smsusb_resume(struct usb_interface *intf) | |||
481 | return 0; | 481 | return 0; |
482 | } | 482 | } |
483 | 483 | ||
484 | static const struct usb_device_id smsusb_id_table[] __devinitconst = { | 484 | static const struct usb_device_id smsusb_id_table[] = { |
485 | { USB_DEVICE(0x187f, 0x0010), | 485 | { USB_DEVICE(0x187f, 0x0010), |
486 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, | 486 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, |
487 | { USB_DEVICE(0x187f, 0x0100), | 487 | { USB_DEVICE(0x187f, 0x0100), |
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 9288fbd5001..5577381b5bf 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c | |||
@@ -338,6 +338,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
338 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { | 338 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { |
339 | buf->error = 0; | 339 | buf->error = 0; |
340 | buf->state = UVC_BUF_STATE_QUEUED; | 340 | buf->state = UVC_BUF_STATE_QUEUED; |
341 | buf->bytesused = 0; | ||
341 | vb2_set_plane_payload(&buf->buf, 0, 0); | 342 | vb2_set_plane_payload(&buf->buf, 0, 0); |
342 | return buf; | 343 | return buf; |
343 | } | 344 | } |
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index c3b7b5f59b3..6bc47fc82fe 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
@@ -402,8 +402,10 @@ static void v4l_print_hw_freq_seek(const void *arg, bool write_only) | |||
402 | { | 402 | { |
403 | const struct v4l2_hw_freq_seek *p = arg; | 403 | const struct v4l2_hw_freq_seek *p = arg; |
404 | 404 | ||
405 | pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n", | 405 | pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, " |
406 | p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing); | 406 | "rangelow=%u, rangehigh=%u\n", |
407 | p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing, | ||
408 | p->rangelow, p->rangehigh); | ||
407 | } | 409 | } |
408 | 410 | ||
409 | static void v4l_print_requestbuffers(const void *arg, bool write_only) | 411 | static void v4l_print_requestbuffers(const void *arg, bool write_only) |
@@ -1853,6 +1855,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, | |||
1853 | .type = type, | 1855 | .type = type, |
1854 | }; | 1856 | }; |
1855 | 1857 | ||
1858 | if (p->index) | ||
1859 | return -EINVAL; | ||
1856 | err = ops->vidioc_g_tuner(file, fh, &t); | 1860 | err = ops->vidioc_g_tuner(file, fh, &t); |
1857 | if (err) | 1861 | if (err) |
1858 | return err; | 1862 | return err; |
@@ -1870,6 +1874,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, | |||
1870 | 1874 | ||
1871 | if (type != V4L2_TUNER_RADIO) | 1875 | if (type != V4L2_TUNER_RADIO) |
1872 | return -EINVAL; | 1876 | return -EINVAL; |
1877 | if (p->index) | ||
1878 | return -EINVAL; | ||
1873 | err = ops->vidioc_g_modulator(file, fh, &m); | 1879 | err = ops->vidioc_g_modulator(file, fh, &m); |
1874 | if (err) | 1880 | if (err) |
1875 | return err; | 1881 | return err; |