X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fusb%2Fcore%2Fdriver.c;h=2f3dc4cdf79bc12d2bc2cafbfa3ec7ecc43292ee;hb=571dc79d62a163fd043de47d7d39bae58831e81e;hp=ed1cc8530a93d6759229a65e5586a1720306a5ed;hpb=65605ae8e587d714f73e674369bc4cd5a1e53a9b;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ed1cc85..2f3dc4c 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -23,9 +23,10 @@ */ #include +#include #include #include -#include +#include #include "hcd.h" #include "usb.h" @@ -83,6 +84,47 @@ static ssize_t store_new_id(struct device_driver *driver, } static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); +/** + * store_remove_id - remove a USB device ID from this driver + * @driver: target device driver + * @buf: buffer for scanning device ID data + * @count: input size + * + * Removes a dynamic usb device ID from this driver. + */ +static ssize_t +store_remove_id(struct device_driver *driver, const char *buf, size_t count) +{ + struct usb_dynid *dynid, *n; + struct usb_driver *usb_driver = to_usb_driver(driver); + u32 idVendor = 0; + u32 idProduct = 0; + int fields = 0; + int retval = 0; + + fields = sscanf(buf, "%x %x", &idVendor, &idProduct); + if (fields < 2) + return -EINVAL; + + spin_lock(&usb_driver->dynids.lock); + list_for_each_entry_safe(dynid, n, &usb_driver->dynids.list, node) { + struct usb_device_id *id = &dynid->id; + if ((id->idVendor == idVendor) && + (id->idProduct == idProduct)) { + list_del(&dynid->node); + kfree(dynid); + retval = 0; + break; + } + } + spin_unlock(&usb_driver->dynids.lock); + + if (retval) + return retval; + return count; +} +static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); + static int usb_create_newid_file(struct usb_driver *usb_drv) { int error = 0; @@ -107,6 +149,21 @@ static void usb_remove_newid_file(struct usb_driver *usb_drv) &driver_attr_new_id); } +static int +usb_create_removeid_file(struct usb_driver *drv) +{ + int error = 0; + if (drv->probe != NULL) + error = driver_create_file(&drv->drvwrap.driver, + &driver_attr_remove_id); + return error; +} + +static void usb_remove_removeid_file(struct usb_driver *drv) +{ + driver_remove_file(&drv->drvwrap.driver, &driver_attr_remove_id); +} + static void usb_free_dynids(struct usb_driver *usb_drv) { struct usb_dynid *dynid, *n; @@ -128,6 +185,16 @@ static void usb_remove_newid_file(struct usb_driver *usb_drv) { } +static int +usb_create_removeid_file(struct usb_driver *drv) +{ + return 0; +} + +static void usb_remove_removeid_file(struct usb_driver *drv) +{ +} + static inline void usb_free_dynids(struct usb_driver *usb_drv) { } @@ -154,93 +221,122 @@ static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *in static int usb_probe_device(struct device *dev) { struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); - struct usb_device *udev; - int error = -ENODEV; + struct usb_device *udev = to_usb_device(dev); + int error = 0; dev_dbg(dev, "%s\n", __func__); - if (!is_usb_device(dev)) /* Sanity check */ - return error; - - udev = to_usb_device(dev); - /* TODO: Add real matching code */ /* The device should always appear to be in use * unless the driver suports autosuspend. */ - udev->pm_usage_cnt = !(udriver->supports_autosuspend); + if (!udriver->supports_autosuspend) + error = usb_autoresume_device(udev); - error = udriver->probe(udev); + if (!error) + error = udriver->probe(udev); return error; } /* called from driver core with dev locked */ static int usb_unbind_device(struct device *dev) { + struct usb_device *udev = to_usb_device(dev); struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); - udriver->disconnect(to_usb_device(dev)); + udriver->disconnect(udev); + if (!udriver->supports_autosuspend) + usb_autosuspend_device(udev); return 0; } +/* + * Cancel any pending scheduled resets + * + * [see usb_queue_reset_device()] + * + * Called after unconfiguring / when releasing interfaces. See + * comments in __usb_queue_reset_device() regarding + * udev->reset_running. + */ +static void usb_cancel_queued_reset(struct usb_interface *iface) +{ + if (iface->reset_running == 0) + cancel_work_sync(&iface->reset_ws); +} /* called from driver core with dev locked */ static int usb_probe_interface(struct device *dev) { struct usb_driver *driver = to_usb_driver(dev->driver); - struct usb_interface *intf; - struct usb_device *udev; + struct usb_interface *intf = to_usb_interface(dev); + struct usb_device *udev = interface_to_usbdev(intf); const struct usb_device_id *id; int error = -ENODEV; dev_dbg(dev, "%s\n", __func__); - if (is_usb_device(dev)) /* Sanity check */ - return error; - - intf = to_usb_interface(dev); - udev = interface_to_usbdev(intf); intf->needs_binding = 0; + if (usb_device_is_owned(udev)) + return error; + if (udev->authorized == 0) { dev_err(&intf->dev, "Device is not authorized for usage\n"); - return -ENODEV; + return error; } id = usb_match_id(intf, driver->id_table); if (!id) id = usb_match_dynamic_id(intf, driver); - if (id) { - dev_dbg(dev, "%s - got id\n", __func__); - - error = usb_autoresume_device(udev); - if (error) - return error; + if (!id) + return error; - /* Interface "power state" doesn't correspond to any hardware - * state whatsoever. We use it to record when it's bound to - * a driver that may start I/0: it's not frozen/quiesced. - */ - mark_active(intf); - intf->condition = USB_INTERFACE_BINDING; + dev_dbg(dev, "%s - got id\n", __func__); - /* The interface should always appear to be in use - * unless the driver suports autosuspend. - */ - intf->pm_usage_cnt = !(driver->supports_autosuspend); + error = usb_autoresume_device(udev); + if (error) + return error; - error = driver->probe(intf, id); - if (error) { - mark_quiesced(intf); - intf->needs_remote_wakeup = 0; - intf->condition = USB_INTERFACE_UNBOUND; - } else - intf->condition = USB_INTERFACE_BOUND; + intf->condition = USB_INTERFACE_BINDING; - usb_autosuspend_device(udev); + /* Probed interfaces are initially active. They are + * runtime-PM-enabled only if the driver has autosuspend support. + * They are sensitive to their children's power states. + */ + pm_runtime_set_active(dev); + pm_suspend_ignore_children(dev, false); + if (driver->supports_autosuspend) + pm_runtime_enable(dev); + + /* Carry out a deferred switch to altsetting 0 */ + if (intf->needs_altsetting0) { + error = usb_set_interface(udev, intf->altsetting[0]. + desc.bInterfaceNumber, 0); + if (error < 0) + goto err; + intf->needs_altsetting0 = 0; } + error = driver->probe(intf, id); + if (error) + goto err; + + intf->condition = USB_INTERFACE_BOUND; + usb_autosuspend_device(udev); + return error; + + err: + intf->needs_remote_wakeup = 0; + intf->condition = USB_INTERFACE_UNBOUND; + usb_cancel_queued_reset(intf); + + /* Unbound interfaces are always runtime-PM-disabled and -suspended */ + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + + usb_autosuspend_device(udev); return error; } @@ -250,7 +346,7 @@ static int usb_unbind_interface(struct device *dev) struct usb_driver *driver = to_usb_driver(dev->driver); struct usb_interface *intf = to_usb_interface(dev); struct usb_device *udev; - int error; + int error, r; intf->condition = USB_INTERFACE_UNBINDING; @@ -262,18 +358,44 @@ static int usb_unbind_interface(struct device *dev) * supports "soft" unbinding. */ if (!driver->soft_unbind) - usb_disable_interface(udev, intf); + usb_disable_interface(udev, intf, false); driver->disconnect(intf); + usb_cancel_queued_reset(intf); - /* reset other interface state */ - usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0); + /* Reset other interface state. + * We cannot do a Set-Interface if the device is suspended or + * if it is prepared for a system sleep (since installing a new + * altsetting means creating new endpoint device entries). + * When either of these happens, defer the Set-Interface. + */ + if (intf->cur_altsetting->desc.bAlternateSetting == 0) { + /* Already in altsetting 0 so skip Set-Interface. + * Just re-enable it without affecting the endpoint toggles. + */ + usb_enable_interface(udev, intf, false); + } else if (!error && intf->dev.power.status == DPM_ON) { + r = usb_set_interface(udev, intf->altsetting[0]. + desc.bInterfaceNumber, 0); + if (r < 0) + intf->needs_altsetting0 = 1; + } else { + intf->needs_altsetting0 = 1; + } usb_set_intfdata(intf, NULL); intf->condition = USB_INTERFACE_UNBOUND; - mark_quiesced(intf); intf->needs_remote_wakeup = 0; + /* Unbound interfaces are always runtime-PM-disabled and -suspended */ + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + + /* Undo any residual pm_autopm_get_interface_* calls */ + for (r = atomic_read(&intf->pm_usage_cnt); r > 0; --r) + usb_autopm_put_interface_no_suspend(intf); + atomic_set(&intf->pm_usage_cnt, 0); + if (!error) usb_autosuspend_device(udev); @@ -304,7 +426,6 @@ int usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void *priv) { struct device *dev = &iface->dev; - struct usb_device *udev = interface_to_usbdev(iface); int retval = 0; if (dev->driver) @@ -314,11 +435,16 @@ int usb_driver_claim_interface(struct usb_driver *driver, usb_set_intfdata(iface, priv); iface->needs_binding = 0; - usb_pm_lock(udev); iface->condition = USB_INTERFACE_BOUND; - mark_active(iface); - iface->pm_usage_cnt = !(driver->supports_autosuspend); - usb_pm_unlock(udev); + + /* Claimed interfaces are initially inactive (suspended). They are + * runtime-PM-enabled only if the driver has autosuspend support. + * They are sensitive to their children's power states. + */ + pm_runtime_set_suspended(dev); + pm_suspend_ignore_children(dev, false); + if (driver->supports_autosuspend) + pm_runtime_enable(dev); /* if interface was already added, bind now; else let * the future device_add() bind it, bypassing probe() @@ -348,7 +474,6 @@ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface) { struct device *dev = &iface->dev; - struct usb_device *udev = interface_to_usbdev(iface); /* this should never happen, don't release something that's not ours */ if (!dev->driver || dev->driver != &driver->drvwrap.driver) @@ -357,21 +482,19 @@ void usb_driver_release_interface(struct usb_driver *driver, /* don't release from within disconnect() */ if (iface->condition != USB_INTERFACE_BOUND) return; + iface->condition = USB_INTERFACE_UNBINDING; - /* don't release if the interface hasn't been added yet */ + /* Release via the driver core only if the interface + * has already been registered + */ if (device_is_registered(dev)) { - iface->condition = USB_INTERFACE_UNBINDING; device_release_driver(dev); + } else { + device_lock(dev); + usb_unbind_interface(dev); + dev->driver = NULL; + device_unlock(dev); } - - dev->driver = NULL; - usb_set_intfdata(iface, NULL); - - usb_pm_lock(udev); - iface->condition = USB_INTERFACE_UNBOUND; - mark_quiesced(iface); - iface->needs_remote_wakeup = 0; - usb_pm_unlock(udev); } EXPORT_SYMBOL_GPL(usb_driver_release_interface); @@ -559,7 +682,7 @@ static int usb_device_match(struct device *dev, struct device_driver *drv) /* TODO: Add real matching code */ return 1; - } else { + } else if (is_usb_interface(dev)) { struct usb_interface *intf; struct usb_driver *usb_drv; const struct usb_device_id *id; @@ -588,17 +711,18 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; - /* driver is often null here; dev_dbg() would oops */ - pr_debug("usb %s: uevent\n", dev_name(dev)); - - if (is_usb_device(dev)) + if (is_usb_device(dev)) { usb_dev = to_usb_device(dev); - else { + } else if (is_usb_interface(dev)) { struct usb_interface *intf = to_usb_interface(dev); + usb_dev = interface_to_usbdev(intf); + } else { + return 0; } if (usb_dev->devnum < 0) { + /* driver is often null here; dev_dbg() would oops */ pr_debug("usb %s: already deleted?\n", dev_name(dev)); return -ENODEV; } @@ -734,19 +858,34 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, INIT_LIST_HEAD(&new_driver->dynids.list); retval = driver_register(&new_driver->drvwrap.driver); + if (retval) + goto out; - if (!retval) { - pr_info("%s: registered new interface driver %s\n", + usbfs_update_special(); + + retval = usb_create_newid_file(new_driver); + if (retval) + goto out_newid; + + retval = usb_create_removeid_file(new_driver); + if (retval) + goto out_removeid; + + pr_info("%s: registered new interface driver %s\n", usbcore_name, new_driver->name); - usbfs_update_special(); - usb_create_newid_file(new_driver); - } else { - printk(KERN_ERR "%s: error %d registering interface " - " driver %s\n", - usbcore_name, retval, new_driver->name); - } +out: return retval; + +out_removeid: + usb_remove_newid_file(new_driver); +out_newid: + driver_unregister(&new_driver->drvwrap.driver); + + printk(KERN_ERR "%s: error %d registering interface " + " driver %s\n", + usbcore_name, retval, new_driver->name); + goto out; } EXPORT_SYMBOL_GPL(usb_register_driver); @@ -766,6 +905,7 @@ void usb_deregister(struct usb_driver *driver) pr_info("%s: deregistering interface driver %s\n", usbcore_name, driver->name); + usb_remove_removeid_file(driver); usb_remove_newid_file(driver); usb_free_dynids(driver); driver_unregister(&driver->drvwrap.driver); @@ -798,7 +938,8 @@ void usb_forced_unbind_intf(struct usb_interface *intf) * The caller must hold @intf's device's lock, but not its pm_mutex * and not @intf->dev.sem. * - * FIXME: The caller must block system sleep transitions. + * Note: Rebinds will be skipped if a system sleep transition is in + * progress and the PM "complete" callback hasn't occurred yet. */ void usb_rebind_intf(struct usb_interface *intf) { @@ -814,10 +955,12 @@ void usb_rebind_intf(struct usb_interface *intf) } /* Try to rebind the interface */ - intf->needs_binding = 0; - rc = device_attach(&intf->dev); - if (rc < 0) - dev_warn(&intf->dev, "rebind failed: %d\n", rc); + if (intf->dev.power.status == DPM_ON) { + intf->needs_binding = 0; + rc = device_attach(&intf->dev); + if (rc < 0) + dev_warn(&intf->dev, "rebind failed: %d\n", rc); + } } #ifdef CONFIG_PM @@ -829,7 +972,6 @@ void usb_rebind_intf(struct usb_interface *intf) * or rebind interfaces that have been unbound, according to @action. * * The caller must hold @udev's device lock. - * FIXME: For rebinds, the caller must block system sleep transitions. */ static void do_unbind_rebind(struct usb_device *udev, int action) { @@ -851,29 +993,14 @@ static void do_unbind_rebind(struct usb_device *udev, int action) } break; case DO_REBIND: - if (intf->needs_binding) { - - /* FIXME: The next line is needed because we are going to probe - * the interface, but as far as the PM core is concerned the - * interface is still suspended. The problem wouldn't exist - * if we could rebind the interface during the interface's own - * resume() call, but at the time the usb_device isn't locked! - * - * The real solution will be to carry this out during the device's - * complete() callback. Until that is implemented, we have to - * use this hack. - */ -// intf->dev.power.sleeping = 0; - + if (intf->needs_binding) usb_rebind_intf(intf); - } break; } } } } -/* Caller has locked udev's pm_mutex */ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) { struct usb_device_driver *udriver; @@ -897,8 +1024,7 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) return status; } -/* Caller has locked udev's pm_mutex */ -static int usb_resume_device(struct usb_device *udev) +static int usb_resume_device(struct usb_device *udev, pm_message_t msg) { struct usb_device_driver *udriver; int status = 0; @@ -912,39 +1038,39 @@ static int usb_resume_device(struct usb_device *udev) goto done; } + /* Non-root devices on a full/low-speed bus must wait for their + * companion high-speed root hub, in case a handoff is needed. + */ + if (!(msg.event & PM_EVENT_AUTO) && udev->parent && + udev->bus->hs_companion) + device_pm_wait_for_dev(&udev->dev, + &udev->bus->hs_companion->root_hub->dev); + if (udev->quirks & USB_QUIRK_RESET_RESUME) udev->reset_resume = 1; udriver = to_usb_device_driver(udev->dev.driver); - status = udriver->resume(udev); + status = udriver->resume(udev, msg); done: dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); - if (status == 0) - udev->autoresume_disabled = 0; return status; } -/* Caller has locked intf's usb_device's pm mutex */ static int usb_suspend_interface(struct usb_device *udev, struct usb_interface *intf, pm_message_t msg) { struct usb_driver *driver; int status = 0; - /* with no hardware, USB interfaces only use FREEZE and ON states */ - if (udev->state == USB_STATE_NOTATTACHED || !is_active(intf)) - goto done; - - if (intf->condition == USB_INTERFACE_UNBOUND) /* This can't happen */ + if (udev->state == USB_STATE_NOTATTACHED || + intf->condition == USB_INTERFACE_UNBOUND) goto done; driver = to_usb_driver(intf->dev.driver); if (driver->suspend) { status = driver->suspend(intf, msg); - if (status == 0) - mark_quiesced(intf); - else if (!udev->auto_pm) + if (status && !(msg.event & PM_EVENT_AUTO)) dev_err(&intf->dev, "%s error %d\n", "suspend", status); } else { @@ -952,7 +1078,6 @@ static int usb_suspend_interface(struct usb_device *udev, intf->needs_binding = 1; dev_warn(&intf->dev, "no %s for driver %s?\n", "suspend", driver->name); - mark_quiesced(intf); } done: @@ -960,14 +1085,13 @@ static int usb_suspend_interface(struct usb_device *udev, return status; } -/* Caller has locked intf's usb_device's pm_mutex */ static int usb_resume_interface(struct usb_device *udev, - struct usb_interface *intf, int reset_resume) + struct usb_interface *intf, pm_message_t msg, int reset_resume) { struct usb_driver *driver; int status = 0; - if (udev->state == USB_STATE_NOTATTACHED || is_active(intf)) + if (udev->state == USB_STATE_NOTATTACHED) goto done; /* Don't let autoresume interfere with unbinding */ @@ -975,8 +1099,17 @@ static int usb_resume_interface(struct usb_device *udev, goto done; /* Can't resume it if it doesn't have a driver. */ - if (intf->condition == USB_INTERFACE_UNBOUND) + if (intf->condition == USB_INTERFACE_UNBOUND) { + + /* Carry out a deferred switch to altsetting 0 */ + if (intf->needs_altsetting0 && + intf->dev.power.status == DPM_ON) { + usb_set_interface(udev, intf->altsetting[0]. + desc.bInterfaceNumber, 0); + intf->needs_altsetting0 = 0; + } goto done; + } /* Don't resume if the interface is marked for rebinding */ if (intf->needs_binding) @@ -1009,89 +1142,11 @@ static int usb_resume_interface(struct usb_device *udev, done: dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); - if (status == 0 && intf->condition == USB_INTERFACE_BOUND) - mark_active(intf); /* Later we will unbind the driver and/or reprobe, if necessary */ return status; } -#ifdef CONFIG_USB_SUSPEND - -/* Internal routine to check whether we may autosuspend a device. */ -static int autosuspend_check(struct usb_device *udev, int reschedule) -{ - int i; - struct usb_interface *intf; - unsigned long suspend_time, j; - - /* For autosuspend, fail fast if anything is in use or autosuspend - * is disabled. Also fail if any interfaces require remote wakeup - * but it isn't available. - */ - if (udev->pm_usage_cnt > 0) - return -EBUSY; - if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled) - return -EPERM; - - suspend_time = udev->last_busy + udev->autosuspend_delay; - if (udev->actconfig) { - for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { - intf = udev->actconfig->interface[i]; - if (!is_active(intf)) - continue; - if (intf->pm_usage_cnt > 0) - return -EBUSY; - if (intf->needs_remote_wakeup && - !udev->do_remote_wakeup) { - dev_dbg(&udev->dev, "remote wakeup needed " - "for autosuspend\n"); - return -EOPNOTSUPP; - } - - /* Don't allow autosuspend if the device will need - * a reset-resume and any of its interface drivers - * doesn't include support. - */ - if (udev->quirks & USB_QUIRK_RESET_RESUME) { - struct usb_driver *driver; - - driver = to_usb_driver(intf->dev.driver); - if (!driver->reset_resume) - return -EOPNOTSUPP; - } - } - } - - /* If everything is okay but the device hasn't been idle for long - * enough, queue a delayed autosuspend request. If the device - * _has_ been idle for long enough and the reschedule flag is set, - * likewise queue a delayed (1 second) autosuspend request. - */ - j = jiffies; - if (time_before(j, suspend_time)) - reschedule = 1; - else - suspend_time = j + HZ; - if (reschedule) { - if (!timer_pending(&udev->autosuspend.timer)) { - queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, - round_jiffies_relative(suspend_time - j)); - } - return -EAGAIN; - } - return 0; -} - -#else - -static inline int autosuspend_check(struct usb_device *udev, int reschedule) -{ - return 0; -} - -#endif /* CONFIG_USB_SUSPEND */ - /** * usb_suspend_both - suspend a USB device and its interfaces * @udev: the usb_device to suspend @@ -1103,53 +1158,29 @@ static inline int autosuspend_check(struct usb_device *udev, int reschedule) * all the interfaces which were suspended are resumed so that they remain * in the same state as the device. * - * If an autosuspend is in progress (@udev->auto_pm is set), the routine - * checks first to make sure that neither the device itself or any of its - * active interfaces is in use (pm_usage_cnt is greater than 0). If they - * are, the autosuspend fails. - * - * If the suspend succeeds, the routine recursively queues an autosuspend - * request for @udev's parent device, thereby propagating the change up - * the device tree. If all of the parent's children are now suspended, - * the parent will autosuspend in turn. - * - * The suspend method calls are subject to mutual exclusion under control - * of @udev's pm_mutex. Many of these calls are also under the protection - * of @udev's device lock (including all requests originating outside the - * USB subsystem), but autosuspend requests generated by a child device or - * interface driver may not be. Usbcore will insure that the method calls - * do not arrive during bind, unbind, or reset operations. However, drivers - * must be prepared to handle suspend calls arriving at unpredictable times. - * The only way to block such calls is to do an autoresume (preventing - * autosuspends) while holding @udev's device lock (preventing outside - * suspends). - * - * The caller must hold @udev->pm_mutex. + * Autosuspend requests originating from a child device or an interface + * driver may be made without the protection of @udev's device lock, but + * all other suspend calls will hold the lock. Usbcore will insure that + * method calls do not arrive during bind, unbind, or reset operations. + * However drivers must be prepared to handle suspend calls arriving at + * unpredictable times. * * This routine can run only in process context. */ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) { int status = 0; - int i = 0; + int i = 0, n = 0; struct usb_interface *intf; - struct usb_device *parent = udev->parent; if (udev->state == USB_STATE_NOTATTACHED || udev->state == USB_STATE_SUSPENDED) goto done; - udev->do_remote_wakeup = device_may_wakeup(&udev->dev); - - if (udev->auto_pm) { - status = autosuspend_check(udev, 0); - if (status < 0) - goto done; - } - /* Suspend all the interfaces and then udev itself */ if (udev->actconfig) { - for (; i < udev->actconfig->desc.bNumInterfaces; i++) { + n = udev->actconfig->desc.bNumInterfaces; + for (i = n - 1; i >= 0; --i) { intf = udev->actconfig->interface[i]; status = usb_suspend_interface(udev, intf, msg); if (status != 0) @@ -1161,32 +1192,21 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) /* If the suspend failed, resume interfaces that did get suspended */ if (status != 0) { - while (--i >= 0) { + msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); + while (++i < n) { intf = udev->actconfig->interface[i]; - usb_resume_interface(udev, intf, 0); + usb_resume_interface(udev, intf, msg, 0); } - /* Try another autosuspend when the interfaces aren't busy */ - if (udev->auto_pm) - autosuspend_check(udev, status == -EBUSY); - - /* If the suspend succeeded then prevent any more URB submissions, - * flush any outstanding URBs, and propagate the suspend up the tree. + /* If the suspend succeeded then prevent any more URB submissions + * and flush any outstanding URBs. */ } else { - cancel_delayed_work(&udev->autosuspend); udev->can_submit = 0; for (i = 0; i < 16; ++i) { usb_hcd_flush_endpoint(udev, udev->ep_out[i]); usb_hcd_flush_endpoint(udev, udev->ep_in[i]); } - - /* If this is just a FREEZE or a PRETHAW, udev might - * not really be suspended. Only true suspends get - * propagated up the device tree. - */ - if (parent && udev->state == USB_STATE_SUSPENDED) - usb_autosuspend_device(parent); } done: @@ -1197,86 +1217,43 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) /** * usb_resume_both - resume a USB device and its interfaces * @udev: the usb_device to resume + * @msg: Power Management message describing this state transition * * This is the central routine for resuming USB devices. It calls the * the resume method for @udev and then calls the resume methods for all * the interface drivers in @udev. * - * Before starting the resume, the routine calls itself recursively for - * the parent device of @udev, thereby propagating the change up the device - * tree and assuring that @udev will be able to resume. If the parent is - * unable to resume successfully, the routine fails. - * - * The resume method calls are subject to mutual exclusion under control - * of @udev's pm_mutex. Many of these calls are also under the protection - * of @udev's device lock (including all requests originating outside the - * USB subsystem), but autoresume requests generated by a child device or - * interface driver may not be. Usbcore will insure that the method calls - * do not arrive during bind, unbind, or reset operations. However, drivers - * must be prepared to handle resume calls arriving at unpredictable times. - * The only way to block such calls is to do an autoresume (preventing - * other autoresumes) while holding @udev's device lock (preventing outside - * resumes). - * - * The caller must hold @udev->pm_mutex. + * Autoresume requests originating from a child device or an interface + * driver may be made without the protection of @udev's device lock, but + * all other resume calls will hold the lock. Usbcore will insure that + * method calls do not arrive during bind, unbind, or reset operations. + * However drivers must be prepared to handle resume calls arriving at + * unpredictable times. * * This routine can run only in process context. */ -static int usb_resume_both(struct usb_device *udev) +static int usb_resume_both(struct usb_device *udev, pm_message_t msg) { int status = 0; int i; struct usb_interface *intf; - struct usb_device *parent = udev->parent; - cancel_delayed_work(&udev->autosuspend); if (udev->state == USB_STATE_NOTATTACHED) { status = -ENODEV; goto done; } udev->can_submit = 1; - /* Propagate the resume up the tree, if necessary */ - if (udev->state == USB_STATE_SUSPENDED) { - if (udev->auto_pm && udev->autoresume_disabled) { - status = -EPERM; - goto done; - } - if (parent) { - status = usb_autoresume_device(parent); - if (status == 0) { - status = usb_resume_device(udev); - if (status || udev->state == - USB_STATE_NOTATTACHED) { - usb_autosuspend_device(parent); - - /* It's possible usb_resume_device() - * failed after the port was - * unsuspended, causing udev to be - * logically disconnected. We don't - * want usb_disconnect() to autosuspend - * the parent again, so tell it that - * udev disconnected while still - * suspended. */ - if (udev->state == - USB_STATE_NOTATTACHED) - udev->discon_suspended = 1; - } - } - } else { - - /* We can't progagate beyond the USB subsystem, - * so if a root hub's controller is suspended - * then we're stuck. */ - status = usb_resume_device(udev); - } - } else if (udev->reset_resume) - status = usb_resume_device(udev); + /* Resume the device */ + if (udev->state == USB_STATE_SUSPENDED || udev->reset_resume) + status = usb_resume_device(udev, msg); + /* Resume the interfaces */ if (status == 0 && udev->actconfig) { for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { intf = udev->actconfig->interface[i]; - usb_resume_interface(udev, intf, udev->reset_resume); + usb_resume_interface(udev, intf, msg, + udev->reset_resume); } } @@ -1287,43 +1264,128 @@ static int usb_resume_both(struct usb_device *udev) return status; } -#ifdef CONFIG_USB_SUSPEND +static void choose_wakeup(struct usb_device *udev, pm_message_t msg) +{ + int w, i; + struct usb_interface *intf; -/* Internal routine to adjust a device's usage counter and change - * its autosuspend state. - */ -static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) + /* Remote wakeup is needed only when we actually go to sleep. + * For things like FREEZE and QUIESCE, if the device is already + * autosuspended then its current wakeup setting is okay. + */ + if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) { + if (udev->state != USB_STATE_SUSPENDED) + udev->do_remote_wakeup = 0; + return; + } + + /* If remote wakeup is permitted, see whether any interface drivers + * actually want it. + */ + w = 0; + if (device_may_wakeup(&udev->dev) && udev->actconfig) { + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + intf = udev->actconfig->interface[i]; + w |= intf->needs_remote_wakeup; + } + } + + /* If the device is autosuspended with the wrong wakeup setting, + * autoresume now so the setting can be changed. + */ + if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup) + pm_runtime_resume(&udev->dev); + udev->do_remote_wakeup = w; +} + +/* The device lock is held by the PM core */ +int usb_suspend(struct device *dev, pm_message_t msg) { - int status = 0; + struct usb_device *udev = to_usb_device(dev); - usb_pm_lock(udev); - udev->auto_pm = 1; - udev->pm_usage_cnt += inc_usage_cnt; - WARN_ON(udev->pm_usage_cnt < 0); - if (inc_usage_cnt) - udev->last_busy = jiffies; - if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { - if (udev->state == USB_STATE_SUSPENDED) - status = usb_resume_both(udev); - if (status != 0) - udev->pm_usage_cnt -= inc_usage_cnt; - else if (inc_usage_cnt) + do_unbind_rebind(udev, DO_UNBIND); + choose_wakeup(udev, msg); + return usb_suspend_both(udev, msg); +} + +/* The device lock is held by the PM core */ +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 */ + if (msg.event == PM_EVENT_ON) { + if (udev->state != USB_STATE_NOTATTACHED) + do_unbind_rebind(udev, DO_REBIND); + status = 0; + + /* For all other calls, take the device back to full power and + * tell the PM core in case it was autosuspended previously. + */ + } else { + status = usb_resume_both(udev, msg); + if (status == 0) { + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); udev->last_busy = jiffies; - } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { - status = usb_suspend_both(udev, PMSG_SUSPEND); + } } - usb_pm_unlock(udev); + + /* Avoid PM error messages for devices disconnected while suspended + * as we'll display regular disconnect messages just a bit later. + */ + if (status == -ENODEV) + status = 0; return status; } -/* usb_autosuspend_work - callback routine to autosuspend a USB device */ -void usb_autosuspend_work(struct work_struct *work) +#endif /* CONFIG_PM */ + +#ifdef CONFIG_USB_SUSPEND + +/** + * usb_enable_autosuspend - allow a USB device to be autosuspended + * @udev: the USB device which may be autosuspended + * + * This routine allows @udev to be autosuspended. An autosuspend won't + * take place until the autosuspend_delay has elapsed and all the other + * necessary conditions are satisfied. + * + * The caller must hold @udev's device lock. + */ +int usb_enable_autosuspend(struct usb_device *udev) { - struct usb_device *udev = - container_of(work, struct usb_device, autosuspend.work); + if (udev->autosuspend_disabled) { + udev->autosuspend_disabled = 0; + usb_autosuspend_device(udev); + } + return 0; +} +EXPORT_SYMBOL_GPL(usb_enable_autosuspend); - usb_autopm_do_device(udev, 0); +/** + * usb_disable_autosuspend - prevent a USB device from being autosuspended + * @udev: the USB device which may not be autosuspended + * + * This routine prevents @udev from being autosuspended and wakes it up + * if it is already autosuspended. + * + * The caller must hold @udev's device lock. + */ +int usb_disable_autosuspend(struct usb_device *udev) +{ + int rc = 0; + + if (!udev->autosuspend_disabled) { + rc = usb_autoresume_device(udev); + if (rc == 0) + udev->autosuspend_disabled = 1; + } + return rc; } +EXPORT_SYMBOL_GPL(usb_disable_autosuspend); /** * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces @@ -1333,15 +1395,11 @@ void usb_autosuspend_work(struct work_struct *work) * @udev and wants to allow it to autosuspend. Examples would be when * @udev's device file in usbfs is closed or after a configuration change. * - * @udev's usage counter is decremented. If it or any of the usage counters - * for an active interface is greater than 0, no autosuspend request will be - * queued. (If an interface driver does not support autosuspend then its - * usage counter is permanently positive.) Furthermore, if an interface - * driver requires remote-wakeup capability during autosuspend but remote - * wakeup is disabled, the autosuspend will fail. + * @udev's usage counter is decremented; if it drops to 0 and all the + * interfaces are inactive then a delayed autosuspend will be attempted. + * The attempt may fail (see autosuspend_check()). * - * Often the caller will hold @udev's device lock, but this is not - * necessary. + * The caller must hold @udev's device lock. * * This routine can run only in process context. */ @@ -1349,9 +1407,11 @@ void usb_autosuspend_device(struct usb_device *udev) { int status; - status = usb_autopm_do_device(udev, -1); - dev_vdbg(&udev->dev, "%s: cnt %d\n", - __func__, udev->pm_usage_cnt); + udev->last_busy = jiffies; + status = pm_runtime_put_sync(&udev->dev); + dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", + __func__, atomic_read(&udev->dev.power.usage_count), + status); } /** @@ -1361,17 +1421,22 @@ void usb_autosuspend_device(struct usb_device *udev) * This routine should be called when a core subsystem thinks @udev may * be ready to autosuspend. * - * @udev's usage counter left unchanged. If it or any of the usage counters - * for an active interface is greater than 0, or autosuspend is not allowed - * for any other reason, no autosuspend request will be queued. + * @udev's usage counter left unchanged. If it is 0 and all the interfaces + * are inactive then an autosuspend will be attempted. The attempt may + * fail or be delayed. + * + * The caller must hold @udev's device lock. * * This routine can run only in process context. */ void usb_try_autosuspend_device(struct usb_device *udev) { - usb_autopm_do_device(udev, 0); - dev_vdbg(&udev->dev, "%s: cnt %d\n", - __func__, udev->pm_usage_cnt); + int status; + + status = pm_runtime_idle(&udev->dev); + dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", + __func__, atomic_read(&udev->dev.power.usage_count), + status); } /** @@ -1380,16 +1445,15 @@ void usb_try_autosuspend_device(struct usb_device *udev) * * This routine should be called when a core subsystem wants to use @udev * and needs to guarantee that it is not suspended. No autosuspend will - * occur until usb_autosuspend_device is called. (Note that this will not - * prevent suspend events originating in the PM core.) Examples would be - * when @udev's device file in usbfs is opened or when a remote-wakeup + * occur until usb_autosuspend_device() is called. (Note that this will + * not prevent suspend events originating in the PM core.) Examples would + * be when @udev's device file in usbfs is opened or when a remote-wakeup * request is received. * * @udev's usage counter is incremented to prevent subsequent autosuspends. * However if the autoresume fails then the usage counter is re-decremented. * - * Often the caller will hold @udev's device lock, but this is not - * necessary (and attempting it might cause deadlock). + * The caller must hold @udev's device lock. * * This routine can run only in process context. */ @@ -1397,40 +1461,14 @@ int usb_autoresume_device(struct usb_device *udev) { int status; - status = usb_autopm_do_device(udev, 1); - dev_vdbg(&udev->dev, "%s: status %d cnt %d\n", - __func__, status, udev->pm_usage_cnt); - return status; -} - -/* Internal routine to adjust an interface's usage counter and change - * its device's autosuspend state. - */ -static int usb_autopm_do_interface(struct usb_interface *intf, - int inc_usage_cnt) -{ - struct usb_device *udev = interface_to_usbdev(intf); - int status = 0; - - usb_pm_lock(udev); - if (intf->condition == USB_INTERFACE_UNBOUND) - status = -ENODEV; - else { - udev->auto_pm = 1; - intf->pm_usage_cnt += inc_usage_cnt; - udev->last_busy = jiffies; - if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { - if (udev->state == USB_STATE_SUSPENDED) - status = usb_resume_both(udev); - if (status != 0) - intf->pm_usage_cnt -= inc_usage_cnt; - else - udev->last_busy = jiffies; - } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { - status = usb_suspend_both(udev, PMSG_SUSPEND); - } - } - usb_pm_unlock(udev); + status = pm_runtime_get_sync(&udev->dev); + if (status < 0) + pm_runtime_put_sync(&udev->dev); + dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", + __func__, atomic_read(&udev->dev.power.usage_count), + status); + if (status > 0) + status = 0; return status; } @@ -1444,38 +1482,98 @@ static int usb_autopm_do_interface(struct usb_interface *intf, * closed. * * The routine decrements @intf's usage counter. When the counter reaches - * 0, a delayed autosuspend request for @intf's device is queued. When - * the delay expires, if @intf->pm_usage_cnt is still <= 0 along with all - * the other usage counters for the sibling interfaces and @intf's - * usb_device, the device and all its interfaces will be autosuspended. - * - * Note that @intf->pm_usage_cnt is owned by the interface driver. The - * core will not change its value other than the increment and decrement - * in usb_autopm_get_interface and usb_autopm_put_interface. The driver - * may use this simple counter-oriented discipline or may set the value - * any way it likes. + * 0, a delayed autosuspend request for @intf's device is attempted. The + * attempt may fail (see autosuspend_check()). * * If the driver has set @intf->needs_remote_wakeup then autosuspend will * take place only if the device's remote-wakeup facility is enabled. * - * Suspend method calls queued by this routine can arrive at any time - * while @intf is resumed and its usage counter is equal to 0. They are - * not protected by the usb_device's lock but only by its pm_mutex. - * Drivers must provide their own synchronization. - * * This routine can run only in process context. */ void usb_autopm_put_interface(struct usb_interface *intf) { - int status; + struct usb_device *udev = interface_to_usbdev(intf); + int status; - status = usb_autopm_do_interface(intf, -1); - dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", - __func__, status, intf->pm_usage_cnt); + udev->last_busy = jiffies; + atomic_dec(&intf->pm_usage_cnt); + status = pm_runtime_put_sync(&intf->dev); + dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", + __func__, atomic_read(&intf->dev.power.usage_count), + status); } EXPORT_SYMBOL_GPL(usb_autopm_put_interface); /** + * usb_autopm_put_interface_async - decrement a USB interface's PM-usage counter + * @intf: the usb_interface whose counter should be decremented + * + * This routine does much the same thing as usb_autopm_put_interface(): + * It decrements @intf's usage counter and schedules a delayed + * autosuspend request if the counter is <= 0. The difference is that it + * does not perform any synchronization; callers should hold a private + * lock and handle all synchronization issues themselves. + * + * Typically a driver would call this routine during an URB's completion + * handler, if no more URBs were pending. + * + * This routine can run in atomic context. + */ +void usb_autopm_put_interface_async(struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + unsigned long last_busy; + int status = 0; + + last_busy = udev->last_busy; + udev->last_busy = jiffies; + atomic_dec(&intf->pm_usage_cnt); + pm_runtime_put_noidle(&intf->dev); + + if (!udev->autosuspend_disabled) { + /* Optimization: Don't schedule a delayed autosuspend if + * the timer is already running and the expiration time + * wouldn't change. + * + * We have to use the interface's timer. Attempts to + * schedule a suspend for the device would fail because + * the interface is still active. + */ + if (intf->dev.power.timer_expires == 0 || + round_jiffies_up(last_busy) != + round_jiffies_up(jiffies)) { + status = pm_schedule_suspend(&intf->dev, + jiffies_to_msecs( + round_jiffies_up_relative( + udev->autosuspend_delay))); + } + } + dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", + __func__, atomic_read(&intf->dev.power.usage_count), + status); +} +EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async); + +/** + * usb_autopm_put_interface_no_suspend - decrement a USB interface's PM-usage counter + * @intf: the usb_interface whose counter should be decremented + * + * This routine decrements @intf's usage counter but does not carry out an + * autosuspend. + * + * This routine can run in atomic context. + */ +void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + + udev->last_busy = jiffies; + atomic_dec(&intf->pm_usage_cnt); + pm_runtime_put_noidle(&intf->dev); +} +EXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend); + +/** * usb_autopm_get_interface - increment a USB interface's PM-usage counter * @intf: the usb_interface whose counter should be incremented * @@ -1487,25 +1585,8 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface); * or @intf is unbound. A typical example would be a character-device * driver when its device file is opened. * - * - * The routine increments @intf's usage counter. (However if the - * autoresume fails then the counter is re-decremented.) So long as the - * counter is greater than 0, autosuspend will not be allowed for @intf - * or its usb_device. When the driver is finished using @intf it should - * call usb_autopm_put_interface() to decrement the usage counter and - * queue a delayed autosuspend request (if the counter is <= 0). - * - * - * Note that @intf->pm_usage_cnt is owned by the interface driver. The - * core will not change its value other than the increment and decrement - * in usb_autopm_get_interface and usb_autopm_put_interface. The driver - * may use this simple counter-oriented discipline or may set the value - * any way it likes. - * - * Resume method calls generated by this routine can arrive at any time - * while @intf is suspended. They are not protected by the usb_device's - * lock but only by its pm_mutex. Drivers must provide their own - * synchronization. + * @intf's usage counter is incremented to prevent subsequent autosuspends. + * However if the autoresume fails then the counter is re-decremented. * * This routine can run only in process context. */ @@ -1513,150 +1594,226 @@ int usb_autopm_get_interface(struct usb_interface *intf) { int status; - status = usb_autopm_do_interface(intf, 1); - dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", - __func__, status, intf->pm_usage_cnt); + status = pm_runtime_get_sync(&intf->dev); + if (status < 0) + pm_runtime_put_sync(&intf->dev); + else + atomic_inc(&intf->pm_usage_cnt); + dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", + __func__, atomic_read(&intf->dev.power.usage_count), + status); + if (status > 0) + status = 0; return status; } EXPORT_SYMBOL_GPL(usb_autopm_get_interface); /** - * usb_autopm_set_interface - set a USB interface's autosuspend state - * @intf: the usb_interface whose state should be set - * - * This routine sets the autosuspend state of @intf's device according - * to @intf's usage counter, which the caller must have set previously. - * If the counter is <= 0, the device is autosuspended (if it isn't - * already suspended and if nothing else prevents the autosuspend). If - * the counter is > 0, the device is autoresumed (if it isn't already - * awake). + * usb_autopm_get_interface_async - increment a USB interface's PM-usage counter + * @intf: the usb_interface whose counter should be incremented + * + * This routine does much the same thing as + * usb_autopm_get_interface(): It increments @intf's usage counter and + * queues an autoresume request if the device is suspended. The + * differences are that it does not perform any synchronization (callers + * should hold a private lock and handle all synchronization issues + * themselves), and it does not autoresume the device directly (it only + * queues a request). After a successful call, the device may not yet be + * resumed. + * + * This routine can run in atomic context. */ -int usb_autopm_set_interface(struct usb_interface *intf) +int usb_autopm_get_interface_async(struct usb_interface *intf) { - int status; + int status = 0; + enum rpm_status s; - status = usb_autopm_do_interface(intf, 0); - dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", - __func__, status, intf->pm_usage_cnt); + /* Don't request a resume unless the interface is already suspending + * or suspended. Doing so would force a running suspend timer to be + * cancelled. + */ + pm_runtime_get_noresume(&intf->dev); + s = ACCESS_ONCE(intf->dev.power.runtime_status); + if (s == RPM_SUSPENDING || s == RPM_SUSPENDED) + status = pm_request_resume(&intf->dev); + + if (status < 0 && status != -EINPROGRESS) + pm_runtime_put_noidle(&intf->dev); + else + atomic_inc(&intf->pm_usage_cnt); + dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", + __func__, atomic_read(&intf->dev.power.usage_count), + status); + if (status > 0) + status = 0; return status; } -EXPORT_SYMBOL_GPL(usb_autopm_set_interface); - -#else - -void usb_autosuspend_work(struct work_struct *work) -{} - -#endif /* CONFIG_USB_SUSPEND */ +EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async); /** - * usb_external_suspend_device - external suspend of a USB device and its interfaces - * @udev: the usb_device to suspend - * @msg: Power Management message describing this state transition + * usb_autopm_get_interface_no_resume - increment a USB interface's PM-usage counter + * @intf: the usb_interface whose counter should be incremented * - * This routine handles external suspend requests: ones not generated - * internally by a USB driver (autosuspend) but rather coming from the user - * (via sysfs) or the PM core (system sleep). The suspend will be carried - * out regardless of @udev's usage counter or those of its interfaces, - * and regardless of whether or not remote wakeup is enabled. Of course, - * interface drivers still have the option of failing the suspend (if - * there are unsuspended children, for example). + * This routine increments @intf's usage counter but does not carry out an + * autoresume. * - * The caller must hold @udev's device lock. + * This routine can run in atomic context. */ -int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg) +void usb_autopm_get_interface_no_resume(struct usb_interface *intf) { - int status; + struct usb_device *udev = interface_to_usbdev(intf); - do_unbind_rebind(udev, DO_UNBIND); - usb_pm_lock(udev); - udev->auto_pm = 0; - status = usb_suspend_both(udev, msg); - usb_pm_unlock(udev); - return status; + udev->last_busy = jiffies; + atomic_inc(&intf->pm_usage_cnt); + pm_runtime_get_noresume(&intf->dev); } +EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume); -/** - * usb_external_resume_device - external resume of a USB device and its interfaces - * @udev: the usb_device to resume - * - * This routine handles external resume requests: ones not generated - * internally by a USB driver (autoresume) but rather coming from the user - * (via sysfs), the PM core (system resume), or the device itself (remote - * wakeup). @udev's usage counter is unaffected. - * - * The caller must hold @udev's device lock. - */ -int usb_external_resume_device(struct usb_device *udev) +/* Internal routine to check whether we may autosuspend a device. */ +static int autosuspend_check(struct usb_device *udev) { - int status; + int i; + struct usb_interface *intf; + unsigned long suspend_time, j; - usb_pm_lock(udev); - udev->auto_pm = 0; - status = usb_resume_both(udev); - udev->last_busy = jiffies; - usb_pm_unlock(udev); - do_unbind_rebind(udev, DO_REBIND); + /* Fail if autosuspend is disabled, or any interfaces are in use, or + * any interface drivers require remote wakeup but it isn't available. + */ + udev->do_remote_wakeup = device_may_wakeup(&udev->dev); + if (udev->actconfig) { + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + intf = udev->actconfig->interface[i]; - /* Now that the device is awake, we can start trying to autosuspend - * it again. */ - if (status == 0) - usb_try_autosuspend_device(udev); - return status; + /* We don't need to check interfaces that are + * disabled for runtime PM. Either they are unbound + * or else their drivers don't support autosuspend + * and so they are permanently active. + */ + if (intf->dev.power.disable_depth) + continue; + if (atomic_read(&intf->dev.power.usage_count) > 0) + return -EBUSY; + if (intf->needs_remote_wakeup && + !udev->do_remote_wakeup) { + dev_dbg(&udev->dev, "remote wakeup needed " + "for autosuspend\n"); + return -EOPNOTSUPP; + } + + /* Don't allow autosuspend if the device will need + * a reset-resume and any of its interface drivers + * doesn't include support or needs remote wakeup. + */ + if (udev->quirks & USB_QUIRK_RESET_RESUME) { + struct usb_driver *driver; + + driver = to_usb_driver(intf->dev.driver); + if (!driver->reset_resume || + intf->needs_remote_wakeup) + return -EOPNOTSUPP; + } + } + } + + /* If everything is okay but the device hasn't been idle for long + * enough, queue a delayed autosuspend request. + */ + j = ACCESS_ONCE(jiffies); + suspend_time = udev->last_busy + udev->autosuspend_delay; + if (time_before(j, suspend_time)) { + pm_schedule_suspend(&udev->dev, jiffies_to_msecs( + round_jiffies_up_relative(suspend_time - j))); + return -EAGAIN; + } + return 0; } -static int usb_suspend(struct device *dev, pm_message_t message) +static int usb_runtime_suspend(struct device *dev) { - struct usb_device *udev; - - if (!is_usb_device(dev)) /* Ignore PM for interfaces */ - return 0; - udev = to_usb_device(dev); + int status = 0; - /* If udev is already suspended, we can skip this suspend and - * we should also skip the upcoming system resume. High-speed - * root hubs are an exception; they need to resume whenever the - * system wakes up in order for USB-PERSIST port handover to work - * properly. + /* A USB device can be suspended if it passes the various autosuspend + * checks. Runtime suspend for a USB device means suspending all the + * interfaces and then the device itself. */ - if (udev->state == USB_STATE_SUSPENDED) { - if (udev->parent || udev->speed != USB_SPEED_HIGH) - udev->skip_sys_resume = 1; - return 0; + if (is_usb_device(dev)) { + struct usb_device *udev = to_usb_device(dev); + + if (autosuspend_check(udev) != 0) + return -EAGAIN; + + status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); + + /* If an interface fails the suspend, adjust the last_busy + * time so that we don't get another suspend attempt right + * away. + */ + if (status) { + udev->last_busy = jiffies + + (udev->autosuspend_delay == 0 ? + HZ/2 : 0); + } + + /* Prevent the parent from suspending immediately after */ + else if (udev->parent) { + udev->parent->last_busy = jiffies; + } } - udev->skip_sys_resume = 0; - return usb_external_suspend_device(udev, message); + /* Runtime suspend for a USB interface doesn't mean anything. */ + return status; } -static int usb_resume(struct device *dev) +static int usb_runtime_resume(struct device *dev) { - struct usb_device *udev; + /* Runtime resume for a USB device means resuming both the device + * and all its interfaces. + */ + if (is_usb_device(dev)) { + struct usb_device *udev = to_usb_device(dev); + int status; - if (!is_usb_device(dev)) /* Ignore PM for interfaces */ - return 0; - udev = to_usb_device(dev); + status = usb_resume_both(udev, PMSG_AUTO_RESUME); + udev->last_busy = jiffies; + return status; + } + + /* Runtime resume for a USB interface doesn't mean anything. */ + return 0; +} - /* If udev->skip_sys_resume is set then udev was already suspended - * when the system sleep started, so we don't want to resume it - * during this system wakeup. +static int usb_runtime_idle(struct device *dev) +{ + /* An idle USB device can be suspended if it passes the various + * autosuspend checks. An idle interface can be suspended at + * any time. */ - if (udev->skip_sys_resume) - return 0; - return usb_external_resume_device(udev); + if (is_usb_device(dev)) { + struct usb_device *udev = to_usb_device(dev); + + if (autosuspend_check(udev) != 0) + return 0; + } + + pm_runtime_suspend(dev); + return 0; } +static struct dev_pm_ops usb_bus_pm_ops = { + .runtime_suspend = usb_runtime_suspend, + .runtime_resume = usb_runtime_resume, + .runtime_idle = usb_runtime_idle, +}; + #else -#define usb_suspend NULL -#define usb_resume NULL +#define usb_bus_pm_ops (*(struct dev_pm_ops *) NULL) -#endif /* CONFIG_PM */ +#endif /* CONFIG_USB_SUSPEND */ struct bus_type usb_bus_type = { .name = "usb", .match = usb_device_match, .uevent = usb_uevent, - .suspend = usb_suspend, - .resume = usb_resume, + .pm = &usb_bus_pm_ops, };