diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-21 19:54:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-21 19:54:38 -0400 |
| commit | a484147a52e6910d990ae7cf2a5d16b5bc58dcbe (patch) | |
| tree | f92b30dd7d2bad08e224c171da77e4f7554ed11b | |
| parent | 8f8ba75ee2065738644382667f833a4eb6f6db1d (diff) | |
| parent | 991b3137f21e13db4711f313edbe67d49bed795b (diff) | |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media fixes from Mauro Carvalho Chehab:
"For bug fixes, at soc_camera, si470x, uvcvideo, iguanaworks IR driver,
radio_shark Kbuild fixes, and at the V4L2 core (radio fixes)."
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
[media] media: soc_camera: don't clear pix->sizeimage in JPEG mode
[media] media: mx2_camera: Fix clock handling for i.MX27
[media] video: mx2_camera: Use clk_prepare_enable/clk_disable_unprepare
[media] video: mx1_camera: Use clk_prepare_enable/clk_disable_unprepare
[media] media: mx3_camera: buf_init() add buffer state check
[media] radio-shark2: Only compile led support when CONFIG_LED_CLASS is set
[media] radio-shark: Only compile led support when CONFIG_LED_CLASS is set
[media] radio-shark*: Call cancel_work_sync from disconnect rather then release
[media] radio-shark*: Remove work-around for dangling pointer in usb intfdata
[media] Add USB dependency for IguanaWorks USB IR Transceiver
[media] Add missing logging for rangelow/high of hwseek
[media] VIDIOC_ENUM_FREQ_BANDS fix
[media] mem2mem_testdev: fix querycap regression
[media] si470x: v4l2-compliance fixes
[media] DocBook: Remove a spurious character
[media] uvcvideo: Reset the bytesused field when recycling an erroneous buffer
| -rw-r--r-- | Documentation/DocBook/media/v4l/vidioc-g-tuner.xml | 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/video/mem2mem_testdev.c | 2 | ||||
| -rw-r--r-- | drivers/media/video/mx1_camera.c | 4 | ||||
| -rw-r--r-- | drivers/media/video/mx2_camera.c | 47 | ||||
| -rw-r--r-- | drivers/media/video/mx3_camera.c | 22 | ||||
| -rw-r--r-- | drivers/media/video/soc_camera.c | 3 | ||||
| -rw-r--r-- | drivers/media/video/soc_mediabus.c | 6 | ||||
| -rw-r--r-- | drivers/media/video/uvc/uvc_queue.c | 1 | ||||
| -rw-r--r-- | drivers/media/video/v4l2-ioctl.c | 10 |
15 files changed, 217 insertions, 179 deletions
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml index 720395127904..701138f1209d 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml | |||
| @@ -125,7 +125,7 @@ the structure refers to a radio tuner the | |||
| 125 | <constant>V4L2_TUNER_CAP_NORM</constant> flags can't be used.</para> | 125 | <constant>V4L2_TUNER_CAP_NORM</constant> flags can't be used.</para> |
| 126 | <para>If multiple frequency bands are supported, then | 126 | <para>If multiple frequency bands are supported, then |
| 127 | <structfield>capability</structfield> is the union of all | 127 | <structfield>capability</structfield> is the union of all |
| 128 | <structfield>capability></structfield> fields of each &v4l2-frequency-band;. | 128 | <structfield>capability</structfield> fields of each &v4l2-frequency-band;. |
| 129 | </para></entry> | 129 | </para></entry> |
| 130 | </row> | 130 | </row> |
| 131 | <row> | 131 | <row> |
diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c index d0b6bb507634..72ded29728bb 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 b9575de3e7e8..7b4efdfaae28 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 | }; |
| @@ -161,18 +147,12 @@ static struct radio_tea5777_ops shark_tea_ops = { | |||
| 161 | .read_reg = shark_read_reg, | 147 | .read_reg = shark_read_reg, |
| 162 | }; | 148 | }; |
| 163 | 149 | ||
| 150 | #ifdef SHARK_USE_LEDS | ||
| 164 | static void shark_led_work(struct work_struct *work) | 151 | static void shark_led_work(struct work_struct *work) |
| 165 | { | 152 | { |
| 166 | struct shark_device *shark = | 153 | struct shark_device *shark = |
| 167 | container_of(work, struct shark_device, led_work); | 154 | container_of(work, struct shark_device, led_work); |
| 168 | int i, res, brightness, actual_len; | 155 | int i, res, brightness, actual_len; |
| 169 | /* | ||
| 170 | * We use the v4l2_dev lock and registered bit to ensure the device | ||
| 171 | * does not get unplugged and unreffed while we're running. | ||
| 172 | */ | ||
| 173 | mutex_lock(&shark->tea.mutex); | ||
| 174 | if (!video_is_registered(&shark->tea.vd)) | ||
| 175 | goto leave; | ||
| 176 | 156 | ||
| 177 | for (i = 0; i < 2; i++) { | 157 | for (i = 0; i < 2; i++) { |
| 178 | if (!test_and_clear_bit(i, &shark->brightness_new)) | 158 | if (!test_and_clear_bit(i, &shark->brightness_new)) |
| @@ -191,8 +171,6 @@ static void shark_led_work(struct work_struct *work) | |||
| 191 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", | 171 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", |
| 192 | shark->led_names[i], res); | 172 | shark->led_names[i], res); |
| 193 | } | 173 | } |
| 194 | leave: | ||
| 195 | mutex_unlock(&shark->tea.mutex); | ||
| 196 | } | 174 | } |
| 197 | 175 | ||
| 198 | static void shark_led_set_blue(struct led_classdev *led_cdev, | 176 | static void shark_led_set_blue(struct led_classdev *led_cdev, |
| @@ -217,19 +195,72 @@ static void shark_led_set_red(struct led_classdev *led_cdev, | |||
| 217 | schedule_work(&shark->led_work); | 195 | schedule_work(&shark->led_work); |
| 218 | } | 196 | } |
| 219 | 197 | ||
| 198 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
| 199 | [BLUE_LED] = { | ||
| 200 | .name = "%s:blue:", | ||
| 201 | .brightness = LED_OFF, | ||
| 202 | .max_brightness = 127, | ||
| 203 | .brightness_set = shark_led_set_blue, | ||
| 204 | }, | ||
| 205 | [RED_LED] = { | ||
| 206 | .name = "%s:red:", | ||
| 207 | .brightness = LED_OFF, | ||
| 208 | .max_brightness = 1, | ||
| 209 | .brightness_set = shark_led_set_red, | ||
| 210 | }, | ||
| 211 | }; | ||
| 212 | |||
| 213 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
| 214 | { | ||
| 215 | int i, retval; | ||
| 216 | |||
| 217 | INIT_WORK(&shark->led_work, shark_led_work); | ||
| 218 | for (i = 0; i < NO_LEDS; i++) { | ||
| 219 | shark->leds[i] = shark_led_templates[i]; | ||
| 220 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
| 221 | shark->leds[i].name, shark->v4l2_dev.name); | ||
| 222 | shark->leds[i].name = shark->led_names[i]; | ||
| 223 | retval = led_classdev_register(dev, &shark->leds[i]); | ||
| 224 | if (retval) { | ||
| 225 | v4l2_err(&shark->v4l2_dev, | ||
| 226 | "couldn't register led: %s\n", | ||
| 227 | shark->led_names[i]); | ||
| 228 | return retval; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | |||
| 234 | static void shark_unregister_leds(struct shark_device *shark) | ||
| 235 | { | ||
| 236 | int i; | ||
| 237 | |||
| 238 | for (i = 0; i < NO_LEDS; i++) | ||
| 239 | led_classdev_unregister(&shark->leds[i]); | ||
| 240 | |||
| 241 | cancel_work_sync(&shark->led_work); | ||
| 242 | } | ||
| 243 | #else | ||
| 244 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
| 245 | { | ||
| 246 | v4l2_warn(&shark->v4l2_dev, | ||
| 247 | "CONFIG_LED_CLASS not enabled, LED support disabled\n"); | ||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | static inline void shark_unregister_leds(struct shark_device *shark) { } | ||
| 251 | #endif | ||
| 252 | |||
| 220 | static void usb_shark_disconnect(struct usb_interface *intf) | 253 | static void usb_shark_disconnect(struct usb_interface *intf) |
| 221 | { | 254 | { |
| 222 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); | 255 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); |
| 223 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 256 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
| 224 | int i; | ||
| 225 | 257 | ||
| 226 | mutex_lock(&shark->tea.mutex); | 258 | mutex_lock(&shark->tea.mutex); |
| 227 | v4l2_device_disconnect(&shark->v4l2_dev); | 259 | v4l2_device_disconnect(&shark->v4l2_dev); |
| 228 | radio_tea5777_exit(&shark->tea); | 260 | radio_tea5777_exit(&shark->tea); |
| 229 | mutex_unlock(&shark->tea.mutex); | 261 | mutex_unlock(&shark->tea.mutex); |
| 230 | 262 | ||
| 231 | for (i = 0; i < NO_LEDS; i++) | 263 | shark_unregister_leds(shark); |
| 232 | led_classdev_unregister(&shark->leds[i]); | ||
| 233 | 264 | ||
| 234 | v4l2_device_put(&shark->v4l2_dev); | 265 | v4l2_device_put(&shark->v4l2_dev); |
| 235 | } | 266 | } |
| @@ -238,7 +269,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev) | |||
| 238 | { | 269 | { |
| 239 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 270 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
| 240 | 271 | ||
| 241 | cancel_work_sync(&shark->led_work); | ||
| 242 | v4l2_device_unregister(&shark->v4l2_dev); | 272 | v4l2_device_unregister(&shark->v4l2_dev); |
| 243 | kfree(shark->transfer_buffer); | 273 | kfree(shark->transfer_buffer); |
| 244 | kfree(shark); | 274 | kfree(shark); |
| @@ -248,7 +278,7 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
| 248 | const struct usb_device_id *id) | 278 | const struct usb_device_id *id) |
| 249 | { | 279 | { |
| 250 | struct shark_device *shark; | 280 | struct shark_device *shark; |
| 251 | int i, retval = -ENOMEM; | 281 | int retval = -ENOMEM; |
| 252 | 282 | ||
| 253 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); | 283 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); |
| 254 | if (!shark) | 284 | if (!shark) |
| @@ -258,17 +288,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
| 258 | if (!shark->transfer_buffer) | 288 | if (!shark->transfer_buffer) |
| 259 | goto err_alloc_buffer; | 289 | goto err_alloc_buffer; |
| 260 | 290 | ||
| 261 | /* | 291 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); |
| 262 | * Work around a bug in usbhid/hid-core.c, where it leaves a dangling | 292 | |
| 263 | * pointer in intfdata causing v4l2-device.c to not set it. Which | 293 | retval = shark_register_leds(shark, &intf->dev); |
| 264 | * results in usb_shark_disconnect() referencing the dangling pointer | 294 | if (retval) |
| 265 | * | 295 | goto err_reg_leds; |
| 266 | * REMOVE (as soon as the above bug is fixed, patch submitted) | ||
| 267 | */ | ||
| 268 | usb_set_intfdata(intf, NULL); | ||
| 269 | 296 | ||
| 270 | shark->v4l2_dev.release = usb_shark_release; | 297 | shark->v4l2_dev.release = usb_shark_release; |
| 271 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); | ||
| 272 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); | 298 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); |
| 273 | if (retval) { | 299 | if (retval) { |
| 274 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); | 300 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); |
| @@ -292,32 +318,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
| 292 | goto err_init_tea; | 318 | goto err_init_tea; |
| 293 | } | 319 | } |
| 294 | 320 | ||
| 295 | INIT_WORK(&shark->led_work, shark_led_work); | ||
| 296 | for (i = 0; i < NO_LEDS; i++) { | ||
| 297 | shark->leds[i] = shark_led_templates[i]; | ||
| 298 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
| 299 | shark->leds[i].name, shark->v4l2_dev.name); | ||
| 300 | shark->leds[i].name = shark->led_names[i]; | ||
| 301 | /* | ||
| 302 | * We don't fail the probe if we fail to register the leds, | ||
| 303 | * because once we've called radio_tea5777_init, the /dev/radio0 | ||
| 304 | * node may be opened from userspace holding a reference to us! | ||
| 305 | * | ||
| 306 | * Note we cannot register the leds first instead as | ||
| 307 | * shark_led_work depends on the v4l2 mutex and registered bit. | ||
| 308 | */ | ||
| 309 | retval = led_classdev_register(&intf->dev, &shark->leds[i]); | ||
| 310 | if (retval) | ||
| 311 | v4l2_err(&shark->v4l2_dev, | ||
| 312 | "couldn't register led: %s\n", | ||
| 313 | shark->led_names[i]); | ||
| 314 | } | ||
| 315 | |||
| 316 | return 0; | 321 | return 0; |
| 317 | 322 | ||
| 318 | err_init_tea: | 323 | err_init_tea: |
| 319 | v4l2_device_unregister(&shark->v4l2_dev); | 324 | v4l2_device_unregister(&shark->v4l2_dev); |
| 320 | err_reg_dev: | 325 | err_reg_dev: |
| 326 | shark_unregister_leds(shark); | ||
| 327 | err_reg_leds: | ||
| 321 | kfree(shark->transfer_buffer); | 328 | kfree(shark->transfer_buffer); |
| 322 | err_alloc_buffer: | 329 | err_alloc_buffer: |
| 323 | kfree(shark); | 330 | kfree(shark); |
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 9e38132afec6..9bb65e170d99 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 643a6ff7c5d0..f867f04cccc9 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 146be4263ea1..be076f7181e7 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 5180390be7ab..8be57634ba60 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/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index 7efe9ad7acc7..0b91a5cd38eb 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/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/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index d2e6f82ecfac..560a65aa7038 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
| @@ -403,7 +403,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) | |||
| 403 | 403 | ||
| 404 | dev_dbg(pcdev->icd->parent, "Activate device\n"); | 404 | dev_dbg(pcdev->icd->parent, "Activate device\n"); |
| 405 | 405 | ||
| 406 | clk_enable(pcdev->clk); | 406 | clk_prepare_enable(pcdev->clk); |
| 407 | 407 | ||
| 408 | /* enable CSI before doing anything else */ | 408 | /* enable CSI before doing anything else */ |
| 409 | __raw_writel(csicr1, pcdev->base + CSICR1); | 409 | __raw_writel(csicr1, pcdev->base + CSICR1); |
| @@ -422,7 +422,7 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) | |||
| 422 | /* Disable all CSI interface */ | 422 | /* Disable all CSI interface */ |
| 423 | __raw_writel(0x00, pcdev->base + CSICR1); | 423 | __raw_writel(0x00, pcdev->base + CSICR1); |
| 424 | 424 | ||
| 425 | clk_disable(pcdev->clk); | 425 | clk_disable_unprepare(pcdev->clk); |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | /* | 428 | /* |
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 637bde8aca28..ac175406e582 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
| @@ -272,7 +272,7 @@ struct mx2_camera_dev { | |||
| 272 | struct device *dev; | 272 | struct device *dev; |
| 273 | struct soc_camera_host soc_host; | 273 | struct soc_camera_host soc_host; |
| 274 | struct soc_camera_device *icd; | 274 | struct soc_camera_device *icd; |
| 275 | struct clk *clk_csi, *clk_emma; | 275 | struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg; |
| 276 | 276 | ||
| 277 | unsigned int irq_csi, irq_emma; | 277 | unsigned int irq_csi, irq_emma; |
| 278 | void __iomem *base_csi, *base_emma; | 278 | void __iomem *base_csi, *base_emma; |
| @@ -407,7 +407,7 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) | |||
| 407 | { | 407 | { |
| 408 | unsigned long flags; | 408 | unsigned long flags; |
| 409 | 409 | ||
| 410 | clk_disable(pcdev->clk_csi); | 410 | clk_disable_unprepare(pcdev->clk_csi); |
| 411 | writel(0, pcdev->base_csi + CSICR1); | 411 | writel(0, pcdev->base_csi + CSICR1); |
| 412 | if (cpu_is_mx27()) { | 412 | if (cpu_is_mx27()) { |
| 413 | writel(0, pcdev->base_emma + PRP_CNTL); | 413 | writel(0, pcdev->base_emma + PRP_CNTL); |
| @@ -435,7 +435,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) | |||
| 435 | if (pcdev->icd) | 435 | if (pcdev->icd) |
| 436 | return -EBUSY; | 436 | return -EBUSY; |
| 437 | 437 | ||
| 438 | ret = clk_enable(pcdev->clk_csi); | 438 | ret = clk_prepare_enable(pcdev->clk_csi); |
| 439 | if (ret < 0) | 439 | if (ret < 0) |
| 440 | return ret; | 440 | return ret; |
| 441 | 441 | ||
| @@ -1633,23 +1633,34 @@ static int __devinit mx27_camera_emma_init(struct mx2_camera_dev *pcdev) | |||
| 1633 | goto exit_iounmap; | 1633 | goto exit_iounmap; |
| 1634 | } | 1634 | } |
| 1635 | 1635 | ||
| 1636 | pcdev->clk_emma = clk_get(NULL, "emma"); | 1636 | pcdev->clk_emma_ipg = clk_get(pcdev->dev, "emma-ipg"); |
| 1637 | if (IS_ERR(pcdev->clk_emma)) { | 1637 | if (IS_ERR(pcdev->clk_emma_ipg)) { |
| 1638 | err = PTR_ERR(pcdev->clk_emma); | 1638 | err = PTR_ERR(pcdev->clk_emma_ipg); |
| 1639 | goto exit_free_irq; | 1639 | goto exit_free_irq; |
| 1640 | } | 1640 | } |
| 1641 | 1641 | ||
| 1642 | clk_enable(pcdev->clk_emma); | 1642 | clk_prepare_enable(pcdev->clk_emma_ipg); |
| 1643 | |||
| 1644 | pcdev->clk_emma_ahb = clk_get(pcdev->dev, "emma-ahb"); | ||
| 1645 | if (IS_ERR(pcdev->clk_emma_ahb)) { | ||
| 1646 | err = PTR_ERR(pcdev->clk_emma_ahb); | ||
| 1647 | goto exit_clk_emma_ipg_put; | ||
| 1648 | } | ||
| 1649 | |||
| 1650 | clk_prepare_enable(pcdev->clk_emma_ahb); | ||
| 1643 | 1651 | ||
| 1644 | err = mx27_camera_emma_prp_reset(pcdev); | 1652 | err = mx27_camera_emma_prp_reset(pcdev); |
| 1645 | if (err) | 1653 | if (err) |
| 1646 | goto exit_clk_emma_put; | 1654 | goto exit_clk_emma_ahb_put; |
| 1647 | 1655 | ||
| 1648 | return err; | 1656 | return err; |
| 1649 | 1657 | ||
| 1650 | exit_clk_emma_put: | 1658 | exit_clk_emma_ahb_put: |
| 1651 | clk_disable(pcdev->clk_emma); | 1659 | clk_disable_unprepare(pcdev->clk_emma_ahb); |
| 1652 | clk_put(pcdev->clk_emma); | 1660 | clk_put(pcdev->clk_emma_ahb); |
| 1661 | exit_clk_emma_ipg_put: | ||
| 1662 | clk_disable_unprepare(pcdev->clk_emma_ipg); | ||
| 1663 | clk_put(pcdev->clk_emma_ipg); | ||
| 1653 | exit_free_irq: | 1664 | exit_free_irq: |
| 1654 | free_irq(pcdev->irq_emma, pcdev); | 1665 | free_irq(pcdev->irq_emma, pcdev); |
| 1655 | exit_iounmap: | 1666 | exit_iounmap: |
| @@ -1685,7 +1696,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
| 1685 | goto exit; | 1696 | goto exit; |
| 1686 | } | 1697 | } |
| 1687 | 1698 | ||
| 1688 | pcdev->clk_csi = clk_get(&pdev->dev, NULL); | 1699 | pcdev->clk_csi = clk_get(&pdev->dev, "ahb"); |
| 1689 | if (IS_ERR(pcdev->clk_csi)) { | 1700 | if (IS_ERR(pcdev->clk_csi)) { |
| 1690 | dev_err(&pdev->dev, "Could not get csi clock\n"); | 1701 | dev_err(&pdev->dev, "Could not get csi clock\n"); |
| 1691 | err = PTR_ERR(pcdev->clk_csi); | 1702 | err = PTR_ERR(pcdev->clk_csi); |
| @@ -1785,8 +1796,10 @@ exit_free_emma: | |||
| 1785 | eallocctx: | 1796 | eallocctx: |
| 1786 | if (cpu_is_mx27()) { | 1797 | if (cpu_is_mx27()) { |
| 1787 | free_irq(pcdev->irq_emma, pcdev); | 1798 | free_irq(pcdev->irq_emma, pcdev); |
| 1788 | clk_disable(pcdev->clk_emma); | 1799 | clk_disable_unprepare(pcdev->clk_emma_ipg); |
| 1789 | clk_put(pcdev->clk_emma); | 1800 | clk_put(pcdev->clk_emma_ipg); |
| 1801 | clk_disable_unprepare(pcdev->clk_emma_ahb); | ||
| 1802 | clk_put(pcdev->clk_emma_ahb); | ||
| 1790 | iounmap(pcdev->base_emma); | 1803 | iounmap(pcdev->base_emma); |
| 1791 | release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma)); | 1804 | release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma)); |
| 1792 | } | 1805 | } |
| @@ -1825,8 +1838,10 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev) | |||
| 1825 | iounmap(pcdev->base_csi); | 1838 | iounmap(pcdev->base_csi); |
| 1826 | 1839 | ||
| 1827 | if (cpu_is_mx27()) { | 1840 | if (cpu_is_mx27()) { |
| 1828 | clk_disable(pcdev->clk_emma); | 1841 | clk_disable_unprepare(pcdev->clk_emma_ipg); |
| 1829 | clk_put(pcdev->clk_emma); | 1842 | clk_put(pcdev->clk_emma_ipg); |
| 1843 | clk_disable_unprepare(pcdev->clk_emma_ahb); | ||
| 1844 | clk_put(pcdev->clk_emma_ahb); | ||
| 1830 | iounmap(pcdev->base_emma); | 1845 | iounmap(pcdev->base_emma); |
| 1831 | res = pcdev->res_emma; | 1846 | res = pcdev->res_emma; |
| 1832 | release_mem_region(res->start, resource_size(res)); | 1847 | release_mem_region(res->start, resource_size(res)); |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index f13643d31353..af2297dd49c8 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
| @@ -61,15 +61,9 @@ | |||
| 61 | 61 | ||
| 62 | #define MAX_VIDEO_MEM 16 | 62 | #define MAX_VIDEO_MEM 16 |
| 63 | 63 | ||
| 64 | enum csi_buffer_state { | ||
| 65 | CSI_BUF_NEEDS_INIT, | ||
| 66 | CSI_BUF_PREPARED, | ||
| 67 | }; | ||
| 68 | |||
| 69 | struct mx3_camera_buffer { | 64 | struct mx3_camera_buffer { |
| 70 | /* common v4l buffer stuff -- must be first */ | 65 | /* common v4l buffer stuff -- must be first */ |
| 71 | struct vb2_buffer vb; | 66 | struct vb2_buffer vb; |
| 72 | enum csi_buffer_state state; | ||
| 73 | struct list_head queue; | 67 | struct list_head queue; |
| 74 | 68 | ||
| 75 | /* One descriptot per scatterlist (per frame) */ | 69 | /* One descriptot per scatterlist (per frame) */ |
| @@ -285,7 +279,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) | |||
| 285 | goto error; | 279 | goto error; |
| 286 | } | 280 | } |
| 287 | 281 | ||
| 288 | if (buf->state == CSI_BUF_NEEDS_INIT) { | 282 | if (!buf->txd) { |
| 289 | sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0); | 283 | sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0); |
| 290 | sg_dma_len(sg) = new_size; | 284 | sg_dma_len(sg) = new_size; |
| 291 | 285 | ||
| @@ -298,7 +292,6 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) | |||
| 298 | txd->callback_param = txd; | 292 | txd->callback_param = txd; |
| 299 | txd->callback = mx3_cam_dma_done; | 293 | txd->callback = mx3_cam_dma_done; |
| 300 | 294 | ||
| 301 | buf->state = CSI_BUF_PREPARED; | ||
| 302 | buf->txd = txd; | 295 | buf->txd = txd; |
| 303 | } else { | 296 | } else { |
| 304 | txd = buf->txd; | 297 | txd = buf->txd; |
| @@ -385,7 +378,6 @@ static void mx3_videobuf_release(struct vb2_buffer *vb) | |||
| 385 | 378 | ||
| 386 | /* Doesn't hurt also if the list is empty */ | 379 | /* Doesn't hurt also if the list is empty */ |
| 387 | list_del_init(&buf->queue); | 380 | list_del_init(&buf->queue); |
| 388 | buf->state = CSI_BUF_NEEDS_INIT; | ||
| 389 | 381 | ||
| 390 | if (txd) { | 382 | if (txd) { |
| 391 | buf->txd = NULL; | 383 | buf->txd = NULL; |
| @@ -405,13 +397,13 @@ static int mx3_videobuf_init(struct vb2_buffer *vb) | |||
| 405 | struct mx3_camera_dev *mx3_cam = ici->priv; | 397 | struct mx3_camera_dev *mx3_cam = ici->priv; |
| 406 | struct mx3_camera_buffer *buf = to_mx3_vb(vb); | 398 | struct mx3_camera_buffer *buf = to_mx3_vb(vb); |
| 407 | 399 | ||
| 408 | /* This is for locking debugging only */ | 400 | if (!buf->txd) { |
| 409 | INIT_LIST_HEAD(&buf->queue); | 401 | /* This is for locking debugging only */ |
| 410 | sg_init_table(&buf->sg, 1); | 402 | INIT_LIST_HEAD(&buf->queue); |
| 403 | sg_init_table(&buf->sg, 1); | ||
| 411 | 404 | ||
| 412 | buf->state = CSI_BUF_NEEDS_INIT; | 405 | mx3_cam->buf_total += vb2_plane_size(vb, 0); |
| 413 | 406 | } | |
| 414 | mx3_cam->buf_total += vb2_plane_size(vb, 0); | ||
| 415 | 407 | ||
| 416 | return 0; | 408 | return 0; |
| 417 | } | 409 | } |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index b03ffecb7438..1bde255e45df 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
| @@ -171,7 +171,8 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd, | |||
| 171 | dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n", | 171 | dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n", |
| 172 | pixfmtstr(pix->pixelformat), pix->width, pix->height); | 172 | pixfmtstr(pix->pixelformat), pix->width, pix->height); |
| 173 | 173 | ||
| 174 | if (!(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) { | 174 | if (pix->pixelformat != V4L2_PIX_FMT_JPEG && |
| 175 | !(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) { | ||
| 175 | pix->bytesperline = 0; | 176 | pix->bytesperline = 0; |
| 176 | pix->sizeimage = 0; | 177 | pix->sizeimage = 0; |
| 177 | } | 178 | } |
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c index 89dce097a827..a397812635d6 100644 --- a/drivers/media/video/soc_mediabus.c +++ b/drivers/media/video/soc_mediabus.c | |||
| @@ -378,6 +378,9 @@ EXPORT_SYMBOL(soc_mbus_samples_per_pixel); | |||
| 378 | 378 | ||
| 379 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) | 379 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) |
| 380 | { | 380 | { |
| 381 | if (mf->fourcc == V4L2_PIX_FMT_JPEG) | ||
| 382 | return 0; | ||
| 383 | |||
| 381 | if (mf->layout != SOC_MBUS_LAYOUT_PACKED) | 384 | if (mf->layout != SOC_MBUS_LAYOUT_PACKED) |
| 382 | return width * mf->bits_per_sample / 8; | 385 | return width * mf->bits_per_sample / 8; |
| 383 | 386 | ||
| @@ -400,6 +403,9 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line); | |||
| 400 | s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, | 403 | s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, |
| 401 | u32 bytes_per_line, u32 height) | 404 | u32 bytes_per_line, u32 height) |
| 402 | { | 405 | { |
| 406 | if (mf->fourcc == V4L2_PIX_FMT_JPEG) | ||
| 407 | return 0; | ||
| 408 | |||
| 403 | if (mf->layout == SOC_MBUS_LAYOUT_PACKED) | 409 | if (mf->layout == SOC_MBUS_LAYOUT_PACKED) |
| 404 | return bytes_per_line * height; | 410 | return bytes_per_line * height; |
| 405 | 411 | ||
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 9288fbd5001b..5577381b5bf0 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/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/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index c3b7b5f59b32..6bc47fc82fe2 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/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; |
