summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony LIU <junjie.liu@freescale.com>2012-03-07 15:55:32 +0800
committerTony LIU <junjie.liu@freescale.com>2012-03-21 09:59:53 +0800
commita6cbe35a5d2ea61fa12ee5ccc4b89bab0563aebe (patch)
tree1ddbc29754a72d345254999eb3bd7ea78dd1350a
parent69d533be68e085039d0561f469dbd7c3c3a259b5 (diff)
ENGR00176299-2 usb host suspend/resume can't work randomly
usb core part Signed-off-by: Tony LIU <junjie.liu@freescale.com>
-rw-r--r--drivers/usb/core/hub.c32
-rw-r--r--drivers/usb/host/ehci-hub.c20
2 files changed, 36 insertions, 16 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 4ef23fe6789d..2dcf9ffe97c1 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -32,10 +32,7 @@
#ifdef CONFIG_ARCH_MX6
#define MX6_USB_HOST_HACK
-
#include <linux/fsl_devices.h>
-extern void fsl_platform_set_usb_phy_dis(struct fsl_usb2_platform_data *pdata,
- bool enable);
#endif
/* if we are in debug mode, always announce new devices */
#ifdef DEBUG
@@ -2539,6 +2536,17 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
(msg.event & PM_EVENT_AUTO ? "auto-" : ""));
msleep(25);
+#ifdef MX6_USB_HOST_HACK
+ if (hub->hdev->parent == NULL) {
+ struct usb_device *hdev = hub->hdev;
+ struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
+ struct fsl_usb2_platform_data *pdata;
+ pdata = hcd->self.controller->platform_data;
+ if (pdata->platform_rh_resume)
+ pdata->platform_rh_resume(pdata);
+ }
+#endif
+
/* Virtual root hubs can trigger on GET_PORT_STATUS to
* stop resume signaling. Then finish the resume
* sequence.
@@ -2550,6 +2558,16 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
}
SuspendCleared:
+#ifdef MX6_USB_HOST_HACK
+ if (hub->hdev->parent == NULL) {
+ struct usb_device *hdev = hub->hdev;
+ struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
+ struct fsl_usb2_platform_data *pdata;
+ pdata = hcd->self.controller->platform_data;
+ if (pdata->platform_rh_resume)
+ pdata->platform_rh_resume(pdata);
+ }
+#endif
if (status == 0) {
if (hub_is_superspeed(hub->hdev)) {
if (portchange & USB_PORT_STAT_C_LINK_STATE)
@@ -3036,7 +3054,8 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
struct fsl_usb2_platform_data *pdata;
pdata = (struct fsl_usb2_platform_data *)
dev->platform_data;
- fsl_platform_set_usb_phy_dis(pdata, 1);
+ if (pdata && pdata->platform_set_disconnect_det)
+ pdata->platform_set_disconnect_det(pdata, 1);
}
}
}
@@ -3189,9 +3208,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
pdata->init(NULL);
}
if ((port1 == 1) && (hdev->level == 0)) {
- if (!(portstatus&USB_PORT_STAT_CONNECTION)) {
+ if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
/* Must clear HOSTDISCONDETECT when disconnect*/
- fsl_platform_set_usb_phy_dis(pdata, 0);
+ if (pdata->platform_set_disconnect_det)
+ pdata->platform_set_disconnect_det(pdata, 0);
}
}
}
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index d6a80d9731a2..b49e65f8d89e 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -430,6 +430,14 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
spin_unlock_irq(&ehci->lock);
msleep(20);
spin_lock_irq(&ehci->lock);
+#ifdef MX6_USB_HOST_HACK
+ {
+ struct fsl_usb2_platform_data *pdata;
+ pdata = hcd->self.controller->platform_data;
+ if (pdata->platform_rh_resume)
+ pdata->platform_rh_resume(pdata);
+ }
+#endif
}
i = HCS_N_PORTS (ehci->hcs_params);
@@ -826,14 +834,6 @@ static int ehci_hub_control (
msleep(5);/* wait to leave low-power mode */
spin_lock_irqsave(&ehci->lock, flags);
}
- #ifdef MX6_USB_HOST_HACK
- {
- struct fsl_usb2_platform_data *pdata;
- pdata = hcd->self.controller->platform_data;
- if (pdata->platform_resume)
- pdata->platform_resume(pdata);
- }
- #endif
/* resume signaling for 20 msec */
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
@@ -1079,8 +1079,8 @@ static int ehci_hub_control (
{
struct fsl_usb2_platform_data *pdata;
pdata = hcd->self.controller->platform_data;
- if (pdata->platform_suspend)
- pdata->platform_suspend(pdata);
+ if (pdata->platform_rh_suspend)
+ pdata->platform_rh_suspend(pdata);
}
#endif
if (hostpc_reg) {