Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4b7d3bb authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  usb: Increase timeout value for device reset
  USB: put claimed interfaces in the "suspended" state
  USB: EHCI: defer reclamation of siTDs
  USB: fix remote wakeup settings during system sleep
  USB: pl2303: add AdLink ND-6530 USB IDs
  USB: Add id for HP ev2210 a.k.a Sierra MC5725 miniPCI-e Cell Modem.
  USB: OHCI: DA8xx/OMAP-L1x: fix up macro rename
  USB: qcaux: add LG Rumor and Sanyo Katana LX device IDs
  usb: wusb: don't overflow the Keep Alive IE buffer
  USB: ehci: omap: fix kernel panic with rmmod
  USB: fixed bug in usbsevseg using USB autosuspend incorrectly
  USB: ti_usb_3410_5052: adding multitech dialup fax/modem devices
parents a2340be0 6307e096
Loading
Loading
Loading
Loading
+42 −7
Original line number Diff line number Diff line
@@ -301,7 +301,7 @@ static int usb_probe_interface(struct device *dev)

	intf->condition = USB_INTERFACE_BINDING;

	/* Bound interfaces are initially active.  They are
	/* 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.
	 */
@@ -437,11 +437,11 @@ int usb_driver_claim_interface(struct usb_driver *driver,

	iface->condition = USB_INTERFACE_BOUND;

	/* Bound interfaces are initially active.  They are
	/* 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_active(dev);
	pm_runtime_set_suspended(dev);
	pm_suspend_ignore_children(dev, false);
	if (driver->supports_autosuspend)
		pm_runtime_enable(dev);
@@ -1170,7 +1170,7 @@ done:
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;

	if (udev->state == USB_STATE_NOTATTACHED ||
@@ -1179,7 +1179,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)

	/* 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)
@@ -1192,7 +1193,7 @@ 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) {
		msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
		while (--i >= 0) {
		while (++i < n) {
			intf = udev->actconfig->interface[i];
			usb_resume_interface(udev, intf, msg, 0);
		}
@@ -1263,13 +1264,47 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
	return status;
}

static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
{
	int			w, i;
	struct usb_interface	*intf;

	/* 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)
{
	struct usb_device	*udev = to_usb_device(dev);

	do_unbind_rebind(udev, DO_UNBIND);
	udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
	choose_wakeup(udev, msg);
	return usb_suspend_both(udev, msg);
}

+1 −0
Original line number Diff line number Diff line
@@ -543,6 +543,7 @@ static int ehci_init(struct usb_hcd *hcd)
	 */
	ehci->periodic_size = DEFAULT_I_TDPS;
	INIT_LIST_HEAD(&ehci->cached_itd_list);
	INIT_LIST_HEAD(&ehci->cached_sitd_list);
	if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
		return retval;

+1 −1
Original line number Diff line number Diff line
@@ -801,7 +801,7 @@ static int ehci_hub_control (
			 * this bit; seems too long to spin routinely...
			 */
			retval = handshake(ehci, status_reg,
					PORT_RESET, 0, 750);
					PORT_RESET, 0, 1000);
			if (retval != 0) {
				ehci_err (ehci, "port %d reset error %d\n",
					wIndex + 1, retval);
+1 −1
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ static inline void qh_put (struct ehci_qh *qh)

static void ehci_mem_cleanup (struct ehci_hcd *ehci)
{
	free_cached_itd_list(ehci);
	free_cached_lists(ehci);
	if (ehci->async)
		qh_put (ehci->async);
	ehci->async = NULL;
+4 −2
Original line number Diff line number Diff line
@@ -629,12 +629,14 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
		}
		snprintf(supply, sizeof(supply), "hsusb%d", i);
		omap->regulator[i] = regulator_get(omap->dev, supply);
		if (IS_ERR(omap->regulator[i]))
		if (IS_ERR(omap->regulator[i])) {
			omap->regulator[i] = NULL;
			dev_dbg(&pdev->dev,
			"failed to get ehci port%d regulator\n", i);
		else
		} else {
			regulator_enable(omap->regulator[i]);
		}
	}

	ret = omap_start_ehc(omap, hcd);
	if (ret) {
Loading