diff options
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/driver.c | 5 | ||||
-rw-r--r-- | drivers/usb/core/generic.c | 27 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 27 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 14 |
4 files changed, 19 insertions, 54 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 69e5773abfce..07f503aa9078 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1754,6 +1754,9 @@ int usb_resume(struct device *dev, pm_message_t msg) udev = to_usb_device(dev); +/* At otg mode, if it is a device wakeup interrupt, the host should do nothing */ + if (udev->bus->is_b_host) + 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. @@ -1765,7 +1768,7 @@ int usb_resume(struct device *dev, pm_message_t msg) /* Avoid PM error messages for devices disconnected while suspended * as we'll display regular disconnect messages just a bit later. */ - if (status == -ENODEV) + if (status == -ENODEV || status == -ESHUTDOWN) return 0; return status; } diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 66e8a424c9f4..539a2c0dde00 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -196,7 +196,6 @@ extern void usb_host_set_wakeup(struct device *wkup_dev, bool para); static int generic_suspend(struct usb_device *udev, pm_message_t msg) { int rc; - u32 temp; /* Normal USB devices suspend through their upstream port. * Root hubs don't have upstream ports to suspend, @@ -204,25 +203,7 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) * interfaces manually by doing a bus (or "global") suspend. */ if (!udev->parent) { - struct usb_hcd *hcd = - container_of(udev->bus, struct usb_hcd, self); - struct fsl_usb2_platform_data *pdata; - pdata = hcd->self.controller->platform_data; - rc = hcd_bus_suspend(udev, msg); - - if (device_may_wakeup(hcd->self.controller)) { - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - /* enable remote wake up irq */ - usb_host_set_wakeup(hcd->self.controller, true); - - /* Put PHY into low power mode */ - temp = readl(hcd->regs + 0x184); - writel(temp | (1 << 23), (hcd->regs + 0x184)); - - if (pdata->usb_clock_for_pm) - pdata->usb_clock_for_pm(false); - } /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ } else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) @@ -236,7 +217,6 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) static int generic_resume(struct usb_device *udev, pm_message_t msg) { int rc; - u32 temp; /* Normal USB devices resume/reset through their upstream port. * Root hubs don't have upstream ports to resume or reset, @@ -244,13 +224,6 @@ static int generic_resume(struct usb_device *udev, pm_message_t msg) * interfaces manually by doing a bus (or "global") resume. */ if (!udev->parent) { - struct usb_hcd *hcd = - container_of(udev->bus, struct usb_hcd, self); - - if (device_may_wakeup(hcd->self.controller)) { - temp = readl(hcd->regs + 0x184); - writel(temp & (~(1 << 23)), (hcd->regs + 0x184)); - } rc = hcd_bus_resume(udev, msg); } else rc = usb_port_resume(udev, msg); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index d27ad104731c..2f47bdc7c93a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1739,6 +1739,7 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) int status; int old_state = hcd->state; + printk("%s\n", __func__); dev_dbg(&rhdev->dev, "bus %s%s\n", (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend"); if (!hcd->driver->bus_suspend) { @@ -1876,7 +1877,6 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); irqreturn_t usb_hcd_irq (int irq, void *__hcd) { struct usb_hcd *hcd = __hcd; - struct fsl_usb2_platform_data *pdata; unsigned long flags; irqreturn_t rc; @@ -1885,25 +1885,14 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) * assume it's never used. */ local_irq_save(flags); - - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { - /* Need open clock for register access */ - pdata = hcd->self.controller->platform_data; - if (pdata->usb_clock_for_pm) - pdata->usb_clock_for_pm(true); - - /* if receive a remote wakeup interrrupt after suspend */ - if (usb_host_wakeup_irq(hcd->self.controller)) { - /* disable remote wake up irq */ - usb_host_set_wakeup(hcd->self.controller, false); - - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - hcd->driver->irq(hcd); - rc = IRQ_HANDLED; - } else + /* At otg mode, the host does need to handle device interrupt */ + if (hcd->self.is_b_host){ + local_irq_restore(flags); + return IRQ_NONE; + } + else if (unlikely(hcd->state == HC_STATE_HALT || + !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { rc = IRQ_NONE; - } else if (unlikely(hcd->state == HC_STATE_HALT)) { - rc = IRQ_NONE; } else if (hcd->driver->irq(hcd) == IRQ_NONE) { rc = IRQ_NONE; } else { diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d47201c75915..cc8f911afbc4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1177,12 +1177,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) "Unsupported bus topology: hub nested too deep\n"); return -E2BIG; } -#ifdef CONFIG_PM - /* Defaultly disable autosuspend for hub and reley on sys - * to enable it. - */ - hdev->autosuspend_disabled = 1; -#endif #ifdef CONFIG_USB_OTG_BLACKLIST_HUB if (hdev->parent) { @@ -2304,7 +2298,6 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) struct usb_hub *hub = usb_get_intfdata (intf); struct usb_device *hdev = hub->hdev; unsigned port1; - /* fail if children aren't already suspended */ for (port1 = 1; port1 <= hdev->maxchild; port1++) { struct usb_device *udev; @@ -2328,8 +2321,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) static int hub_resume(struct usb_interface *intf) { struct usb_hub *hub = usb_get_intfdata(intf); + struct usb_hcd *hcd = bus_to_hcd(hub->hdev->bus); dev_dbg(&intf->dev, "%s\n", __func__); + /* At otg mode, if the hcd which the hub is attached to is not accessible, + * It should do nothing. + */ + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) + return 0; + hub_activate(hub, HUB_RESUME); return 0; } |