diff options
author | Antti Palosaari <crope@iki.fi> | 2013-07-30 16:22:25 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-08-18 06:55:06 -0400 |
commit | dd0f5e0b75540f7bfca99c5a664c61ac90e52514 (patch) | |
tree | 6d1ebbfd9bab5908550cde612e3d1686ee7bc919 | |
parent | e42efde4e4ce6bae9b728e8cc12ca73440204650 (diff) |
[media] dvb_usb_v2: get rid of deferred probe
Deferred probe was added in order to avoid udev vs. Kernel firmware
download problems. It is not needed anymore.
https://bugzilla.redhat.com/show_bug.cgi?id=827538
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/dvb_usb.h | 5 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 134 |
2 files changed, 45 insertions, 94 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index 399916bd588f..124b4baa7e97 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h | |||
@@ -352,9 +352,7 @@ struct dvb_usb_adapter { | |||
352 | * @rc_map: name of rc codes table | 352 | * @rc_map: name of rc codes table |
353 | * @rc_polling_active: set when RC polling is active | 353 | * @rc_polling_active: set when RC polling is active |
354 | * @udev: pointer to the device's struct usb_device | 354 | * @udev: pointer to the device's struct usb_device |
355 | * @intf: pointer to the device's usb interface | ||
356 | * @rc: remote controller configuration | 355 | * @rc: remote controller configuration |
357 | * @probe_work: work to defer .probe() | ||
358 | * @powered: indicated whether the device is power or not | 356 | * @powered: indicated whether the device is power or not |
359 | * @usb_mutex: mutex for usb control messages | 357 | * @usb_mutex: mutex for usb control messages |
360 | * @i2c_mutex: mutex for i2c-transfers | 358 | * @i2c_mutex: mutex for i2c-transfers |
@@ -370,10 +368,7 @@ struct dvb_usb_device { | |||
370 | const char *rc_map; | 368 | const char *rc_map; |
371 | bool rc_polling_active; | 369 | bool rc_polling_active; |
372 | struct usb_device *udev; | 370 | struct usb_device *udev; |
373 | struct usb_interface *intf; | ||
374 | struct dvb_usb_rc rc; | 371 | struct dvb_usb_rc rc; |
375 | struct work_struct probe_work; | ||
376 | pid_t work_pid; | ||
377 | int powered; | 372 | int powered; |
378 | 373 | ||
379 | /* locking */ | 374 | /* locking */ |
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 19f6737d9817..8a054d66e708 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | |||
@@ -833,20 +833,44 @@ err: | |||
833 | return ret; | 833 | return ret; |
834 | } | 834 | } |
835 | 835 | ||
836 | /* | 836 | int dvb_usbv2_probe(struct usb_interface *intf, |
837 | * udev, which is used for the firmware downloading, requires we cannot | 837 | const struct usb_device_id *id) |
838 | * block during module_init(). module_init() calls USB probe() which | ||
839 | * is this routine. Due to that we delay actual operation using workqueue | ||
840 | * and return always success here. | ||
841 | */ | ||
842 | static void dvb_usbv2_init_work(struct work_struct *work) | ||
843 | { | 838 | { |
844 | int ret; | 839 | int ret; |
845 | struct dvb_usb_device *d = | 840 | struct dvb_usb_device *d; |
846 | container_of(work, struct dvb_usb_device, probe_work); | 841 | struct usb_device *udev = interface_to_usbdev(intf); |
842 | struct dvb_usb_driver_info *driver_info = | ||
843 | (struct dvb_usb_driver_info *) id->driver_info; | ||
844 | |||
845 | dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__, | ||
846 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
847 | |||
848 | if (!id->driver_info) { | ||
849 | dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME); | ||
850 | ret = -ENODEV; | ||
851 | goto err; | ||
852 | } | ||
853 | |||
854 | d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); | ||
855 | if (!d) { | ||
856 | dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); | ||
857 | ret = -ENOMEM; | ||
858 | goto err; | ||
859 | } | ||
847 | 860 | ||
848 | d->work_pid = current->pid; | 861 | d->name = driver_info->name; |
849 | dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid); | 862 | d->rc_map = driver_info->rc_map; |
863 | d->udev = udev; | ||
864 | d->props = driver_info->props; | ||
865 | |||
866 | if (intf->cur_altsetting->desc.bInterfaceNumber != | ||
867 | d->props->bInterfaceNumber) { | ||
868 | ret = -ENODEV; | ||
869 | goto err_free_all; | ||
870 | } | ||
871 | |||
872 | mutex_init(&d->usb_mutex); | ||
873 | mutex_init(&d->i2c_mutex); | ||
850 | 874 | ||
851 | if (d->props->size_of_priv) { | 875 | if (d->props->size_of_priv) { |
852 | d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL); | 876 | d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL); |
@@ -854,7 +878,7 @@ static void dvb_usbv2_init_work(struct work_struct *work) | |||
854 | dev_err(&d->udev->dev, "%s: kzalloc() failed\n", | 878 | dev_err(&d->udev->dev, "%s: kzalloc() failed\n", |
855 | KBUILD_MODNAME); | 879 | KBUILD_MODNAME); |
856 | ret = -ENOMEM; | 880 | ret = -ENOMEM; |
857 | goto err_usb_driver_release_interface; | 881 | goto err_free_all; |
858 | } | 882 | } |
859 | } | 883 | } |
860 | 884 | ||
@@ -884,20 +908,12 @@ static void dvb_usbv2_init_work(struct work_struct *work) | |||
884 | * device. As 'new' device is warm we should | 908 | * device. As 'new' device is warm we should |
885 | * never go here again. | 909 | * never go here again. |
886 | */ | 910 | */ |
887 | return; | 911 | goto exit; |
888 | } else { | 912 | } else { |
889 | /* | 913 | goto err_free_all; |
890 | * Unexpected error. We must unregister driver | ||
891 | * manually from the device, because device is | ||
892 | * already register by returning from probe() | ||
893 | * with success. usb_driver_release_interface() | ||
894 | * finally calls disconnect() in order to free | ||
895 | * resources. | ||
896 | */ | ||
897 | goto err_usb_driver_release_interface; | ||
898 | } | 914 | } |
899 | } else { | 915 | } else { |
900 | goto err_usb_driver_release_interface; | 916 | goto err_free_all; |
901 | } | 917 | } |
902 | } | 918 | } |
903 | 919 | ||
@@ -906,73 +922,17 @@ static void dvb_usbv2_init_work(struct work_struct *work) | |||
906 | 922 | ||
907 | ret = dvb_usbv2_init(d); | 923 | ret = dvb_usbv2_init(d); |
908 | if (ret < 0) | 924 | if (ret < 0) |
909 | goto err_usb_driver_release_interface; | 925 | goto err_free_all; |
910 | 926 | ||
911 | dev_info(&d->udev->dev, | 927 | dev_info(&d->udev->dev, |
912 | "%s: '%s' successfully initialized and connected\n", | 928 | "%s: '%s' successfully initialized and connected\n", |
913 | KBUILD_MODNAME, d->name); | 929 | KBUILD_MODNAME, d->name); |
914 | 930 | exit: | |
915 | return; | ||
916 | err_usb_driver_release_interface: | ||
917 | dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n", | ||
918 | KBUILD_MODNAME, d->name, ret); | ||
919 | usb_driver_release_interface(to_usb_driver(d->intf->dev.driver), | ||
920 | d->intf); | ||
921 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | ||
922 | return; | ||
923 | } | ||
924 | |||
925 | int dvb_usbv2_probe(struct usb_interface *intf, | ||
926 | const struct usb_device_id *id) | ||
927 | { | ||
928 | int ret; | ||
929 | struct dvb_usb_device *d; | ||
930 | struct usb_device *udev = interface_to_usbdev(intf); | ||
931 | struct dvb_usb_driver_info *driver_info = | ||
932 | (struct dvb_usb_driver_info *) id->driver_info; | ||
933 | |||
934 | dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__, | ||
935 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
936 | |||
937 | if (!id->driver_info) { | ||
938 | dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME); | ||
939 | ret = -ENODEV; | ||
940 | goto err; | ||
941 | } | ||
942 | |||
943 | d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); | ||
944 | if (!d) { | ||
945 | dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); | ||
946 | ret = -ENOMEM; | ||
947 | goto err; | ||
948 | } | ||
949 | |||
950 | d->name = driver_info->name; | ||
951 | d->rc_map = driver_info->rc_map; | ||
952 | d->udev = udev; | ||
953 | d->intf = intf; | ||
954 | d->props = driver_info->props; | ||
955 | |||
956 | if (d->intf->cur_altsetting->desc.bInterfaceNumber != | ||
957 | d->props->bInterfaceNumber) { | ||
958 | ret = -ENODEV; | ||
959 | goto err_kfree; | ||
960 | } | ||
961 | |||
962 | mutex_init(&d->usb_mutex); | ||
963 | mutex_init(&d->i2c_mutex); | ||
964 | INIT_WORK(&d->probe_work, dvb_usbv2_init_work); | ||
965 | usb_set_intfdata(intf, d); | 931 | usb_set_intfdata(intf, d); |
966 | ret = schedule_work(&d->probe_work); | ||
967 | if (ret < 0) { | ||
968 | dev_err(&d->udev->dev, "%s: schedule_work() failed\n", | ||
969 | KBUILD_MODNAME); | ||
970 | goto err_kfree; | ||
971 | } | ||
972 | 932 | ||
973 | return 0; | 933 | return 0; |
974 | err_kfree: | 934 | err_free_all: |
975 | kfree(d); | 935 | dvb_usbv2_exit(d); |
976 | err: | 936 | err: |
977 | dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret); | 937 | dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret); |
978 | return ret; | 938 | return ret; |
@@ -984,12 +944,8 @@ void dvb_usbv2_disconnect(struct usb_interface *intf) | |||
984 | struct dvb_usb_device *d = usb_get_intfdata(intf); | 944 | struct dvb_usb_device *d = usb_get_intfdata(intf); |
985 | const char *name = d->name; | 945 | const char *name = d->name; |
986 | struct device dev = d->udev->dev; | 946 | struct device dev = d->udev->dev; |
987 | dev_dbg(&d->udev->dev, "%s: pid=%d work_pid=%d\n", __func__, | 947 | dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__, |
988 | current->pid, d->work_pid); | 948 | intf->cur_altsetting->desc.bInterfaceNumber); |
989 | |||
990 | /* ensure initialization work is finished until release resources */ | ||
991 | if (d->work_pid != current->pid) | ||
992 | cancel_work_sync(&d->probe_work); | ||
993 | 949 | ||
994 | if (d->props->exit) | 950 | if (d->props->exit) |
995 | d->props->exit(d); | 951 | d->props->exit(d); |