>From 186ed6425f31636d1bb52de0f48a76dddf8e6224 Mon Sep 17 00:00:00 2001 From: Oliver Neukum <oliver@xxxxxxxxxx> Date: Tue, 3 Jan 2012 12:34:31 +0100 Subject: [PATCH] USB: code cleanup in suspend/resume path Do the cleanup to avoid behaviorial parameters Linus requested. Signed-off-by: Oliver Neukum <oneukum@xxxxxxx> --- drivers/usb/core/driver.c | 54 ++++++++++++++++++++++++++++---------------- 1 files changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 07f8718..9d708c3 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -974,12 +974,11 @@ void usb_rebind_intf(struct usb_interface *intf) #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 * * The caller must hold @udev's device lock. */ -static void do_unbind_rebind(struct usb_device *udev, int action) +static void kick_unsupportive_drivers_from_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; @@ -990,23 +989,32 @@ 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: - if (intf->needs_binding) - usb_rebind_intf(intf); - break; + + if (intf->dev.driver) { + drv = to_usb_driver(intf->dev.driver); + if (!drv->suspend || !drv->resume) + usb_forced_unbind_intf(intf); } } } } +static void do_rebind(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); + } + } +} + static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) { struct usb_device_driver *udriver; @@ -1296,7 +1304,11 @@ int usb_suspend(struct device *dev, pm_message_t msg) { struct usb_device *udev = to_usb_device(dev); - do_unbind_rebind(udev, DO_UNBIND); + kick_unsupportive_drivers_from_interfaces(udev); + /* From now on we are sure all drivers support suspend/resume + * but not necessarily reset_resume() + * so we may still need to rebind upon resumption + */ choose_wakeup(udev, msg); return usb_suspend_both(udev, msg); } @@ -1307,15 +1319,17 @@ 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 + * if the need has arisen earlier + */ if (msg.event == PM_EVENT_ON) { if (udev->state != USB_STATE_NOTATTACHED) - do_unbind_rebind(udev, DO_REBIND); + do_rebind(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. + * Rebind the interfaces that need it. */ } else { status = usb_resume_both(udev, msg); @@ -1323,7 +1337,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); + do_rebind(udev); } } -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html