diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 13:16:28 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 13:16:28 -0800 |
commit | 3e5b08cbbf78bedd316904ab0cf3b27119433ee5 (patch) | |
tree | 0365745c1b7441c1868551c024410c829c3accc6 /drivers/usb | |
parent | da40d036fd716f0efb2917076220814b1e927ae1 (diff) | |
parent | 2af10844eb6ed104f9505bf3a7ba3ceb02264f31 (diff) |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (144 commits)
USB: add support for Dream Cheeky DL100B Webmail Notifier (1d34:0004)
USB: serial: ftdi_sio: add support for TIOCSERGETLSR
USB: ehci-mxc: Setup portsc register prior to accessing OTG viewport
USB: atmel_usba_udc: fix freeing irq in usba_udc_remove()
usb: ehci-omap: fix tll channel enable mask
usb: ohci-omap3: fix trivial typo
USB: gadget: ci13xxx: don't assume that PAGE_SIZE is 4096
USB: gadget: ci13xxx: fix complete() callback for no_interrupt rq's
USB: gadget: update ci13xxx to work with g_ether
USB: gadgets: ci13xxx: fix probing of compiled-in gadget drivers
Revert "USB: musb: pm: don't rely fully on clock support"
Revert "USB: musb: blackfin: pm: make it work"
USB: uas: Use GFP_NOIO instead of GFP_KERNEL in I/O submission path
USB: uas: Ensure we only bind to a UAS interface
USB: uas: Rename sense pipe and sense urb to status pipe and status urb
USB: uas: Use kzalloc instead of kmalloc
USB: uas: Fix up the Sense IU
usb: musb: core: kill unneeded #include's
DA8xx: assign name to MUSB IRQ resource
usb: gadget: g_ncm added
...
Manually fix up trivial conflicts in USB Kconfig changes in:
arch/arm/mach-omap2/Kconfig
arch/sh/Kconfig
drivers/usb/Kconfig
drivers/usb/host/ehci-hcd.c
and annoying chip clock data conflicts in:
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clock44xx_data.c
Diffstat (limited to 'drivers/usb')
91 files changed, 14503 insertions, 1873 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 5a7c8f1d76c..fceea5e4e02 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -42,17 +42,13 @@ config USB_ARCH_HAS_OHCI default y if ARCH_W90X900 default y if ARCH_DAVINCI_DA8XX default y if ARCH_CNS3XXX + default y if PLAT_SPEAR # PPC: default y if STB03xxx default y if PPC_MPC52xx # MIPS: default y if MIPS_ALCHEMY default y if MACH_JZ4740 - # SH: - default y if CPU_SUBTYPE_SH7720 - default y if CPU_SUBTYPE_SH7721 - default y if CPU_SUBTYPE_SH7763 - default y if CPU_SUBTYPE_SH7786 # more: default PCI @@ -68,6 +64,9 @@ config USB_ARCH_HAS_EHCI default y if ARCH_MXC default y if ARCH_OMAP3 default y if ARCH_CNS3XXX + default y if ARCH_VT8500 + default y if PLAT_SPEAR + default y if ARCH_MSM default PCI # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c0e60fbcb04..b9278a1fb9e 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -27,7 +27,6 @@ #include <linux/usb.h> #include <linux/usb/quirks.h> #include <linux/usb/hcd.h> -#include <linux/pm_runtime.h> #include "usb.h" @@ -1262,6 +1261,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) udev->reset_resume); } } + usb_mark_last_busy(udev); done: dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); @@ -1329,7 +1329,6 @@ int usb_resume(struct device *dev, pm_message_t msg) pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - udev->last_busy = jiffies; do_unbind_rebind(udev, DO_REBIND); } } @@ -1397,33 +1396,8 @@ void usb_autosuspend_device(struct usb_device *udev) { int status; - 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); -} - -/** - * usb_try_autosuspend_device - attempt an autosuspend of a USB device and its interfaces - * @udev: the usb_device to autosuspend - * - * This routine should be called when a core subsystem thinks @udev may - * be ready to autosuspend. - * - * @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) -{ - int status; - - status = pm_runtime_idle(&udev->dev); + usb_mark_last_busy(udev); + status = pm_runtime_put_sync_autosuspend(&udev->dev); dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", __func__, atomic_read(&udev->dev.power.usage_count), status); @@ -1482,7 +1456,7 @@ void usb_autopm_put_interface(struct usb_interface *intf) struct usb_device *udev = interface_to_usbdev(intf); int status; - udev->last_busy = jiffies; + usb_mark_last_busy(udev); atomic_dec(&intf->pm_usage_cnt); status = pm_runtime_put_sync(&intf->dev); dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", @@ -1509,32 +1483,11 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface); 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; + int status; - last_busy = udev->last_busy; - udev->last_busy = jiffies; + usb_mark_last_busy(udev); atomic_dec(&intf->pm_usage_cnt); - pm_runtime_put_noidle(&intf->dev); - - if (udev->dev.power.runtime_auto) { - /* 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))); - } - } + status = pm_runtime_put(&intf->dev); dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", __func__, atomic_read(&intf->dev.power.usage_count), status); @@ -1554,7 +1507,7 @@ void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) { struct usb_device *udev = interface_to_usbdev(intf); - udev->last_busy = jiffies; + usb_mark_last_busy(udev); atomic_dec(&intf->pm_usage_cnt); pm_runtime_put_noidle(&intf->dev); } @@ -1612,18 +1565,9 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface); */ int usb_autopm_get_interface_async(struct usb_interface *intf) { - int status = 0; - enum rpm_status s; - - /* 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); + int status; + status = pm_runtime_get(&intf->dev); if (status < 0 && status != -EINPROGRESS) pm_runtime_put_noidle(&intf->dev); else @@ -1650,7 +1594,7 @@ void usb_autopm_get_interface_no_resume(struct usb_interface *intf) { struct usb_device *udev = interface_to_usbdev(intf); - udev->last_busy = jiffies; + usb_mark_last_busy(udev); atomic_inc(&intf->pm_usage_cnt); pm_runtime_get_noresume(&intf->dev); } @@ -1661,7 +1605,6 @@ static int autosuspend_check(struct usb_device *udev) { int w, i; struct usb_interface *intf; - unsigned long suspend_time, j; /* Fail if autosuspend is disabled, or any interfaces are in use, or * any interface drivers require remote wakeup but it isn't available. @@ -1701,87 +1644,46 @@ static int autosuspend_check(struct usb_device *udev) return -EOPNOTSUPP; } udev->do_remote_wakeup = w; - - /* 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_runtime_suspend(struct device *dev) { - int status = 0; + struct usb_device *udev = to_usb_device(dev); + int status; /* 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 (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; - } + if (autosuspend_check(udev) != 0) + return -EAGAIN; - /* Runtime suspend for a USB interface doesn't mean anything. */ + status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); return status; } static int usb_runtime_resume(struct device *dev) { + struct usb_device *udev = to_usb_device(dev); + int status; + /* 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; - - 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; + status = usb_resume_both(udev, PMSG_AUTO_RESUME); + return status; } static int usb_runtime_idle(struct device *dev) { + struct usb_device *udev = to_usb_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. + * autosuspend checks. */ - if (is_usb_device(dev)) { - struct usb_device *udev = to_usb_device(dev); - - if (autosuspend_check(udev) != 0) - return 0; - } - - pm_runtime_suspend(dev); + if (autosuspend_check(udev) == 0) + pm_runtime_autosuspend(dev); return 0; } diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 3799573bd38..b55d46070a2 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -19,7 +19,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> -#include <linux/pm_runtime.h> #include <linux/usb.h> #include <linux/usb/hcd.h> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ced846ac414..6a95017fa62 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -38,7 +38,6 @@ #include <asm/unaligned.h> #include <linux/platform_device.h> #include <linux/workqueue.h> -#include <linux/pm_runtime.h> #include <linux/usb.h> #include <linux/usb/hcd.h> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 27115b45edc..b98efae6a1c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -24,7 +24,6 @@ #include <linux/kthread.h> #include <linux/mutex.h> #include <linux/freezer.h> -#include <linux/pm_runtime.h> #include <asm/uaccess.h> #include <asm/byteorder.h> @@ -1804,8 +1803,15 @@ int usb_new_device(struct usb_device *udev) /* Tell the runtime-PM framework the device is active */ pm_runtime_set_active(&udev->dev); + pm_runtime_get_noresume(&udev->dev); + pm_runtime_use_autosuspend(&udev->dev); pm_runtime_enable(&udev->dev); + /* By default, forbid autosuspend for all devices. It will be + * allowed for hubs during binding. + */ |