summaryrefslogtreecommitdiff
path: root/drivers/usb/core/hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r--drivers/usb/core/hcd.c23
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;