summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2014-03-31 13:54:46 +0800
committerPeter Chen <peter.chen@freescale.com>2014-04-01 09:34:37 +0800
commit8062f7e4af338f1520a6cd13133ff01fffd82a46 (patch)
tree68dda447f8788914eb73d37d9d6f5f73a7b2a347 /drivers
parent24c1d64737577fba4b4cc8d83170c9dfd6fd6dec (diff)
ENGR00303543 usb: ehci-arc: do noop during resume if it is not in host mode
We find a bug that the usb will produce endless interrupt during the resume after below steps: - nothing connected at usb otg port, but enable usb gadget driver - system enters suspend - plug in usb cable - system leaves suspend The reasons of endless interrupt is: the host controller resume routine leaves the phy low power mode, but device controller resume routine has still not been called, so the software considers it is still at low power mode. After this time, the vbus change interrupt comes, the wakeup routine considers it is an wakeup interrupt, but in fact it is not. So, the endless interrupt occurs. The solution of this problem is do noop during host controller resume routine if current usb mode is not host mode, and the device controller reusme routine will handle it. Signed-off-by: Peter Chen <peter.chen@freescale.com>
Diffstat (limited to 'drivers')
-rwxr-xr-xdrivers/usb/host/ehci-arc.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c
index dde47dd76e5f..5e5d4e011d73 100755
--- a/drivers/usb/host/ehci-arc.c
+++ b/drivers/usb/host/ehci-arc.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2005 MontaVista Software
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -802,6 +802,18 @@ static int ehci_fsl_drv_resume(struct platform_device *pdev)
if (!host_can_wakeup_system(pdev)) {
/* Need open clock for register access */
fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
+ u32 __iomem *reg_ptr;
+
+ reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
+ tmp = ehci_readl(ehci, reg_ptr);
+
+ /* quit, if not in host mode */
+ if ((tmp & USBMODE_CM_HC) != USBMODE_CM_HC) {
+ usb_host_set_wakeup(hcd->self.controller, true);
+ fsl_usb_clk_gate(hcd->self.controller->platform_data, false);
+ enable_irq(hcd->irq);
+ return 0;
+ }
fsl_usb_lowpower_mode(pdata, false);
tmp = ehci_readl(ehci, &ehci->regs->port_status[0]);