diff options
Diffstat (limited to 'drivers')
95 files changed, 14436 insertions, 1840 deletions
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c index c91424c0c13..99c81a9a4f4 100644 --- a/drivers/media/video/tlg2300/pd-main.c +++ b/drivers/media/video/tlg2300/pd-main.c @@ -452,7 +452,8 @@ static int poseidon_probe(struct usb_interface *interface, device_init_wakeup(&udev->dev, 1); #ifdef CONFIG_PM - pd->udev->autosuspend_delay = HZ * PM_SUSPEND_DELAY; + pm_runtime_set_autosuspend_delay(&pd->udev->dev, + 1000 * PM_SUSPEND_DELAY); usb_enable_autosuspend(pd->udev); if (in_hibernation(pd)) { diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 35275ba7096..12abd5b924b 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -95,7 +95,8 @@ #define twl_has_rtc() false #endif -#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) +#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) ||\ + defined(CONFIG_TWL6030_USB) || defined(CONFIG_TWL6030_USB_MODULE) #define twl_has_usb() true #else #define twl_has_usb() false @@ -682,6 +683,43 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) usb3v1.dev = child; } } + if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { + + static struct regulator_consumer_supply usb3v3 = { + .supply = "vusb", + }; + + if (twl_has_regulator()) { + /* this is a template that gets copied */ + struct regulator_init_data usb_fixed = { + .constraints.valid_modes_mask = + REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .constraints.valid_ops_mask = + REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }; + + child = add_regulator_linked(TWL6030_REG_VUSB, + &usb_fixed, &usb3v3, 1); + if (IS_ERR(child)) + return PTR_ERR(child); + } + + child = add_child(0, "twl6030_usb", + pdata->usb, sizeof(*pdata->usb), + true, + /* irq1 = VBUS_PRES, irq0 = USB ID */ + pdata->irq_base + USBOTG_INTR_OFFSET, + pdata->irq_base + USB_PRES_INTR_OFFSET); + + if (IS_ERR(child)) + return PTR_ERR(child); + /* we need to connect regulators to this transceiver */ + if (twl_has_regulator() && child) + usb3v3.dev = child; + + } if (twl_has_watchdog()) { child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); @@ -815,10 +853,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VUSB, pdata->vusb); - if (IS_ERR(child)) - return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1); if (IS_ERR(child)) return PTR_ERR(child); diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index aaedb11d9d2..06c8955907e 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -74,7 +74,7 @@ static int twl6030_interrupt_mapping[24] = { USBOTG_INTR_OFFSET, /* Bit 16 ID_WKUP */ USBOTG_INTR_OFFSET, /* Bit 17 VBUS_WKUP */ USBOTG_INTR_OFFSET, /* Bit 18 ID */ - USBOTG_INTR_OFFSET, /* Bit 19 VBUS */ + USB_PRES_INTR_OFFSET, /* Bit 19 VBUS */ CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */ CHARGER_INTR_OFFSET, /* Bit 21 EXT_CHRG */ CHARGER_INTR_OFFSET, /* Bit 22 INT_CHRG */ @@ -128,6 +128,13 @@ static int twl6030_irq_thread(void *data) sts.bytes[3] = 0; /* Only 24 bits are valid*/ + /* + * Since VBUS status bit is not reliable for VBUS disconnect + * use CHARGER VBUS detection status bit instead. + */ + if (sts.bytes[2] & 0x10) + sts.bytes[2] |= 0x08; + for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) { local_irq_disable(); if (sts.int_sts & 0x1) { diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index d3365ac85dd..7cb375515e1 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c @@ -514,7 +514,7 @@ int i2400mu_probe(struct usb_interface *iface, #ifdef CONFIG_PM iface->needs_remote_wakeup = 1; /* autosuspend (15s delay) */ device_init_wakeup(dev, 1); - usb_dev->autosuspend_delay = 15 * HZ; + pm_runtime_set_autosuspend_delay(&usb_dev->dev, 15000); usb_enable_autosuspend(usb_dev); #endif diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 824f9a45007..e97ad99b1bb 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -277,7 +277,7 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) if(psAdapter->bDoSuspend) { #ifdef CONFIG_PM - udev->autosuspend_delay = 0; + pm_runtime_set_autosuspend_delay(&udev->dev, 0); intf->needs_remote_wakeup = 1; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) udev->autosuspend_disabled = 0; diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 67eb3770868..b8e70a982fd 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -41,17 +41,13 @@ config USB_ARCH_HAS_OHCI default y if MFD_TC6393XB default y if ARCH_W90X900 default y if ARCH_DAVINCI_DA8XX + 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 @@ -66,6 +62,9 @@ config USB_ARCH_HAS_EHCI default y if ARCH_AT91SAM9G45 default y if ARCH_MXC default y if ARCH_OMAP3 + 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 |