Loading drivers/usb/core/driver.c +63 −30 Original line number Diff line number Diff line Loading @@ -958,13 +958,8 @@ void usb_rebind_intf(struct usb_interface *intf) int rc; /* Delayed unbind of an existing driver */ if (intf->dev.driver) { struct usb_driver *driver = to_usb_driver(intf->dev.driver); dev_dbg(&intf->dev, "forced unbind\n"); usb_driver_release_interface(driver, intf); } if (intf->dev.driver) usb_forced_unbind_intf(intf); /* Try to rebind the interface */ if (!intf->dev.power.is_prepared) { Loading @@ -977,15 +972,13 @@ void usb_rebind_intf(struct usb_interface *intf) #ifdef CONFIG_PM #define DO_UNBIND 0 #define DO_REBIND 1 /* Unbind drivers for @udev's interfaces that don't support suspend/resume, * or rebind interfaces that have been unbound, according to @action. /* Unbind drivers for @udev's interfaces that don't support suspend/resume * There is no check for reset_resume here because it can be determined * only during resume whether reset_resume is needed. * * The caller must hold @udev's device lock. */ static void do_unbind_rebind(struct usb_device *udev, int action) static void unbind_no_pm_drivers_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; Loading @@ -996,19 +989,49 @@ static void do_unbind_rebind(struct usb_device *udev, int action) if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; switch (action) { case DO_UNBIND: if (intf->dev.driver) { drv = to_usb_driver(intf->dev.driver); if (!drv->suspend || !drv->resume) usb_forced_unbind_intf(intf); } break; case DO_REBIND: } } } /* Unbind drivers for @udev's interfaces that failed to support reset-resume. * These interfaces have the needs_binding flag set by usb_resume_interface(). * * The caller must hold @udev's device lock. */ static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; struct usb_interface *intf; config = udev->actconfig; if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; if (intf->dev.driver && intf->needs_binding) usb_forced_unbind_intf(intf); } } } static void do_rebind_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; struct usb_interface *intf; config = udev->actconfig; if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; if (intf->needs_binding) usb_rebind_intf(intf); break; } } } } Loading Loading @@ -1302,7 +1325,12 @@ int usb_suspend(struct device *dev, pm_message_t msg) { struct usb_device *udev = to_usb_device(dev); do_unbind_rebind(udev, DO_UNBIND); unbind_no_pm_drivers_interfaces(udev); /* From now on we are sure all drivers support suspend/resume * but not necessarily reset_resume() * so we may still need to unbind and rebind upon resume */ choose_wakeup(udev, msg); return usb_suspend_both(udev, msg); } Loading @@ -1313,15 +1341,20 @@ int usb_resume(struct device *dev, pm_message_t msg) struct usb_device *udev = to_usb_device(dev); int status; /* For PM complete calls, all we do is rebind interfaces */ /* For PM complete calls, all we do is rebind interfaces * whose needs_binding flag is set */ if (msg.event == PM_EVENT_ON) { if (udev->state != USB_STATE_NOTATTACHED) do_unbind_rebind(udev, DO_REBIND); do_rebind_interfaces(udev); status = 0; /* For all other calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. * Unbind the interfaces that will need rebinding later. * Unbind the interfaces that will need rebinding later, * because they fail to support reset_resume. * (This can't be done in usb_resume_interface() * above because it doesn't own the right set of locks.) */ } else { status = usb_resume_both(udev, msg); Loading @@ -1329,7 +1362,7 @@ int usb_resume(struct device *dev, pm_message_t msg) pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); do_unbind_rebind(udev, DO_REBIND); unbind_no_reset_resume_drivers_interfaces(udev); } } Loading Loading
drivers/usb/core/driver.c +63 −30 Original line number Diff line number Diff line Loading @@ -958,13 +958,8 @@ void usb_rebind_intf(struct usb_interface *intf) int rc; /* Delayed unbind of an existing driver */ if (intf->dev.driver) { struct usb_driver *driver = to_usb_driver(intf->dev.driver); dev_dbg(&intf->dev, "forced unbind\n"); usb_driver_release_interface(driver, intf); } if (intf->dev.driver) usb_forced_unbind_intf(intf); /* Try to rebind the interface */ if (!intf->dev.power.is_prepared) { Loading @@ -977,15 +972,13 @@ void usb_rebind_intf(struct usb_interface *intf) #ifdef CONFIG_PM #define DO_UNBIND 0 #define DO_REBIND 1 /* Unbind drivers for @udev's interfaces that don't support suspend/resume, * or rebind interfaces that have been unbound, according to @action. /* Unbind drivers for @udev's interfaces that don't support suspend/resume * There is no check for reset_resume here because it can be determined * only during resume whether reset_resume is needed. * * The caller must hold @udev's device lock. */ static void do_unbind_rebind(struct usb_device *udev, int action) static void unbind_no_pm_drivers_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; Loading @@ -996,19 +989,49 @@ static void do_unbind_rebind(struct usb_device *udev, int action) if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; switch (action) { case DO_UNBIND: if (intf->dev.driver) { drv = to_usb_driver(intf->dev.driver); if (!drv->suspend || !drv->resume) usb_forced_unbind_intf(intf); } break; case DO_REBIND: } } } /* Unbind drivers for @udev's interfaces that failed to support reset-resume. * These interfaces have the needs_binding flag set by usb_resume_interface(). * * The caller must hold @udev's device lock. */ static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; struct usb_interface *intf; config = udev->actconfig; if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; if (intf->dev.driver && intf->needs_binding) usb_forced_unbind_intf(intf); } } } static void do_rebind_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; struct usb_interface *intf; config = udev->actconfig; if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; if (intf->needs_binding) usb_rebind_intf(intf); break; } } } } Loading Loading @@ -1302,7 +1325,12 @@ int usb_suspend(struct device *dev, pm_message_t msg) { struct usb_device *udev = to_usb_device(dev); do_unbind_rebind(udev, DO_UNBIND); unbind_no_pm_drivers_interfaces(udev); /* From now on we are sure all drivers support suspend/resume * but not necessarily reset_resume() * so we may still need to unbind and rebind upon resume */ choose_wakeup(udev, msg); return usb_suspend_both(udev, msg); } Loading @@ -1313,15 +1341,20 @@ int usb_resume(struct device *dev, pm_message_t msg) struct usb_device *udev = to_usb_device(dev); int status; /* For PM complete calls, all we do is rebind interfaces */ /* For PM complete calls, all we do is rebind interfaces * whose needs_binding flag is set */ if (msg.event == PM_EVENT_ON) { if (udev->state != USB_STATE_NOTATTACHED) do_unbind_rebind(udev, DO_REBIND); do_rebind_interfaces(udev); status = 0; /* For all other calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. * Unbind the interfaces that will need rebinding later. * Unbind the interfaces that will need rebinding later, * because they fail to support reset_resume. * (This can't be done in usb_resume_interface() * above because it doesn't own the right set of locks.) */ } else { status = usb_resume_both(udev, msg); Loading @@ -1329,7 +1362,7 @@ int usb_resume(struct device *dev, pm_message_t msg) pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); do_unbind_rebind(udev, DO_REBIND); unbind_no_reset_resume_drivers_interfaces(udev); } } Loading