diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/driver.c | 30 |
1 files changed, 9 insertions, 21 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 2da70b4d33fe..5a7fa6f09958 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -814,7 +814,8 @@ void usb_forced_unbind_intf(struct usb_interface *intf) | |||
814 | * The caller must hold @intf's device's lock, but not its pm_mutex | 814 | * The caller must hold @intf's device's lock, but not its pm_mutex |
815 | * and not @intf->dev.sem. | 815 | * and not @intf->dev.sem. |
816 | * | 816 | * |
817 | * FIXME: The caller must block system sleep transitions. | 817 | * Note: Rebinds will be skipped if a system sleep transition is in |
818 | * progress and the PM "complete" callback hasn't occurred yet. | ||
818 | */ | 819 | */ |
819 | void usb_rebind_intf(struct usb_interface *intf) | 820 | void usb_rebind_intf(struct usb_interface *intf) |
820 | { | 821 | { |
@@ -830,10 +831,12 @@ void usb_rebind_intf(struct usb_interface *intf) | |||
830 | } | 831 | } |
831 | 832 | ||
832 | /* Try to rebind the interface */ | 833 | /* Try to rebind the interface */ |
833 | intf->needs_binding = 0; | 834 | if (intf->dev.power.status == DPM_ON) { |
834 | rc = device_attach(&intf->dev); | 835 | intf->needs_binding = 0; |
835 | if (rc < 0) | 836 | rc = device_attach(&intf->dev); |
836 | dev_warn(&intf->dev, "rebind failed: %d\n", rc); | 837 | if (rc < 0) |
838 | dev_warn(&intf->dev, "rebind failed: %d\n", rc); | ||
839 | } | ||
837 | } | 840 | } |
838 | 841 | ||
839 | #ifdef CONFIG_PM | 842 | #ifdef CONFIG_PM |
@@ -845,7 +848,6 @@ void usb_rebind_intf(struct usb_interface *intf) | |||
845 | * or rebind interfaces that have been unbound, according to @action. | 848 | * or rebind interfaces that have been unbound, according to @action. |
846 | * | 849 | * |
847 | * The caller must hold @udev's device lock. | 850 | * The caller must hold @udev's device lock. |
848 | * FIXME: For rebinds, the caller must block system sleep transitions. | ||
849 | */ | 851 | */ |
850 | static void do_unbind_rebind(struct usb_device *udev, int action) | 852 | static void do_unbind_rebind(struct usb_device *udev, int action) |
851 | { | 853 | { |
@@ -867,22 +869,8 @@ static void do_unbind_rebind(struct usb_device *udev, int action) | |||
867 | } | 869 | } |
868 | break; | 870 | break; |
869 | case DO_REBIND: | 871 | case DO_REBIND: |
870 | if (intf->needs_binding) { | 872 | if (intf->needs_binding) |
871 | |||
872 | /* FIXME: The next line is needed because we are going to probe | ||
873 | * the interface, but as far as the PM core is concerned the | ||
874 | * interface is still suspended. The problem wouldn't exist | ||
875 | * if we could rebind the interface during the interface's own | ||
876 | * resume() call, but at the time the usb_device isn't locked! | ||
877 | * | ||
878 | * The real solution will be to carry this out during the device's | ||
879 | * complete() callback. Until that is implemented, we have to | ||
880 | * use this hack. | ||
881 | */ | ||
882 | // intf->dev.power.sleeping = 0; | ||
883 | |||
884 | usb_rebind_intf(intf); | 873 | usb_rebind_intf(intf); |
885 | } | ||
886 | break; | 874 | break; |
887 | } | 875 | } |
888 | } | 876 | } |