diff options
Diffstat (limited to 'drivers')
66 files changed, 805 insertions, 873 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index f291587d753e..8e0f9256eb58 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -2834,6 +2834,8 @@ static int cciss_revalidate(struct gendisk *disk) | |||
| 2834 | InquiryData_struct *inq_buff = NULL; | 2834 | InquiryData_struct *inq_buff = NULL; |
| 2835 | 2835 | ||
| 2836 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { | 2836 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { |
| 2837 | if (!h->drv[logvol]) | ||
| 2838 | continue; | ||
| 2837 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, | 2839 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, |
| 2838 | sizeof(drv->LunID)) == 0) { | 2840 | sizeof(drv->LunID)) == 0) { |
| 2839 | FOUND = 1; | 2841 | FOUND = 1; |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 89d8a7cc4054..24487d4fb202 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
| @@ -3627,17 +3627,19 @@ static void drbdd(struct drbd_conf *mdev) | |||
| 3627 | } | 3627 | } |
| 3628 | 3628 | ||
| 3629 | shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header); | 3629 | shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header); |
| 3630 | rv = drbd_recv(mdev, &header->h80.payload, shs); | ||
| 3631 | if (unlikely(rv != shs)) { | ||
| 3632 | dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); | ||
| 3633 | goto err_out; | ||
| 3634 | } | ||
| 3635 | |||
| 3636 | if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) { | 3630 | if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) { |
| 3637 | dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size); | 3631 | dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size); |
| 3638 | goto err_out; | 3632 | goto err_out; |
| 3639 | } | 3633 | } |
| 3640 | 3634 | ||
| 3635 | if (shs) { | ||
| 3636 | rv = drbd_recv(mdev, &header->h80.payload, shs); | ||
| 3637 | if (unlikely(rv != shs)) { | ||
| 3638 | dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); | ||
| 3639 | goto err_out; | ||
| 3640 | } | ||
| 3641 | } | ||
| 3642 | |||
| 3641 | rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs); | 3643 | rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs); |
| 3642 | 3644 | ||
| 3643 | if (unlikely(!rv)) { | 3645 | if (unlikely(!rv)) { |
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index 181ea0364822..ab2bd09d54b4 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h | |||
| @@ -339,7 +339,8 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) | |||
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | /* completion of master bio is outside of spinlock. | 341 | /* completion of master bio is outside of spinlock. |
| 342 | * If you need it irqsave, do it your self! */ | 342 | * If you need it irqsave, do it your self! |
| 343 | * Which means: don't use from bio endio callback. */ | ||
| 343 | static inline int req_mod(struct drbd_request *req, | 344 | static inline int req_mod(struct drbd_request *req, |
| 344 | enum drbd_req_event what) | 345 | enum drbd_req_event what) |
| 345 | { | 346 | { |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 47d223c2409c..34f224b018b3 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
| @@ -193,8 +193,10 @@ void drbd_endio_sec(struct bio *bio, int error) | |||
| 193 | */ | 193 | */ |
| 194 | void drbd_endio_pri(struct bio *bio, int error) | 194 | void drbd_endio_pri(struct bio *bio, int error) |
| 195 | { | 195 | { |
| 196 | unsigned long flags; | ||
| 196 | struct drbd_request *req = bio->bi_private; | 197 | struct drbd_request *req = bio->bi_private; |
| 197 | struct drbd_conf *mdev = req->mdev; | 198 | struct drbd_conf *mdev = req->mdev; |
| 199 | struct bio_and_error m; | ||
| 198 | enum drbd_req_event what; | 200 | enum drbd_req_event what; |
| 199 | int uptodate = bio_flagged(bio, BIO_UPTODATE); | 201 | int uptodate = bio_flagged(bio, BIO_UPTODATE); |
| 200 | 202 | ||
| @@ -220,7 +222,13 @@ void drbd_endio_pri(struct bio *bio, int error) | |||
| 220 | bio_put(req->private_bio); | 222 | bio_put(req->private_bio); |
| 221 | req->private_bio = ERR_PTR(error); | 223 | req->private_bio = ERR_PTR(error); |
| 222 | 224 | ||
| 223 | req_mod(req, what); | 225 | /* not req_mod(), we need irqsave here! */ |
| 226 | spin_lock_irqsave(&mdev->req_lock, flags); | ||
| 227 | __req_mod(req, what, &m); | ||
| 228 | spin_unlock_irqrestore(&mdev->req_lock, flags); | ||
| 229 | |||
| 230 | if (m.bio) | ||
| 231 | complete_master_bio(mdev, &m); | ||
| 224 | } | 232 | } |
| 225 | 233 | ||
| 226 | int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | 234 | int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) |
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index d68d3aa1814b..f975d24890fa 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
| @@ -283,16 +283,21 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p, | |||
| 283 | } while (delay); | 283 | } while (delay); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) | 286 | static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) |
| 287 | { | 287 | { |
| 288 | unsigned long flags; | ||
| 289 | |||
| 290 | if (delta > p->max_match_value) | 288 | if (delta > p->max_match_value) |
| 291 | dev_warn(&p->pdev->dev, "delta out of range\n"); | 289 | dev_warn(&p->pdev->dev, "delta out of range\n"); |
| 292 | 290 | ||
| 293 | spin_lock_irqsave(&p->lock, flags); | ||
| 294 | p->next_match_value = delta; | 291 | p->next_match_value = delta; |
| 295 | sh_cmt_clock_event_program_verify(p, 0); | 292 | sh_cmt_clock_event_program_verify(p, 0); |
| 293 | } | ||
| 294 | |||
| 295 | static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) | ||
| 296 | { | ||
| 297 | unsigned long flags; | ||
| 298 | |||
| 299 | spin_lock_irqsave(&p->lock, flags); | ||
| 300 | __sh_cmt_set_next(p, delta); | ||
| 296 | spin_unlock_irqrestore(&p->lock, flags); | 301 | spin_unlock_irqrestore(&p->lock, flags); |
| 297 | } | 302 | } |
| 298 | 303 | ||
| @@ -359,7 +364,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) | |||
| 359 | 364 | ||
| 360 | /* setup timeout if no clockevent */ | 365 | /* setup timeout if no clockevent */ |
| 361 | if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) | 366 | if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) |
| 362 | sh_cmt_set_next(p, p->max_match_value); | 367 | __sh_cmt_set_next(p, p->max_match_value); |
| 363 | out: | 368 | out: |
| 364 | spin_unlock_irqrestore(&p->lock, flags); | 369 | spin_unlock_irqrestore(&p->lock, flags); |
| 365 | 370 | ||
| @@ -381,7 +386,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) | |||
| 381 | 386 | ||
| 382 | /* adjust the timeout to maximum if only clocksource left */ | 387 | /* adjust the timeout to maximum if only clocksource left */ |
| 383 | if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) | 388 | if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) |
| 384 | sh_cmt_set_next(p, p->max_match_value); | 389 | __sh_cmt_set_next(p, p->max_match_value); |
| 385 | 390 | ||
| 386 | spin_unlock_irqrestore(&p->lock, flags); | 391 | spin_unlock_irqrestore(&p->lock, flags); |
| 387 | } | 392 | } |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e3f7fc6f9565..68f09a868434 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -534,76 +534,73 @@ static int handle_eviocgbit(struct input_dev *dev, | |||
| 534 | } | 534 | } |
| 535 | #undef OLD_KEY_MAX | 535 | #undef OLD_KEY_MAX |
| 536 | 536 | ||
| 537 | static int evdev_handle_get_keycode(struct input_dev *dev, | 537 | static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p) |
| 538 | void __user *p, size_t size) | ||
| 539 | { | 538 | { |
| 540 | struct input_keymap_entry ke; | 539 | struct input_keymap_entry ke = { |
| 540 | .len = sizeof(unsigned int), | ||
| 541 | .flags = 0, | ||
| 542 | }; | ||
| 543 | int __user *ip = (int __user *)p; | ||
| 541 | int error; | 544 | int error; |
| 542 | 545 | ||
| 543 | memset(&ke, 0, sizeof(ke)); | 546 | /* legacy case */ |
| 544 | 547 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | |
| 545 | if (size == sizeof(unsigned int[2])) { | 548 | return -EFAULT; |
| 546 | /* legacy case */ | ||
| 547 | int __user *ip = (int __user *)p; | ||
| 548 | 549 | ||
| 549 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | 550 | error = input_get_keycode(dev, &ke); |
| 550 | return -EFAULT; | 551 | if (error) |
| 552 | return error; | ||
| 551 | 553 | ||
| 552 | ke.len = sizeof(unsigned int); | 554 | if (put_user(ke.keycode, ip + 1)) |
| 553 | ke.flags = 0; | 555 | return -EFAULT; |
| 554 | 556 | ||
| 555 | error = input_get_keycode(dev, &ke); | 557 | return 0; |
| 556 | if (error) | 558 | } |
| 557 | return error; | ||
| 558 | 559 | ||
| 559 | if (put_user(ke.keycode, ip + 1)) | 560 | static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p) |
| 560 | return -EFAULT; | 561 | { |
| 562 | struct input_keymap_entry ke; | ||
| 563 | int error; | ||
| 561 | 564 | ||
| 562 | } else { | 565 | if (copy_from_user(&ke, p, sizeof(ke))) |
| 563 | size = min(size, sizeof(ke)); | 566 | return -EFAULT; |
| 564 | 567 | ||
| 565 | if (copy_from_user(&ke, p, size)) | 568 | error = input_get_keycode(dev, &ke); |
| 566 | return -EFAULT; | 569 | if (error) |
| 570 | return error; | ||
| 567 | 571 | ||
| 568 | error = input_get_keycode(dev, &ke); | 572 | if (copy_to_user(p, &ke, sizeof(ke))) |
| 569 | if (error) | 573 | return -EFAULT; |
| 570 | return error; | ||
| 571 | 574 | ||
| 572 | if (copy_to_user(p, &ke, size)) | ||
| 573 | return -EFAULT; | ||
| 574 | } | ||
| 575 | return 0; | 575 | return 0; |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | static int evdev_handle_set_keycode(struct input_dev *dev, | 578 | static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p) |
| 579 | void __user *p, size_t size) | ||
| 580 | { | 579 | { |
| 581 | struct input_keymap_entry ke; | 580 | struct input_keymap_entry ke = { |
| 582 | 581 | .len = sizeof(unsigned int), | |
| 583 | memset(&ke, 0, sizeof(ke)); | 582 | .flags = 0, |
| 583 | }; | ||
| 584 | int __user *ip = (int __user *)p; | ||
| 584 | 585 | ||
| 585 | if (size == sizeof(unsigned int[2])) { | 586 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) |
| 586 | /* legacy case */ | 587 | return -EFAULT; |
| 587 | int __user *ip = (int __user *)p; | ||
| 588 | 588 | ||
| 589 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | 589 | if (get_user(ke.keycode, ip + 1)) |
| 590 | return -EFAULT; | 590 | return -EFAULT; |
| 591 | 591 | ||
| 592 | if (get_user(ke.keycode, ip + 1)) | 592 | return input_set_keycode(dev, &ke); |
| 593 | return -EFAULT; | 593 | } |
| 594 | 594 | ||
| 595 | ke.len = sizeof(unsigned int); | 595 | static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) |
| 596 | ke.flags = 0; | 596 | { |
| 597 | struct input_keymap_entry ke; | ||
| 597 | 598 | ||
| 598 | } else { | 599 | if (copy_from_user(&ke, p, sizeof(ke))) |
| 599 | size = min(size, sizeof(ke)); | 600 | return -EFAULT; |
| 600 | 601 | ||
| 601 | if (copy_from_user(&ke, p, size)) | 602 | if (ke.len > sizeof(ke.scancode)) |
| 602 | return -EFAULT; | 603 | return -EINVAL; |
| 603 | |||
| 604 | if (ke.len > sizeof(ke.scancode)) | ||
| 605 | return -EINVAL; | ||
| 606 | } | ||
| 607 | 604 | ||
| 608 | return input_set_keycode(dev, &ke); | 605 | return input_set_keycode(dev, &ke); |
| 609 | } | 606 | } |
| @@ -669,6 +666,18 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 669 | return evdev_grab(evdev, client); | 666 | return evdev_grab(evdev, client); |
| 670 | else | 667 | else |
| 671 | return evdev_ungrab(evdev, client); | 668 | return evdev_ungrab(evdev, client); |
| 669 | |||
| 670 | case EVIOCGKEYCODE: | ||
| 671 | return evdev_handle_get_keycode(dev, p); | ||
| 672 | |||
| 673 | case EVIOCSKEYCODE: | ||
| 674 | return evdev_handle_set_keycode(dev, p); | ||
| 675 | |||
| 676 | case EVIOCGKEYCODE_V2: | ||
| 677 | return evdev_handle_get_keycode_v2(dev, p); | ||
| 678 | |||
| 679 | case EVIOCSKEYCODE_V2: | ||
| 680 | return evdev_handle_set_keycode_v2(dev, p); | ||
| 672 | } | 681 | } |
| 673 | 682 | ||
| 674 | size = _IOC_SIZE(cmd); | 683 | size = _IOC_SIZE(cmd); |
| @@ -708,12 +717,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 708 | return -EFAULT; | 717 | return -EFAULT; |
| 709 | 718 | ||
| 710 | return error; | 719 | return error; |
| 711 | |||
| 712 | case EVIOC_MASK_SIZE(EVIOCGKEYCODE): | ||
| 713 | return evdev_handle_get_keycode(dev, p, size); | ||
| 714 | |||
| 715 | case EVIOC_MASK_SIZE(EVIOCSKEYCODE): | ||
| 716 | return evdev_handle_set_keycode(dev, p, size); | ||
| 717 | } | 720 | } |
| 718 | 721 | ||
| 719 | /* Multi-number variable-length handlers */ | 722 | /* Multi-number variable-length handlers */ |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 4852b440960a..435b0af401e4 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -1436,6 +1436,8 @@ static struct wacom_features wacom_features_0xD2 = | |||
| 1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | 1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; |
| 1437 | static struct wacom_features wacom_features_0xD3 = | 1437 | static struct wacom_features wacom_features_0xD3 = |
| 1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
| 1439 | static const struct wacom_features wacom_features_0xD4 = | ||
| 1440 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT }; | ||
| 1439 | static struct wacom_features wacom_features_0xD8 = | 1441 | static struct wacom_features wacom_features_0xD8 = |
| 1440 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1442 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
| 1441 | static struct wacom_features wacom_features_0xDA = | 1443 | static struct wacom_features wacom_features_0xDA = |
| @@ -1510,6 +1512,7 @@ const struct usb_device_id wacom_ids[] = { | |||
| 1510 | { USB_DEVICE_WACOM(0xD1) }, | 1512 | { USB_DEVICE_WACOM(0xD1) }, |
| 1511 | { USB_DEVICE_WACOM(0xD2) }, | 1513 | { USB_DEVICE_WACOM(0xD2) }, |
| 1512 | { USB_DEVICE_WACOM(0xD3) }, | 1514 | { USB_DEVICE_WACOM(0xD3) }, |
| 1515 | { USB_DEVICE_WACOM(0xD4) }, | ||
| 1513 | { USB_DEVICE_WACOM(0xD8) }, | 1516 | { USB_DEVICE_WACOM(0xD8) }, |
| 1514 | { USB_DEVICE_WACOM(0xDA) }, | 1517 | { USB_DEVICE_WACOM(0xDA) }, |
| 1515 | { USB_DEVICE_WACOM(0xDB) }, | 1518 | { USB_DEVICE_WACOM(0xDB) }, |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 90267f8d64ee..4d705cea0f8c 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
| @@ -517,9 +517,8 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, | |||
| 517 | */ | 517 | */ |
| 518 | 518 | ||
| 519 | if (q->merge_bvec_fn && !ti->type->merge) | 519 | if (q->merge_bvec_fn && !ti->type->merge) |
| 520 | limits->max_sectors = | 520 | blk_limits_max_hw_sectors(limits, |
| 521 | min_not_zero(limits->max_sectors, | 521 | (unsigned int) (PAGE_SIZE >> 9)); |
| 522 | (unsigned int) (PAGE_SIZE >> 9)); | ||
| 523 | return 0; | 522 | return 0; |
| 524 | } | 523 | } |
| 525 | EXPORT_SYMBOL_GPL(dm_set_device_limits); | 524 | EXPORT_SYMBOL_GPL(dm_set_device_limits); |
| @@ -1131,11 +1130,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
| 1131 | */ | 1130 | */ |
| 1132 | q->limits = *limits; | 1131 | q->limits = *limits; |
| 1133 | 1132 | ||
| 1134 | if (limits->no_cluster) | ||
| 1135 | queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); | ||
| 1136 | else | ||
| 1137 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q); | ||
| 1138 | |||
| 1139 | if (!dm_table_supports_discards(t)) | 1133 | if (!dm_table_supports_discards(t)) |
| 1140 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); | 1134 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); |
| 1141 | else | 1135 | else |
diff --git a/drivers/md/md.c b/drivers/md/md.c index e71c5fa527f5..175c424f201f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -4295,9 +4295,6 @@ static int md_alloc(dev_t dev, char *name) | |||
| 4295 | goto abort; | 4295 | goto abort; |
| 4296 | mddev->queue->queuedata = mddev; | 4296 | mddev->queue->queuedata = mddev; |
| 4297 | 4297 | ||
| 4298 | /* Can be unlocked because the queue is new: no concurrency */ | ||
| 4299 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue); | ||
| 4300 | |||
| 4301 | blk_queue_make_request(mddev->queue, md_make_request); | 4298 | blk_queue_make_request(mddev->queue, md_make_request); |
| 4302 | 4299 | ||
| 4303 | disk = alloc_disk(1 << shift); | 4300 | disk = alloc_disk(1 << shift); |
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c index 05bde9ccb770..1d1d8d200755 100644 --- a/drivers/media/common/saa7146_hlp.c +++ b/drivers/media/common/saa7146_hlp.c | |||
| @@ -558,7 +558,7 @@ static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, e | |||
| 558 | static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat) | 558 | static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat) |
| 559 | { | 559 | { |
| 560 | struct saa7146_vv *vv = dev->vv_data; | 560 | struct saa7146_vv *vv = dev->vv_data; |
| 561 | struct saa7146_format *sfmt = format_by_fourcc(dev, pixelformat); | 561 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat); |
| 562 | 562 | ||
| 563 | int b_depth = vv->ov_fmt->depth; | 563 | int b_depth = vv->ov_fmt->depth; |
| 564 | int b_bpl = vv->ov_fb.fmt.bytesperline; | 564 | int b_bpl = vv->ov_fb.fmt.bytesperline; |
| @@ -702,7 +702,7 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71 | |||
| 702 | struct saa7146_vv *vv = dev->vv_data; | 702 | struct saa7146_vv *vv = dev->vv_data; |
| 703 | struct saa7146_video_dma vdma1; | 703 | struct saa7146_video_dma vdma1; |
| 704 | 704 | ||
| 705 | struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 705 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
| 706 | 706 | ||
| 707 | int width = buf->fmt->width; | 707 | int width = buf->fmt->width; |
| 708 | int height = buf->fmt->height; | 708 | int height = buf->fmt->height; |
| @@ -827,7 +827,7 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71 | |||
| 827 | struct saa7146_video_dma vdma2; | 827 | struct saa7146_video_dma vdma2; |
| 828 | struct saa7146_video_dma vdma3; | 828 | struct saa7146_video_dma vdma3; |
| 829 | 829 | ||
| 830 | struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 830 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
| 831 | 831 | ||
| 832 | int width = buf->fmt->width; | 832 | int width = buf->fmt->width; |
| 833 | int height = buf->fmt->height; | 833 | int height = buf->fmt->height; |
| @@ -994,7 +994,7 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar) | |||
| 994 | 994 | ||
| 995 | void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) | 995 | void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) |
| 996 | { | 996 | { |
| 997 | struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 997 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
| 998 | struct saa7146_vv *vv = dev->vv_data; | 998 | struct saa7146_vv *vv = dev->vv_data; |
| 999 | u32 vdma1_prot_addr; | 999 | u32 vdma1_prot_addr; |
| 1000 | 1000 | ||
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 741c5732b430..d246910129e8 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
| @@ -84,7 +84,7 @@ static struct saa7146_format formats[] = { | |||
| 84 | 84 | ||
| 85 | static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format); | 85 | static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format); |
| 86 | 86 | ||
| 87 | struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc) | 87 | struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc) |
| 88 | { | 88 | { |
| 89 | int i, j = NUM_FORMATS; | 89 | int i, j = NUM_FORMATS; |
| 90 | 90 | ||
| @@ -266,7 +266,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu | |||
| 266 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 266 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
| 267 | struct scatterlist *list = dma->sglist; | 267 | struct scatterlist *list = dma->sglist; |
| 268 | int length = dma->sglen; | 268 | int length = dma->sglen; |
| 269 | struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 269 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
| 270 | 270 | ||
| 271 | DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length)); | 271 | DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length)); |
| 272 | 272 | ||
| @@ -408,7 +408,7 @@ static int video_begin(struct saa7146_fh *fh) | |||
| 408 | } | 408 | } |
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); | 411 | fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); |
| 412 | /* we need to have a valid format set here */ | 412 | /* we need to have a valid format set here */ |
| 413 | BUG_ON(NULL == fmt); | 413 | BUG_ON(NULL == fmt); |
| 414 | 414 | ||
| @@ -460,7 +460,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file) | |||
| 460 | return -EBUSY; | 460 | return -EBUSY; |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); | 463 | fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); |
| 464 | /* we need to have a valid format set here */ | 464 | /* we need to have a valid format set here */ |
| 465 | BUG_ON(NULL == fmt); | 465 | BUG_ON(NULL == fmt); |
| 466 | 466 | ||
| @@ -536,7 +536,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f | |||
| 536 | return -EPERM; | 536 | return -EPERM; |
| 537 | 537 | ||
| 538 | /* check args */ | 538 | /* check args */ |
| 539 | fmt = format_by_fourcc(dev, fb->fmt.pixelformat); | 539 | fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat); |
| 540 | if (NULL == fmt) | 540 | if (NULL == fmt) |
| 541 | return -EINVAL; | 541 | return -EINVAL; |
| 542 | 542 | ||
| @@ -760,7 +760,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma | |||
| 760 | 760 | ||
| 761 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); | 761 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); |
| 762 | 762 | ||
| 763 | fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat); | 763 | fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat); |
| 764 | if (NULL == fmt) | 764 | if (NULL == fmt) |
| 765 | return -EINVAL; | 765 | return -EINVAL; |
| 766 | 766 | ||
| @@ -1264,7 +1264,7 @@ static int buffer_prepare(struct videobuf_queue *q, | |||
| 1264 | buf->fmt = &fh->video_fmt; | 1264 | buf->fmt = &fh->video_fmt; |
| 1265 | buf->vb.field = fh->video_fmt.field; | 1265 | buf->vb.field = fh->video_fmt.field; |
| 1266 | 1266 | ||
| 1267 | sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 1267 | sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
| 1268 | 1268 | ||
| 1269 | release_all_pagetables(dev, buf); | 1269 | release_all_pagetables(dev, buf); |
| 1270 | if( 0 != IS_PLANAR(sfmt->trans)) { | 1270 | if( 0 != IS_PLANAR(sfmt->trans)) { |
| @@ -1378,7 +1378,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file) | |||
| 1378 | fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24; | 1378 | fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24; |
| 1379 | fh->video_fmt.bytesperline = 0; | 1379 | fh->video_fmt.bytesperline = 0; |
| 1380 | fh->video_fmt.field = V4L2_FIELD_ANY; | 1380 | fh->video_fmt.field = V4L2_FIELD_ANY; |
| 1381 | sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); | 1381 | sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); |
| 1382 | fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8; | 1382 | fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8; |
| 1383 | 1383 | ||
| 1384 | videobuf_queue_sg_init(&fh->video_q, &video_qops, | 1384 | videobuf_queue_sg_init(&fh->video_q, &video_qops, |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 5bf4985daede..05e832f61c3e 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
| @@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 361 | 361 | ||
| 362 | static const struct v4l2_file_operations rtrack_fops = { | 362 | static const struct v4l2_file_operations rtrack_fops = { |
| 363 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
| 364 | .ioctl = video_ioctl2, | 364 | .unlocked_ioctl = video_ioctl2, |
| 365 | }; | 365 | }; |
| 366 | 366 | ||
| 367 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { | 367 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { |
| @@ -412,13 +412,6 @@ static int __init rtrack_init(void) | |||
| 412 | rt->vdev.release = video_device_release_empty; | 412 | rt->vdev.release = video_device_release_empty; |
| 413 | video_set_drvdata(&rt->vdev, rt); | 413 | video_set_drvdata(&rt->vdev, rt); |
| 414 | 414 | ||
| 415 | if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 416 | v4l2_device_unregister(&rt->v4l2_dev); | ||
| 417 | release_region(rt->io, 2); | ||
| 418 | return -EINVAL; | ||
| 419 | } | ||
| 420 | v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); | ||
| 421 | |||
| 422 | /* Set up the I/O locking */ | 415 | /* Set up the I/O locking */ |
| 423 | 416 | ||
| 424 | mutex_init(&rt->lock); | 417 | mutex_init(&rt->lock); |
| @@ -430,6 +423,13 @@ static int __init rtrack_init(void) | |||
| 430 | sleep_delay(2000000); /* make sure it's totally down */ | 423 | sleep_delay(2000000); /* make sure it's totally down */ |
| 431 | outb(0xc0, rt->io); /* steady volume, mute card */ | 424 | outb(0xc0, rt->io); /* steady volume, mute card */ |
| 432 | 425 | ||
| 426 | if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 427 | v4l2_device_unregister(&rt->v4l2_dev); | ||
| 428 | release_region(rt->io, 2); | ||
| 429 | return -EINVAL; | ||
| 430 | } | ||
| 431 | v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); | ||
| 432 | |||
| 433 | return 0; | 433 | return 0; |
| 434 | } | 434 | } |
| 435 | 435 | ||
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index c22311393624..dd8a6ab0d437 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
| @@ -324,7 +324,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 324 | 324 | ||
| 325 | static const struct v4l2_file_operations aztech_fops = { | 325 | static const struct v4l2_file_operations aztech_fops = { |
| 326 | .owner = THIS_MODULE, | 326 | .owner = THIS_MODULE, |
| 327 | .ioctl = video_ioctl2, | 327 | .unlocked_ioctl = video_ioctl2, |
| 328 | }; | 328 | }; |
| 329 | 329 | ||
| 330 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { | 330 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { |
| @@ -375,6 +375,8 @@ static int __init aztech_init(void) | |||
| 375 | az->vdev.ioctl_ops = &aztech_ioctl_ops; | 375 | az->vdev.ioctl_ops = &aztech_ioctl_ops; |
| 376 | az->vdev.release = video_device_release_empty; | 376 | az->vdev.release = video_device_release_empty; |
| 377 | video_set_drvdata(&az->vdev, az); | 377 | video_set_drvdata(&az->vdev, az); |
| 378 | /* mute card - prevents noisy bootups */ | ||
| 379 | outb(0, az->io); | ||
| 378 | 380 | ||
| 379 | if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 381 | if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 380 | v4l2_device_unregister(v4l2_dev); | 382 | v4l2_device_unregister(v4l2_dev); |
| @@ -383,8 +385,6 @@ static int __init aztech_init(void) | |||
| 383 | } | 385 | } |
| 384 | 386 | ||
| 385 | v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); | 387 | v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); |
| 386 | /* mute card - prevents noisy bootups */ | ||
| 387 | outb(0, az->io); | ||
| 388 | return 0; | 388 | return 0; |
| 389 | } | 389 | } |
| 390 | 390 | ||
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index b701ea6e7c73..bc9ad0897c55 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
| @@ -328,11 +328,10 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo | |||
| 328 | unsigned char readbuf[RDS_BUFFER]; | 328 | unsigned char readbuf[RDS_BUFFER]; |
| 329 | int i = 0; | 329 | int i = 0; |
| 330 | 330 | ||
| 331 | mutex_lock(&dev->lock); | ||
| 331 | if (dev->rdsstat == 0) { | 332 | if (dev->rdsstat == 0) { |
| 332 | mutex_lock(&dev->lock); | ||
| 333 | dev->rdsstat = 1; | 333 | dev->rdsstat = 1; |
| 334 | outb(0x80, dev->io); /* Select RDS fifo */ | 334 | outb(0x80, dev->io); /* Select RDS fifo */ |
| 335 | mutex_unlock(&dev->lock); | ||
| 336 | init_timer(&dev->readtimer); | 335 | init_timer(&dev->readtimer); |
| 337 | dev->readtimer.function = cadet_handler; | 336 | dev->readtimer.function = cadet_handler; |
| 338 | dev->readtimer.data = (unsigned long)dev; | 337 | dev->readtimer.data = (unsigned long)dev; |
| @@ -340,12 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo | |||
| 340 | add_timer(&dev->readtimer); | 339 | add_timer(&dev->readtimer); |
| 341 | } | 340 | } |
| 342 | if (dev->rdsin == dev->rdsout) { | 341 | if (dev->rdsin == dev->rdsout) { |
| 342 | mutex_unlock(&dev->lock); | ||
| 343 | if (file->f_flags & O_NONBLOCK) | 343 | if (file->f_flags & O_NONBLOCK) |
| 344 | return -EWOULDBLOCK; | 344 | return -EWOULDBLOCK; |
| 345 | interruptible_sleep_on(&dev->read_queue); | 345 | interruptible_sleep_on(&dev->read_queue); |
| 346 | mutex_lock(&dev->lock); | ||
| 346 | } | 347 | } |
| 347 | while (i < count && dev->rdsin != dev->rdsout) | 348 | while (i < count && dev->rdsin != dev->rdsout) |
| 348 | readbuf[i++] = dev->rdsbuf[dev->rdsout++]; | 349 | readbuf[i++] = dev->rdsbuf[dev->rdsout++]; |
| 350 | mutex_unlock(&dev->lock); | ||
| 349 | 351 | ||
| 350 | if (copy_to_user(data, readbuf, i)) | 352 | if (copy_to_user(data, readbuf, i)) |
| 351 | return -EFAULT; | 353 | return -EFAULT; |
| @@ -525,9 +527,11 @@ static int cadet_open(struct file *file) | |||
| 525 | { | 527 | { |
| 526 | struct cadet *dev = video_drvdata(file); | 528 | struct cadet *dev = video_drvdata(file); |
| 527 | 529 | ||
| 530 | mutex_lock(&dev->lock); | ||
| 528 | dev->users++; | 531 | dev->users++; |
| 529 | if (1 == dev->users) | 532 | if (1 == dev->users) |
| 530 | init_waitqueue_head(&dev->read_queue); | 533 | init_waitqueue_head(&dev->read_queue); |
| 534 | mutex_unlock(&dev->lock); | ||
| 531 | return 0; | 535 | return 0; |
| 532 | } | 536 | } |
| 533 | 537 | ||
| @@ -535,11 +539,13 @@ static int cadet_release(struct file *file) | |||
| 535 | { | 539 | { |
| 536 | struct cadet *dev = video_drvdata(file); | 540 | struct cadet *dev = video_drvdata(file); |
| 537 | 541 | ||
| 542 | mutex_lock(&dev->lock); | ||
| 538 | dev->users--; | 543 | dev->users--; |
| 539 | if (0 == dev->users) { | 544 | if (0 == dev->users) { |
| 540 | del_timer_sync(&dev->readtimer); | 545 | del_timer_sync(&dev->readtimer); |
| 541 | dev->rdsstat = 0; | 546 | dev->rdsstat = 0; |
| 542 | } | 547 | } |
| 548 | mutex_unlock(&dev->lock); | ||
| 543 | return 0; | 549 | return 0; |
| 544 | } | 550 | } |
| 545 | 551 | ||
| @@ -559,7 +565,7 @@ static const struct v4l2_file_operations cadet_fops = { | |||
| 559 | .open = cadet_open, | 565 | .open = cadet_open, |
| 560 | .release = cadet_release, | 566 | .release = cadet_release, |
| 561 | .read = cadet_read, | 567 | .read = cadet_read, |
| 562 | .ioctl = video_ioctl2, | 568 | .unlocked_ioctl = video_ioctl2, |
| 563 | .poll = cadet_poll, | 569 | .poll = cadet_poll, |
| 564 | }; | 570 | }; |
| 565 | 571 | ||
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 79039674a0e0..28fa85ba2087 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
| @@ -361,7 +361,7 @@ MODULE_DEVICE_TABLE(pci, gemtek_pci_id); | |||
| 361 | 361 | ||
| 362 | static const struct v4l2_file_operations gemtek_pci_fops = { | 362 | static const struct v4l2_file_operations gemtek_pci_fops = { |
| 363 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
| 364 | .ioctl = video_ioctl2, | 364 | .unlocked_ioctl = video_ioctl2, |
| 365 | }; | 365 | }; |
| 366 | 366 | ||
| 367 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { | 367 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { |
| @@ -422,11 +422,11 @@ static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_dev | |||
| 422 | card->vdev.release = video_device_release_empty; | 422 | card->vdev.release = video_device_release_empty; |
| 423 | video_set_drvdata(&card->vdev, card); | 423 | video_set_drvdata(&card->vdev, card); |
| 424 | 424 | ||
| 425 | gemtek_pci_mute(card); | ||
| 426 | |||
| 425 | if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) | 427 | if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) |
| 426 | goto err_video; | 428 | goto err_video; |
| 427 | 429 | ||
| 428 | gemtek_pci_mute(card); | ||
| 429 | |||
| 430 | v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", | 430 | v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", |
| 431 | pdev->revision, card->iobase, card->iobase + card->length - 1); | 431 | pdev->revision, card->iobase, card->iobase + card->length - 1); |
| 432 | 432 | ||
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 73985f641f07..259936422e49 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
| @@ -378,7 +378,7 @@ static int gemtek_probe(struct gemtek *gt) | |||
| 378 | 378 | ||
| 379 | static const struct v4l2_file_operations gemtek_fops = { | 379 | static const struct v4l2_file_operations gemtek_fops = { |
| 380 | .owner = THIS_MODULE, | 380 | .owner = THIS_MODULE, |
| 381 | .ioctl = video_ioctl2, | 381 | .unlocked_ioctl = video_ioctl2, |
| 382 | }; | 382 | }; |
| 383 | 383 | ||
| 384 | static int vidioc_querycap(struct file *file, void *priv, | 384 | static int vidioc_querycap(struct file *file, void *priv, |
| @@ -577,12 +577,6 @@ static int __init gemtek_init(void) | |||
| 577 | gt->vdev.release = video_device_release_empty; | 577 | gt->vdev.release = video_device_release_empty; |
| 578 | video_set_drvdata(>->vdev, gt); | 578 | video_set_drvdata(>->vdev, gt); |
| 579 | 579 | ||
| 580 | if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 581 | v4l2_device_unregister(v4l2_dev); | ||
| 582 | release_region(gt->io, 1); | ||
| 583 | return -EBUSY; | ||
| 584 | } | ||
| 585 | |||
| 586 | /* Set defaults */ | 580 | /* Set defaults */ |
| 587 | gt->lastfreq = GEMTEK_LOWFREQ; | 581 | gt->lastfreq = GEMTEK_LOWFREQ; |
| 588 | gt->bu2614data = 0; | 582 | gt->bu2614data = 0; |
| @@ -590,6 +584,12 @@ static int __init gemtek_init(void) | |||
| 590 | if (initmute) | 584 | if (initmute) |
| 591 | gemtek_mute(gt); | 585 | gemtek_mute(gt); |
| 592 | 586 | ||
| 587 | if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 588 | v4l2_device_unregister(v4l2_dev); | ||
| 589 | release_region(gt->io, 1); | ||
| 590 | return -EBUSY; | ||
| 591 | } | ||
| 592 | |||
| 593 | return 0; | 593 | return 0; |
| 594 | } | 594 | } |
| 595 | 595 | ||
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 08f1051979ca..6af61bfeb178 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
| @@ -299,7 +299,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 299 | 299 | ||
| 300 | static const struct v4l2_file_operations maestro_fops = { | 300 | static const struct v4l2_file_operations maestro_fops = { |
| 301 | .owner = THIS_MODULE, | 301 | .owner = THIS_MODULE, |
| 302 | .ioctl = video_ioctl2, | 302 | .unlocked_ioctl = video_ioctl2, |
| 303 | }; | 303 | }; |
| 304 | 304 | ||
| 305 | static const struct v4l2_ioctl_ops maestro_ioctl_ops = { | 305 | static const struct v4l2_ioctl_ops maestro_ioctl_ops = { |
| @@ -383,22 +383,20 @@ static int __devinit maestro_probe(struct pci_dev *pdev, | |||
| 383 | dev->vdev.release = video_device_release_empty; | 383 | dev->vdev.release = video_device_release_empty; |
| 384 | video_set_drvdata(&dev->vdev, dev); | 384 | video_set_drvdata(&dev->vdev, dev); |
| 385 | 385 | ||
| 386 | if (!radio_power_on(dev)) { | ||
| 387 | retval = -EIO; | ||
| 388 | goto errfr1; | ||
| 389 | } | ||
| 390 | |||
| 386 | retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); | 391 | retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); |
| 387 | if (retval) { | 392 | if (retval) { |
| 388 | v4l2_err(v4l2_dev, "can't register video device!\n"); | 393 | v4l2_err(v4l2_dev, "can't register video device!\n"); |
| 389 | goto errfr1; | 394 | goto errfr1; |
| 390 | } | 395 | } |
| 391 | 396 | ||
| 392 | if (!radio_power_on(dev)) { | ||
| 393 | retval = -EIO; | ||
| 394 | goto errunr; | ||
| 395 | } | ||
| 396 | |||
| 397 | v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); | 397 | v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); |
| 398 | 398 | ||
| 399 | return 0; | 399 | return 0; |
| 400 | errunr: | ||
| 401 | video_unregister_device(&dev->vdev); | ||
| 402 | errfr1: | 400 | errfr1: |
| 403 | v4l2_device_unregister(v4l2_dev); | 401 | v4l2_device_unregister(v4l2_dev); |
| 404 | errfr: | 402 | errfr: |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 255d40df4b46..6459a220b0dd 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
| @@ -346,7 +346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 346 | 346 | ||
| 347 | static const struct v4l2_file_operations maxiradio_fops = { | 347 | static const struct v4l2_file_operations maxiradio_fops = { |
| 348 | .owner = THIS_MODULE, | 348 | .owner = THIS_MODULE, |
| 349 | .ioctl = video_ioctl2, | 349 | .unlocked_ioctl = video_ioctl2, |
| 350 | }; | 350 | }; |
| 351 | 351 | ||
| 352 | static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { | 352 | static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c index 4ff885445fd4..3fb76e3834c9 100644 --- a/drivers/media/radio/radio-miropcm20.c +++ b/drivers/media/radio/radio-miropcm20.c | |||
| @@ -33,6 +33,7 @@ struct pcm20 { | |||
| 33 | unsigned long freq; | 33 | unsigned long freq; |
| 34 | int muted; | 34 | int muted; |
| 35 | struct snd_miro_aci *aci; | 35 | struct snd_miro_aci *aci; |
| 36 | struct mutex lock; | ||
| 36 | }; | 37 | }; |
| 37 | 38 | ||
| 38 | static struct pcm20 pcm20_card = { | 39 | static struct pcm20 pcm20_card = { |
| @@ -72,7 +73,7 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq) | |||
| 72 | 73 | ||
| 73 | static const struct v4l2_file_operations pcm20_fops = { | 74 | static const struct v4l2_file_operations pcm20_fops = { |
| 74 | .owner = THIS_MODULE, | 75 | .owner = THIS_MODULE, |
| 75 | .ioctl = video_ioctl2, | 76 | .unlocked_ioctl = video_ioctl2, |
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | static int vidioc_querycap(struct file *file, void *priv, | 79 | static int vidioc_querycap(struct file *file, void *priv, |
| @@ -229,7 +230,7 @@ static int __init pcm20_init(void) | |||
| 229 | return -ENODEV; | 230 | return -ENODEV; |
| 230 | } | 231 | } |
| 231 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); | 232 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); |
| 232 | 233 | mutex_init(&dev->lock); | |
| 233 | 234 | ||
| 234 | res = v4l2_device_register(NULL, v4l2_dev); | 235 | res = v4l2_device_register(NULL, v4l2_dev); |
| 235 | if (res < 0) { | 236 | if (res < 0) { |
| @@ -242,6 +243,7 @@ static int __init pcm20_init(void) | |||
| 242 | dev->vdev.fops = &pcm20_fops; | 243 | dev->vdev.fops = &pcm20_fops; |
| 243 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; | 244 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; |
| 244 | dev->vdev.release = video_device_release_empty; | 245 | dev->vdev.release = video_device_release_empty; |
| 246 | dev->vdev.lock = &dev->lock; | ||
| 245 | video_set_drvdata(&dev->vdev, dev); | 247 | video_set_drvdata(&dev->vdev, dev); |
| 246 | 248 | ||
| 247 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) | 249 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index a79296aac9a9..8d6ea591bd18 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
| @@ -266,7 +266,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 266 | 266 | ||
| 267 | static const struct v4l2_file_operations rtrack2_fops = { | 267 | static const struct v4l2_file_operations rtrack2_fops = { |
| 268 | .owner = THIS_MODULE, | 268 | .owner = THIS_MODULE, |
| 269 | .ioctl = video_ioctl2, | 269 | .unlocked_ioctl = video_ioctl2, |
| 270 | }; | 270 | }; |
| 271 | 271 | ||
| 272 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { | 272 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { |
| @@ -315,6 +315,10 @@ static int __init rtrack2_init(void) | |||
| 315 | dev->vdev.release = video_device_release_empty; | 315 | dev->vdev.release = video_device_release_empty; |
| 316 | video_set_drvdata(&dev->vdev, dev); | 316 | video_set_drvdata(&dev->vdev, dev); |
| 317 | 317 | ||
| 318 | /* mute card - prevents noisy bootups */ | ||
| 319 | outb(1, dev->io); | ||
| 320 | dev->muted = 1; | ||
| 321 | |||
| 318 | mutex_init(&dev->lock); | 322 | mutex_init(&dev->lock); |
| 319 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 323 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 320 | v4l2_device_unregister(v4l2_dev); | 324 | v4l2_device_unregister(v4l2_dev); |
| @@ -324,10 +328,6 @@ static int __init rtrack2_init(void) | |||
| 324 | 328 | ||
| 325 | v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); | 329 | v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); |
| 326 | 330 | ||
| 327 | /* mute card - prevents noisy bootups */ | ||
| 328 | outb(1, dev->io); | ||
| 329 | dev->muted = 1; | ||
| 330 | |||
| 331 | return 0; | 331 | return 0; |
| 332 | } | 332 | } |
| 333 | 333 | ||
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 985359d18aa5..b5a5f89e238a 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
| @@ -260,7 +260,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 260 | 260 | ||
| 261 | static const struct v4l2_file_operations fmi_fops = { | 261 | static const struct v4l2_file_operations fmi_fops = { |
| 262 | .owner = THIS_MODULE, | 262 | .owner = THIS_MODULE, |
| 263 | .ioctl = video_ioctl2, | 263 | .unlocked_ioctl = video_ioctl2, |
| 264 | }; | 264 | }; |
| 265 | 265 | ||
| 266 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { | 266 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { |
| @@ -382,6 +382,9 @@ static int __init fmi_init(void) | |||
| 382 | 382 | ||
| 383 | mutex_init(&fmi->lock); | 383 | mutex_init(&fmi->lock); |
| 384 | 384 | ||
| 385 | /* mute card - prevents noisy bootups */ | ||
| 386 | fmi_mute(fmi); | ||
| 387 | |||
| 385 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 388 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 386 | v4l2_device_unregister(v4l2_dev); | 389 | v4l2_device_unregister(v4l2_dev); |
| 387 | release_region(fmi->io, 2); | 390 | release_region(fmi->io, 2); |
| @@ -391,8 +394,6 @@ static int __init fmi_init(void) | |||
| 391 | } | 394 | } |
| 392 | 395 | ||
| 393 | v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); | 396 | v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); |
| 394 | /* mute card - prevents noisy bootups */ | ||
| 395 | fmi_mute(fmi); | ||
| 396 | return 0; | 397 | return 0; |
| 397 | } | 398 | } |
| 398 | 399 | ||
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 52c7bbb32b8b..dc3f04c52d5e 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
| @@ -376,7 +376,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 376 | 376 | ||
| 377 | static const struct v4l2_file_operations fmr2_fops = { | 377 | static const struct v4l2_file_operations fmr2_fops = { |
| 378 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
| 379 | .ioctl = video_ioctl2, | 379 | .unlocked_ioctl = video_ioctl2, |
| 380 | }; | 380 | }; |
| 381 | 381 | ||
| 382 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { | 382 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { |
| @@ -424,6 +424,10 @@ static int __init fmr2_init(void) | |||
| 424 | fmr2->vdev.release = video_device_release_empty; | 424 | fmr2->vdev.release = video_device_release_empty; |
| 425 | video_set_drvdata(&fmr2->vdev, fmr2); | 425 | video_set_drvdata(&fmr2->vdev, fmr2); |
| 426 | 426 | ||
| 427 | /* mute card - prevents noisy bootups */ | ||
| 428 | fmr2_mute(fmr2->io); | ||
| 429 | fmr2_product_info(fmr2); | ||
| 430 | |||
| 427 | if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 431 | if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 428 | v4l2_device_unregister(v4l2_dev); | 432 | v4l2_device_unregister(v4l2_dev); |
| 429 | release_region(fmr2->io, 2); | 433 | release_region(fmr2->io, 2); |
| @@ -431,11 +435,6 @@ static int __init fmr2_init(void) | |||
| 431 | } | 435 | } |
| 432 | 436 | ||
| 433 | v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); | 437 | v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); |
| 434 | /* mute card - prevents noisy bootups */ | ||
| 435 | mutex_lock(&fmr2->lock); | ||
| 436 | fmr2_mute(fmr2->io); | ||
| 437 | fmr2_product_info(fmr2); | ||
| 438 | mutex_unlock(&fmr2->lock); | ||
| 439 | debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); | 438 | debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); |
| 440 | return 0; | 439 | return 0; |
| 441 | } | 440 | } |
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 03829e6818bd..726d367ad8d0 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c | |||
| @@ -53,7 +53,8 @@ struct radio_si4713_device { | |||
| 53 | /* radio_si4713_fops - file operations interface */ | 53 | /* radio_si4713_fops - file operations interface */ |
| 54 | static const struct v4l2_file_operations radio_si4713_fops = { | 54 | static const struct v4l2_file_operations radio_si4713_fops = { |
| 55 | .owner = THIS_MODULE, | 55 | .owner = THIS_MODULE, |
| 56 | .ioctl = video_ioctl2, | 56 | /* Note: locking is done at the subdev level in the i2c driver. */ |
| 57 | .unlocked_ioctl = video_ioctl2, | ||
| 57 | }; | 58 | }; |
| 58 | 59 | ||
| 59 | /* Video4Linux Interface */ | 60 | /* Video4Linux Interface */ |
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 789d2ec66e19..0e71d816c725 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c | |||
| @@ -142,7 +142,6 @@ struct tea5764_device { | |||
| 142 | struct video_device *videodev; | 142 | struct video_device *videodev; |
| 143 | struct tea5764_regs regs; | 143 | struct tea5764_regs regs; |
| 144 | struct mutex mutex; | 144 | struct mutex mutex; |
| 145 | int users; | ||
| 146 | }; | 145 | }; |
| 147 | 146 | ||
| 148 | /* I2C code related */ | 147 | /* I2C code related */ |
| @@ -458,41 +457,10 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 458 | return 0; | 457 | return 0; |
| 459 | } | 458 | } |
| 460 | 459 | ||
| 461 | static int tea5764_open(struct file *file) | ||
| 462 | { | ||
| 463 | /* Currently we support only one device */ | ||
| 464 | struct tea5764_device *radio = video_drvdata(file); | ||
| 465 | |||
| 466 | mutex_lock(&radio->mutex); | ||
| 467 | /* Only exclusive access */ | ||
| 468 | if (radio->users) { | ||
| 469 | mutex_unlock(&radio->mutex); | ||
| 470 | return -EBUSY; | ||
| 471 | } | ||
| 472 | radio->users++; | ||
| 473 | mutex_unlock(&radio->mutex); | ||
| 474 | file->private_data = radio; | ||
| 475 | return 0; | ||
| 476 | } | ||
| 477 | |||
| 478 | static int tea5764_close(struct file *file) | ||
| 479 | { | ||
| 480 | struct tea5764_device *radio = video_drvdata(file); | ||
| 481 | |||
| 482 | if (!radio) | ||
| 483 | return -ENODEV; | ||
| 484 | mutex_lock(&radio->mutex); | ||
| 485 | radio->users--; | ||
| 486 | mutex_unlock(&radio->mutex); | ||
| 487 | return 0; | ||
| 488 | } | ||
| 489 | |||
| 490 | /* File system interface */ | 460 | /* File system interface */ |
| 491 | static const struct v4l2_file_operations tea5764_fops = { | 461 | static const struct v4l2_file_operations tea5764_fops = { |
| 492 | .owner = THIS_MODULE, | 462 | .owner = THIS_MODULE, |
| 493 | .open = tea5764_open, | 463 | .unlocked_ioctl = video_ioctl2, |
| 494 | .release = tea5764_close, | ||
| 495 | .ioctl = video_ioctl2, | ||
| 496 | }; | 464 | }; |
| 497 | 465 | ||
| 498 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { | 466 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { |
| @@ -527,7 +495,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 527 | int ret; | 495 | int ret; |
| 528 | 496 | ||
| 529 | PDEBUG("probe"); | 497 | PDEBUG("probe"); |
| 530 | radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL); | 498 | radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL); |
| 531 | if (!radio) | 499 | if (!radio) |
| 532 | return -ENOMEM; | 500 | return -ENOMEM; |
| 533 | 501 | ||
| @@ -555,12 +523,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 555 | 523 | ||
| 556 | i2c_set_clientdata(client, radio); | 524 | i2c_set_clientdata(client, radio); |
| 557 | video_set_drvdata(radio->videodev, radio); | 525 | video_set_drvdata(radio->videodev, radio); |
| 558 | 526 | radio->videodev->lock = &radio->mutex; | |
| 559 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
| 560 | if (ret < 0) { | ||
| 561 | PWARN("Could not register video device!"); | ||
| 562 | goto errrel; | ||
| 563 | } | ||
| 564 | 527 | ||
| 565 | /* initialize and power off the chip */ | 528 | /* initialize and power off the chip */ |
| 566 | tea5764_i2c_read(radio); | 529 | tea5764_i2c_read(radio); |
| @@ -568,6 +531,12 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 568 | tea5764_mute(radio, 1); | 531 | tea5764_mute(radio, 1); |
| 569 | tea5764_power_down(radio); | 532 | tea5764_power_down(radio); |
| 570 | 533 | ||
| 534 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
| 535 | if (ret < 0) { | ||
| 536 | PWARN("Could not register video device!"); | ||
| 537 | goto errrel; | ||
| 538 | } | ||
| 539 | |||
| 571 | PINFO("registered."); | 540 | PINFO("registered."); |
| 572 | return 0; | 541 | return 0; |
| 573 | errrel: | 542 | errrel: |
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index fc1c860fd438..a32663917059 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
| @@ -338,7 +338,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 338 | 338 | ||
| 339 | static const struct v4l2_file_operations terratec_fops = { | 339 | static const struct v4l2_file_operations terratec_fops = { |
| 340 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
| 341 | .ioctl = video_ioctl2, | 341 | .unlocked_ioctl = video_ioctl2, |
| 342 | }; | 342 | }; |
| 343 | 343 | ||
| 344 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { | 344 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { |
| @@ -389,6 +389,9 @@ static int __init terratec_init(void) | |||
| 389 | 389 | ||
| 390 | mutex_init(&tt->lock); | 390 | mutex_init(&tt->lock); |
| 391 | 391 | ||
| 392 | /* mute card - prevents noisy bootups */ | ||
| 393 | tt_write_vol(tt, 0); | ||
| 394 | |||
| 392 | if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 395 | if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 393 | v4l2_device_unregister(&tt->v4l2_dev); | 396 | v4l2_device_unregister(&tt->v4l2_dev); |
| 394 | release_region(tt->io, 2); | 397 | release_region(tt->io, 2); |
| @@ -396,9 +399,6 @@ static int __init terratec_init(void) | |||
| 396 | } | 399 | } |
| 397 | 400 | ||
| 398 | v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); | 401 | v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); |
| 399 | |||
| 400 | /* mute card - prevents noisy bootups */ | ||
| 401 | tt_write_vol(tt, 0); | ||
| 402 | return 0; | 402 | return 0; |
| 403 | } | 403 | } |
| 404 | 404 | ||
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c index b8bb3ef47df5..a185610b376b 100644 --- a/drivers/media/radio/radio-timb.c +++ b/drivers/media/radio/radio-timb.c | |||
| @@ -34,6 +34,7 @@ struct timbradio { | |||
| 34 | struct v4l2_subdev *sd_dsp; | 34 | struct v4l2_subdev *sd_dsp; |
| 35 | struct video_device video_dev; | 35 | struct video_device video_dev; |
| 36 | struct v4l2_device v4l2_dev; | 36 | struct v4l2_device v4l2_dev; |
| 37 | struct mutex lock; | ||
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | 40 | ||
| @@ -142,7 +143,7 @@ static const struct v4l2_ioctl_ops timbradio_ioctl_ops = { | |||
| 142 | 143 | ||
| 143 | static const struct v4l2_file_operations timbradio_fops = { | 144 | static const struct v4l2_file_operations timbradio_fops = { |
| 144 | .owner = THIS_MODULE, | 145 | .owner = THIS_MODULE, |
| 145 | .ioctl = video_ioctl2, | 146 | .unlocked_ioctl = video_ioctl2, |
| 146 | }; | 147 | }; |
| 147 | 148 | ||
| 148 | static int __devinit timbradio_probe(struct platform_device *pdev) | 149 | static int __devinit timbradio_probe(struct platform_device *pdev) |
| @@ -164,6 +165,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev) | |||
| 164 | } | 165 | } |
| 165 | 166 | ||
| 166 | tr->pdata = *pdata; | 167 | tr->pdata = *pdata; |
| 168 | mutex_init(&tr->lock); | ||
| 167 | 169 | ||
| 168 | strlcpy(tr->video_dev.name, "Timberdale Radio", | 170 | strlcpy(tr->video_dev.name, "Timberdale Radio", |
| 169 | sizeof(tr->video_dev.name)); | 171 | sizeof(tr->video_dev.name)); |
| @@ -171,6 +173,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev) | |||
| 171 | tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; | 173 | tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; |
| 172 | tr->video_dev.release = video_device_release_empty; | 174 | tr->video_dev.release = video_device_release_empty; |
| 173 | tr->video_dev.minor = -1; | 175 | tr->video_dev.minor = -1; |
| 176 | tr->video_dev.lock = &tr->lock; | ||
| 174 | 177 | ||
| 175 | strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); | 178 | strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); |
| 176 | err = v4l2_device_register(NULL, &tr->v4l2_dev); | 179 | err = v4l2_device_register(NULL, &tr->v4l2_dev); |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 9d6dcf8af5b0..22fa9cc28abe 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
| @@ -344,7 +344,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 344 | 344 | ||
| 345 | static const struct v4l2_file_operations trust_fops = { | 345 | static const struct v4l2_file_operations trust_fops = { |
| 346 | .owner = THIS_MODULE, | 346 | .owner = THIS_MODULE, |
| 347 | .ioctl = video_ioctl2, | 347 | .unlocked_ioctl = video_ioctl2, |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { | 350 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { |
| @@ -396,14 +396,6 @@ static int __init trust_init(void) | |||
| 396 | tr->vdev.release = video_device_release_empty; | 396 | tr->vdev.release = video_device_release_empty; |
| 397 | video_set_drvdata(&tr->vdev, tr); | 397 | video_set_drvdata(&tr->vdev, tr); |
| 398 | 398 | ||
| 399 | if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 400 | v4l2_device_unregister(v4l2_dev); | ||
| 401 | release_region(tr->io, 2); | ||
| 402 | return -EINVAL; | ||
| 403 | } | ||
| 404 | |||
| 405 | v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); | ||
| 406 | |||
| 407 | write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ | 399 | write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ |
| 408 | write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ | 400 | write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ |
| 409 | write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ | 401 | write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ |
| @@ -418,6 +410,14 @@ static int __init trust_init(void) | |||
| 418 | /* mute card - prevents noisy bootups */ | 410 | /* mute card - prevents noisy bootups */ |
| 419 | tr_setmute(tr, 1); | 411 | tr_setmute(tr, 1); |
| 420 | 412 | ||
| 413 | if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 414 | v4l2_device_unregister(v4l2_dev); | ||
| 415 | release_region(tr->io, 2); | ||
| 416 | return -EINVAL; | ||
| 417 | } | ||
| 418 | |||
| 419 | v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); | ||
| 420 | |||
| 421 | return 0; | 421 | return 0; |
| 422 | } | 422 | } |
| 423 | 423 | ||
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index b1f630527dc1..8dbbf08f2207 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
| @@ -317,7 +317,7 @@ static int vidioc_log_status(struct file *file, void *priv) | |||
| 317 | 317 | ||
| 318 | static const struct v4l2_file_operations typhoon_fops = { | 318 | static const struct v4l2_file_operations typhoon_fops = { |
| 319 | .owner = THIS_MODULE, | 319 | .owner = THIS_MODULE, |
| 320 | .ioctl = video_ioctl2, | 320 | .unlocked_ioctl = video_ioctl2, |
| 321 | }; | 321 | }; |
| 322 | 322 | ||
| 323 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { | 323 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { |
| @@ -344,18 +344,18 @@ static int __init typhoon_init(void) | |||
| 344 | 344 | ||
| 345 | strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); | 345 | strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); |
| 346 | dev->io = io; | 346 | dev->io = io; |
| 347 | dev->curfreq = dev->mutefreq = mutefreq; | ||
| 348 | 347 | ||
| 349 | if (dev->io == -1) { | 348 | if (dev->io == -1) { |
| 350 | v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); | 349 | v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); |
| 351 | return -EINVAL; | 350 | return -EINVAL; |
| 352 | } | 351 | } |
| 353 | 352 | ||
| 354 | if (dev->mutefreq < 87000 || dev->mutefreq > 108500) { | 353 | if (mutefreq < 87000 || mutefreq > 108500) { |
| 355 | v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); | 354 | v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); |
| 356 | v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); | 355 | v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); |
| 357 | return -EINVAL; | 356 | return -EINVAL; |
| 358 | } | 357 | } |
| 358 | dev->curfreq = dev->mutefreq = mutefreq << 4; | ||
| 359 | 359 | ||
| 360 | mutex_init(&dev->lock); | 360 | mutex_init(&dev->lock); |
| 361 | if (!request_region(dev->io, 8, "typhoon")) { | 361 | if (!request_region(dev->io, 8, "typhoon")) { |
| @@ -378,17 +378,17 @@ static int __init typhoon_init(void) | |||
| 378 | dev->vdev.ioctl_ops = &typhoon_ioctl_ops; | 378 | dev->vdev.ioctl_ops = &typhoon_ioctl_ops; |
| 379 | dev->vdev.release = video_device_release_empty; | 379 | dev->vdev.release = video_device_release_empty; |
| 380 | video_set_drvdata(&dev->vdev, dev); | 380 | video_set_drvdata(&dev->vdev, dev); |
| 381 | |||
| 382 | /* mute card - prevents noisy bootups */ | ||
| 383 | typhoon_mute(dev); | ||
| 384 | |||
| 381 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 385 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 382 | v4l2_device_unregister(&dev->v4l2_dev); | 386 | v4l2_device_unregister(&dev->v4l2_dev); |
| 383 | release_region(dev->io, 8); | 387 | release_region(dev->io, 8); |
| 384 | return -EINVAL; | 388 | return -EINVAL; |
| 385 | } | 389 | } |
| 386 | v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); | 390 | v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); |
| 387 | v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq); | 391 | v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq); |
| 388 | dev->mutefreq <<= 4; | ||
| 389 | |||
| 390 | /* mute card - prevents noisy bootups */ | ||
| 391 | typhoon_mute(dev); | ||
| 392 | 392 | ||
| 393 | return 0; | 393 | return 0; |
| 394 | } | 394 | } |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index f31eab99c943..af99c5bd88c1 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
| @@ -377,7 +377,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 377 | static const struct v4l2_file_operations zoltrix_fops = | 377 | static const struct v4l2_file_operations zoltrix_fops = |
| 378 | { | 378 | { |
| 379 | .owner = THIS_MODULE, | 379 | .owner = THIS_MODULE, |
| 380 | .ioctl = video_ioctl2, | 380 | .unlocked_ioctl = video_ioctl2, |
| 381 | }; | 381 | }; |
| 382 | 382 | ||
| 383 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { | 383 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { |
| @@ -424,20 +424,6 @@ static int __init zoltrix_init(void) | |||
| 424 | return res; | 424 | return res; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); | ||
| 428 | zol->vdev.v4l2_dev = v4l2_dev; | ||
| 429 | zol->vdev.fops = &zoltrix_fops; | ||
| 430 | zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; | ||
| 431 | zol->vdev.release = video_device_release_empty; | ||
| 432 | video_set_drvdata(&zol->vdev, zol); | ||
| 433 | |||
| 434 | if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 435 | v4l2_device_unregister(v4l2_dev); | ||
| 436 | release_region(zol->io, 2); | ||
| 437 | return -EINVAL; | ||
| 438 | } | ||
| 439 | v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); | ||
| 440 | |||
| 441 | mutex_init(&zol->lock); | 427 | mutex_init(&zol->lock); |
| 442 | 428 | ||
| 443 | /* mute card - prevents noisy bootups */ | 429 | /* mute card - prevents noisy bootups */ |
| @@ -452,6 +438,20 @@ static int __init zoltrix_init(void) | |||
| 452 | zol->curvol = 0; | 438 | zol->curvol = 0; |
| 453 | zol->stereo = 1; | 439 | zol->stereo = 1; |
| 454 | 440 | ||
| 441 | strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); | ||
| 442 | zol->vdev.v4l2_dev = v4l2_dev; | ||
| 443 | zol->vdev.fops = &zoltrix_fops; | ||
| 444 | zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; | ||
| 445 | zol->vdev.release = video_device_release_empty; | ||
| 446 | video_set_drvdata(&zol->vdev, zol); | ||
| 447 | |||
| 448 | if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 449 | v4l2_device_unregister(v4l2_dev); | ||
| 450 | release_region(zol->io, 2); | ||
| 451 | return -EINVAL; | ||
| 452 | } | ||
| 453 | v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); | ||
| 454 | |||
| 455 | return 0; | 455 | return 0; |
| 456 | } | 456 | } |
| 457 | 457 | ||
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 31e7a123d19a..f989f2820d88 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
| @@ -712,7 +712,7 @@ static int ar_initialize(struct ar *ar) | |||
| 712 | static const struct v4l2_file_operations ar_fops = { | 712 | static const struct v4l2_file_operations ar_fops = { |
| 713 | .owner = THIS_MODULE, | 713 | .owner = THIS_MODULE, |
| 714 | .read = ar_read, | 714 | .read = ar_read, |
| 715 | .ioctl = video_ioctl2, | 715 | .unlocked_ioctl = video_ioctl2, |
| 716 | }; | 716 | }; |
| 717 | 717 | ||
| 718 | static const struct v4l2_ioctl_ops ar_ioctl_ops = { | 718 | static const struct v4l2_ioctl_ops ar_ioctl_ops = { |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a529619e51f6..0902ec041c7a 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
| @@ -854,7 +854,6 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit) | |||
| 854 | xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM; | 854 | xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM; |
| 855 | 855 | ||
| 856 | /* is it free? */ | 856 | /* is it free? */ |
| 857 | mutex_lock(&btv->lock); | ||
| 858 | if (btv->resources & xbits) { | 857 | if (btv->resources & xbits) { |
| 859 | /* no, someone else uses it */ | 858 | /* no, someone else uses it */ |
| 860 | goto fail; | 859 | goto fail; |
| @@ -884,11 +883,9 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit) | |||
| 884 | /* it's free, grab it */ | 883 | /* it's free, grab it */ |
| 885 | fh->resources |= bit; | 884 | fh->resources |= bit; |
| 886 | btv->resources |= bit; | 885 | btv->resources |= bit; |
| 887 | mutex_unlock(&btv->lock); | ||
| 888 | return 1; | 886 | return 1; |
| 889 | 887 | ||
| 890 | fail: | 888 | fail: |
| 891 | mutex_unlock(&btv->lock); | ||
| 892 | return 0; | 889 | return 0; |
| 893 | } | 890 | } |
| 894 | 891 | ||
| @@ -940,7 +937,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits) | |||
| 940 | /* trying to free ressources not allocated by us ... */ | 937 | /* trying to free ressources not allocated by us ... */ |
| 941 | printk("bttv: BUG! (btres)\n"); | 938 | printk("bttv: BUG! (btres)\n"); |
| 942 | } | 939 | } |
| 943 | mutex_lock(&btv->lock); | ||
| 944 | fh->resources &= ~bits; | 940 | fh->resources &= ~bits; |
| 945 | btv->resources &= ~bits; | 941 | btv->resources &= ~bits; |
| 946 | 942 | ||
| @@ -951,8 +947,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits) | |||
| 951 | 947 | ||
| 952 | if (0 == (bits & VBI_RESOURCES)) | 948 | if (0 == (bits & VBI_RESOURCES)) |
| 953 | disclaim_vbi_lines(btv); | 949 | disclaim_vbi_lines(btv); |
| 954 | |||
| 955 | mutex_unlock(&btv->lock); | ||
| 956 | } | 950 | } |
| 957 | 951 | ||
| 958 | /* ----------------------------------------------------------------------- */ | 952 | /* ----------------------------------------------------------------------- */ |
| @@ -1713,28 +1707,20 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, | |||
| 1713 | 1707 | ||
| 1714 | /* Make sure tvnorm and vbi_end remain consistent | 1708 | /* Make sure tvnorm and vbi_end remain consistent |
| 1715 | until we're done. */ | 1709 | until we're done. */ |
| 1716 | mutex_lock(&btv->lock); | ||
| 1717 | 1710 | ||
| 1718 | norm = btv->tvnorm; | 1711 | norm = btv->tvnorm; |
| 1719 | 1712 | ||
| 1720 | /* In this mode capturing always starts at defrect.top | 1713 | /* In this mode capturing always starts at defrect.top |
| 1721 | (default VDELAY), ignoring cropping parameters. */ | 1714 | (default VDELAY), ignoring cropping parameters. */ |
| 1722 | if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) { | 1715 | if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) { |
| 1723 | mutex_unlock(&btv->lock); | ||
| 1724 | return -EINVAL; | 1716 | return -EINVAL; |
| 1725 | } | 1717 | } |
| 1726 | 1718 | ||
| 1727 | mutex_unlock(&btv->lock); | ||
| 1728 | |||
| 1729 | c.rect = bttv_tvnorms[norm].cropcap.defrect; | 1719 | c.rect = bttv_tvnorms[norm].cropcap.defrect; |
| 1730 | } else { | 1720 | } else { |
| 1731 | mutex_lock(&btv->lock); | ||
| 1732 | |||
| 1733 | norm = btv->tvnorm; | 1721 | norm = btv->tvnorm; |
| 1734 | c = btv->crop[!!fh->do_crop]; | 1722 | c = btv->crop[!!fh->do_crop]; |
| 1735 | 1723 | ||
| 1736 | mutex_unlock(&btv->lock); | ||
| 1737 | |||
| 1738 | if (width < c.min_scaled_width || | 1724 | if (width < c.min_scaled_width || |
| 1739 | width > c.max_scaled_width || | 1725 | width > c.max_scaled_width || |
| 1740 | height < c.min_scaled_height) | 1726 | height < c.min_scaled_height) |
| @@ -1858,7 +1844,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) | |||
| 1858 | unsigned int i; | 1844 | unsigned int i; |
| 1859 | int err; | 1845 | int err; |
| 1860 | 1846 | ||
| 1861 | mutex_lock(&btv->lock); | ||
| 1862 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1847 | err = v4l2_prio_check(&btv->prio, fh->prio); |
| 1863 | if (err) | 1848 | if (err) |
| 1864 | goto err; | 1849 | goto err; |
| @@ -1874,7 +1859,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) | |||
| 1874 | set_tvnorm(btv, i); | 1859 | set_tvnorm(btv, i); |
| 1875 | 1860 | ||
| 1876 | err: | 1861 | err: |
| 1877 | mutex_unlock(&btv->lock); | ||
| 1878 | 1862 | ||
| 1879 | return err; | 1863 | return err; |
| 1880 | } | 1864 | } |
| @@ -1898,7 +1882,6 @@ static int bttv_enum_input(struct file *file, void *priv, | |||
| 1898 | struct bttv *btv = fh->btv; | 1882 | struct bttv *btv = fh->btv; |
| 1899 | int rc = 0; | 1883 | int rc = 0; |
| 1900 | 1884 | ||
| 1901 | mutex_lock(&btv->lock); | ||
| 1902 | if (i->index >= bttv_tvcards[btv->c.type].video_inputs) { | 1885 | if (i->index >= bttv_tvcards[btv->c.type].video_inputs) { |
| 1903 | rc = -EINVAL; | 1886 | rc = -EINVAL; |
| 1904 | goto err; | 1887 | goto err; |
| @@ -1928,7 +1911,6 @@ static int bttv_enum_input(struct file *file, void *priv, | |||
| 1928 | i->std = BTTV_NORMS; | 1911 | i->std = BTTV_NORMS; |
| 1929 | 1912 | ||
| 1930 | err: | 1913 | err: |
| 1931 | mutex_unlock(&btv->lock); | ||
| 1932 | 1914 | ||
| 1933 | return rc; | 1915 | return rc; |
| 1934 | } | 1916 | } |
| @@ -1938,9 +1920,7 @@ static int bttv_g_input(struct file *file, void *priv, unsigned int *i) | |||
| 1938 | struct bttv_fh *fh = priv; | 1920 | struct bttv_fh *fh = priv; |
| 1939 | struct bttv *btv = fh->btv; | 1921 | struct bttv *btv = fh->btv; |
| 1940 | 1922 | ||
| 1941 | mutex_lock(&btv->lock); | ||
| 1942 | *i = btv->input; | 1923 | *i = btv->input; |
| 1943 | mutex_unlock(&btv->lock); | ||
| 1944 | 1924 | ||
| 1945 | return 0; | 1925 | return 0; |
| 1946 | } | 1926 | } |
| @@ -1952,7 +1932,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i) | |||
| 1952 | 1932 | ||
| 1953 | int err; | 1933 | int err; |
| 1954 | 1934 | ||
| 1955 | mutex_lock(&btv->lock); | ||
| 1956 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1935 | err = v4l2_prio_check(&btv->prio, fh->prio); |
| 1957 | if (unlikely(err)) | 1936 | if (unlikely(err)) |
| 1958 | goto err; | 1937 | goto err; |
| @@ -1965,7 +1944,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i) | |||
| 1965 | set_input(btv, i, btv->tvnorm); | 1944 | set_input(btv, i, btv->tvnorm); |
| 1966 | 1945 | ||
| 1967 | err: | 1946 | err: |
| 1968 | mutex_unlock(&btv->lock); | ||
| 1969 | return 0; | 1947 | return 0; |
| 1970 | } | 1948 | } |
| 1971 | 1949 | ||
| @@ -1979,7 +1957,6 @@ static int bttv_s_tuner(struct file *file, void *priv, | |||
| 1979 | if (unlikely(0 != t->index)) | 1957 | if (unlikely(0 != t->index)) |
| 1980 | return -EINVAL; | 1958 | return -EINVAL; |
| 1981 | 1959 | ||
| 1982 | mutex_lock(&btv->lock); | ||
| 1983 | if (unlikely(btv->tuner_type == TUNER_ABSENT)) { | 1960 | if (unlikely(btv->tuner_type == TUNER_ABSENT)) { |
| 1984 | err = -EINVAL; | 1961 | err = -EINVAL; |
| 1985 | goto err; | 1962 | goto err; |
| @@ -1995,7 +1972,6 @@ static int bttv_s_tuner(struct file *file, void *priv, | |||
| 1995 | btv->audio_mode_gpio(btv, t, 1); | 1972 | btv->audio_mode_gpio(btv, t, 1); |
| 1996 | 1973 | ||
| 1997 | err: | 1974 | err: |
| 1998 | mutex_unlock(&btv->lock); | ||
| 1999 | 1975 | ||
| 2000 | return 0; | 1976 | return 0; |
| 2001 | } | 1977 | } |
| @@ -2006,10 +1982,8 @@ static int bttv_g_frequency(struct file *file, void *priv, | |||
| 2006 | struct bttv_fh *fh = priv; | 1982 | struct bttv_fh *fh = priv; |
| 2007 | struct bttv *btv = fh->btv; | 1983 | struct bttv *btv = fh->btv; |
| 2008 | 1984 | ||
| 2009 | mutex_lock(&btv->lock); | ||
| 2010 | f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1985 | f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
| 2011 | f->frequency = btv->freq; | 1986 | f->frequency = btv->freq; |
| 2012 | mutex_unlock(&btv->lock); | ||
| 2013 | 1987 | ||
| 2014 | return 0; | 1988 | return 0; |
| 2015 | } | 1989 | } |
| @@ -2024,7 +1998,6 @@ static int bttv_s_frequency(struct file *file, void *priv, | |||
| 2024 | if (unlikely(f->tuner != 0)) | 1998 | if (unlikely(f->tuner != 0)) |
| 2025 | return -EINVAL; | 1999 | return -EINVAL; |
| 2026 | 2000 | ||
| 2027 | mutex_lock(&btv->lock); | ||
| 2028 | err = v4l2_prio_check(&btv->prio, fh->prio); | 2001 | err = v4l2_prio_check(&btv->prio, fh->prio); |
| 2029 | if (unlikely(err)) | 2002 | if (unlikely(err)) |
| 2030 | goto err; | 2003 | goto err; |
| @@ -2039,7 +2012,6 @@ static int bttv_s_frequency(struct file *file, void *priv, | |||
| 2039 | if (btv->has_matchbox && btv->radio_user) | 2012 | if (btv->has_matchbox && btv->radio_user) |
| 2040 | tea5757_set_freq(btv, btv->freq); | 2013 | tea5757_set_freq(btv, btv->freq); |
| 2041 | err: | 2014 | err: |
| 2042 | mutex_unlock(&btv->lock); | ||
| 2043 | 2015 | ||
| 2044 | return 0; | 2016 | return 0; |
| 2045 | } | 2017 | } |
| @@ -2172,7 +2144,6 @@ limit_scaled_size_lock (struct bttv_fh * fh, | |||
| 2172 | 2144 | ||
| 2173 | /* Make sure tvnorm, vbi_end and the current cropping parameters | 2145 | /* Make sure tvnorm, vbi_end and the current cropping parameters |
| 2174 | remain consistent until we're done. */ | 2146 | remain consistent until we're done. */ |
| 2175 | mutex_lock(&btv->lock); | ||
| 2176 | 2147 | ||
| 2177 | b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; | 2148 | b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; |
| 2178 | 2149 | ||
| @@ -2250,7 +2221,6 @@ limit_scaled_size_lock (struct bttv_fh * fh, | |||
| 2250 | rc = 0; /* success */ | 2221 | rc = 0; /* success */ |
| 2251 | 2222 | ||
| 2252 | fail: | 2223 | fail: |
| 2253 | mutex_unlock(&btv->lock); | ||
| 2254 | 2224 | ||
| 2255 | return rc; | 2225 | return rc; |
| 2256 | } | 2226 | } |
| @@ -2282,9 +2252,7 @@ verify_window_lock (struct bttv_fh * fh, | |||
| 2282 | if (V4L2_FIELD_ANY == field) { | 2252 | if (V4L2_FIELD_ANY == field) { |
| 2283 | __s32 height2; | 2253 | __s32 height2; |
| 2284 | 2254 | ||
| 2285 | mutex_lock(&fh->btv->lock); | ||
| 2286 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; | 2255 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; |
| 2287 | mutex_unlock(&fh->btv->lock); | ||
| 2288 | field = (win->w.height > height2) | 2256 | field = (win->w.height > height2) |
| 2289 | ? V4L2_FIELD_INTERLACED | 2257 | ? V4L2_FIELD_INTERLACED |
| 2290 | : V4L2_FIELD_TOP; | 2258 | : V4L2_FIELD_TOP; |
| @@ -2360,7 +2328,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
| 2360 | } | 2328 | } |
| 2361 | } | 2329 | } |
| 2362 | 2330 | ||
| 2363 | mutex_lock(&fh->cap.vb_lock); | ||
| 2364 | /* clip against screen */ | 2331 | /* clip against screen */ |
| 2365 | if (NULL != btv->fbuf.base) | 2332 | if (NULL != btv->fbuf.base) |
| 2366 | n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, | 2333 | n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, |
| @@ -2391,13 +2358,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
| 2391 | fh->ov.field = win->field; | 2358 | fh->ov.field = win->field; |
| 2392 | fh->ov.setup_ok = 1; | 2359 | fh->ov.setup_ok = 1; |
| 2393 | 2360 | ||
| 2394 | /* | ||
| 2395 | * FIXME: btv is protected by btv->lock mutex, while btv->init | ||
| 2396 | * is protected by fh->cap.vb_lock. This seems to open the | ||
| 2397 | * possibility for some race situations. Maybe the better would | ||
| 2398 | * be to unify those locks or to use another way to store the | ||
| 2399 | * init values that will be consumed by videobuf callbacks | ||
| 2400 | */ | ||
| 2401 | btv->init.ov.w.width = win->w.width; | 2361 | btv->init.ov.w.width = win->w.width; |
| 2402 | btv->init.ov.w.height = win->w.height; | 2362 | btv->init.ov.w.height = win->w.height; |
| 2403 | btv->init.ov.field = win->field; | 2363 | btv->init.ov.field = win->field; |
| @@ -2412,7 +2372,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
| 2412 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 2372 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
| 2413 | retval = bttv_switch_overlay(btv,fh,new); | 2373 | retval = bttv_switch_overlay(btv,fh,new); |
| 2414 | } | 2374 | } |
| 2415 | mutex_unlock(&fh->cap.vb_lock); | ||
| 2416 | return retval; | 2375 | return retval; |
| 2417 | } | 2376 | } |
| 2418 | 2377 | ||
| @@ -2526,9 +2485,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 2526 | if (V4L2_FIELD_ANY == field) { | 2485 | if (V4L2_FIELD_ANY == field) { |
| 2527 | __s32 height2; | 2486 | __s32 height2; |
| 2528 | 2487 | ||
| 2529 | mutex_lock(&btv->lock); | ||
| 2530 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; | 2488 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; |
| 2531 | mutex_unlock(&btv->lock); | ||
| 2532 | field = (f->fmt.pix.height > height2) | 2489 | field = (f->fmt.pix.height > height2) |
| 2533 | ? V4L2_FIELD_INTERLACED | 2490 | ? V4L2_FIELD_INTERLACED |
| 2534 | : V4L2_FIELD_BOTTOM; | 2491 | : V4L2_FIELD_BOTTOM; |
| @@ -2614,7 +2571,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 2614 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 2571 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
| 2615 | 2572 | ||
| 2616 | /* update our state informations */ | 2573 | /* update our state informations */ |
| 2617 | mutex_lock(&fh->cap.vb_lock); | ||
| 2618 | fh->fmt = fmt; | 2574 | fh->fmt = fmt; |
| 2619 | fh->cap.field = f->fmt.pix.field; | 2575 | fh->cap.field = f->fmt.pix.field; |
| 2620 | fh->cap.last = V4L2_FIELD_NONE; | 2576 | fh->cap.last = V4L2_FIELD_NONE; |
| @@ -2623,7 +2579,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 2623 | btv->init.fmt = fmt; | 2579 | btv->init.fmt = fmt; |
| 2624 | btv->init.width = f->fmt.pix.width; | 2580 | btv->init.width = f->fmt.pix.width; |
| 2625 | btv->init.height = f->fmt.pix.height; | 2581 | btv->init.height = f->fmt.pix.height; |
| 2626 | mutex_unlock(&fh->cap.vb_lock); | ||
| 2627 | 2582 | ||
| 2628 | return 0; | 2583 | return 0; |
| 2629 | } | 2584 | } |
| @@ -2649,11 +2604,9 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | |||
| 2649 | unsigned int i; | 2604 | unsigned int i; |
| 2650 | struct bttv_fh *fh = priv; | 2605 | struct bttv_fh *fh = priv; |
| 2651 | 2606 | ||
| 2652 | mutex_lock(&fh->cap.vb_lock); | ||
| 2653 | retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, | 2607 | retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, |
| 2654 | V4L2_MEMORY_MMAP); | 2608 | V4L2_MEMORY_MMAP); |
| 2655 | if (retval < 0) { | 2609 | if (retval < 0) { |
| 2656 | mutex_unlock(&fh->cap.vb_lock); | ||
| 2657 | return retval; | 2610 | return retval; |
| 2658 | } | 2611 | } |
| 2659 | 2612 | ||
| @@ -2665,7 +2618,6 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | |||
| 2665 | for (i = 0; i < gbuffers; i++) | 2618 | for (i = 0; i < gbuffers; i++) |
| 2666 | mbuf->offsets[i] = i * gbufsize; | 2619 | mbuf->offsets[i] = i * gbufsize; |
| 2667 | 2620 | ||
| 2668 | mutex_unlock(&fh->cap.vb_lock); | ||
| 2669 | return 0; | 2621 | return 0; |
| 2670 | } | 2622 | } |
| 2671 | #endif | 2623 | #endif |
| @@ -2775,10 +2727,8 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
| 2775 | int retval = 0; | 2727 | int retval = 0; |
| 2776 | 2728 | ||
| 2777 | if (on) { | 2729 | if (on) { |
| 2778 | mutex_lock(&fh->cap.vb_lock); | ||
| 2779 | /* verify args */ | 2730 | /* verify args */ |
| 2780 | if (unlikely(!btv->fbuf.base)) { | 2731 | if (unlikely(!btv->fbuf.base)) { |
| 2781 | mutex_unlock(&fh->cap.vb_lock); | ||
| 2782 | return -EINVAL; | 2732 | return -EINVAL; |
| 2783 | } | 2733 | } |
| 2784 | if (unlikely(!fh->ov.setup_ok)) { | 2734 | if (unlikely(!fh->ov.setup_ok)) { |
| @@ -2787,13 +2737,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
| 2787 | } | 2737 | } |
| 2788 | if (retval) | 2738 | if (retval) |
| 2789 | return retval; | 2739 | return retval; |
| 2790 | mutex_unlock(&fh->cap.vb_lock); | ||
| 2791 | } | 2740 | } |
| 2792 | 2741 | ||
| 2793 | if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) | 2742 | if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) |
| 2794 | return -EBUSY; | 2743 | return -EBUSY; |
| 2795 | 2744 | ||
| 2796 | mutex_lock(&fh->cap.vb_lock); | ||
| 2797 | if (on) { | 2745 | if (on) { |
| 2798 | fh->ov.tvnorm = btv->tvnorm; | 2746 | fh->ov.tvnorm = btv->tvnorm; |
| 2799 | new = videobuf_sg_alloc(sizeof(*new)); | 2747 | new = videobuf_sg_alloc(sizeof(*new)); |
| @@ -2805,7 +2753,6 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
| 2805 | 2753 | ||
| 2806 | /* switch over */ | 2754 | /* switch over */ |
| 2807 | retval = bttv_switch_overlay(btv, fh, new); | 2755 | retval = bttv_switch_overlay(btv, fh, new); |
| 2808 | mutex_unlock(&fh->cap.vb_lock); | ||
| 2809 | return retval; | 2756 | return retval; |
| 2810 | } | 2757 | } |
| 2811 | 2758 | ||
| @@ -2844,7 +2791,6 @@ static int bttv_s_fbuf(struct file *file, void *f, | |||
| 2844 | } | 2791 | } |
| 2845 | 2792 | ||
| 2846 | /* ok, accept it */ | 2793 | /* ok, accept it */ |
| 2847 | mutex_lock(&fh->cap.vb_lock); | ||
| 2848 | btv->fbuf.base = fb->base; | 2794 | btv->fbuf.base = fb->base; |
| 2849 | btv->fbuf.fmt.width = fb->fmt.width; | 2795 | btv->fbuf.fmt.width = fb->fmt.width; |
| 2850 | btv->fbuf.fmt.height = fb->fmt.height; | 2796 | btv->fbuf.fmt.height = fb->fmt.height; |
| @@ -2876,7 +2822,6 @@ static int bttv_s_fbuf(struct file *file, void *f, | |||
| 2876 | retval = bttv_switch_overlay(btv, fh, new); | 2822 | retval = bttv_switch_overlay(btv, fh, new); |
| 2877 | } | 2823 | } |
| 2878 | } | 2824 | } |
| 2879 | mutex_unlock(&fh->cap.vb_lock); | ||
| 2880 | return retval; | 2825 | return retval; |
| 2881 | } | 2826 | } |
| 2882 | 2827 | ||
| @@ -2955,7 +2900,6 @@ static int bttv_queryctrl(struct file *file, void *priv, | |||
| 2955 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | 2900 | c->id >= V4L2_CID_PRIVATE_LASTP1)) |
| 2956 | return -EINVAL; | 2901 | return -EINVAL; |
| 2957 | 2902 | ||
| 2958 | mutex_lock(&btv->lock); | ||
| 2959 | if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) | 2903 | if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) |
| 2960 | *c = no_ctl; | 2904 | *c = no_ctl; |
| 2961 | else { | 2905 | else { |
| @@ -2963,7 +2907,6 @@ static int bttv_queryctrl(struct file *file, void *priv, | |||
| 2963 | 2907 | ||
| 2964 | *c = (NULL != ctrl) ? *ctrl : no_ctl; | 2908 | *c = (NULL != ctrl) ? *ctrl : no_ctl; |
| 2965 | } | 2909 | } |
| 2966 | mutex_unlock(&btv->lock); | ||
| 2967 | 2910 | ||
| 2968 | return 0; | 2911 | return 0; |
| 2969 | } | 2912 | } |
| @@ -2974,10 +2917,8 @@ static int bttv_g_parm(struct file *file, void *f, | |||
| 2974 | struct bttv_fh *fh = f; | 2917 | struct bttv_fh *fh = f; |
| 2975 | struct bttv *btv = fh->btv; | 2918 | struct bttv *btv = fh->btv; |
| 2976 | 2919 | ||
| 2977 | mutex_lock(&btv->lock); | ||
| 2978 | v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, | 2920 | v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, |
| 2979 | &parm->parm.capture.timeperframe); | 2921 | &parm->parm.capture.timeperframe); |
| 2980 | mutex_unlock(&btv->lock); | ||
| 2981 | 2922 | ||
| 2982 | return 0; | 2923 | return 0; |
| 2983 | } | 2924 | } |
| @@ -2993,7 +2934,6 @@ static int bttv_g_tuner(struct file *file, void *priv, | |||
| 2993 | if (0 != t->index) | 2934 | if (0 != t->index) |
| 2994 | return -EINVAL; | 2935 | return -EINVAL; |
| 2995 | 2936 | ||
| 2996 | mutex_lock(&btv->lock); | ||
| 2997 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | 2937 | t->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 2998 | bttv_call_all(btv, tuner, g_tuner, t); | 2938 | bttv_call_all(btv, tuner, g_tuner, t); |
| 2999 | strcpy(t->name, "Television"); | 2939 | strcpy(t->name, "Television"); |
| @@ -3005,7 +2945,6 @@ static int bttv_g_tuner(struct file *file, void *priv, | |||
| 3005 | if (btv->audio_mode_gpio) | 2945 | if (btv->audio_mode_gpio) |
| 3006 | btv->audio_mode_gpio(btv, t, 0); | 2946 | btv->audio_mode_gpio(btv, t, 0); |
| 3007 | 2947 | ||
| 3008 | mutex_unlock(&btv->lock); | ||
| 3009 | return 0; | 2948 | return 0; |
| 3010 | } | 2949 | } |
| 3011 | 2950 | ||
| @@ -3014,9 +2953,7 @@ static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p) | |||
| 3014 | struct bttv_fh *fh = f; | 2953 | struct bttv_fh *fh = f; |
| 3015 | struct bttv *btv = fh->btv; | 2954 | struct bttv *btv = fh->btv; |
| 3016 | 2955 | ||
| 3017 | mutex_lock(&btv->lock); | ||
| 3018 | *p = v4l2_prio_max(&btv->prio); | 2956 | *p = v4l2_prio_max(&btv->prio); |
| 3019 | mutex_unlock(&btv->lock); | ||
| 3020 | 2957 | ||
| 3021 | return 0; | 2958 | return 0; |
| 3022 | } | 2959 | } |
| @@ -3028,9 +2965,7 @@ static int bttv_s_priority(struct file *file, void *f, | |||
| 3028 | struct bttv *btv = fh->btv; | 2965 | struct bttv *btv = fh->btv; |
| 3029 | int rc; | 2966 | int rc; |
| 3030 | 2967 | ||
| 3031 | mutex_lock(&btv->lock); | ||
| 3032 | rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); | 2968 | rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); |
| 3033 | mutex_unlock(&btv->lock); | ||
| 3034 | 2969 | ||
| 3035 | return rc; | 2970 | return rc; |
| 3036 | } | 2971 | } |
| @@ -3045,9 +2980,7 @@ static int bttv_cropcap(struct file *file, void *priv, | |||
| 3045 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 2980 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
| 3046 | return -EINVAL; | 2981 | return -EINVAL; |
| 3047 | 2982 | ||
| 3048 | mutex_lock(&btv->lock); | ||
| 3049 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; | 2983 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; |
| 3050 | mutex_unlock(&btv->lock); | ||
| 3051 | 2984 | ||
| 3052 | return 0; | 2985 | return 0; |
| 3053 | } | 2986 | } |
| @@ -3065,9 +2998,7 @@ static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
| 3065 | inconsistent with fh->width or fh->height and apps | 2998 | inconsistent with fh->width or fh->height and apps |
| 3066 | do not expect a change here. */ | 2999 | do not expect a change here. */ |
| 3067 | 3000 | ||
| 3068 | mutex_lock(&btv->lock); | ||
| 3069 | crop->c = btv->crop[!!fh->do_crop].rect; | 3001 | crop->c = btv->crop[!!fh->do_crop].rect; |
| 3070 | mutex_unlock(&btv->lock); | ||
| 3071 | 3002 | ||
| 3072 | return 0; | 3003 | return 0; |
| 3073 | } | 3004 | } |
| @@ -3091,17 +3022,14 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
| 3091 | /* Make sure tvnorm, vbi_end and the current cropping | 3022 | /* Make sure tvnorm, vbi_end and the current cropping |
| 3092 | parameters remain consistent until we're done. Note | 3023 | parameters remain consistent until we're done. Note |
| 3093 | read() may change vbi_end in check_alloc_btres_lock(). */ | 3024 | read() may change vbi_end in check_alloc_btres_lock(). */ |
| 3094 | mutex_lock(&btv->lock); | ||
| 3095 | retval = v4l2_prio_check(&btv->prio, fh->prio); | 3025 | retval = v4l2_prio_check(&btv->prio, fh->prio); |
| 3096 | if (0 != retval) { | 3026 | if (0 != retval) { |
| 3097 | mutex_unlock(&btv->lock); | ||
| 3098 | return retval; | 3027 | return retval; |
| 3099 | } | 3028 | } |
| 3100 | 3029 | ||
| 3101 | retval = -EBUSY; | 3030 | retval = -EBUSY; |
| 3102 | 3031 | ||
| 3103 | if (locked_btres(fh->btv, VIDEO_RESOURCES)) { | 3032 | if (locked_btres(fh->btv, VIDEO_RESOURCES)) { |
| 3104 | mutex_unlock(&btv->lock); | ||
| 3105 | return retval; | 3033 | return retval; |
| 3106 | } | 3034 | } |
| 3107 | 3035 | ||
| @@ -3113,7 +3041,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
| 3113 | 3041 | ||
| 3114 | b_top = max(b->top, btv->vbi_end); | 3042 | b_top = max(b->top, btv->vbi_end); |
| 3115 | if (b_top + 32 >= b_bottom) { | 3043 | if (b_top + 32 >= b_bottom) { |
| 3116 | mutex_unlock(&btv->lock); | ||
| 3117 | return retval; | 3044 | return retval; |
| 3118 | } | 3045 | } |
| 3119 | 3046 | ||
| @@ -3136,12 +3063,8 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
| 3136 | 3063 | ||
| 3137 | btv->crop[1] = c; | 3064 | btv->crop[1] = c; |
| 3138 | 3065 | ||
| 3139 | mutex_unlock(&btv->lock); | ||
| 3140 | |||
| 3141 | fh->do_crop = 1; | 3066 | fh->do_crop = 1; |
| 3142 | 3067 | ||
| 3143 | mutex_lock(&fh->cap.vb_lock); | ||
| 3144 | |||
| 3145 | if (fh->width < c.min_scaled_width) { | 3068 | if (fh->width < c.min_scaled_width) { |
| 3146 | fh->width = c.min_scaled_width; | 3069 | fh->width = c.min_scaled_width; |
| 3147 | btv->init.width = c.min_scaled_width; | 3070 | btv->init.width = c.min_scaled_width; |
| @@ -3158,8 +3081,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
| 3158 | btv->init.height = c.max_scaled_height; | 3081 | btv->init.height = c.max_scaled_height; |
| 3159 | } | 3082 | } |
| 3160 | 3083 | ||
| 3161 | mutex_unlock(&fh->cap.vb_lock); | ||
| 3162 | |||
| 3163 | return 0; | 3084 | return 0; |
| 3164 | } | 3085 | } |
| 3165 | 3086 | ||
| @@ -3227,7 +3148,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
| 3227 | return videobuf_poll_stream(file, &fh->vbi, wait); | 3148 | return videobuf_poll_stream(file, &fh->vbi, wait); |
| 3228 | } | 3149 | } |
| 3229 | 3150 | ||
| 3230 | mutex_lock(&fh->cap.vb_lock); | ||
| 3231 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { | 3151 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { |
| 3232 | /* streaming capture */ | 3152 | /* streaming capture */ |
| 3233 | if (list_empty(&fh->cap.stream)) | 3153 | if (list_empty(&fh->cap.stream)) |
| @@ -3262,7 +3182,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
| 3262 | else | 3182 | else |
| 3263 | rc = 0; | 3183 | rc = 0; |
| 3264 | err: | 3184 | err: |
| 3265 | mutex_unlock(&fh->cap.vb_lock); | ||
| 3266 | return rc; | 3185 | return rc; |
| 3267 | } | 3186 | } |
| 3268 | 3187 | ||
| @@ -3293,23 +3212,11 @@ static int bttv_open(struct file *file) | |||
| 3293 | return -ENOMEM; | 3212 | return -ENOMEM; |
| 3294 | file->private_data = fh; | 3213 | file->private_data = fh; |
| 3295 | 3214 | ||
| 3296 | /* | ||
| 3297 | * btv is protected by btv->lock mutex, while btv->init and other | ||
| 3298 | * streaming vars are protected by fh->cap.vb_lock. We need to take | ||
| 3299 | * care of both locks to avoid troubles. However, vb_lock is used also | ||
| 3300 | * inside videobuf, without calling buf->lock. So, it is a very bad | ||
| 3301 | * idea to hold both locks at the same time. | ||
| 3302 | * Let's first copy btv->init at fh, holding cap.vb_lock, and then work | ||
| 3303 | * with the rest of init, holding btv->lock. | ||
| 3304 | */ | ||
| 3305 | mutex_lock(&fh->cap.vb_lock); | ||
| 3306 | *fh = btv->init; | 3215 | *fh = btv->init; |
| 3307 | mutex_unlock(&fh->cap.vb_lock); | ||
| 3308 | 3216 | ||
| 3309 | fh->type = type; | 3217 | fh->type = type; |
| 3310 | fh->ov.setup_ok = 0; | 3218 | fh->ov.setup_ok = 0; |
| 3311 | 3219 | ||
| 3312 | mutex_lock(&btv->lock); | ||
| 3313 | v4l2_prio_open(&btv->prio, &fh->prio); | 3220 | v4l2_prio_open(&btv->prio, &fh->prio); |
| 3314 | 3221 | ||
| 3315 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, | 3222 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, |
| @@ -3317,13 +3224,13 @@ static int bttv_open(struct file *file) | |||
| 3317 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 3224 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
| 3318 | V4L2_FIELD_INTERLACED, | 3225 | V4L2_FIELD_INTERLACED, |
| 3319 | sizeof(struct bttv_buffer), | 3226 | sizeof(struct bttv_buffer), |
| 3320 | fh, NULL); | 3227 | fh, &btv->lock); |
| 3321 | videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, | 3228 | videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, |
| 3322 | &btv->c.pci->dev, &btv->s_lock, | 3229 | &btv->c.pci->dev, &btv->s_lock, |
| 3323 | V4L2_BUF_TYPE_VBI_CAPTURE, | 3230 | V4L2_BUF_TYPE_VBI_CAPTURE, |
| 3324 | V4L2_FIELD_SEQ_TB, | 3231 | V4L2_FIELD_SEQ_TB, |
| 3325 | sizeof(struct bttv_buffer), | 3232 | sizeof(struct bttv_buffer), |
| 3326 | fh, NULL); | 3233 | fh, &btv->lock); |
| 3327 | set_tvnorm(btv,btv->tvnorm); | 3234 | set_tvnorm(btv,btv->tvnorm); |
| 3328 | set_input(btv, btv->input, btv->tvnorm); | 3235 | set_input(btv, btv->input, btv->tvnorm); |
| 3329 | 3236 | ||
| @@ -3346,7 +3253,6 @@ static int bttv_open(struct file *file) | |||
| 3346 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); | 3253 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); |
| 3347 | 3254 | ||
| 3348 | bttv_field_count(btv); | 3255 | bttv_field_count(btv); |
| 3349 | mutex_unlock(&btv->lock); | ||
| 3350 | return 0; | 3256 | return 0; |
| 3351 | } | 3257 | } |
| 3352 | 3258 | ||
| @@ -3355,7 +3261,6 @@ static int bttv_release(struct file *file) | |||
| 3355 | struct bttv_fh *fh = file->private_data; | 3261 | struct bttv_fh *fh = file->private_data; |
| 3356 | struct bttv *btv = fh->btv; | 3262 | struct bttv *btv = fh->btv; |
| 3357 | 3263 | ||
| 3358 | mutex_lock(&btv->lock); | ||
| 3359 | /* turn off overlay */ | 3264 | /* turn off overlay */ |
| 3360 | if (check_btres(fh, RESOURCE_OVERLAY)) | 3265 | if (check_btres(fh, RESOURCE_OVERLAY)) |
| 3361 | bttv_switch_overlay(btv,fh,NULL); | 3266 | bttv_switch_overlay(btv,fh,NULL); |
| @@ -3381,14 +3286,8 @@ static int bttv_release(struct file *file) | |||
| 3381 | 3286 | ||
| 3382 | /* free stuff */ | 3287 | /* free stuff */ |
| 3383 | 3288 | ||
| 3384 | /* | ||
| 3385 | * videobuf uses cap.vb_lock - we should avoid holding btv->lock, | ||
| 3386 | * otherwise we may have dead lock conditions | ||
| 3387 | */ | ||
| 3388 | mutex_unlock(&btv->lock); | ||
| 3389 | videobuf_mmap_free(&fh->cap); | 3289 | videobuf_mmap_free(&fh->cap); |
| 3390 | videobuf_mmap_free(&fh->vbi); | 3290 | videobuf_mmap_free(&fh->vbi); |
| 3391 | mutex_lock(&btv->lock); | ||
| 3392 | v4l2_prio_close(&btv->prio, fh->prio); | 3291 | v4l2_prio_close(&btv->prio, fh->prio); |
| 3393 | file->private_data = NULL; | 3292 | file->private_data = NULL; |
| 3394 | kfree(fh); | 3293 | kfree(fh); |
| @@ -3398,7 +3297,6 @@ static int bttv_release(struct file *file) | |||
| 3398 | 3297 | ||
| 3399 | if (!btv->users) | 3298 | if (!btv->users) |
| 3400 | audio_mute(btv, 1); | 3299 | audio_mute(btv, 1); |
| 3401 | mutex_unlock(&btv->lock); | ||
| 3402 | 3300 | ||
| 3403 | return 0; | 3301 | return 0; |
| 3404 | } | 3302 | } |
| @@ -3502,11 +3400,8 @@ static int radio_open(struct file *file) | |||
| 3502 | if (unlikely(!fh)) | 3400 | if (unlikely(!fh)) |
| 3503 | return -ENOMEM; | 3401 | return -ENOMEM; |
| 3504 | file->private_data = fh; | 3402 | file->private_data = fh; |
| 3505 | mutex_lock(&fh->cap.vb_lock); | ||
| 3506 | *fh = btv->init; | 3403 | *fh = btv->init; |
| 3507 | mutex_unlock(&fh->cap.vb_lock); | ||
| 3508 | 3404 | ||
| 3509 | mutex_lock(&btv->lock); | ||
| 3510 | v4l2_prio_open(&btv->prio, &fh->prio); | 3405 | v4l2_prio_open(&btv->prio, &fh->prio); |
| 3511 | 3406 | ||
| 3512 | btv->radio_user++; | 3407 | btv->radio_user++; |
| @@ -3514,7 +3409,6 @@ static int radio_open(struct file *file) | |||
| 3514 | bttv_call_all(btv, tuner, s_radio); | 3409 | bttv_call_all(btv, tuner, s_radio); |
| 3515 | audio_input(btv,TVAUDIO_INPUT_RADIO); | 3410 | audio_input(btv,TVAUDIO_INPUT_RADIO); |
| 3516 | 3411 | ||
| 3517 | mutex_unlock(&btv->lock); | ||
| 3518 | return 0; | 3412 | return 0; |
| 3519 | } | 3413 | } |
| 3520 | 3414 | ||
| @@ -3524,7 +3418,6 @@ static int radio_release(struct file *file) | |||
| 3524 | struct bttv *btv = fh->btv; | 3418 | struct bttv *btv = fh->btv; |
| 3525 | struct rds_command cmd; | 3419 | struct rds_command cmd; |
| 3526 | 3420 | ||
| 3527 | mutex_lock(&btv->lock); | ||
| 3528 | v4l2_prio_close(&btv->prio, fh->prio); | 3421 | v4l2_prio_close(&btv->prio, fh->prio); |
| 3529 | file->private_data = NULL; | 3422 | file->private_data = NULL; |
| 3530 | kfree(fh); | 3423 | kfree(fh); |
| @@ -3532,7 +3425,6 @@ static int radio_release(struct file *file) | |||
| 3532 | btv->radio_user--; | 3425 | btv->radio_user--; |
| 3533 | 3426 | ||
| 3534 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); | 3427 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); |
| 3535 | mutex_unlock(&btv->lock); | ||
| 3536 | 3428 | ||
| 3537 | return 0; | 3429 | return 0; |
| 3538 | } | 3430 | } |
| @@ -3561,7 +3453,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
| 3561 | return -EINVAL; | 3453 | return -EINVAL; |
| 3562 | if (0 != t->index) | 3454 | if (0 != t->index) |
| 3563 | return -EINVAL; | 3455 | return -EINVAL; |
| 3564 | mutex_lock(&btv->lock); | ||
| 3565 | strcpy(t->name, "Radio"); | 3456 | strcpy(t->name, "Radio"); |
| 3566 | t->type = V4L2_TUNER_RADIO; | 3457 | t->type = V4L2_TUNER_RADIO; |
| 3567 | 3458 | ||
| @@ -3570,8 +3461,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
| 3570 | if (btv->audio_mode_gpio) | 3461 | if (btv->audio_mode_gpio) |
| 3571 | btv->audio_mode_gpio(btv, t, 0); | 3462 | btv->audio_mode_gpio(btv, t, 0); |
| 3572 | 3463 | ||
| 3573 | mutex_unlock(&btv->lock); | ||
| 3574 | |||
| 3575 | return 0; | 3464 | return 0; |
| 3576 | } | 3465 | } |
| 3577 | 3466 | ||
| @@ -3692,7 +3581,7 @@ static const struct v4l2_file_operations radio_fops = | |||
| 3692 | .open = radio_open, | 3581 | .open = radio_open, |
| 3693 | .read = radio_read, | 3582 | .read = radio_read, |
| 3694 | .release = radio_release, | 3583 | .release = radio_release, |
| 3695 | .ioctl = video_ioctl2, | 3584 | .unlocked_ioctl = video_ioctl2, |
| 3696 | .poll = radio_poll, | 3585 | .poll = radio_poll, |
| 3697 | }; | 3586 | }; |
| 3698 | 3587 | ||
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 935e0c9a9674..c1193506131c 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
| @@ -860,7 +860,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 860 | 860 | ||
| 861 | static const struct v4l2_file_operations qcam_fops = { | 861 | static const struct v4l2_file_operations qcam_fops = { |
| 862 | .owner = THIS_MODULE, | 862 | .owner = THIS_MODULE, |
| 863 | .ioctl = video_ioctl2, | 863 | .unlocked_ioctl = video_ioctl2, |
| 864 | .read = qcam_read, | 864 | .read = qcam_read, |
| 865 | }; | 865 | }; |
| 866 | 866 | ||
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 6e4b19698c13..24fc00965a12 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
| @@ -718,7 +718,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 718 | 718 | ||
| 719 | static const struct v4l2_file_operations qcam_fops = { | 719 | static const struct v4l2_file_operations qcam_fops = { |
| 720 | .owner = THIS_MODULE, | 720 | .owner = THIS_MODULE, |
| 721 | .ioctl = video_ioctl2, | 721 | .unlocked_ioctl = video_ioctl2, |
| 722 | .read = qcam_read, | 722 | .read = qcam_read, |
| 723 | }; | 723 | }; |
| 724 | 724 | ||
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 260c666ce931..0dfff50891e4 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
| @@ -1775,7 +1775,7 @@ static const struct v4l2_file_operations cafe_v4l_fops = { | |||
| 1775 | .read = cafe_v4l_read, | 1775 | .read = cafe_v4l_read, |
| 1776 | .poll = cafe_v4l_poll, | 1776 | .poll = cafe_v4l_poll, |
| 1777 | .mmap = cafe_v4l_mmap, | 1777 | .mmap = cafe_v4l_mmap, |
| 1778 | .ioctl = video_ioctl2, | 1778 | .unlocked_ioctl = video_ioctl2, |
| 1779 | }; | 1779 | }; |
| 1780 | 1780 | ||
| 1781 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { | 1781 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { |
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c index 8f55692db36d..82d195be9197 100644 --- a/drivers/media/video/cx18/cx18-alsa-pcm.c +++ b/drivers/media/video/cx18/cx18-alsa-pcm.c | |||
| @@ -218,7 +218,13 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) | |||
| 218 | static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, | 218 | static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, |
| 219 | unsigned int cmd, void *arg) | 219 | unsigned int cmd, void *arg) |
| 220 | { | 220 | { |
| 221 | return snd_pcm_lib_ioctl(substream, cmd, arg); | 221 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); |
| 222 | int ret; | ||
| 223 | |||
| 224 | snd_cx18_lock(cxsc); | ||
| 225 | ret = snd_pcm_lib_ioctl(substream, cmd, arg); | ||
| 226 | snd_cx18_unlock(cxsc); | ||
| 227 | return ret; | ||
| 222 | } | 228 | } |
| 223 | 229 | ||
| 224 | 230 | ||
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 9045f1ece0eb..ab461e27d9dd 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
| @@ -41,7 +41,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = { | |||
| 41 | .read = cx18_v4l2_read, | 41 | .read = cx18_v4l2_read, |
| 42 | .open = cx18_v4l2_open, | 42 | .open = cx18_v4l2_open, |
| 43 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ | 43 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ |
| 44 | .ioctl = cx18_v4l2_ioctl, | 44 | .unlocked_ioctl = cx18_v4l2_ioctl, |
| 45 | .release = cx18_v4l2_close, | 45 | .release = cx18_v4l2_close, |
| 46 | .poll = cx18_v4l2_enc_poll, | 46 | .poll = cx18_v4l2_enc_poll, |
| 47 | }; | 47 | }; |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index a5cfc76b40b7..bb164099ea2c 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
| @@ -2530,7 +2530,7 @@ static const struct v4l2_file_operations et61x251_fops = { | |||
| 2530 | .owner = THIS_MODULE, | 2530 | .owner = THIS_MODULE, |
| 2531 | .open = et61x251_open, | 2531 | .open = et61x251_open, |
| 2532 | .release = et61x251_release, | 2532 | .release = et61x251_release, |
| 2533 | .ioctl = et61x251_ioctl, | 2533 | .unlocked_ioctl = et61x251_ioctl, |
| 2534 | .read = et61x251_read, | 2534 | .read = et61x251_read, |
| 2535 | .poll = et61x251_poll, | 2535 | .poll = et61x251_poll, |
| 2536 | .mmap = et61x251_mmap, | 2536 | .mmap = et61x251_mmap, |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 330dadc00106..e23de57e2c73 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
| @@ -63,7 +63,10 @@ struct sd { | |||
| 63 | #define QUALITY_DEF 80 | 63 | #define QUALITY_DEF 80 |
| 64 | u8 jpegqual; /* webcam quality */ | 64 | u8 jpegqual; /* webcam quality */ |
| 65 | 65 | ||
| 66 | u8 reg01; | ||
| 67 | u8 reg17; | ||
| 66 | u8 reg18; | 68 | u8 reg18; |
| 69 | u8 flags; | ||
| 67 | 70 | ||
| 68 | s8 ag_cnt; | 71 | s8 ag_cnt; |
| 69 | #define AG_CNT_START 13 | 72 | #define AG_CNT_START 13 |
| @@ -96,6 +99,22 @@ enum sensors { | |||
| 96 | SENSOR_SP80708, | 99 | SENSOR_SP80708, |
| 97 | }; | 100 | }; |
| 98 | 101 | ||
| 102 | /* device flags */ | ||
| 103 | #define PDN_INV 1 /* inverse pin S_PWR_DN / sn_xxx tables */ | ||
| 104 | |||
| 105 | /* sn9c1xx definitions */ | ||
| 106 | /* register 0x01 */ | ||
| 107 | #define S_PWR_DN 0x01 /* sensor power down */ | ||
| 108 | #define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */ | ||
| 109 | #define V_TX_EN 0x04 /* video transfer enable */ | ||
| 110 | #define LED 0x08 /* output to pin LED */ | ||
| 111 | #define SCL_SEL_OD 0x20 /* open-drain mode */ | ||
| 112 | #define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */ | ||
| 113 | /* register 0x17 */ | ||
| 114 | #define MCK_SIZE_MASK 0x1f /* sensor master clock */ | ||
| 115 | #define SEN_CLK_EN 0x20 /* enable sensor clock */ | ||
| 116 | #define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */ | ||
| 117 | |||
| 99 | /* V4L2 controls supported by the driver */ | 118 | /* V4L2 controls supported by the driver */ |
| 100 | static void setbrightness(struct gspca_dev *gspca_dev); | 119 | static void setbrightness(struct gspca_dev *gspca_dev); |
| 101 | static void setcontrast(struct gspca_dev *gspca_dev); | 120 | static void setcontrast(struct gspca_dev *gspca_dev); |
| @@ -1755,141 +1774,6 @@ static void po2030n_probe(struct gspca_dev *gspca_dev) | |||
| 1755 | } | 1774 | } |
| 1756 | } | 1775 | } |
| 1757 | 1776 | ||
| 1758 | static void bridge_init(struct gspca_dev *gspca_dev, | ||
| 1759 | const u8 *sn9c1xx) | ||
| 1760 | { | ||
| 1761 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 1762 | u8 reg0102[2]; | ||
| 1763 | const u8 *reg9a; | ||
| 1764 | static const u8 reg9a_def[] = | ||
| 1765 | {0x00, 0x40, 0x20, 0x00, 0x00, 0x00}; | ||
| 1766 | static const u8 reg9a_spec[] = | ||
| 1767 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
| 1768 | static const u8 regd4[] = {0x60, 0x00, 0x00}; | ||
| 1769 | |||
| 1770 | /* sensor clock already enabled in sd_init */ | ||
| 1771 | /* reg_w1(gspca_dev, 0xf1, 0x00); */ | ||
| 1772 | reg_w1(gspca_dev, 0x01, sn9c1xx[1]); | ||
| 1773 | |||
| 1774 | /* configure gpio */ | ||
| 1775 | reg0102[0] = sn9c1xx[1]; | ||
| 1776 | reg0102[1] = sn9c1xx[2]; | ||
| 1777 | if (gspca_dev->audio) | ||
| 1778 | reg0102[1] |= 0x04; /* keep the audio connection */ | ||
| 1779 | reg_w(gspca_dev, 0x01, reg0102, 2); | ||
| 1780 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | ||
| 1781 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); | ||
| 1782 | switch (sd->sensor) { | ||
| 1783 | case SENSOR_GC0307: | ||
| 1784 | case SENSOR_OV7660: | ||
| 1785 | case SENSOR_PO1030: | ||
| 1786 | case SENSOR_PO2030N: | ||
| 1787 | case SENSOR_SOI768: | ||
| 1788 | case SENSOR_SP80708: | ||
| 1789 | reg9a = reg9a_spec; | ||
| 1790 | break; | ||
| 1791 | default: | ||
| 1792 | reg9a = reg9a_def; | ||
| 1793 | break; | ||
| 1794 | } | ||
| 1795 | reg_w(gspca_dev, 0x9a, reg9a, 6); | ||
| 1796 | |||
| 1797 | reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); | ||
| 1798 | |||
| 1799 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | ||
| 1800 | |||
| 1801 | switch (sd->sensor) { | ||
| 1802 | case SENSOR_ADCM1700: | ||
| 1803 | reg_w1(gspca_dev, 0x01, 0x43); | ||
| 1804 | reg_w1(gspca_dev, 0x17, 0x62); | ||
| 1805 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1806 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1807 | break; | ||
| 1808 | case SENSOR_GC0307: | ||
| 1809 | msleep(50); | ||
| 1810 | reg_w1(gspca_dev, 0x01, 0x61); | ||
| 1811 | reg_w1(gspca_dev, 0x17, 0x22); | ||
| 1812 | reg_w1(gspca_dev, 0x01, 0x60); | ||
| 1813 | reg_w1(gspca_dev, 0x01, 0x40); | ||
| 1814 | msleep(50); | ||
| 1815 | break; | ||
| 1816 | case SENSOR_MI0360B: | ||
| 1817 | reg_w1(gspca_dev, 0x01, 0x61); | ||
| 1818 | reg_w1(gspca_dev, 0x17, 0x60); | ||
| 1819 | reg_w1(gspca_dev, 0x01, 0x60); | ||
| 1820 | reg_w1(gspca_dev, 0x01, 0x40); | ||
| 1821 | break; | ||
| 1822 | case SENSOR_MT9V111: | ||
| 1823 | reg_w1(gspca_dev, 0x01, 0x61); | ||
| 1824 | reg_w1(gspca_dev, 0x17, 0x61); | ||
| 1825 | reg_w1(gspca_dev, 0x01, 0x60); | ||
| 1826 | reg_w1(gspca_dev, 0x01, 0x40); | ||
| 1827 | break; | ||
| 1828 | case SENSOR_OM6802: | ||
| 1829 | msleep(10); | ||
| 1830 | reg_w1(gspca_dev, 0x02, 0x73); | ||
| 1831 | reg_w1(gspca_dev, 0x17, 0x60); | ||
| 1832 | reg_w1(gspca_dev, 0x01, 0x22); | ||
| 1833 | msleep(100); | ||
| 1834 | reg_w1(gspca_dev, 0x01, 0x62); | ||
| 1835 | reg_w1(gspca_dev, 0x17, 0x64); | ||
| 1836 | reg_w1(gspca_dev, 0x17, 0x64); | ||
| 1837 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1838 | msleep(10); | ||
| 1839 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1840 | i2c_w8(gspca_dev, om6802_init0[0]); | ||
| 1841 | i2c_w8(gspca_dev, om6802_init0[1]); | ||
| 1842 | msleep(15); | ||
| 1843 | reg_w1(gspca_dev, 0x02, 0x71); | ||
| 1844 | msleep(150); | ||
| 1845 | break; | ||
| 1846 | case SENSOR_OV7630: | ||
| 1847 | reg_w1(gspca_dev, 0x01, 0x61); | ||
| 1848 | reg_w1(gspca_dev, 0x17, 0xe2); | ||
| 1849 | reg_w1(gspca_dev, 0x01, 0x60); | ||
| 1850 | reg_w1(gspca_dev, 0x01, 0x40); | ||
| 1851 | break; | ||
| 1852 | case SENSOR_OV7648: | ||
| 1853 | reg_w1(gspca_dev, 0x01, 0x63); | ||
| 1854 | reg_w1(gspca_dev, 0x17, 0x20); | ||
| 1855 | reg_w1(gspca_dev, 0x01, 0x62); | ||
| 1856 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1857 | break; | ||
| 1858 | case SENSOR_PO1030: | ||
| 1859 | case SENSOR_SOI768: | ||
| 1860 | reg_w1(gspca_dev, 0x01, 0x61); | ||
| 1861 | reg_w1(gspca_dev, 0x17, 0x20); | ||
| 1862 | reg_w1(gspca_dev, 0x01, 0x60); | ||
| 1863 | reg_w1(gspca_dev, 0x01, 0x40); | ||
| 1864 | break; | ||
| 1865 | case SENSOR_PO2030N: | ||
| 1866 | case SENSOR_OV7660: | ||
| 1867 | reg_w1(gspca_dev, 0x01, 0x63); | ||
| 1868 | reg_w1(gspca_dev, 0x17, 0x20); | ||
| 1869 | reg_w1(gspca_dev, 0x01, 0x62); | ||
| 1870 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1871 | break; | ||
| 1872 | case SENSOR_SP80708: | ||
| 1873 | reg_w1(gspca_dev, 0x01, 0x63); | ||
| 1874 | reg_w1(gspca_dev, 0x17, 0x20); | ||
| 1875 | reg_w1(gspca_dev, 0x01, 0x62); | ||
| 1876 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1877 | msleep(100); | ||
| 1878 | reg_w1(gspca_dev, 0x02, 0x62); | ||
| 1879 | break; | ||
| 1880 | default: | ||
| 1881 | /* case SENSOR_HV7131R: */ | ||
| 1882 | /* case SENSOR_MI0360: */ | ||
| 1883 | /* case SENSOR_MO4000: */ | ||
| 1884 | reg_w1(gspca_dev, 0x01, 0x43); | ||
| 1885 | reg_w1(gspca_dev, 0x17, 0x61); | ||
| 1886 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1887 | if (sd->sensor == SENSOR_HV7131R) | ||
| 1888 | hv7131r_probe(gspca_dev); | ||
| 1889 | break; | ||
| 1890 | } | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | /* this function is called at probe time */ | 1777 | /* this function is called at probe time */ |
| 1894 | static int sd_config(struct gspca_dev *gspca_dev, | 1778 | static int sd_config(struct gspca_dev *gspca_dev, |
| 1895 | const struct usb_device_id *id) | 1779 | const struct usb_device_id *id) |
| @@ -1898,7 +1782,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 1898 | struct cam *cam; | 1782 | struct cam *cam; |
| 1899 | 1783 | ||
| 1900 | sd->bridge = id->driver_info >> 16; | 1784 | sd->bridge = id->driver_info >> 16; |
| 1901 | sd->sensor = id->driver_info; | 1785 | sd->sensor = id->driver_info >> 8; |
| 1786 | sd->flags = id->driver_info; | ||
| 1902 | 1787 | ||
| 1903 | cam = &gspca_dev->cam; | 1788 | cam = &gspca_dev->cam; |
| 1904 | if (sd->sensor == SENSOR_ADCM1700) { | 1789 | if (sd->sensor == SENSOR_ADCM1700) { |
| @@ -1929,7 +1814,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
| 1929 | /* setup a selector by bridge */ | 1814 | /* setup a selector by bridge */ |
| 1930 | reg_w1(gspca_dev, 0xf1, 0x01); | 1815 | reg_w1(gspca_dev, 0xf1, 0x01); |
| 1931 | reg_r(gspca_dev, 0x00, 1); | 1816 | reg_r(gspca_dev, 0x00, 1); |
| 1932 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | 1817 | reg_w1(gspca_dev, 0xf1, 0x00); |
| 1933 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ | 1818 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ |
| 1934 | regF1 = gspca_dev->usb_buf[0]; | 1819 | regF1 = gspca_dev->usb_buf[0]; |
| 1935 | if (gspca_dev->usb_err < 0) | 1820 | if (gspca_dev->usb_err < 0) |
| @@ -2423,10 +2308,17 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2423 | { | 2308 | { |
| 2424 | struct sd *sd = (struct sd *) gspca_dev; | 2309 | struct sd *sd = (struct sd *) gspca_dev; |
| 2425 | int i; | 2310 | int i; |
| 2426 | u8 reg1, reg17; | 2311 | u8 reg01, reg17; |
| 2312 | u8 reg0102[2]; | ||
| 2427 | const u8 *sn9c1xx; | 2313 | const u8 *sn9c1xx; |
| 2428 | const u8 (*init)[8]; | 2314 | const u8 (*init)[8]; |
| 2315 | const u8 *reg9a; | ||
| 2429 | int mode; | 2316 | int mode; |
| 2317 | static const u8 reg9a_def[] = | ||
| 2318 | {0x00, 0x40, 0x20, 0x00, 0x00, 0x00}; | ||
| 2319 | static const u8 reg9a_spec[] = | ||
| 2320 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
| 2321 | static const u8 regd4[] = {0x60, 0x00, 0x00}; | ||
| 2430 | static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; | 2322 | static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; |
| 2431 | static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | 2323 | static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; |
| 2432 | static const u8 CA_adcm1700[] = | 2324 | static const u8 CA_adcm1700[] = |
| @@ -2448,7 +2340,85 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2448 | 2340 | ||
| 2449 | /* initialize the bridge */ | 2341 | /* initialize the bridge */ |
| 2450 | sn9c1xx = sn_tb[sd->sensor]; | 2342 | sn9c1xx = sn_tb[sd->sensor]; |
| 2451 | bridge_init(gspca_dev, sn9c1xx); | 2343 | |
| 2344 | /* sensor clock already enabled in sd_init */ | ||
| 2345 | /* reg_w1(gspca_dev, 0xf1, 0x00); */ | ||
| 2346 | reg01 = sn9c1xx[1]; | ||
| 2347 | if (sd->flags & PDN_INV) | ||
| 2348 | reg01 ^= S_PDN_INV; /* power down inverted */ | ||
| 2349 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2350 | |||
| 2351 | /* configure gpio */ | ||
| 2352 | reg0102[0] = reg01; | ||
| 2353 | reg0102[1] = sn9c1xx[2]; | ||
| 2354 | if (gspca_dev->audio) | ||
| 2355 | reg0102[1] |= 0x04; /* keep the audio connection */ | ||
| 2356 | reg_w(gspca_dev, 0x01, reg0102, 2); | ||
| 2357 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | ||
| 2358 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); | ||
| 2359 | switch (sd->sensor) { | ||
| 2360 | case SENSOR_GC0307: | ||
| 2361 | case SENSOR_OV7660: | ||
| 2362 | case SENSOR_PO1030: | ||
| 2363 | case SENSOR_PO2030N: | ||
| 2364 | case SENSOR_SOI768: | ||
| 2365 | case SENSOR_SP80708: | ||
| 2366 | reg9a = reg9a_spec; | ||
| 2367 | break; | ||
| 2368 | default: | ||
| 2369 | reg9a = reg9a_def; | ||
| 2370 | break; | ||
| 2371 | } | ||
| 2372 | reg_w(gspca_dev, 0x9a, reg9a, 6); | ||
| 2373 | |||
| 2374 | reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); | ||
| 2375 | |||
| 2376 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | ||
| 2377 | |||
| 2378 | reg17 = sn9c1xx[0x17]; | ||
| 2379 | switch (sd->sensor) { | ||
| 2380 | case SENSOR_GC0307: | ||
| 2381 | msleep(50); /*fixme: is it useful? */ | ||
| 2382 | break; | ||
| 2383 | case SENSOR_OM6802: | ||
| 2384 | msleep(10); | ||
| 2385 | reg_w1(gspca_dev, 0x02, 0x73); | ||
| 2386 | reg17 |= SEN_CLK_EN; | ||
| 2387 | reg_w1(gspca_dev, 0x17, reg17); | ||
| 2388 | reg_w1(gspca_dev, 0x01, 0x22); | ||
| 2389 | msleep(100); | ||
| 2390 | reg01 = SCL_SEL_OD | S_PDN_INV; | ||
| 2391 | reg17 &= MCK_SIZE_MASK; | ||
| 2392 | reg17 |= 0x04; /* clock / 4 */ | ||
| 2393 | break; | ||
| 2394 | } | ||
| 2395 | reg01 |= SYS_SEL_48M; | ||
| 2396 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2397 | reg17 |= SEN_CLK_EN; | ||
| 2398 | reg_w1(gspca_dev, 0x17, reg17); | ||
| 2399 | reg01 &= ~S_PWR_DN; /* sensor power on */ | ||
| 2400 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2401 | reg01 &= ~SYS_SEL_48M; | ||
| 2402 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2403 | |||
| 2404 | switch (sd->sensor) { | ||
| 2405 | case SENSOR_HV7131R: | ||
| 2406 | hv7131r_probe(gspca_dev); /*fixme: is it useful? */ | ||
| 2407 | break; | ||
| 2408 | case SENSOR_OM6802: | ||
| 2409 | msleep(10); | ||
| 2410 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2411 | i2c_w8(gspca_dev, om6802_init0[0]); | ||
| 2412 | i2c_w8(gspca_dev, om6802_init0[1]); | ||
| 2413 | msleep(15); | ||
| 2414 | reg_w1(gspca_dev, 0x02, 0x71); | ||
| 2415 | msleep(150); | ||
| 2416 | break; | ||
| 2417 | case SENSOR_SP80708: | ||
| 2418 | msleep(100); | ||
| 2419 | reg_w1(gspca_dev, 0x02, 0x62); | ||
| 2420 | break; | ||
| 2421 | } | ||
| 2452 | 2422 | ||
| 2453 | /* initialize the sensor */ | 2423 | /* initialize the sensor */ |
| 2454 | i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); | 2424 | i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); |
| @@ -2476,30 +2446,11 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2476 | } | 2446 | } |
| 2477 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); | 2447 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); |
| 2478 | switch (sd->sensor) { | 2448 | switch (sd->sensor) { |
| 2479 | case SENSOR_GC0307: | 2449 | case SENSOR_OM6802: |
| 2480 | reg17 = 0xa2; | 2450 | /* case SENSOR_OV7648: * fixme: sometimes */ |
| 2481 | break; | ||
| 2482 | case SENSOR_MT9V111: | ||
| 2483 | case SENSOR_MI0360B: | ||
| 2484 | reg17 = 0xe0; | ||
| 2485 | break; | ||
| 2486 | case SENSOR_ADCM1700: | ||
| 2487 | case SENSOR_OV7630: | ||
| 2488 | reg17 = 0xe2; | ||
| 2489 | break; | ||
| 2490 | case SENSOR_OV7648: | ||
| 2491 | reg17 = 0x20; | ||
| 2492 | break; | ||
| 2493 | case SENSOR_OV7660: | ||
| 2494 | case SENSOR_SOI768: | ||
| 2495 | reg17 = 0xa0; | ||
| 2496 | break; | ||
| 2497 | case SENSOR_PO1030: | ||
| 2498 | case SENSOR_PO2030N: | ||
| 2499 | reg17 = 0xa0; | ||
| 2500 | break; | 2451 | break; |
| 2501 | default: | 2452 | default: |
| 2502 | reg17 = 0x60; | 2453 | reg17 |= DEF_EN; |
| 2503 | break; | 2454 | break; |
| 2504 | } | 2455 | } |
| 2505 | reg_w1(gspca_dev, 0x17, reg17); | 2456 | reg_w1(gspca_dev, 0x17, reg17); |
| @@ -2546,95 +2497,67 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2546 | 2497 | ||
| 2547 | init = NULL; | 2498 | init = NULL; |
| 2548 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | 2499 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
| 2549 | if (mode) | 2500 | reg01 |= SYS_SEL_48M | V_TX_EN; |
| 2550 | reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */ | 2501 | reg17 &= ~MCK_SIZE_MASK; |
| 2551 | else | 2502 | reg17 |= 0x02; /* clock / 2 */ |
| 2552 | reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */ | ||
| 2553 | reg17 = 0x61; /* 0x:20: enable sensor clock */ | ||
| 2554 | switch (sd->sensor) { | 2503 | switch (sd->sensor) { |
| 2555 | case SENSOR_ADCM1700: | 2504 | case SENSOR_ADCM1700: |
| 2556 | init = adcm1700_sensor_param1; | 2505 | init = adcm1700_sensor_param1; |
| 2557 | reg1 = 0x46; | ||
| 2558 | reg17 = 0xe2; | ||
| 2559 | break; | 2506 | break; |
| 2560 | case SENSOR_GC0307: | 2507 | case SENSOR_GC0307: |
| 2561 | init = gc0307_sensor_param1; | 2508 | init = gc0307_sensor_param1; |
| 2562 | reg17 = 0xa2; | 2509 | break; |
| 2563 | reg1 = 0x44; | 2510 | case SENSOR_HV7131R: |
| 2511 | case SENSOR_MI0360: | ||
| 2512 | if (mode) | ||
| 2513 | reg01 |= SYS_SEL_48M; /* 320x240: clk 48Mhz */ | ||
| 2514 | else | ||
| 2515 | reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */ | ||
| 2516 | reg17 &= ~MCK_SIZE_MASK; | ||
| 2517 | reg17 |= 0x01; /* clock / 1 */ | ||
| 2564 | break; | 2518 | break; |
| 2565 | case SENSOR_MI0360B: | 2519 | case SENSOR_MI0360B: |
| 2566 | init = mi0360b_sensor_param1; | 2520 | init = mi0360b_sensor_param1; |
| 2567 | reg1 &= ~0x02; /* don't inverse pin S_PWR_DN */ | ||
| 2568 | reg17 = 0xe2; | ||
| 2569 | break; | 2521 | break; |
| 2570 | case SENSOR_MO4000: | 2522 | case SENSOR_MO4000: |
| 2571 | if (mode) { | 2523 | if (mode) { /* if 320x240 */ |
| 2572 | /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ | 2524 | reg01 &= ~SYS_SEL_48M; /* clk 24Mz */ |
| 2573 | reg1 = 0x06; /* clk 24Mz */ | 2525 | reg17 &= ~MCK_SIZE_MASK; |
| 2574 | } else { | 2526 | reg17 |= 0x01; /* clock / 1 */ |
| 2575 | reg17 = 0x22; /* 640 MCKSIZE */ | ||
| 2576 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ | ||
| 2577 | } | 2527 | } |
| 2578 | break; | 2528 | break; |
| 2579 | case SENSOR_MT9V111: | 2529 | case SENSOR_MT9V111: |
| 2580 | init = mt9v111_sensor_param1; | 2530 | init = mt9v111_sensor_param1; |
| 2581 | if (mode) { | ||
| 2582 | reg1 = 0x04; /* 320 clk 48Mhz */ | ||
| 2583 | } else { | ||
| 2584 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ | ||
| 2585 | reg17 = 0xc2; | ||
| 2586 | } | ||
| 2587 | break; | 2531 | break; |
| 2588 | case SENSOR_OM6802: | 2532 | case SENSOR_OM6802: |
| 2589 | init = om6802_sensor_param1; | 2533 | init = om6802_sensor_param1; |
| 2590 | reg17 = 0x64; /* 640 MCKSIZE */ | 2534 | if (!mode) { /* if 640x480 */ |
| 2535 | reg17 &= ~MCK_SIZE_MASK; | ||
| 2536 | reg17 |= 0x01; /* clock / 4 */ | ||
| 2537 | } | ||
| 2591 | break; | 2538 | break; |
| 2592 | case SENSOR_OV7630: | 2539 | case SENSOR_OV7630: |
| 2593 | init = ov7630_sensor_param1; | 2540 | init = ov7630_sensor_param1; |
| 2594 | reg17 = 0xe2; | ||
| 2595 | reg1 = 0x44; | ||
| 2596 | break; | 2541 | break; |
| 2597 | case SENSOR_OV7648: | 2542 | case SENSOR_OV7648: |
| 2598 | init = ov7648_sensor_param1; | 2543 | init = ov7648_sensor_param1; |
| 2599 | reg17 = 0x21; | 2544 | reg17 &= ~MCK_SIZE_MASK; |
| 2600 | /* reg1 = 0x42; * 42 - 46? */ | 2545 | reg17 |= 0x01; /* clock / 1 */ |
| 2601 | break; | 2546 | break; |
| 2602 | case SENSOR_OV7660: | 2547 | case SENSOR_OV7660: |
| 2603 | init = ov7660_sensor_param1; | 2548 | init = ov7660_sensor_param1; |
| 2604 | if (sd->bridge == BRIDGE_SN9C120) { | ||
| 2605 | if (mode) { /* 320x240 - 160x120 */ | ||
| 2606 | reg17 = 0xa2; | ||
| 2607 | reg1 = 0x44; /* 48 Mhz, video trf eneble */ | ||
| 2608 | } | ||
| 2609 | } else { | ||
| 2610 | reg17 = 0x22; | ||
| 2611 | reg1 = 0x06; /* 24 Mhz, video trf eneble | ||
| 2612 | * inverse power down */ | ||
| 2613 | } | ||
| 2614 | break; | 2549 | break; |
| 2615 | case SENSOR_PO1030: | 2550 | case SENSOR_PO1030: |
| 2616 | init = po1030_sensor_param1; | 2551 | init = po1030_sensor_param1; |
| 2617 | reg17 = 0xa2; | ||
| 2618 | reg1 = 0x44; | ||
| 2619 | break; | 2552 | break; |
| 2620 | case SENSOR_PO2030N: | 2553 | case SENSOR_PO2030N: |
| 2621 | init = po2030n_sensor_param1; | 2554 | init = po2030n_sensor_param1; |
| 2622 | reg1 = 0x46; | ||
| 2623 | reg17 = 0xa2; | ||
| 2624 | break; | 2555 | break; |
| 2625 | case SENSOR_SOI768: | 2556 | case SENSOR_SOI768: |
| 2626 | init = soi768_sensor_param1; | 2557 | init = soi768_sensor_param1; |
| 2627 | reg1 = 0x44; | ||
| 2628 | reg17 = 0xa2; | ||
| 2629 | break; | 2558 | break; |
| 2630 | case SENSOR_SP80708: | 2559 | case SENSOR_SP80708: |
| 2631 | init = sp80708_sensor_param1; | 2560 | init = sp80708_sensor_param1; |
| 2632 | if (mode) { | ||
| 2633 | /*?? reg1 = 0x04; * 320 clk 48Mhz */ | ||
| 2634 | } else { | ||
| 2635 | reg1 = 0x46; /* 640 clk 48Mz */ | ||
| 2636 | reg17 = 0xa2; | ||
| 2637 | } | ||
| 2638 | break; | 2561 | break; |
| 2639 | } | 2562 | } |
| 2640 | 2563 | ||
| @@ -2684,7 +2607,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2684 | setjpegqual(gspca_dev); | 2607 | setjpegqual(gspca_dev); |
| 2685 | 2608 | ||
| 2686 | reg_w1(gspca_dev, 0x17, reg17); | 2609 | reg_w1(gspca_dev, 0x17, reg17); |
| 2687 | reg_w1(gspca_dev, 0x01, reg1); | 2610 | reg_w1(gspca_dev, 0x01, reg01); |
| 2611 | sd->reg01 = reg01; | ||
| 2612 | sd->reg17 = reg17; | ||
| 2688 | 2613 | ||
| 2689 | sethvflip(gspca_dev); | 2614 | sethvflip(gspca_dev); |
| 2690 | setbrightness(gspca_dev); | 2615 | setbrightness(gspca_dev); |
| @@ -2706,41 +2631,64 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 2706 | { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; | 2631 | { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; |
| 2707 | static const u8 stopsoi768[] = | 2632 | static const u8 stopsoi768[] = |
| 2708 | { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 }; | 2633 | { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 }; |
| 2709 | u8 data; | 2634 | u8 reg01; |
| 2710 | const u8 *sn9c1xx; | 2635 | u8 reg17; |
| 2711 | 2636 | ||
| 2712 | data = 0x0b; | 2637 | reg01 = sd->reg01; |
| 2638 | reg17 = sd->reg17 & ~SEN_CLK_EN; | ||
| 2713 | switch (sd->sensor) { | 2639 | switch (sd->sensor) { |
| 2640 | case SENSOR_ADCM1700: | ||
| 2714 | case SENSOR_GC0307: | 2641 | case SENSOR_GC0307: |
| 2715 | data = 0x29; | 2642 | case SENSOR_PO2030N: |
| 2643 | case SENSOR_SP80708: | ||
| 2644 | reg01 |= LED; | ||
| 2645 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2646 | reg01 &= ~(LED | V_TX_EN); | ||
| 2647 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2648 | /* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */ | ||
| 2716 | break; | 2649 | break; |
| 2717 | case SENSOR_HV7131R: | 2650 | case SENSOR_HV7131R: |
| 2651 | reg01 &= ~V_TX_EN; | ||
| 2652 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2718 | i2c_w8(gspca_dev, stophv7131); | 2653 | i2c_w8(gspca_dev, stophv7131); |
| 2719 | data = 0x2b; | ||
| 2720 | break; | 2654 | break; |
| 2721 | case SENSOR_MI0360: | 2655 | case SENSOR_MI0360: |
| 2722 | case SENSOR_MI0360B: | 2656 | case SENSOR_MI0360B: |
| 2657 | reg01 &= ~V_TX_EN; | ||
| 2658 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2659 | /* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */ | ||
| 2723 | i2c_w8(gspca_dev, stopmi0360); | 2660 | i2c_w8(gspca_dev, stopmi0360); |
| 2724 | data = 0x29; | ||
| 2725 | break; | 2661 | break; |
| 2726 | case SENSOR_OV7648: | ||
| 2727 | i2c_w8(gspca_dev, stopov7648); | ||
| 2728 | /* fall thru */ | ||
| 2729 | case SENSOR_MT9V111: | 2662 | case SENSOR_MT9V111: |
| 2730 | case SENSOR_OV7630: | 2663 | case SENSOR_OM6802: |
| 2731 | case SENSOR_PO1030: | 2664 | case SENSOR_PO1030: |
| 2732 | data = 0x29; | 2665 | reg01 &= ~V_TX_EN; |
| 2666 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2667 | break; | ||
| 2668 | case SENSOR_OV7630: | ||
| 2669 | case SENSOR_OV7648: | ||
| 2670 | reg01 &= ~V_TX_EN; | ||
| 2671 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2672 | i2c_w8(gspca_dev, stopov7648); | ||
| 2673 | break; | ||
| 2674 | case SENSOR_OV7660: | ||
| 2675 | reg01 &= ~V_TX_EN; | ||
| 2676 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2733 | break; | 2677 | break; |
| 2734 | case SENSOR_SOI768: | 2678 | case SENSOR_SOI768: |
| 2735 | i2c_w8(gspca_dev, stopsoi768); | 2679 | i2c_w8(gspca_dev, stopsoi768); |
| 2736 | data = 0x29; | ||
| 2737 | break; | 2680 | break; |
| 2738 | } | 2681 | } |
| 2739 | sn9c1xx = sn_tb[sd->sensor]; | 2682 | |
| 2740 | reg_w1(gspca_dev, 0x01, sn9c1xx[1]); | 2683 | reg01 |= SCL_SEL_OD; |
| 2741 | reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); | 2684 | reg_w1(gspca_dev, 0x01, reg01); |
| 2742 | reg_w1(gspca_dev, 0x01, sn9c1xx[1]); | 2685 | reg01 |= S_PWR_DN; /* sensor power down */ |
| 2743 | reg_w1(gspca_dev, 0x01, data); | 2686 | reg_w1(gspca_dev, 0x01, reg01); |
| 2687 | reg_w1(gspca_dev, 0x17, reg17); | ||
| 2688 | reg01 &= ~SYS_SEL_48M; /* clock 24MHz */ | ||
| 2689 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2690 | reg01 |= LED; | ||
| 2691 | reg_w1(gspca_dev, 0x01, reg01); | ||
| 2744 | /* Don't disable sensor clock as that disables the button on the cam */ | 2692 | /* Don't disable sensor clock as that disables the button on the cam */ |
| 2745 | /* reg_w1(gspca_dev, 0xf1, 0x01); */ | 2693 | /* reg_w1(gspca_dev, 0xf1, 0x01); */ |
| 2746 | } | 2694 | } |
| @@ -2954,14 +2902,18 @@ static const struct sd_desc sd_desc = { | |||
| 2954 | /* -- module initialisation -- */ | 2902 | /* -- module initialisation -- */ |
| 2955 | #define BS(bridge, sensor) \ | 2903 | #define BS(bridge, sensor) \ |
| 2956 | .driver_info = (BRIDGE_ ## bridge << 16) \ | 2904 | .driver_info = (BRIDGE_ ## bridge << 16) \ |
| 2957 | | SENSOR_ ## sensor | 2905 | | (SENSOR_ ## sensor << 8) |
| 2906 | #define BSF(bridge, sensor, flags) \ | ||
| 2907 | .driver_info = (BRIDGE_ ## bridge << 16) \ | ||
| 2908 | | (SENSOR_ ## sensor << 8) \ | ||
| 2909 | | (flags) | ||
| 2958 | static const __devinitdata struct usb_device_id device_table[] = { | 2910 | static const __devinitdata struct usb_device_id device_table[] = { |
| 2959 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 2911 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
| 2960 | {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, | 2912 | {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, |
| 2961 | {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, | 2913 | {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, |
| 2962 | #endif | 2914 | #endif |
| 2963 | {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)}, | 2915 | {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)}, |
| 2964 | {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)}, | 2916 | {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)}, |
| 2965 | {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)}, | 2917 | {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)}, |
| 2966 | {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)}, | 2918 | {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)}, |
| 2967 | {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)}, | 2919 | {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)}, |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 2be23bccd3c8..48d2c2419c13 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
| @@ -1659,7 +1659,7 @@ static const struct v4l2_file_operations meye_fops = { | |||
| 1659 | .open = meye_open, | 1659 | .open = meye_open, |
| 1660 | .release = meye_release, | 1660 | .release = meye_release, |
| 1661 | .mmap = meye_mmap, | 1661 | .mmap = meye_mmap, |
| 1662 | .ioctl = video_ioctl2, | 1662 | .unlocked_ioctl = video_ioctl2, |
| 1663 | .poll = meye_poll, | 1663 | .poll = meye_poll, |
| 1664 | }; | 1664 | }; |
| 1665 | 1665 | ||
| @@ -1831,12 +1831,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
| 1831 | msleep(1); | 1831 | msleep(1); |
| 1832 | mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); | 1832 | mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); |
| 1833 | 1833 | ||
| 1834 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | ||
| 1835 | video_nr) < 0) { | ||
| 1836 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | ||
| 1837 | goto outvideoreg; | ||
| 1838 | } | ||
| 1839 | |||
| 1840 | mutex_init(&meye.lock); | 1834 | mutex_init(&meye.lock); |
| 1841 | init_waitqueue_head(&meye.proc_list); | 1835 | init_waitqueue_head(&meye.proc_list); |
| 1842 | meye.brightness = 32 << 10; | 1836 | meye.brightness = 32 << 10; |
| @@ -1858,6 +1852,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
| 1858 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); | 1852 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); |
| 1859 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); | 1853 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); |
| 1860 | 1854 | ||
| 1855 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | ||
| 1856 | video_nr) < 0) { | ||
| 1857 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | ||
| 1858 | goto outvideoreg; | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", | 1861 | v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", |
| 1862 | MEYE_DRIVER_VERSION); | 1862 | MEYE_DRIVER_VERSION); |
| 1863 | v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", | 1863 | v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", |
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 7129b50757db..7551907f8c28 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
| @@ -932,7 +932,7 @@ static ssize_t pms_read(struct file *file, char __user *buf, | |||
| 932 | 932 | ||
| 933 | static const struct v4l2_file_operations pms_fops = { | 933 | static const struct v4l2_file_operations pms_fops = { |
| 934 | .owner = THIS_MODULE, | 934 | .owner = THIS_MODULE, |
| 935 | .ioctl = video_ioctl2, | 935 | .unlocked_ioctl = video_ioctl2, |
| 936 | .read = pms_read, | 936 | .read = pms_read, |
| 937 | }; | 937 | }; |
| 938 | 938 | ||
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c index 4e5a8cf76ded..07cf0c6c7c1f 100644 --- a/drivers/media/video/sh_vou.c +++ b/drivers/media/video/sh_vou.c | |||
| @@ -75,6 +75,7 @@ struct sh_vou_device { | |||
| 75 | int pix_idx; | 75 | int pix_idx; |
| 76 | struct videobuf_buffer *active; | 76 | struct videobuf_buffer *active; |
| 77 | enum sh_vou_status status; | 77 | enum sh_vou_status status; |
| 78 | struct mutex fop_lock; | ||
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 80 | struct sh_vou_file { | 81 | struct sh_vou_file { |
| @@ -235,7 +236,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
| 235 | vb->state = VIDEOBUF_NEEDS_INIT; | 236 | vb->state = VIDEOBUF_NEEDS_INIT; |
| 236 | } | 237 | } |
| 237 | 238 | ||
| 238 | /* Locking: caller holds vq->vb_lock mutex */ | 239 | /* Locking: caller holds fop_lock mutex */ |
| 239 | static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, | 240 | static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, |
| 240 | unsigned int *size) | 241 | unsigned int *size) |
| 241 | { | 242 | { |
| @@ -257,7 +258,7 @@ static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
| 257 | return 0; | 258 | return 0; |
| 258 | } | 259 | } |
| 259 | 260 | ||
| 260 | /* Locking: caller holds vq->vb_lock mutex */ | 261 | /* Locking: caller holds fop_lock mutex */ |
| 261 | static int sh_vou_buf_prepare(struct videobuf_queue *vq, | 262 | static int sh_vou_buf_prepare(struct videobuf_queue *vq, |
| 262 | struct videobuf_buffer *vb, | 263 | struct videobuf_buffer *vb, |
| 263 | enum v4l2_field field) | 264 | enum v4l2_field field) |
| @@ -306,7 +307,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq, | |||
| 306 | return 0; | 307 | return 0; |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 309 | /* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */ | 310 | /* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */ |
| 310 | static void sh_vou_buf_queue(struct videobuf_queue *vq, | 311 | static void sh_vou_buf_queue(struct videobuf_queue *vq, |
| 311 | struct videobuf_buffer *vb) | 312 | struct videobuf_buffer *vb) |
| 312 | { | 313 | { |
| @@ -1190,7 +1191,7 @@ static int sh_vou_open(struct file *file) | |||
| 1190 | V4L2_BUF_TYPE_VIDEO_OUTPUT, | 1191 | V4L2_BUF_TYPE_VIDEO_OUTPUT, |
| 1191 | V4L2_FIELD_NONE, | 1192 | V4L2_FIELD_NONE, |
| 1192 | sizeof(struct videobuf_buffer), vdev, | 1193 | sizeof(struct videobuf_buffer), vdev, |
| 1193 | NULL); | 1194 | &vou_dev->fop_lock); |
| 1194 | 1195 | ||
| 1195 | return 0; | 1196 | return 0; |
| 1196 | } | 1197 | } |
| @@ -1292,7 +1293,7 @@ static const struct v4l2_file_operations sh_vou_fops = { | |||
| 1292 | .owner = THIS_MODULE, | 1293 | .owner = THIS_MODULE, |
| 1293 | .open = sh_vou_open, | 1294 | .open = sh_vou_open, |
| 1294 | .release = sh_vou_release, | 1295 | .release = sh_vou_release, |
| 1295 | .ioctl = video_ioctl2, | 1296 | .unlocked_ioctl = video_ioctl2, |
| 1296 | .mmap = sh_vou_mmap, | 1297 | .mmap = sh_vou_mmap, |
| 1297 | .poll = sh_vou_poll, | 1298 | .poll = sh_vou_poll, |
| 1298 | }; | 1299 | }; |
| @@ -1331,6 +1332,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
| 1331 | 1332 | ||
| 1332 | INIT_LIST_HEAD(&vou_dev->queue); | 1333 | INIT_LIST_HEAD(&vou_dev->queue); |
| 1333 | spin_lock_init(&vou_dev->lock); | 1334 | spin_lock_init(&vou_dev->lock); |
| 1335 | mutex_init(&vou_dev->fop_lock); | ||
| 1334 | atomic_set(&vou_dev->use_count, 0); | 1336 | atomic_set(&vou_dev->use_count, 0); |
| 1335 | vou_dev->pdata = vou_pdata; | 1337 | vou_dev->pdata = vou_pdata; |
| 1336 | vou_dev->status = SH_VOU_IDLE; | 1338 | vou_dev->status = SH_VOU_IDLE; |
| @@ -1388,6 +1390,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
| 1388 | vdev->tvnorms |= V4L2_STD_PAL; | 1390 | vdev->tvnorms |= V4L2_STD_PAL; |
| 1389 | vdev->v4l2_dev = &vou_dev->v4l2_dev; | 1391 | vdev->v4l2_dev = &vou_dev->v4l2_dev; |
| 1390 | vdev->release = video_device_release; | 1392 | vdev->release = video_device_release; |
| 1393 | vdev->lock = &vou_dev->fop_lock; | ||
| 1391 | 1394 | ||
| 1392 | vou_dev->vdev = vdev; | 1395 | vou_dev->vdev = vdev; |
| 1393 | video_set_drvdata(vdev, vou_dev); | 1396 | video_set_drvdata(vdev, vou_dev); |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 28e19daadec9..f49fbfb7dc13 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
| @@ -3238,7 +3238,7 @@ static const struct v4l2_file_operations sn9c102_fops = { | |||
| 3238 | .owner = THIS_MODULE, | 3238 | .owner = THIS_MODULE, |
| 3239 | .open = sn9c102_open, | 3239 | .open = sn9c102_open, |
| 3240 | .release = sn9c102_release, | 3240 | .release = sn9c102_release, |
| 3241 | .ioctl = sn9c102_ioctl, | 3241 | .unlocked_ioctl = sn9c102_ioctl, |
| 3242 | .read = sn9c102_read, | 3242 | .read = sn9c102_read, |
| 3243 | .poll = sn9c102_poll, | 3243 | .poll = sn9c102_poll, |
| 3244 | .mmap = sn9c102_mmap, | 3244 | .mmap = sn9c102_mmap, |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index f169f7736677..59f8a9ad3796 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
| @@ -785,7 +785,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | |||
| 785 | } | 785 | } |
| 786 | } | 786 | } |
| 787 | 787 | ||
| 788 | struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | 788 | static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, |
| 789 | __u32 v4l2_id, struct uvc_control_mapping **mapping) | 789 | __u32 v4l2_id, struct uvc_control_mapping **mapping) |
| 790 | { | 790 | { |
| 791 | struct uvc_control *ctrl = NULL; | 791 | struct uvc_control *ctrl = NULL; |
| @@ -944,6 +944,52 @@ done: | |||
| 944 | return ret; | 944 | return ret; |
| 945 | } | 945 | } |
| 946 | 946 | ||
| 947 | /* | ||
| 948 | * Mapping V4L2 controls to UVC controls can be straighforward if done well. | ||
| 949 | * Most of the UVC controls exist in V4L2, and can be mapped directly. Some | ||
| 950 | * must be grouped (for instance the Red Balance, Blue Balance and Do White | ||
| 951 | * Balance V4L2 controls use the White Balance Component UVC control) or | ||
| 952 | * otherwise translated. The approach we take here is to use a translation | ||
| 953 | * table for the controls that can be mapped directly, and handle the others | ||
| 954 | * manually. | ||
| 955 | */ | ||
| 956 | int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | ||
| 957 | struct v4l2_querymenu *query_menu) | ||
| 958 | { | ||
| 959 | struct uvc_menu_info *menu_info; | ||
| 960 | struct uvc_control_mapping *mapping; | ||
| 961 | struct uvc_control *ctrl; | ||
| 962 | u32 index = query_menu->index; | ||
| 963 | u32 id = query_menu->id; | ||
| 964 | int ret; | ||
| 965 | |||
| 966 | memset(query_menu, 0, sizeof(*query_menu)); | ||
| 967 | query_menu->id = id; | ||
| 968 | query_menu->index = index; | ||
| 969 | |||
| 970 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); | ||
| 971 | if (ret < 0) | ||
| 972 | return -ERESTARTSYS; | ||
| 973 | |||
| 974 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | ||
| 975 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) { | ||
| 976 | ret = -EINVAL; | ||
| 977 | goto done; | ||
| 978 | } | ||
| 979 | |||
| 980 | if (query_menu->index >= mapping->menu_count) { | ||
| 981 | ret = -EINVAL; | ||
| 982 | goto done; | ||
| 983 | } | ||
| 984 | |||
| 985 | menu_info = &mapping->menu_info[query_menu->index]; | ||
| 986 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | ||
| 987 | |||
| 988 | done: | ||
| 989 | mutex_unlock(&chain->ctrl_mutex); | ||
| 990 | return ret; | ||
| 991 | } | ||
| 992 | |||
| 947 | 993 | ||
| 948 | /* -------------------------------------------------------------------------- | 994 | /* -------------------------------------------------------------------------- |
| 949 | * Control transactions | 995 | * Control transactions |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index ed6d5449741c..f14581bd707f 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
| @@ -90,6 +90,39 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /* | 92 | /* |
| 93 | * Free the video buffers. | ||
| 94 | * | ||
| 95 | * This function must be called with the queue lock held. | ||
| 96 | */ | ||
| 97 | static int __uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 98 | { | ||
| 99 | unsigned int i; | ||
| 100 | |||
| 101 | for (i = 0; i < queue->count; ++i) { | ||
| 102 | if (queue->buffer[i].vma_use_count != 0) | ||
| 103 | return -EBUSY; | ||
| 104 | } | ||
| 105 | |||
| 106 | if (queue->count) { | ||
| 107 | vfree(queue->mem); | ||
| 108 | queue->count = 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | int uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 115 | { | ||
| 116 | int ret; | ||
| 117 | |||
| 118 | mutex_lock(&queue->mutex); | ||
| 119 | ret = __uvc_free_buffers(queue); | ||
| 120 | mutex_unlock(&queue->mutex); | ||
| 121 | |||
| 122 | return ret; | ||
| 123 | } | ||
| 124 | |||
| 125 | /* | ||
| 93 | * Allocate the video buffers. | 126 | * Allocate the video buffers. |
| 94 | * | 127 | * |
| 95 | * Pages are reserved to make sure they will not be swapped, as they will be | 128 | * Pages are reserved to make sure they will not be swapped, as they will be |
| @@ -110,7 +143,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, | |||
| 110 | 143 | ||
| 111 | mutex_lock(&queue->mutex); | 144 | mutex_lock(&queue->mutex); |
| 112 | 145 | ||
| 113 | if ((ret = uvc_free_buffers(queue)) < 0) | 146 | if ((ret = __uvc_free_buffers(queue)) < 0) |
| 114 | goto done; | 147 | goto done; |
| 115 | 148 | ||
| 116 | /* Bail out if no buffers should be allocated. */ | 149 | /* Bail out if no buffers should be allocated. */ |
| @@ -152,28 +185,6 @@ done: | |||
| 152 | } | 185 | } |
| 153 | 186 | ||
| 154 | /* | 187 | /* |
| 155 | * Free the video buffers. | ||
| 156 | * | ||
| 157 | * This function must be called with the queue lock held. | ||
| 158 | */ | ||
| 159 | int uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 160 | { | ||
| 161 | unsigned int i; | ||
| 162 | |||
| 163 | for (i = 0; i < queue->count; ++i) { | ||
| 164 | if (queue->buffer[i].vma_use_count != 0) | ||
| 165 | return -EBUSY; | ||
| 166 | } | ||
| 167 | |||
| 168 | if (queue->count) { | ||
| 169 | vfree(queue->mem); | ||
| 170 | queue->count = 0; | ||
| 171 | } | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | /* | ||
| 177 | * Check if buffers have been allocated. | 188 | * Check if buffers have been allocated. |
| 178 | */ | 189 | */ |
| 179 | int uvc_queue_allocated(struct uvc_video_queue *queue) | 190 | int uvc_queue_allocated(struct uvc_video_queue *queue) |
| @@ -369,6 +380,82 @@ done: | |||
| 369 | } | 380 | } |
| 370 | 381 | ||
| 371 | /* | 382 | /* |
| 383 | * VMA operations. | ||
| 384 | */ | ||
| 385 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
| 386 | { | ||
| 387 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 388 | buffer->vma_use_count++; | ||
| 389 | } | ||
| 390 | |||
| 391 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
| 392 | { | ||
| 393 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 394 | buffer->vma_use_count--; | ||
| 395 | } | ||
| 396 | |||
| 397 | static const struct vm_operations_struct uvc_vm_ops = { | ||
| 398 | .open = uvc_vm_open, | ||
| 399 | .close = uvc_vm_close, | ||
| 400 | }; | ||
| 401 | |||
| 402 | /* | ||
| 403 | * Memory-map a video buffer. | ||
| 404 | * | ||
| 405 | * This function implements video buffers memory mapping and is intended to be | ||
| 406 | * used by the device mmap handler. | ||
| 407 | */ | ||
| 408 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | ||
| 409 | { | ||
| 410 | struct uvc_buffer *uninitialized_var(buffer); | ||
| 411 | struct page *page; | ||
| 412 | unsigned long addr, start, size; | ||
| 413 | unsigned int i; | ||
| 414 | int ret = 0; | ||
| 415 | |||
| 416 | start = vma->vm_start; | ||
| 417 | size = vma->vm_end - vma->vm_start; | ||
| 418 | |||
| 419 | mutex_lock(&queue->mutex); | ||
| 420 | |||
| 421 | for (i = 0; i < queue->count; ++i) { | ||
| 422 | buffer = &queue->buffer[i]; | ||
| 423 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
| 424 | break; | ||
| 425 | } | ||
| 426 | |||
| 427 | if (i == queue->count || size != queue->buf_size) { | ||
| 428 | ret = -EINVAL; | ||
| 429 | goto done; | ||
| 430 | } | ||
| 431 | |||
| 432 | /* | ||
| 433 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
| 434 | * device. It also prevents the region from being core dumped. | ||
| 435 | */ | ||
| 436 | vma->vm_flags |= VM_IO; | ||
| 437 | |||
| 438 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
| 439 | while (size > 0) { | ||
| 440 | page = vmalloc_to_page((void *)addr); | ||
| 441 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
| 442 | goto done; | ||
| 443 | |||
| 444 | start += PAGE_SIZE; | ||
| 445 | addr += PAGE_SIZE; | ||
| 446 | size -= PAGE_SIZE; | ||
| 447 | } | ||
| 448 | |||
| 449 | vma->vm_ops = &uvc_vm_ops; | ||
| 450 | vma->vm_private_data = buffer; | ||
| 451 | uvc_vm_open(vma); | ||
| 452 | |||
| 453 | done: | ||
| 454 | mutex_unlock(&queue->mutex); | ||
| 455 | return ret; | ||
| 456 | } | ||
| 457 | |||
| 458 | /* | ||
| 372 | * Poll the video queue. | 459 | * Poll the video queue. |
| 373 | * | 460 | * |
| 374 | * This function implements video queue polling and is intended to be used by | 461 | * This function implements video queue polling and is intended to be used by |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 6d15de9b5204..8cf61e8a634f 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
| @@ -101,40 +101,6 @@ done: | |||
| 101 | */ | 101 | */ |
| 102 | 102 | ||
| 103 | /* | 103 | /* |
| 104 | * Mapping V4L2 controls to UVC controls can be straighforward if done well. | ||
| 105 | * Most of the UVC controls exist in V4L2, and can be mapped directly. Some | ||
| 106 | * must be grouped (for instance the Red Balance, Blue Balance and Do White | ||
| 107 | * Balance V4L2 controls use the White Balance Component UVC control) or | ||
| 108 | * otherwise translated. The approach we take here is to use a translation | ||
| 109 | * table for the controls that can be mapped directly, and handle the others | ||
| 110 | * manually. | ||
| 111 | */ | ||
| 112 | static int uvc_v4l2_query_menu(struct uvc_video_chain *chain, | ||
| 113 | struct v4l2_querymenu *query_menu) | ||
| 114 | { | ||
| 115 | struct uvc_menu_info *menu_info; | ||
| 116 | struct uvc_control_mapping *mapping; | ||
| 117 | struct uvc_control *ctrl; | ||
| 118 | u32 index = query_menu->index; | ||
| 119 | u32 id = query_menu->id; | ||
| 120 | |||
| 121 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | ||
| 122 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) | ||
| 123 | return -EINVAL; | ||
| 124 | |||
| 125 | if (query_menu->index >= mapping->menu_count) | ||
| 126 | return -EINVAL; | ||
| 127 | |||
| 128 | memset(query_menu, 0, sizeof(*query_menu)); | ||
| 129 | query_menu->id = id; | ||
| 130 | query_menu->index = index; | ||
| 131 | |||
| 132 | menu_info = &mapping->menu_info[query_menu->index]; | ||
| 133 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* | ||
| 138 | * Find the frame interval closest to the requested frame interval for the | 104 | * Find the frame interval closest to the requested frame interval for the |
| 139 | * given frame format and size. This should be done by the device as part of | 105 | * given frame format and size. This should be done by the device as part of |
| 140 | * the Video Probe and Commit negotiation, but some hardware don't implement | 106 | * the Video Probe and Commit negotiation, but some hardware don't implement |
| @@ -260,12 +226,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, | |||
| 260 | * developers test their webcams with the Linux driver as well as with | 226 | * developers test their webcams with the Linux driver as well as with |
| 261 | * the Windows driver). | 227 | * the Windows driver). |
| 262 | */ | 228 | */ |
| 229 | mutex_lock(&stream->mutex); | ||
| 263 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) | 230 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) |
| 264 | probe->dwMaxVideoFrameSize = | 231 | probe->dwMaxVideoFrameSize = |
| 265 | stream->ctrl.dwMaxVideoFrameSize; | 232 | stream->ctrl.dwMaxVideoFrameSize; |
| 266 | 233 | ||
| 267 | /* Probe the device. */ | 234 | /* Probe the device. */ |
| 268 | ret = uvc_probe_video(stream, probe); | 235 | ret = uvc_probe_video(stream, probe); |
| 236 | mutex_unlock(&stream->mutex); | ||
| 269 | if (ret < 0) | 237 | if (ret < 0) |
| 270 | goto done; | 238 | goto done; |
| 271 | 239 | ||
| @@ -289,14 +257,21 @@ done: | |||
| 289 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, | 257 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, |
| 290 | struct v4l2_format *fmt) | 258 | struct v4l2_format *fmt) |
| 291 | { | 259 | { |
| 292 | struct uvc_format *format = stream->cur_format; | 260 | struct uvc_format *format; |
| 293 | struct uvc_frame *frame = stream->cur_frame; | 261 | struct uvc_frame *frame; |
| 262 | int ret = 0; | ||
| 294 | 263 | ||
| 295 | if (fmt->type != stream->type) | 264 | if (fmt->type != stream->type) |
| 296 | return -EINVAL; | 265 | return -EINVAL; |
| 297 | 266 | ||
| 298 | if (format == NULL || frame == NULL) | 267 | mutex_lock(&stream->mutex); |
| 299 | return -EINVAL; | 268 | format = stream->cur_format; |
| 269 | frame = stream->cur_frame; | ||
| 270 | |||
| 271 | if (format == NULL || frame == NULL) { | ||
| 272 | ret = -EINVAL; | ||
| 273 | goto done; | ||
| 274 | } | ||
| 300 | 275 | ||
| 301 | fmt->fmt.pix.pixelformat = format->fcc; | 276 | fmt->fmt.pix.pixelformat = format->fcc; |
| 302 | fmt->fmt.pix.width = frame->wWidth; | 277 | fmt->fmt.pix.width = frame->wWidth; |
| @@ -307,7 +282,9 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream, | |||
| 307 | fmt->fmt.pix.colorspace = format->colorspace; | 282 | fmt->fmt.pix.colorspace = format->colorspace; |
| 308 | fmt->fmt.pix.priv = 0; | 283 | fmt->fmt.pix.priv = 0; |
| 309 | 284 | ||
| 310 | return 0; | 285 | done: |
| 286 | mutex_unlock(&stream->mutex); | ||
| 287 | return ret; | ||
| 311 | } | 288 | } |
| 312 | 289 | ||
| 313 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, | 290 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, |
| @@ -321,18 +298,24 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream, | |||
| 321 | if (fmt->type != stream->type) | 298 | if (fmt->type != stream->type) |
| 322 | return -EINVAL; | 299 | return -EINVAL; |
| 323 | 300 | ||
| 324 | if (uvc_queue_allocated(&stream->queue)) | ||
| 325 | return -EBUSY; | ||
| 326 | |||
| 327 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); | 301 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); |
| 328 | if (ret < 0) | 302 | if (ret < 0) |
| 329 | return ret; | 303 | return ret; |
| 330 | 304 | ||
| 305 | mutex_lock(&stream->mutex); | ||
| 306 | |||
| 307 | if (uvc_queue_allocated(&stream->queue)) { | ||
| 308 | ret = -EBUSY; | ||
| 309 | goto done; | ||
| 310 | } | ||
| 311 | |||
| 331 | memcpy(&stream->ctrl, &probe, sizeof probe); | 312 | memcpy(&stream->ctrl, &probe, sizeof probe); |
| 332 | stream->cur_format = format; | 313 | stream->cur_format = format; |
| 333 | stream->cur_frame = frame; | 314 | stream->cur_frame = frame; |
| 334 | 315 | ||
| 335 | return 0; | 316 | done: |
| 317 | mutex_unlock(&stream->mutex); | ||
| 318 | return ret; | ||
| 336 | } | 319 | } |
| 337 | 320 | ||
| 338 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | 321 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, |
| @@ -343,7 +326,10 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
| 343 | if (parm->type != stream->type) | 326 | if (parm->type != stream->type) |
| 344 | return -EINVAL; | 327 | return -EINVAL; |
| 345 | 328 | ||
| 329 | mutex_lock(&stream->mutex); | ||
| 346 | numerator = stream->ctrl.dwFrameInterval; | 330 | numerator = stream->ctrl.dwFrameInterval; |
| 331 | mutex_unlock(&stream->mutex); | ||
| 332 | |||
| 347 | denominator = 10000000; | 333 | denominator = 10000000; |
| 348 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); | 334 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); |
| 349 | 335 | ||
| @@ -370,7 +356,6 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
| 370 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | 356 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, |
| 371 | struct v4l2_streamparm *parm) | 357 | struct v4l2_streamparm *parm) |
| 372 | { | 358 | { |
| 373 | struct uvc_frame *frame = stream->cur_frame; | ||
| 374 | struct uvc_streaming_control probe; | 359 | struct uvc_streaming_control probe; |
| 375 | struct v4l2_fract timeperframe; | 360 | struct v4l2_fract timeperframe; |
| 376 | uint32_t interval; | 361 | uint32_t interval; |
| @@ -379,28 +364,36 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | |||
| 379 | if (parm->type != stream->type) | 364 | if (parm->type != stream->type) |
| 380 | return -EINVAL; | 365 | return -EINVAL; |
| 381 | 366 | ||
| 382 | if (uvc_queue_streaming(&stream->queue)) | ||
| 383 | return -EBUSY; | ||
| 384 | |||
| 385 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 367 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 386 | timeperframe = parm->parm.capture.timeperframe; | 368 | timeperframe = parm->parm.capture.timeperframe; |
| 387 | else | 369 | else |
| 388 | timeperframe = parm->parm.output.timeperframe; | 370 | timeperframe = parm->parm.output.timeperframe; |
| 389 | 371 | ||
| 390 | memcpy(&probe, &stream->ctrl, sizeof probe); | ||
| 391 | interval = uvc_fraction_to_interval(timeperframe.numerator, | 372 | interval = uvc_fraction_to_interval(timeperframe.numerator, |
| 392 | timeperframe.denominator); | 373 | timeperframe.denominator); |
| 393 | |||
| 394 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", | 374 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", |
| 395 | timeperframe.numerator, timeperframe.denominator, interval); | 375 | timeperframe.numerator, timeperframe.denominator, interval); |
| 396 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); | 376 | |
| 377 | mutex_lock(&stream->mutex); | ||
| 378 | |||
| 379 | if (uvc_queue_streaming(&stream->queue)) { | ||
| 380 | mutex_unlock(&stream->mutex); | ||
| 381 | return -EBUSY; | ||
| 382 | } | ||
| 383 | |||
| 384 | memcpy(&probe, &stream->ctrl, sizeof probe); | ||
| 385 | probe.dwFrameInterval = | ||
| 386 | uvc_try_frame_interval(stream->cur_frame, interval); | ||
| 397 | 387 | ||
| 398 | /* Probe the device with the new settings. */ | 388 | /* Probe the device with the new settings. */ |
| 399 | ret = uvc_probe_video(stream, &probe); | 389 | ret = uvc_probe_video(stream, &probe); |
| 400 | if (ret < 0) | 390 | if (ret < 0) { |
| 391 | mutex_unlock(&stream->mutex); | ||
| 401 | return ret; | 392 | return ret; |
| 393 | } | ||
| 402 | 394 | ||
| 403 | memcpy(&stream->ctrl, &probe, sizeof probe); | 395 | memcpy(&stream->ctrl, &probe, sizeof probe); |
| 396 | mutex_unlock(&stream->mutex); | ||
| 404 | 397 | ||
| 405 | /* Return the actual frame period. */ | 398 | /* Return the actual frame period. */ |
| 406 | timeperframe.numerator = probe.dwFrameInterval; | 399 | timeperframe.numerator = probe.dwFrameInterval; |
| @@ -528,11 +521,9 @@ static int uvc_v4l2_release(struct file *file) | |||
| 528 | if (uvc_has_privileges(handle)) { | 521 | if (uvc_has_privileges(handle)) { |
| 529 | uvc_video_enable(stream, 0); | 522 | uvc_video_enable(stream, 0); |
| 530 | 523 | ||
| 531 | mutex_lock(&stream->queue.mutex); | ||
| 532 | if (uvc_free_buffers(&stream->queue) < 0) | 524 | if (uvc_free_buffers(&stream->queue) < 0) |
| 533 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " | 525 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " |
| 534 | "free buffers.\n"); | 526 | "free buffers.\n"); |
| 535 | mutex_unlock(&stream->queue.mutex); | ||
| 536 | } | 527 | } |
| 537 | 528 | ||
| 538 | /* Release the file handle. */ | 529 | /* Release the file handle. */ |
| @@ -624,7 +615,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 624 | } | 615 | } |
| 625 | 616 | ||
| 626 | case VIDIOC_QUERYMENU: | 617 | case VIDIOC_QUERYMENU: |
| 627 | return uvc_v4l2_query_menu(chain, arg); | 618 | return uvc_query_v4l2_menu(chain, arg); |
| 628 | 619 | ||
| 629 | case VIDIOC_G_EXT_CTRLS: | 620 | case VIDIOC_G_EXT_CTRLS: |
| 630 | { | 621 | { |
| @@ -905,15 +896,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 905 | case VIDIOC_CROPCAP: | 896 | case VIDIOC_CROPCAP: |
| 906 | { | 897 | { |
| 907 | struct v4l2_cropcap *ccap = arg; | 898 | struct v4l2_cropcap *ccap = arg; |
| 908 | struct uvc_frame *frame = stream->cur_frame; | ||
| 909 | 899 | ||
| 910 | if (ccap->type != stream->type) | 900 | if (ccap->type != stream->type) |
| 911 | return -EINVAL; | 901 | return -EINVAL; |
| 912 | 902 | ||
| 913 | ccap->bounds.left = 0; | 903 | ccap->bounds.left = 0; |
| 914 | ccap->bounds.top = 0; | 904 | ccap->bounds.top = 0; |
| 915 | ccap->bounds.width = frame->wWidth; | 905 | |
| 916 | ccap->bounds.height = frame->wHeight; | 906 | mutex_lock(&stream->mutex); |
| 907 | ccap->bounds.width = stream->cur_frame->wWidth; | ||
| 908 | ccap->bounds.height = stream->cur_frame->wHeight; | ||
| 909 | mutex_unlock(&stream->mutex); | ||
| 917 | 910 | ||
| 918 | ccap->defrect = ccap->bounds; | 911 | ccap->defrect = ccap->bounds; |
| 919 | 912 | ||
| @@ -930,8 +923,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 930 | case VIDIOC_REQBUFS: | 923 | case VIDIOC_REQBUFS: |
| 931 | { | 924 | { |
| 932 | struct v4l2_requestbuffers *rb = arg; | 925 | struct v4l2_requestbuffers *rb = arg; |
| 933 | unsigned int bufsize = | ||
| 934 | stream->ctrl.dwMaxVideoFrameSize; | ||
| 935 | 926 | ||
| 936 | if (rb->type != stream->type || | 927 | if (rb->type != stream->type || |
| 937 | rb->memory != V4L2_MEMORY_MMAP) | 928 | rb->memory != V4L2_MEMORY_MMAP) |
| @@ -940,7 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 940 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 931 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
| 941 | return ret; | 932 | return ret; |
| 942 | 933 | ||
| 943 | ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize); | 934 | mutex_lock(&stream->mutex); |
| 935 | ret = uvc_alloc_buffers(&stream->queue, rb->count, | ||
| 936 | stream->ctrl.dwMaxVideoFrameSize); | ||
| 937 | mutex_unlock(&stream->mutex); | ||
| 944 | if (ret < 0) | 938 | if (ret < 0) |
| 945 | return ret; | 939 | return ret; |
| 946 | 940 | ||
| @@ -988,7 +982,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 988 | if (!uvc_has_privileges(handle)) | 982 | if (!uvc_has_privileges(handle)) |
| 989 | return -EBUSY; | 983 | return -EBUSY; |
| 990 | 984 | ||
| 985 | mutex_lock(&stream->mutex); | ||
| 991 | ret = uvc_video_enable(stream, 1); | 986 | ret = uvc_video_enable(stream, 1); |
| 987 | mutex_unlock(&stream->mutex); | ||
| 992 | if (ret < 0) | 988 | if (ret < 0) |
| 993 | return ret; | 989 | return ret; |
| 994 | break; | 990 | break; |
| @@ -1068,79 +1064,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data, | |||
| 1068 | return -EINVAL; | 1064 | return -EINVAL; |
| 1069 | } | 1065 | } |
| 1070 | 1066 | ||
| 1071 | /* | ||
| 1072 | * VMA operations. | ||
| 1073 | */ | ||
| 1074 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
| 1075 | { | ||
| 1076 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 1077 | buffer->vma_use_count++; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
| 1081 | { | ||
| 1082 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 1083 | buffer->vma_use_count--; | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | static const struct vm_operations_struct uvc_vm_ops = { | ||
| 1087 | .open = uvc_vm_open, | ||
| 1088 | .close = uvc_vm_close, | ||
| 1089 | }; | ||
| 1090 | |||
| 1091 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | 1067 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) |
| 1092 | { | 1068 | { |
| 1093 | struct uvc_fh *handle = file->private_data; | 1069 | struct uvc_fh *handle = file->private_data; |
| 1094 | struct uvc_streaming *stream = handle->stream; | 1070 | struct uvc_streaming *stream = handle->stream; |
| 1095 | struct uvc_video_queue *queue = &stream->queue; | ||
| 1096 | struct uvc_buffer *uninitialized_var(buffer); | ||
| 1097 | struct page *page; | ||
| 1098 | unsigned long addr, start, size; | ||
| 1099 | unsigned int i; | ||
| 1100 | int ret = 0; | ||
| 1101 | 1071 | ||
| 1102 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); | 1072 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); |
| 1103 | 1073 | ||
| 1104 | start = vma->vm_start; | 1074 | return uvc_queue_mmap(&stream->queue, vma); |
| 1105 | size = vma->vm_end - vma->vm_start; | ||
| 1106 | |||
| 1107 | mutex_lock(&queue->mutex); | ||
| 1108 | |||
| 1109 | for (i = 0; i < queue->count; ++i) { | ||
| 1110 | buffer = &queue->buffer[i]; | ||
| 1111 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
| 1112 | break; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | if (i == queue->count || size != queue->buf_size) { | ||
| 1116 | ret = -EINVAL; | ||
| 1117 | goto done; | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | /* | ||
| 1121 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
| 1122 | * device. It also prevents the region from being core dumped. | ||
| 1123 | */ | ||
| 1124 | vma->vm_flags |= VM_IO; | ||
| 1125 | |||
| 1126 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
| 1127 | while (size > 0) { | ||
| 1128 | page = vmalloc_to_page((void *)addr); | ||
| 1129 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
| 1130 | goto done; | ||
| 1131 | |||
| 1132 | start += PAGE_SIZE; | ||
| 1133 | addr += PAGE_SIZE; | ||
| 1134 | size -= PAGE_SIZE; | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | vma->vm_ops = &uvc_vm_ops; | ||
| 1138 | vma->vm_private_data = buffer; | ||
| 1139 | uvc_vm_open(vma); | ||
| 1140 | |||
| 1141 | done: | ||
| 1142 | mutex_unlock(&queue->mutex); | ||
| 1143 | return ret; | ||
| 1144 | } | 1075 | } |
| 1145 | 1076 | ||
| 1146 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) | 1077 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) |
| @@ -1157,7 +1088,7 @@ const struct v4l2_file_operations uvc_fops = { | |||
| 1157 | .owner = THIS_MODULE, | 1088 | .owner = THIS_MODULE, |
| 1158 | .open = uvc_v4l2_open, | 1089 | .open = uvc_v4l2_open, |
| 1159 | .release = uvc_v4l2_release, | 1090 | .release = uvc_v4l2_release, |
| 1160 | .ioctl = uvc_v4l2_ioctl, | 1091 | .unlocked_ioctl = uvc_v4l2_ioctl, |
| 1161 | .read = uvc_v4l2_read, | 1092 | .read = uvc_v4l2_read, |
| 1162 | .mmap = uvc_v4l2_mmap, | 1093 | .mmap = uvc_v4l2_mmap, |
| 1163 | .poll = uvc_v4l2_poll, | 1094 | .poll = uvc_v4l2_poll, |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 5555f0102838..5673d673504b 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
| @@ -293,8 +293,6 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
| 293 | unsigned int i; | 293 | unsigned int i; |
| 294 | int ret; | 294 | int ret; |
| 295 | 295 | ||
| 296 | mutex_lock(&stream->mutex); | ||
| 297 | |||
| 298 | /* Perform probing. The device should adjust the requested values | 296 | /* Perform probing. The device should adjust the requested values |
| 299 | * according to its capabilities. However, some devices, namely the | 297 | * according to its capabilities. However, some devices, namely the |
| 300 | * first generation UVC Logitech webcams, don't implement the Video | 298 | * first generation UVC Logitech webcams, don't implement the Video |
| @@ -346,7 +344,6 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
| 346 | } | 344 | } |
| 347 | 345 | ||
| 348 | done: | 346 | done: |
| 349 | mutex_unlock(&stream->mutex); | ||
| 350 | return ret; | 347 | return ret; |
| 351 | } | 348 | } |
| 352 | 349 | ||
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index d97cf6d6a4f9..45f01e7e13d2 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
| @@ -436,7 +436,9 @@ struct uvc_streaming { | |||
| 436 | struct uvc_streaming_control ctrl; | 436 | struct uvc_streaming_control ctrl; |
| 437 | struct uvc_format *cur_format; | 437 | struct uvc_format *cur_format; |
| 438 | struct uvc_frame *cur_frame; | 438 | struct uvc_frame *cur_frame; |
| 439 | 439 | /* Protect access to ctrl, cur_format, cur_frame and hardware video | |
| 440 | * probe control. | ||
| 441 | */ | ||
| 440 | struct mutex mutex; | 442 | struct mutex mutex; |
| 441 | 443 | ||
| 442 | unsigned int frozen : 1; | 444 | unsigned int frozen : 1; |
| @@ -574,6 +576,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); | |||
| 574 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); | 576 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); |
| 575 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | 577 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, |
| 576 | struct uvc_buffer *buf); | 578 | struct uvc_buffer *buf); |
| 579 | extern int uvc_queue_mmap(struct uvc_video_queue *queue, | ||
| 580 | struct vm_area_struct *vma); | ||
| 577 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, | 581 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, |
| 578 | struct file *file, poll_table *wait); | 582 | struct file *file, poll_table *wait); |
| 579 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | 583 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); |
| @@ -606,10 +610,10 @@ extern int uvc_status_suspend(struct uvc_device *dev); | |||
| 606 | extern int uvc_status_resume(struct uvc_device *dev); | 610 | extern int uvc_status_resume(struct uvc_device *dev); |
| 607 | 611 | ||
| 608 | /* Controls */ | 612 | /* Controls */ |
| 609 | extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | ||
| 610 | __u32 v4l2_id, struct uvc_control_mapping **mapping); | ||
| 611 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | 613 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
| 612 | struct v4l2_queryctrl *v4l2_ctrl); | 614 | struct v4l2_queryctrl *v4l2_ctrl); |
| 615 | extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | ||
| 616 | struct v4l2_querymenu *query_menu); | ||
| 613 | 617 | ||
| 614 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, | 618 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, |
| 615 | const struct uvc_control_mapping *mapping); | 619 | const struct uvc_control_mapping *mapping); |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 03f7f4670e9b..359e23290a7e 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
| @@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
| 186 | size_t sz, loff_t *off) | 186 | size_t sz, loff_t *off) |
| 187 | { | 187 | { |
| 188 | struct video_device *vdev = video_devdata(filp); | 188 | struct video_device *vdev = video_devdata(filp); |
| 189 | int ret = -EIO; | 189 | int ret = -ENODEV; |
| 190 | 190 | ||
| 191 | if (!vdev->fops->read) | 191 | if (!vdev->fops->read) |
| 192 | return -EINVAL; | 192 | return -EINVAL; |
| 193 | if (vdev->lock) | 193 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 194 | mutex_lock(vdev->lock); | 194 | return -ERESTARTSYS; |
| 195 | if (video_is_registered(vdev)) | 195 | if (video_is_registered(vdev)) |
| 196 | ret = vdev->fops->read(filp, buf, sz, off); | 196 | ret = vdev->fops->read(filp, buf, sz, off); |
| 197 | if (vdev->lock) | 197 | if (vdev->lock) |
| @@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
| 203 | size_t sz, loff_t *off) | 203 | size_t sz, loff_t *off) |
| 204 | { | 204 | { |
| 205 | struct video_device *vdev = video_devdata(filp); | 205 | struct video_device *vdev = video_devdata(filp); |
| 206 | int ret = -EIO; | 206 | int ret = -ENODEV; |
| 207 | 207 | ||
| 208 | if (!vdev->fops->write) | 208 | if (!vdev->fops->write) |
| 209 | return -EINVAL; | 209 | return -EINVAL; |
| 210 | if (vdev->lock) | 210 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 211 | mutex_lock(vdev->lock); | 211 | return -ERESTARTSYS; |
| 212 | if (video_is_registered(vdev)) | 212 | if (video_is_registered(vdev)) |
| 213 | ret = vdev->fops->write(filp, buf, sz, off); | 213 | ret = vdev->fops->write(filp, buf, sz, off); |
| 214 | if (vdev->lock) | 214 | if (vdev->lock) |
| @@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
| 219 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | 219 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) |
| 220 | { | 220 | { |
| 221 | struct video_device *vdev = video_devdata(filp); | 221 | struct video_device *vdev = video_devdata(filp); |
| 222 | int ret = DEFAULT_POLLMASK; | 222 | int ret = POLLERR | POLLHUP; |
| 223 | 223 | ||
| 224 | if (!vdev->fops->poll) | 224 | if (!vdev->fops->poll) |
| 225 | return ret; | 225 | return DEFAULT_POLLMASK; |
| 226 | if (vdev->lock) | 226 | if (vdev->lock) |
| 227 | mutex_lock(vdev->lock); | 227 | mutex_lock(vdev->lock); |
| 228 | if (video_is_registered(vdev)) | 228 | if (video_is_registered(vdev)) |
| @@ -238,20 +238,45 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 238 | int ret = -ENODEV; | 238 | int ret = -ENODEV; |
| 239 | 239 | ||
| 240 | if (vdev->fops->unlocked_ioctl) { | 240 | if (vdev->fops->unlocked_ioctl) { |
| 241 | if (vdev->lock) | 241 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 242 | mutex_lock(vdev->lock); | 242 | return -ERESTARTSYS; |
| 243 | if (video_is_registered(vdev)) | 243 | if (video_is_registered(vdev)) |
| 244 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | 244 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); |
| 245 | if (vdev->lock) | 245 | if (vdev->lock) |
| 246 | mutex_unlock(vdev->lock); | 246 | mutex_unlock(vdev->lock); |
| 247 | } else if (vdev->fops->ioctl) { | 247 | } else if (vdev->fops->ioctl) { |
| 248 | /* TODO: convert all drivers to unlocked_ioctl */ | 248 | /* This code path is a replacement for the BKL. It is a major |
| 249 | * hack but it will have to do for those drivers that are not | ||
| 250 | * yet converted to use unlocked_ioctl. | ||
| 251 | * | ||
| 252 | * There are two options: if the driver implements struct | ||
| 253 | * v4l2_device, then the lock defined there is used to | ||
| 254 | * serialize the ioctls. Otherwise the v4l2 core lock defined | ||
| 255 | * below is used. This lock is really bad since it serializes | ||
| 256 | * completely independent devices. | ||
| 257 | * | ||
| 258 | * Both variants suffer from the same problem: if the driver | ||
| 259 | * sleeps, then it blocks all ioctls since the lock is still | ||
| 260 | * held. This is very common for VIDIOC_DQBUF since that | ||
| 261 | * normally waits for a frame to arrive. As a result any other | ||
| 262 | * ioctl calls will proceed very, very slowly since each call | ||
| 263 | * will have to wait for the VIDIOC_QBUF to finish. Things that | ||
| 264 | * should take 0.01s may now take 10-20 seconds. | ||
| 265 | * | ||
| 266 | * The workaround is to *not* take the lock for VIDIOC_DQBUF. | ||
| 267 | * This actually works OK for videobuf-based drivers, since | ||
| 268 | * videobuf will take its own internal lock. | ||
| 269 | */ | ||
| 249 | static DEFINE_MUTEX(v4l2_ioctl_mutex); | 270 | static DEFINE_MUTEX(v4l2_ioctl_mutex); |
| 271 | struct mutex *m = vdev->v4l2_dev ? | ||
| 272 | &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex; | ||
| 250 | 273 | ||
| 251 | mutex_lock(&v4l2_ioctl_mutex); | 274 | if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m)) |
| 275 | return -ERESTARTSYS; | ||
| 252 | if (video_is_registered(vdev)) | 276 | if (video_is_registered(vdev)) |
| 253 | ret = vdev->fops->ioctl(filp, cmd, arg); | 277 | ret = vdev->fops->ioctl(filp, cmd, arg); |
| 254 | mutex_unlock(&v4l2_ioctl_mutex); | 278 | if (cmd != VIDIOC_DQBUF) |
| 279 | mutex_unlock(m); | ||
| 255 | } else | 280 | } else |
| 256 | ret = -ENOTTY; | 281 | ret = -ENOTTY; |
| 257 | 282 | ||
| @@ -265,8 +290,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
| 265 | 290 | ||
| 266 | if (!vdev->fops->mmap) | 291 | if (!vdev->fops->mmap) |
| 267 | return ret; | 292 | return ret; |
| 268 | if (vdev->lock) | 293 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 269 | mutex_lock(vdev->lock); | 294 | return -ERESTARTSYS; |
| 270 | if (video_is_registered(vdev)) | 295 | if (video_is_registered(vdev)) |
| 271 | ret = vdev->fops->mmap(filp, vm); | 296 | ret = vdev->fops->mmap(filp, vm); |
| 272 | if (vdev->lock) | 297 | if (vdev->lock) |
| @@ -284,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 284 | mutex_lock(&videodev_lock); | 309 | mutex_lock(&videodev_lock); |
| 285 | vdev = video_devdata(filp); | 310 | vdev = video_devdata(filp); |
| 286 | /* return ENODEV if the video device has already been removed. */ | 311 | /* return ENODEV if the video device has already been removed. */ |
| 287 | if (vdev == NULL) { | 312 | if (vdev == NULL || !video_is_registered(vdev)) { |
| 288 | mutex_unlock(&videodev_lock); | 313 | mutex_unlock(&videodev_lock); |
| 289 | return -ENODEV; | 314 | return -ENODEV; |
| 290 | } | 315 | } |
| @@ -292,8 +317,10 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 292 | video_get(vdev); | 317 | video_get(vdev); |
| 293 | mutex_unlock(&videodev_lock); | 318 | mutex_unlock(&videodev_lock); |
| 294 | if (vdev->fops->open) { | 319 | if (vdev->fops->open) { |
| 295 | if (vdev->lock) | 320 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { |
| 296 | mutex_lock(vdev->lock); | 321 | ret = -ERESTARTSYS; |
| 322 | goto err; | ||
| 323 | } | ||
| 297 | if (video_is_registered(vdev)) | 324 | if (video_is_registered(vdev)) |
| 298 | ret = vdev->fops->open(filp); | 325 | ret = vdev->fops->open(filp); |
| 299 | else | 326 | else |
| @@ -302,6 +329,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 302 | mutex_unlock(vdev->lock); | 329 | mutex_unlock(vdev->lock); |
| 303 | } | 330 | } |
| 304 | 331 | ||
| 332 | err: | ||
| 305 | /* decrease the refcount in case of an error */ | 333 | /* decrease the refcount in case of an error */ |
| 306 | if (ret) | 334 | if (ret) |
| 307 | video_put(vdev); | 335 | video_put(vdev); |
| @@ -596,7 +624,12 @@ void video_unregister_device(struct video_device *vdev) | |||
| 596 | if (!vdev || !video_is_registered(vdev)) | 624 | if (!vdev || !video_is_registered(vdev)) |
| 597 | return; | 625 | return; |
| 598 | 626 | ||
| 627 | mutex_lock(&videodev_lock); | ||
| 628 | /* This must be in a critical section to prevent a race with v4l2_open. | ||
| 629 | * Once this bit has been cleared video_get may never be called again. | ||
| 630 | */ | ||
| 599 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); | 631 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); |
| 632 | mutex_unlock(&videodev_lock); | ||
| 600 | device_unregister(&vdev->dev); | 633 | device_unregister(&vdev->dev); |
| 601 | } | 634 | } |
| 602 | EXPORT_SYMBOL(video_unregister_device); | 635 | EXPORT_SYMBOL(video_unregister_device); |
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 0b08f96b74a5..7fe6f92af480 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c | |||
| @@ -35,6 +35,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) | |||
| 35 | 35 | ||
| 36 | INIT_LIST_HEAD(&v4l2_dev->subdevs); | 36 | INIT_LIST_HEAD(&v4l2_dev->subdevs); |
| 37 | spin_lock_init(&v4l2_dev->lock); | 37 | spin_lock_init(&v4l2_dev->lock); |
| 38 | mutex_init(&v4l2_dev->ioctl_lock); | ||
| 38 | v4l2_dev->dev = dev; | 39 | v4l2_dev->dev = dev; |
| 39 | if (dev == NULL) { | 40 | if (dev == NULL) { |
| 40 | /* If dev == NULL, then name must be filled in by the caller */ | 41 | /* If dev == NULL, then name must be filled in by the caller */ |
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 635420d8d84a..019ee206cbee 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
| @@ -815,7 +815,7 @@ out: | |||
| 815 | 815 | ||
| 816 | static const struct v4l2_file_operations w9966_fops = { | 816 | static const struct v4l2_file_operations w9966_fops = { |
| 817 | .owner = THIS_MODULE, | 817 | .owner = THIS_MODULE, |
| 818 | .ioctl = video_ioctl2, | 818 | .unlocked_ioctl = video_ioctl2, |
| 819 | .read = w9966_v4l_read, | 819 | .read = w9966_v4l_read, |
| 820 | }; | 820 | }; |
| 821 | 821 | ||
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 003170ea2e39..69546e9213dd 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
| @@ -64,77 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus) | |||
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static bool pci_bus_resource_better(struct resource *res1, bool pos1, | ||
| 68 | struct resource *res2, bool pos2) | ||
| 69 | { | ||
| 70 | /* If exactly one is positive decode, always prefer that one */ | ||
| 71 | if (pos1 != pos2) | ||
| 72 | return pos1 ? true : false; | ||
| 73 | |||
| 74 | /* Prefer the one that contains the highest address */ | ||
| 75 | if (res1->end != res2->end) | ||
| 76 | return (res1->end > res2->end) ? true : false; | ||
| 77 | |||
| 78 | /* Otherwise, prefer the one with highest "center of gravity" */ | ||
| 79 | if (res1->start != res2->start) | ||
| 80 | return (res1->start > res2->start) ? true : false; | ||
| 81 | |||
| 82 | /* Otherwise, choose one arbitrarily (but consistently) */ | ||
| 83 | return (res1 > res2) ? true : false; | ||
| 84 | } | ||
| 85 | |||
| 86 | static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res) | ||
| 87 | { | ||
| 88 | struct pci_bus_resource *bus_res; | ||
| 89 | |||
| 90 | /* | ||
| 91 | * This relies on the fact that pci_bus.resource[] refers to P2P or | ||
| 92 | * CardBus bridge base/limit registers, which are always positively | ||
| 93 | * decoded. The pci_bus.resources list contains host bridge or | ||
| 94 | * subtractively decoded resources. | ||
| 95 | */ | ||
| 96 | list_for_each_entry(bus_res, &bus->resources, list) { | ||
| 97 | if (bus_res->res == res) | ||
| 98 | return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ? | ||
| 99 | false : true; | ||
| 100 | } | ||
| 101 | return true; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Find the next-best bus resource after the cursor "res". If the cursor is | ||
| 106 | * NULL, return the best resource. "Best" means that we prefer positive | ||
| 107 | * decode regions over subtractive decode, then those at higher addresses. | ||
| 108 | */ | ||
| 109 | static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus, | ||
| 110 | unsigned int type, | ||
| 111 | struct resource *res) | ||
| 112 | { | ||
| 113 | bool res_pos, r_pos, prev_pos = false; | ||
| 114 | struct resource *r, *prev = NULL; | ||
| 115 | int i; | ||
| 116 | |||
| 117 | res_pos = pci_bus_resource_positive(bus, res); | ||
| 118 | pci_bus_for_each_resource(bus, r, i) { | ||
| 119 | if (!r) | ||
| 120 | continue; | ||
| 121 | |||
| 122 | if ((r->flags & IORESOURCE_TYPE_BITS) != type) | ||
| 123 | continue; | ||
| 124 | |||
| 125 | r_pos = pci_bus_resource_positive(bus, r); | ||
| 126 | if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) { | ||
| 127 | if (!prev || pci_bus_resource_better(r, r_pos, | ||
| 128 | prev, prev_pos)) { | ||
| 129 | prev = r; | ||
| 130 | prev_pos = r_pos; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | return prev; | ||
| 136 | } | ||
| 137 | |||
| 138 | /** | 67 | /** |
| 139 | * pci_bus_alloc_resource - allocate a resource from a parent bus | 68 | * pci_bus_alloc_resource - allocate a resource from a parent bus |
| 140 | * @bus: PCI bus | 69 | * @bus: PCI bus |
| @@ -160,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
| 160 | resource_size_t), | 89 | resource_size_t), |
| 161 | void *alignf_data) | 90 | void *alignf_data) |
| 162 | { | 91 | { |
| 163 | int ret = -ENOMEM; | 92 | int i, ret = -ENOMEM; |
| 164 | struct resource *r; | 93 | struct resource *r; |
| 165 | resource_size_t max = -1; | 94 | resource_size_t max = -1; |
| 166 | unsigned int type = res->flags & IORESOURCE_TYPE_BITS; | ||
| 167 | 95 | ||
| 168 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 96 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; |
| 169 | 97 | ||
| @@ -171,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
| 171 | if (!(res->flags & IORESOURCE_MEM_64)) | 99 | if (!(res->flags & IORESOURCE_MEM_64)) |
| 172 | max = PCIBIOS_MAX_MEM_32; | 100 | max = PCIBIOS_MAX_MEM_32; |
| 173 | 101 | ||
| 174 | /* Look for space at highest addresses first */ | 102 | pci_bus_for_each_resource(bus, r, i) { |
| 175 | r = pci_bus_find_resource_prev(bus, type, NULL); | 103 | if (!r) |
| 176 | for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) { | 104 | continue; |
| 105 | |||
| 177 | /* type_mask must match */ | 106 | /* type_mask must match */ |
| 178 | if ((res->flags ^ r->flags) & type_mask) | 107 | if ((res->flags ^ r->flags) & type_mask) |
| 179 | continue; | 108 | continue; |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 0157708d474d..09933eb9126b 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
| @@ -1417,6 +1417,11 @@ int __init enable_drhd_fault_handling(void) | |||
| 1417 | (unsigned long long)drhd->reg_base_addr, ret); | 1417 | (unsigned long long)drhd->reg_base_addr, ret); |
| 1418 | return -1; | 1418 | return -1; |
| 1419 | } | 1419 | } |
| 1420 | |||
| 1421 | /* | ||
| 1422 | * Clear any previous faults. | ||
| 1423 | */ | ||
| 1424 | dmar_fault(iommu->irq, iommu); | ||
| 1420 | } | 1425 | } |
| 1421 | 1426 | ||
| 1422 | return 0; | 1427 | return 0; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6f9350cabbd5..53a786fd0d40 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev) | |||
| 2329 | { | 2329 | { |
| 2330 | u32 cfg; | 2330 | u32 cfg; |
| 2331 | 2331 | ||
| 2332 | if (!pci_find_capability(dev, PCI_CAP_ID_HT)) | ||
| 2333 | return; | ||
| 2334 | |||
| 2332 | pci_read_config_dword(dev, 0x74, &cfg); | 2335 | pci_read_config_dword(dev, 0x74, &cfg); |
| 2333 | 2336 | ||
| 2334 | if (cfg & ((1 << 2) | (1 << 15))) { | 2337 | if (cfg & ((1 << 2) | (1 << 15))) { |
| @@ -2764,6 +2767,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m | |||
| 2764 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | 2767 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); |
| 2765 | #endif /*CONFIG_MMC_RICOH_MMC*/ | 2768 | #endif /*CONFIG_MMC_RICOH_MMC*/ |
| 2766 | 2769 | ||
| 2770 | #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) | ||
| 2771 | #define VTUNCERRMSK_REG 0x1ac | ||
| 2772 | #define VTD_MSK_SPEC_ERRORS (1 << 31) | ||
| 2773 | /* | ||
| 2774 | * This is a quirk for masking vt-d spec defined errors to platform error | ||
| 2775 | * handling logic. With out this, platforms using Intel 7500, 5500 chipsets | ||
| 2776 | * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based | ||
| 2777 | * on the RAS config settings of the platform) when a vt-d fault happens. | ||
| 2778 | * The resulting SMI caused the system to hang. | ||
| 2779 | * | ||
| 2780 | * VT-d spec related errors are already handled by the VT-d OS code, so no | ||
| 2781 | * need to report the same error through other channels. | ||
| 2782 | */ | ||
| 2783 | static void vtd_mask_spec_errors(struct pci_dev *dev) | ||
| 2784 | { | ||
| 2785 | u32 word; | ||
| 2786 | |||
| 2787 | pci_read_config_dword(dev, VTUNCERRMSK_REG, &word); | ||
| 2788 | pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS); | ||
| 2789 | } | ||
| 2790 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors); | ||
| 2791 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); | ||
| 2792 | #endif | ||
| 2767 | 2793 | ||
| 2768 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2794 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
| 2769 | struct pci_fixup *end) | 2795 | struct pci_fixup *end) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 5b6bbaea59fe..4a3842212c50 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -1637,9 +1637,8 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, | |||
| 1637 | 1637 | ||
| 1638 | blk_queue_max_segment_size(q, dma_get_max_seg_size(dev)); | 1638 | blk_queue_max_segment_size(q, dma_get_max_seg_size(dev)); |
| 1639 | 1639 | ||
| 1640 | /* New queue, no concurrency on queue_flags */ | ||
| 1641 | if (!shost->use_clustering) | 1640 | if (!shost->use_clustering) |
| 1642 | queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); | 1641 | q->limits.cluster = 0; |
| 1643 | 1642 | ||
| 1644 | /* | 1643 | /* |
| 1645 | * set a reasonable default alignment on word boundaries: the | 1644 | * set a reasonable default alignment on word boundaries: the |
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index e7f1d5778cec..52389308f333 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c | |||
| @@ -92,7 +92,7 @@ int cx25821_get_format_size(void) | |||
| 92 | return ARRAY_SIZE(formats); | 92 | return ARRAY_SIZE(formats); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | struct cx25821_fmt *format_by_fourcc(unsigned int fourcc) | 95 | struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc) |
| 96 | { | 96 | { |
| 97 | unsigned int i; | 97 | unsigned int i; |
| 98 | 98 | ||
| @@ -848,7 +848,7 @@ static int video_open(struct file *file) | |||
| 848 | pix_format = | 848 | pix_format = |
| 849 | (dev->channels[ch_id].pixel_formats == | 849 | (dev->channels[ch_id].pixel_formats == |
| 850 | PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV; | 850 | PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV; |
| 851 | fh->fmt = format_by_fourcc(pix_format); | 851 | fh->fmt = cx25821_format_by_fourcc(pix_format); |
| 852 | 852 | ||
| 853 | v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); | 853 | v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); |
| 854 | 854 | ||
| @@ -1010,7 +1010,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 1010 | if (0 != err) | 1010 | if (0 != err) |
| 1011 | return err; | 1011 | return err; |
| 1012 | 1012 | ||
| 1013 | fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 1013 | fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); |
| 1014 | fh->vidq.field = f->fmt.pix.field; | 1014 | fh->vidq.field = f->fmt.pix.field; |
| 1015 | 1015 | ||
| 1016 | /* check if width and height is valid based on set standard */ | 1016 | /* check if width and height is valid based on set standard */ |
| @@ -1119,7 +1119,7 @@ int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fo | |||
| 1119 | enum v4l2_field field; | 1119 | enum v4l2_field field; |
| 1120 | unsigned int maxw, maxh; | 1120 | unsigned int maxw, maxh; |
| 1121 | 1121 | ||
| 1122 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 1122 | fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); |
| 1123 | if (NULL == fmt) | 1123 | if (NULL == fmt) |
| 1124 | return -EINVAL; | 1124 | return -EINVAL; |
| 1125 | 1125 | ||
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h index cc6034b1a95d..a2415d33235b 100644 --- a/drivers/staging/cx25821/cx25821-video.h +++ b/drivers/staging/cx25821/cx25821-video.h | |||
| @@ -87,7 +87,7 @@ extern unsigned int vid_limit; | |||
| 87 | 87 | ||
| 88 | #define FORMAT_FLAGS_PACKED 0x01 | 88 | #define FORMAT_FLAGS_PACKED 0x01 |
| 89 | extern struct cx25821_fmt formats[]; | 89 | extern struct cx25821_fmt formats[]; |
| 90 | extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc); | 90 | extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc); |
| 91 | extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; | 91 | extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; |
| 92 | 92 | ||
| 93 | extern void cx25821_dump_video_queue(struct cx25821_dev *dev, | 93 | extern void cx25821_dump_video_queue(struct cx25821_dev *dev, |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 81b46585edf7..c5f8e5bda2b2 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
| @@ -716,8 +716,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) | |||
| 716 | if (msg->len < 128) | 716 | if (msg->len < 128) |
| 717 | *--dp = (msg->len << 1) | EA; | 717 | *--dp = (msg->len << 1) | EA; |
| 718 | else { | 718 | else { |
| 719 | *--dp = ((msg->len & 127) << 1) | EA; | 719 | *--dp = (msg->len >> 7); /* bits 7 - 15 */ |
| 720 | *--dp = (msg->len >> 6) & 0xfe; | 720 | *--dp = (msg->len & 127) << 1; /* bits 0 - 6 */ |
| 721 | } | 721 | } |
| 722 | } | 722 | } |
| 723 | 723 | ||
| @@ -968,6 +968,8 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data, | |||
| 968 | { | 968 | { |
| 969 | struct gsm_msg *msg; | 969 | struct gsm_msg *msg; |
| 970 | msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype); | 970 | msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype); |
| 971 | if (msg == NULL) | ||
| 972 | return; | ||
| 971 | msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */ | 973 | msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */ |
| 972 | msg->data[1] = (dlen << 1) | EA; | 974 | msg->data[1] = (dlen << 1) | EA; |
| 973 | memcpy(msg->data + 2, data, dlen); | 975 | memcpy(msg->data + 2, data, dlen); |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 9eed5b52d9de..bcc24779ba0e 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
| @@ -107,11 +107,19 @@ config USB_SUSPEND | |||
| 107 | If you are unsure about this, say N here. | 107 | If you are unsure about this, say N here. |
| 108 | 108 | ||
| 109 | config USB_OTG | 109 | config USB_OTG |
| 110 | bool | 110 | bool "OTG support" |
| 111 | depends on USB && EXPERIMENTAL | 111 | depends on USB && EXPERIMENTAL |
| 112 | depends on USB_SUSPEND | 112 | depends on USB_SUSPEND |
| 113 | default n | 113 | default n |
| 114 | 114 | help | |
| 115 | The most notable feature of USB OTG is support for a | ||
| 116 | "Dual-Role" device, which can act as either a device | ||
| 117 | or a host. The initial role is decided by the type of | ||
| 118 | plug inserted and can be changed later when two dual | ||
| 119 | role devices talk to each other. | ||
| 120 | |||
| 121 | Select this only if your board has Mini-AB/Micro-AB | ||
| 122 | connector. | ||
| 115 | 123 | ||
| 116 | config USB_OTG_WHITELIST | 124 | config USB_OTG_WHITELIST |
| 117 | bool "Rely on OTG Targeted Peripherals List" | 125 | bool "Rely on OTG Targeted Peripherals List" |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 21dc0da36ab7..f6ff8456d52d 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
| @@ -1047,9 +1047,9 @@ composite_unbind(struct usb_gadget *gadget) | |||
| 1047 | kfree(cdev->req->buf); | 1047 | kfree(cdev->req->buf); |
| 1048 | usb_ep_free_request(gadget->ep0, cdev->req); | 1048 | usb_ep_free_request(gadget->ep0, cdev->req); |
| 1049 | } | 1049 | } |
| 1050 | device_remove_file(&gadget->dev, &dev_attr_suspended); | ||
| 1050 | kfree(cdev); | 1051 | kfree(cdev); |
| 1051 | set_gadget_data(gadget, NULL); | 1052 | set_gadget_data(gadget, NULL); |
| 1052 | device_remove_file(&gadget->dev, &dev_attr_suspended); | ||
| 1053 | composite = NULL; | 1053 | composite = NULL; |
| 1054 | } | 1054 | } |
| 1055 | 1055 | ||
| @@ -1107,14 +1107,6 @@ static int composite_bind(struct usb_gadget *gadget) | |||
| 1107 | */ | 1107 | */ |
| 1108 | usb_ep_autoconfig_reset(cdev->gadget); | 1108 | usb_ep_autoconfig_reset(cdev->gadget); |
| 1109 | 1109 | ||
| 1110 | /* standardized runtime overrides for device ID data */ | ||
| 1111 | if (idVendor) | ||
| 1112 | cdev->desc.idVendor = cpu_to_le16(idVendor); | ||
| 1113 | if (idProduct) | ||
| 1114 | cdev->desc.idProduct = cpu_to_le16(idProduct); | ||
| 1115 | if (bcdDevice) | ||
| 1116 | cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); | ||
| 1117 | |||
| 1118 | /* composite gadget needs to assign strings for whole device (like | 1110 | /* composite gadget needs to assign strings for whole device (like |
| 1119 | * serial number), register function drivers, potentially update | 1111 | * serial number), register function drivers, potentially update |
| 1120 | * power state and consumption, etc | 1112 | * power state and consumption, etc |
| @@ -1126,6 +1118,14 @@ static int composite_bind(struct usb_gadget *gadget) | |||
| 1126 | cdev->desc = *composite->dev; | 1118 | cdev->desc = *composite->dev; |
| 1127 | cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 1119 | cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; |
| 1128 | 1120 | ||
| 1121 | /* standardized runtime overrides for device ID data */ | ||
| 1122 | if (idVendor) | ||
| 1123 | cdev->desc.idVendor = cpu_to_le16(idVendor); | ||
| 1124 | if (idProduct) | ||
| 1125 | cdev->desc.idProduct = cpu_to_le16(idProduct); | ||
| 1126 | if (bcdDevice) | ||
| 1127 | cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); | ||
| 1128 | |||
| 1129 | /* string overrides */ | 1129 | /* string overrides */ |
| 1130 | if (iManufacturer || !cdev->desc.iManufacturer) { | 1130 | if (iManufacturer || !cdev->desc.iManufacturer) { |
| 1131 | if (!iManufacturer && !composite->iManufacturer && | 1131 | if (!iManufacturer && !composite->iManufacturer && |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 0fae58ef8afe..1d0f45f0e7a6 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
| @@ -1680,6 +1680,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, | |||
| 1680 | xhci->port_array[i] = (u8) -1; | 1680 | xhci->port_array[i] = (u8) -1; |
| 1681 | } | 1681 | } |
| 1682 | /* FIXME: Should we disable the port? */ | 1682 | /* FIXME: Should we disable the port? */ |
| 1683 | continue; | ||
| 1683 | } | 1684 | } |
| 1684 | xhci->port_array[i] = major_revision; | 1685 | xhci->port_array[i] = major_revision; |
| 1685 | if (major_revision == 0x03) | 1686 | if (major_revision == 0x03) |
| @@ -1758,16 +1759,20 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) | |||
| 1758 | return -ENOMEM; | 1759 | return -ENOMEM; |
| 1759 | 1760 | ||
| 1760 | port_index = 0; | 1761 | port_index = 0; |
| 1761 | for (i = 0; i < num_ports; i++) | 1762 | for (i = 0; i < num_ports; i++) { |
| 1762 | if (xhci->port_array[i] != 0x03) { | 1763 | if (xhci->port_array[i] == 0x03 || |
| 1763 | xhci->usb2_ports[port_index] = | 1764 | xhci->port_array[i] == 0 || |
| 1764 | &xhci->op_regs->port_status_base + | 1765 | xhci->port_array[i] == -1) |
| 1765 | NUM_PORT_REGS*i; | 1766 | continue; |
| 1766 | xhci_dbg(xhci, "USB 2.0 port at index %u, " | 1767 | |
| 1767 | "addr = %p\n", i, | 1768 | xhci->usb2_ports[port_index] = |
| 1768 | xhci->usb2_ports[port_index]); | 1769 | &xhci->op_regs->port_status_base + |
| 1769 | port_index++; | 1770 | NUM_PORT_REGS*i; |
| 1770 | } | 1771 | xhci_dbg(xhci, "USB 2.0 port at index %u, " |
| 1772 | "addr = %p\n", i, | ||
| 1773 | xhci->usb2_ports[port_index]); | ||
| 1774 | port_index++; | ||
| 1775 | } | ||
| 1771 | } | 1776 | } |
| 1772 | if (xhci->num_usb3_ports) { | 1777 | if (xhci->num_usb3_ports) { |
| 1773 | xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)* | 1778 | xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)* |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 796e2f68f749..4ff21587ab03 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | /* | 3 | /* |
| 4 | * uss720.c -- USS720 USB Parport Cable. | 4 | * uss720.c -- USS720 USB Parport Cable. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1999, 2005 | 6 | * Copyright (C) 1999, 2005, 2010 |
| 7 | * Thomas Sailer (t.sailer@alumni.ethz.ch) | 7 | * Thomas Sailer (t.sailer@alumni.ethz.ch) |
| 8 | * | 8 | * |
| 9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
| @@ -776,6 +776,8 @@ static const struct usb_device_id uss720_table[] = { | |||
| 776 | { USB_DEVICE(0x0557, 0x2001) }, | 776 | { USB_DEVICE(0x0557, 0x2001) }, |
| 777 | { USB_DEVICE(0x0729, 0x1284) }, | 777 | { USB_DEVICE(0x0729, 0x1284) }, |
| 778 | { USB_DEVICE(0x1293, 0x0002) }, | 778 | { USB_DEVICE(0x1293, 0x0002) }, |
| 779 | { USB_DEVICE(0x1293, 0x0002) }, | ||
| 780 | { USB_DEVICE(0x050d, 0x0002) }, | ||
| 779 | { } /* Terminating entry */ | 781 | { } /* Terminating entry */ |
| 780 | }; | 782 | }; |
| 781 | 783 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 2d338737219e..a2668d089260 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -797,6 +797,7 @@ static struct usb_device_id id_table_combined [] = { | |||
| 797 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, | 797 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, |
| 798 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, | 798 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, |
| 799 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, | 799 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, |
| 800 | { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, | ||
| 800 | { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), | 801 | { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), |
| 801 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 802 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 802 | { }, /* Optional parameter entry */ | 803 | { }, /* Optional parameter entry */ |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 1286f1e23d8c..bf0867285481 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
| @@ -1081,6 +1081,11 @@ | |||
| 1081 | #define MJSG_HD_RADIO_PID 0x937C | 1081 | #define MJSG_HD_RADIO_PID 0x937C |
| 1082 | 1082 | ||
| 1083 | /* | 1083 | /* |
| 1084 | * D.O.Tec products (http://www.directout.eu) | ||
| 1085 | */ | ||
| 1086 | #define FTDI_DOTEC_PID 0x9868 | ||
| 1087 | |||
| 1088 | /* | ||
| 1084 | * Xverve Signalyzer tools (http://www.signalyzer.com/) | 1089 | * Xverve Signalyzer tools (http://www.signalyzer.com/) |
| 1085 | */ | 1090 | */ |
| 1086 | #define XVERVE_SIGNALYZER_ST_PID 0xBCA0 | 1091 | #define XVERVE_SIGNALYZER_ST_PID 0xBCA0 |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 6ccdd3dd5259..fcc1e32ce256 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -481,6 +481,13 @@ UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, | |||
| 481 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 481 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 482 | US_FL_MAX_SECTORS_64), | 482 | US_FL_MAX_SECTORS_64), |
| 483 | 483 | ||
| 484 | /* Reported by Vitaly Kuznetsov <vitty@altlinux.ru> */ | ||
| 485 | UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999, | ||
| 486 | "Samsung", | ||
| 487 | "YP-CP3", | ||
| 488 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 489 | US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG), | ||
| 490 | |||
| 484 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. | 491 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. |
| 485 | * Device uses standards-violating 32-byte Bulk Command Block Wrappers and | 492 | * Device uses standards-violating 32-byte Bulk Command Block Wrappers and |
| 486 | * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. | 493 | * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. |
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig index 455c6055325d..083c8fe53e24 100644 --- a/drivers/video/omap/Kconfig +++ b/drivers/video/omap/Kconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | config FB_OMAP | 1 | config FB_OMAP |
| 2 | tristate "OMAP frame buffer support (EXPERIMENTAL)" | 2 | tristate "OMAP frame buffer support (EXPERIMENTAL)" |
| 3 | depends on FB && ARCH_OMAP && (OMAP2_DSS = "n") | 3 | depends on FB && (OMAP2_DSS = "n") |
| 4 | 4 | depends on ARCH_OMAP1 || ARCH_OMAP2 || ARCH_OMAP3 | |
| 5 | select FB_CFB_FILLRECT | 5 | select FB_CFB_FILLRECT |
| 6 | select FB_CFB_COPYAREA | 6 | select FB_CFB_COPYAREA |
| 7 | select FB_CFB_IMAGEBLIT | 7 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c index 2fd7e5271be9..9441e2eb3dee 100644 --- a/drivers/video/omap2/vram.c +++ b/drivers/video/omap2/vram.c | |||
| @@ -551,7 +551,7 @@ void __init omap_vram_reserve_sdram_memblock(void) | |||
| 551 | if (!size) | 551 | if (!size) |
| 552 | return; | 552 | return; |
| 553 | 553 | ||
| 554 | size = PAGE_ALIGN(size); | 554 | size = ALIGN(size, SZ_2M); |
| 555 | 555 | ||
| 556 | if (paddr) { | 556 | if (paddr) { |
| 557 | if (paddr & ~PAGE_MASK) { | 557 | if (paddr & ~PAGE_MASK) { |
| @@ -576,7 +576,7 @@ void __init omap_vram_reserve_sdram_memblock(void) | |||
| 576 | return; | 576 | return; |
| 577 | } | 577 | } |
| 578 | } else { | 578 | } else { |
| 579 | paddr = memblock_alloc(size, PAGE_SIZE); | 579 | paddr = memblock_alloc(size, SZ_2M); |
| 580 | } | 580 | } |
| 581 | 581 | ||
| 582 | memblock_free(paddr, size); | 582 | memblock_free(paddr, size); |
