diff options
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 95ccfa0b9fc5..d27ad104731c 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -40,6 +40,7 @@ #include <linux/workqueue.h> #include <linux/usb.h> +#include <linux/fsl_devices.h> #include "usb.h" #include "hcd.h" @@ -117,6 +118,8 @@ static inline int is_root_hub(struct usb_device *udev) return (udev->parent == NULL); } +extern int usb_host_wakeup_irq(struct device *wkup_dev); +extern void usb_host_set_wakeup(struct device *wkup_dev, bool para); /*-------------------------------------------------------------------------*/ /* @@ -1873,6 +1876,7 @@ 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; @@ -1882,8 +1886,23 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) */ local_irq_save(flags); - if (unlikely(hcd->state == HC_STATE_HALT || - !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->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 + 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; |