aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/soc_camera.c')
-rw-r--r--drivers/media/video/soc_camera.c250
1 files changed, 148 insertions, 102 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 20ef5c773fae..0a1cb40bfbf6 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -170,8 +170,6 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
170 170
171 WARN_ON(priv != file->private_data); 171 WARN_ON(priv != file->private_data);
172 172
173 dev_dbg(&icd->dev, "%s: %d\n", __func__, p->memory);
174
175 ret = videobuf_reqbufs(&icf->vb_vidq, p); 173 ret = videobuf_reqbufs(&icf->vb_vidq, p);
176 if (ret < 0) 174 if (ret < 0)
177 return ret; 175 return ret;
@@ -285,7 +283,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
285 return ret; 283 return ret;
286 } else if (!icd->current_fmt || 284 } else if (!icd->current_fmt ||
287 icd->current_fmt->fourcc != pix->pixelformat) { 285 icd->current_fmt->fourcc != pix->pixelformat) {
288 dev_err(ici->dev, 286 dev_err(ici->v4l2_dev.dev,
289 "Host driver hasn't set up current format correctly!\n"); 287 "Host driver hasn't set up current format correctly!\n");
290 return -EINVAL; 288 return -EINVAL;
291 } 289 }
@@ -308,20 +306,13 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
308 306
309static int soc_camera_open(struct file *file) 307static int soc_camera_open(struct file *file)
310{ 308{
311 struct video_device *vdev; 309 struct video_device *vdev = video_devdata(file);
312 struct soc_camera_device *icd; 310 struct soc_camera_device *icd = container_of(vdev->parent, struct soc_camera_device, dev);
311 struct soc_camera_link *icl = to_soc_camera_link(icd);
313 struct soc_camera_host *ici; 312 struct soc_camera_host *ici;
314 struct soc_camera_file *icf; 313 struct soc_camera_file *icf;
315 int ret; 314 int ret;
316 315
317 /*
318 * It is safe to dereference these pointers now as long as a user has
319 * the video device open - we are protected by the held cdev reference.
320 */
321
322 vdev = video_devdata(file);
323 icd = container_of(vdev->parent, struct soc_camera_device, dev);
324
325 if (!icd->ops) 316 if (!icd->ops)
326 /* No device driver attached */ 317 /* No device driver attached */
327 return -ENODEV; 318 return -ENODEV;
@@ -332,12 +323,6 @@ static int soc_camera_open(struct file *file)
332 if (!icf) 323 if (!icf)
333 return -ENOMEM; 324 return -ENOMEM;
334 325
335 if (!try_module_get(icd->ops->owner)) {
336 dev_err(&icd->dev, "Couldn't lock sensor driver.\n");
337 ret = -EINVAL;
338 goto emgd;
339 }
340
341 if (!try_module_get(ici->ops->owner)) { 326 if (!try_module_get(ici->ops->owner)) {
342 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 327 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
343 ret = -EINVAL; 328 ret = -EINVAL;
@@ -366,47 +351,65 @@ static int soc_camera_open(struct file *file)
366 if (ret < 0) 351 if (ret < 0)
367 goto eiufmt; 352 goto eiufmt;
368 353
369 dev_dbg(&icd->dev, "Using fmt %x\n", icd->current_fmt->fourcc);
370
371 f.fmt.pix.pixelformat = icd->current_fmt->fourcc; 354 f.fmt.pix.pixelformat = icd->current_fmt->fourcc;
372 f.fmt.pix.colorspace = icd->current_fmt->colorspace; 355 f.fmt.pix.colorspace = icd->current_fmt->colorspace;
373 356
357 if (icl->power) {
358 ret = icl->power(icd->pdev, 1);
359 if (ret < 0)
360 goto epower;
361 }
362
363 /* The camera could have been already on, try to reset */
364 if (icl->reset)
365 icl->reset(icd->pdev);
366
374 ret = ici->ops->add(icd); 367 ret = ici->ops->add(icd);
375 if (ret < 0) { 368 if (ret < 0) {
376 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); 369 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
377 goto eiciadd; 370 goto eiciadd;
378 } 371 }
379 372
373 if (icd->ops->init) {
374 ret = icd->ops->init(icd);
375 if (ret < 0)
376 goto einit;
377 }
378
380 /* Try to configure with default parameters */ 379 /* Try to configure with default parameters */
381 ret = soc_camera_set_fmt(icf, &f); 380 ret = soc_camera_set_fmt(icf, &f);
382 if (ret < 0) 381 if (ret < 0)
383 goto esfmt; 382 goto esfmt;
384 } 383 }
385 384
386 mutex_unlock(&icd->video_lock);
387
388 file->private_data = icf; 385 file->private_data = icf;
389 dev_dbg(&icd->dev, "camera device open\n"); 386 dev_dbg(&icd->dev, "camera device open\n");
390 387
391 ici->ops->init_videobuf(&icf->vb_vidq, icd); 388 ici->ops->init_videobuf(&icf->vb_vidq, icd);
392 389
390 mutex_unlock(&icd->video_lock);
391
393 return 0; 392 return 0;
394 393
395 /* 394 /*
396 * First three errors are entered with the .video_lock held 395 * First five errors are entered with the .video_lock held
397 * and use_count == 1 396 * and use_count == 1
398 */ 397 */
399esfmt: 398esfmt:
399 if (icd->ops->release)
400 icd->ops->release(icd);
401einit:
400 ici->ops->remove(icd); 402 ici->ops->remove(icd);
401eiciadd: 403eiciadd:
404 if (icl->power)
405 icl->power(icd->pdev, 0);
406epower:
402 soc_camera_free_user_formats(icd); 407 soc_camera_free_user_formats(icd);
403eiufmt: 408eiufmt:
404 icd->use_count--; 409 icd->use_count--;
405 mutex_unlock(&icd->video_lock); 410 mutex_unlock(&icd->video_lock);
406 module_put(ici->ops->owner); 411 module_put(ici->ops->owner);
407emgi: 412emgi:
408 module_put(icd->ops->owner);
409emgd:
410 vfree(icf); 413 vfree(icf);
411 return ret; 414 return ret;
412} 415}
@@ -421,13 +424,18 @@ static int soc_camera_close(struct file *file)
421 mutex_lock(&icd->video_lock); 424 mutex_lock(&icd->video_lock);
422 icd->use_count--; 425 icd->use_count--;
423 if (!icd->use_count) { 426 if (!icd->use_count) {
427 struct soc_camera_link *icl = to_soc_camera_link(icd);
428
429 if (icd->ops->release)
430 icd->ops->release(icd);
424 ici->ops->remove(icd); 431 ici->ops->remove(icd);
432 if (icl->power)
433 icl->power(icd->pdev, 0);
425 soc_camera_free_user_formats(icd); 434 soc_camera_free_user_formats(icd);
426 } 435 }
427 436
428 mutex_unlock(&icd->video_lock); 437 mutex_unlock(&icd->video_lock);
429 438
430 module_put(icd->ops->owner);
431 module_put(ici->ops->owner); 439 module_put(ici->ops->owner);
432 440
433 vfree(icf); 441 vfree(icf);
@@ -575,18 +583,17 @@ static int soc_camera_streamon(struct file *file, void *priv,
575{ 583{
576 struct soc_camera_file *icf = file->private_data; 584 struct soc_camera_file *icf = file->private_data;
577 struct soc_camera_device *icd = icf->icd; 585 struct soc_camera_device *icd = icf->icd;
586 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
578 int ret; 587 int ret;
579 588
580 WARN_ON(priv != file->private_data); 589 WARN_ON(priv != file->private_data);
581 590
582 dev_dbg(&icd->dev, "%s\n", __func__);
583
584 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 591 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
585 return -EINVAL; 592 return -EINVAL;
586 593
587 mutex_lock(&icd->video_lock); 594 mutex_lock(&icd->video_lock);
588 595
589 icd->ops->start_capture(icd); 596 v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_stream, 1);
590 597
591 /* This calls buf_queue from host driver's videobuf_queue_ops */ 598 /* This calls buf_queue from host driver's videobuf_queue_ops */
592 ret = videobuf_streamon(&icf->vb_vidq); 599 ret = videobuf_streamon(&icf->vb_vidq);
@@ -601,11 +608,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
601{ 608{
602 struct soc_camera_file *icf = file->private_data; 609 struct soc_camera_file *icf = file->private_data;
603 struct soc_camera_device *icd = icf->icd; 610 struct soc_camera_device *icd = icf->icd;
611 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
604 612
605 WARN_ON(priv != file->private_data); 613 WARN_ON(priv != file->private_data);
606 614
607 dev_dbg(&icd->dev, "%s\n", __func__);
608
609 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 615 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
610 return -EINVAL; 616 return -EINVAL;
611 617
@@ -615,7 +621,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
615 * remaining buffers. When the last buffer is freed, stop capture */ 621 * remaining buffers. When the last buffer is freed, stop capture */
616 videobuf_streamoff(&icf->vb_vidq); 622 videobuf_streamoff(&icf->vb_vidq);
617 623
618 icd->ops->stop_capture(icd); 624 v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_stream, 0);
619 625
620 mutex_unlock(&icd->video_lock); 626 mutex_unlock(&icd->video_lock);
621 627
@@ -649,6 +655,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
649{ 655{
650 struct soc_camera_file *icf = file->private_data; 656 struct soc_camera_file *icf = file->private_data;
651 struct soc_camera_device *icd = icf->icd; 657 struct soc_camera_device *icd = icf->icd;
658 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
652 659
653 WARN_ON(priv != file->private_data); 660 WARN_ON(priv != file->private_data);
654 661
@@ -665,9 +672,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
665 return 0; 672 return 0;
666 } 673 }
667 674
668 if (icd->ops->get_control) 675 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_ctrl, ctrl);
669 return icd->ops->get_control(icd, ctrl);
670 return -EINVAL;
671} 676}
672 677
673static int soc_camera_s_ctrl(struct file *file, void *priv, 678static int soc_camera_s_ctrl(struct file *file, void *priv,
@@ -675,12 +680,11 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
675{ 680{
676 struct soc_camera_file *icf = file->private_data; 681 struct soc_camera_file *icf = file->private_data;
677 struct soc_camera_device *icd = icf->icd; 682 struct soc_camera_device *icd = icf->icd;
683 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
678 684
679 WARN_ON(priv != file->private_data); 685 WARN_ON(priv != file->private_data);
680 686
681 if (icd->ops->set_control) 687 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_ctrl, ctrl);
682 return icd->ops->set_control(icd, ctrl);
683 return -EINVAL;
684} 688}
685 689
686static int soc_camera_cropcap(struct file *file, void *fh, 690static int soc_camera_cropcap(struct file *file, void *fh,
@@ -751,11 +755,9 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh,
751{ 755{
752 struct soc_camera_file *icf = file->private_data; 756 struct soc_camera_file *icf = file->private_data;
753 struct soc_camera_device *icd = icf->icd; 757 struct soc_camera_device *icd = icf->icd;
758 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
754 759
755 if (!icd->ops->get_chip_id) 760 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_chip_ident, id);
756 return -EINVAL;
757
758 return icd->ops->get_chip_id(icd, id);
759} 761}
760 762
761#ifdef CONFIG_VIDEO_ADV_DEBUG 763#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -764,11 +766,9 @@ static int soc_camera_g_register(struct file *file, void *fh,
764{ 766{
765 struct soc_camera_file *icf = file->private_data; 767 struct soc_camera_file *icf = file->private_data;
766 struct soc_camera_device *icd = icf->icd; 768 struct soc_camera_device *icd = icf->icd;
769 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
767 770
768 if (!icd->ops->get_register) 771 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_register, reg);
769 return -EINVAL;
770
771 return icd->ops->get_register(icd, reg);
772} 772}
773 773
774static int soc_camera_s_register(struct file *file, void *fh, 774static int soc_camera_s_register(struct file *file, void *fh,
@@ -776,11 +776,9 @@ static int soc_camera_s_register(struct file *file, void *fh,
776{ 776{
777 struct soc_camera_file *icf = file->private_data; 777 struct soc_camera_file *icf = file->private_data;
778 struct soc_camera_device *icd = icf->icd; 778 struct soc_camera_device *icd = icf->icd;
779 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
779 780
780 if (!icd->ops->set_register) 781 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_register, reg);
781 return -EINVAL;
782
783 return icd->ops->set_register(icd, reg);
784} 782}
785#endif 783#endif
786 784
@@ -794,7 +792,7 @@ static void scan_add_host(struct soc_camera_host *ici)
794 list_for_each_entry(icd, &devices, list) { 792 list_for_each_entry(icd, &devices, list) {
795 if (icd->iface == ici->nr) { 793 if (icd->iface == ici->nr) {
796 int ret; 794 int ret;
797 icd->dev.parent = ici->dev; 795 icd->dev.parent = ici->v4l2_dev.dev;
798 dev_set_name(&icd->dev, "%u-%u", icd->iface, 796 dev_set_name(&icd->dev, "%u-%u", icd->iface,
799 icd->devnum); 797 icd->devnum);
800 ret = device_register(&icd->dev); 798 ret = device_register(&icd->dev);
@@ -814,7 +812,9 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
814 struct soc_camera_link *icl) 812 struct soc_camera_link *icl)
815{ 813{
816 struct i2c_client *client; 814 struct i2c_client *client;
815 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
817 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id); 816 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
817 struct v4l2_subdev *subdev;
818 int ret; 818 int ret;
819 819
820 if (!adap) { 820 if (!adap) {
@@ -826,17 +826,16 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
826 826
827 icl->board_info->platform_data = icd; 827 icl->board_info->platform_data = icd;
828 828
829 client = i2c_new_device(adap, icl->board_info); 829 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
830 if (!client) { 830 icl->module_name, icl->board_info, NULL);
831 if (!subdev) {
831 ret = -ENOMEM; 832 ret = -ENOMEM;
832 goto ei2cnd; 833 goto ei2cnd;
833 } 834 }
834 835
835 /* 836 subdev->grp_id = (__u32)icd;
836 * We set icd drvdata at two locations - here and in 837 client = subdev->priv;
837 * soc_camera_video_start(). Depending on the module loading / 838
838 * initialisation order one of these locations will be entered first
839 */
840 /* Use to_i2c_client(dev) to recover the i2c client */ 839 /* Use to_i2c_client(dev) to recover the i2c client */
841 dev_set_drvdata(&icd->dev, &client->dev); 840 dev_set_drvdata(&icd->dev, &client->dev);
842 841
@@ -852,6 +851,7 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd)
852 struct i2c_client *client = 851 struct i2c_client *client =
853 to_i2c_client(to_soc_camera_control(icd)); 852 to_i2c_client(to_soc_camera_control(icd));
854 dev_set_drvdata(&icd->dev, NULL); 853 dev_set_drvdata(&icd->dev, NULL);
854 v4l2_device_unregister_subdev(i2c_get_clientdata(client));
855 i2c_unregister_device(client); 855 i2c_unregister_device(client);
856 i2c_put_adapter(client->adapter); 856 i2c_put_adapter(client->adapter);
857} 857}
@@ -860,16 +860,37 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd)
860#define soc_camera_free_i2c(icd) do {} while (0) 860#define soc_camera_free_i2c(icd) do {} while (0)
861#endif 861#endif
862 862
863static int soc_camera_video_start(struct soc_camera_device *icd);
863static int video_dev_create(struct soc_camera_device *icd); 864static int video_dev_create(struct soc_camera_device *icd);
864/* Called during host-driver probe */ 865/* Called during host-driver probe */
865static int soc_camera_probe(struct device *dev) 866static int soc_camera_probe(struct device *dev)
866{ 867{
867 struct soc_camera_device *icd = to_soc_camera_dev(dev); 868 struct soc_camera_device *icd = to_soc_camera_dev(dev);
869 struct soc_camera_host *ici = to_soc_camera_host(dev->parent);
868 struct soc_camera_link *icl = to_soc_camera_link(icd); 870 struct soc_camera_link *icl = to_soc_camera_link(icd);
871 struct device *control = NULL;
869 int ret; 872 int ret;
870 873
871 dev_info(dev, "Probing %s\n", dev_name(dev)); 874 dev_info(dev, "Probing %s\n", dev_name(dev));
872 875
876 if (icl->power) {
877 ret = icl->power(icd->pdev, 1);
878 if (ret < 0) {
879 dev_err(dev,
880 "Platform failed to power-on the camera.\n");
881 goto epower;
882 }
883 }
884
885 /* The camera could have been already on, try to reset */
886 if (icl->reset)
887 icl->reset(icd->pdev);
888
889 ret = ici->ops->add(icd);
890 if (ret < 0)
891 goto eadd;
892
893 /* Must have icd->vdev before registering the device */
873 ret = video_dev_create(icd); 894 ret = video_dev_create(icd);
874 if (ret < 0) 895 if (ret < 0)
875 goto evdc; 896 goto evdc;
@@ -883,34 +904,61 @@ static int soc_camera_probe(struct device *dev)
883 ret = -EINVAL; 904 ret = -EINVAL;
884 goto eadddev; 905 goto eadddev;
885 } else { 906 } else {
907 if (icl->module_name)
908 ret = request_module(icl->module_name);
909
886 ret = icl->add_device(icl, &icd->dev); 910 ret = icl->add_device(icl, &icd->dev);
887 if (ret < 0) 911 if (ret < 0)
888 goto eadddev; 912 goto eadddev;
889 }
890 913
891 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, icd->vdev->minor); 914 /* FIXME: this is racy, have to use driver-binding notification */
892 if (ret < 0) { 915 control = to_soc_camera_control(icd);
893 dev_err(&icd->dev, "video_register_device failed: %d\n", ret); 916 if (!control || !control->driver ||
894 goto evidregd; 917 !try_module_get(control->driver->owner)) {
918 icl->del_device(icl);
919 goto enodrv;
920 }
895 } 921 }
896 922
923 /* ..._video_start() will create a device node, so we have to protect */
924 mutex_lock(&icd->video_lock);
925
926 ret = soc_camera_video_start(icd);
927 if (ret < 0)
928 goto evidstart;
929
897 /* Do we have to sysfs_remove_link() before device_unregister()? */ 930 /* Do we have to sysfs_remove_link() before device_unregister()? */
898 if (to_soc_camera_control(icd) && 931 if (to_soc_camera_control(icd) &&
899 sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj, 932 sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj,
900 "control")) 933 "control"))
901 dev_warn(&icd->dev, "Failed creating the control symlink\n"); 934 dev_warn(&icd->dev, "Failed creating the control symlink\n");
902 935
936 ici->ops->remove(icd);
937
938 if (icl->power)
939 icl->power(icd->pdev, 0);
940
941 mutex_unlock(&icd->video_lock);
903 942
904 return 0; 943 return 0;
905 944
906evidregd: 945evidstart:
907 if (icl->board_info) 946 mutex_unlock(&icd->video_lock);
947 if (icl->board_info) {
908 soc_camera_free_i2c(icd); 948 soc_camera_free_i2c(icd);
909 else 949 } else {
910 icl->del_device(icl); 950 icl->del_device(icl);
951 module_put(control->driver->owner);
952 }
953enodrv:
911eadddev: 954eadddev:
912 video_device_release(icd->vdev); 955 video_device_release(icd->vdev);
913evdc: 956evdc:
957 ici->ops->remove(icd);
958eadd:
959 if (icl->power)
960 icl->power(icd->pdev, 0);
961epower:
914 return ret; 962 return ret;
915} 963}
916 964
@@ -931,10 +979,16 @@ static int soc_camera_remove(struct device *dev)
931 mutex_unlock(&icd->video_lock); 979 mutex_unlock(&icd->video_lock);
932 } 980 }
933 981
934 if (icl->board_info) 982 if (icl->board_info) {
935 soc_camera_free_i2c(icd); 983 soc_camera_free_i2c(icd);
936 else 984 } else {
937 icl->del_device(icl); 985 struct device_driver *drv = to_soc_camera_control(icd) ?
986 to_soc_camera_control(icd)->driver : NULL;
987 if (drv) {
988 icl->del_device(icl);
989 module_put(drv->owner);
990 }
991 }
938 992
939 return 0; 993 return 0;
940} 994}
@@ -984,6 +1038,7 @@ static void dummy_release(struct device *dev)
984int soc_camera_host_register(struct soc_camera_host *ici) 1038int soc_camera_host_register(struct soc_camera_host *ici)
985{ 1039{
986 struct soc_camera_host *ix; 1040 struct soc_camera_host *ix;
1041 int ret;
987 1042
988 if (!ici || !ici->ops || 1043 if (!ici || !ici->ops ||
989 !ici->ops->try_fmt || 1044 !ici->ops->try_fmt ||
@@ -996,18 +1051,20 @@ int soc_camera_host_register(struct soc_camera_host *ici)
996 !ici->ops->add || 1051 !ici->ops->add ||
997 !ici->ops->remove || 1052 !ici->ops->remove ||
998 !ici->ops->poll || 1053 !ici->ops->poll ||
999 !ici->dev) 1054 !ici->v4l2_dev.dev)
1000 return -EINVAL; 1055 return -EINVAL;
1001 1056
1002 mutex_lock(&list_lock); 1057 mutex_lock(&list_lock);
1003 list_for_each_entry(ix, &hosts, list) { 1058 list_for_each_entry(ix, &hosts, list) {
1004 if (ix->nr == ici->nr) { 1059 if (ix->nr == ici->nr) {
1005 mutex_unlock(&list_lock); 1060 ret = -EBUSY;
1006 return -EBUSY; 1061 goto edevreg;
1007 } 1062 }
1008 } 1063 }
1009 1064
1010 dev_set_drvdata(ici->dev, ici); 1065 ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
1066 if (ret < 0)
1067 goto edevreg;
1011 1068
1012 list_add_tail(&ici->list, &hosts); 1069 list_add_tail(&ici->list, &hosts);
1013 mutex_unlock(&list_lock); 1070 mutex_unlock(&list_lock);
@@ -1015,6 +1072,10 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1015 scan_add_host(ici); 1072 scan_add_host(ici);
1016 1073
1017 return 0; 1074 return 0;
1075
1076edevreg:
1077 mutex_unlock(&list_lock);
1078 return ret;
1018} 1079}
1019EXPORT_SYMBOL(soc_camera_host_register); 1080EXPORT_SYMBOL(soc_camera_host_register);
1020 1081
@@ -1028,7 +1089,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1028 list_del(&ici->list); 1089 list_del(&ici->list);
1029 1090
1030 list_for_each_entry(icd, &devices, list) { 1091 list_for_each_entry(icd, &devices, list) {
1031 if (icd->dev.parent == ici->dev) { 1092 if (icd->iface == ici->nr) {
1032 /* The bus->remove will be called */ 1093 /* The bus->remove will be called */
1033 device_unregister(&icd->dev); 1094 device_unregister(&icd->dev);
1034 /* Not before device_unregister(), .remove 1095 /* Not before device_unregister(), .remove
@@ -1043,7 +1104,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1043 1104
1044 mutex_unlock(&list_lock); 1105 mutex_unlock(&list_lock);
1045 1106
1046 dev_set_drvdata(ici->dev, NULL); 1107 v4l2_device_unregister(&ici->v4l2_dev);
1047} 1108}
1048EXPORT_SYMBOL(soc_camera_host_unregister); 1109EXPORT_SYMBOL(soc_camera_host_unregister);
1049 1110
@@ -1123,7 +1184,6 @@ static int video_dev_create(struct soc_camera_device *icd)
1123 1184
1124 if (!vdev) 1185 if (!vdev)
1125 return -ENOMEM; 1186 return -ENOMEM;
1126 dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
1127 1187
1128 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); 1188 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
1129 1189
@@ -1141,50 +1201,35 @@ static int video_dev_create(struct soc_camera_device *icd)
1141} 1201}
1142 1202
1143/* 1203/*
1144 * Usually called from the struct soc_camera_ops .probe() method, i.e., from 1204 * Called from soc_camera_probe() above (with .video_lock held???)
1145 * soc_camera_probe() above with .video_lock held
1146 */ 1205 */
1147int soc_camera_video_start(struct soc_camera_device *icd, struct device *dev) 1206static int soc_camera_video_start(struct soc_camera_device *icd)
1148{ 1207{
1149 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1150 const struct v4l2_queryctrl *qctrl; 1208 const struct v4l2_queryctrl *qctrl;
1209 int ret;
1151 1210
1152 if (!icd->dev.parent) 1211 if (!icd->dev.parent)
1153 return -ENODEV; 1212 return -ENODEV;
1154 1213
1155 if (!icd->ops || 1214 if (!icd->ops ||
1156 !icd->ops->init ||
1157 !icd->ops->release ||
1158 !icd->ops->start_capture ||
1159 !icd->ops->stop_capture ||
1160 !icd->ops->set_fmt ||
1161 !icd->ops->try_fmt ||
1162 !icd->ops->query_bus_param || 1215 !icd->ops->query_bus_param ||
1163 !icd->ops->set_bus_param) 1216 !icd->ops->set_bus_param)
1164 return -EINVAL; 1217 return -EINVAL;
1165 1218
1166 /* See comment in soc_camera_probe() */ 1219 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER,
1167 dev_set_drvdata(&icd->dev, dev); 1220 icd->vdev->minor);
1221 if (ret < 0) {
1222 dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
1223 return ret;
1224 }
1168 1225
1169 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN); 1226 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN);
1170 icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0; 1227 icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0;
1171 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 1228 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
1172 icd->exposure = qctrl ? qctrl->default_value : (unsigned short)~0; 1229 icd->exposure = qctrl ? qctrl->default_value : (unsigned short)~0;
1173 1230
1174 return ici->ops->add(icd); 1231 return 0;
1175}
1176EXPORT_SYMBOL(soc_camera_video_start);
1177
1178/* Called from client .remove() methods with .video_lock held */
1179void soc_camera_video_stop(struct soc_camera_device *icd)
1180{
1181 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1182
1183 dev_dbg(&icd->dev, "%s\n", __func__);
1184
1185 ici->ops->remove(icd);
1186} 1232}
1187EXPORT_SYMBOL(soc_camera_video_stop);
1188 1233
1189static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) 1234static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1190{ 1235{
@@ -1200,6 +1245,7 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1200 return -ENOMEM; 1245 return -ENOMEM;
1201 1246
1202 icd->iface = icl->bus_id; 1247 icd->iface = icl->bus_id;
1248 icd->pdev = &pdev->dev;
1203 platform_set_drvdata(pdev, icd); 1249 platform_set_drvdata(pdev, icd);
1204 icd->dev.platform_data = icl; 1250 icd->dev.platform_data = icl;
1205 1251