summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2011-09-01 17:33:25 +0800
committerPeter Chen <peter.chen@freescale.com>2011-09-01 17:36:46 +0800
commit99b30f75f47f53a1067695038b040c94c8d51912 (patch)
tree0bc3d26c28f06879544b1baba3535fe9f842fe70
parentca317a06df0eb316fef53abb1a9f0c82822d4a71 (diff)
ENGR00155764 usb-host: fix the system hang when access register with clocks OFF
Fix the system hang when access usb registers with usb's clocks are OFF, open the usb clock before visiting the usb registers resolves this problem Signed-off-by: Peter Chen <peter.chen@freescale.com>
-rw-r--r--drivers/usb/host/ehci-arc.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c
index 74666eeca997..c7e78396e6dc 100644
--- a/drivers/usb/host/ehci-arc.c
+++ b/drivers/usb/host/ehci-arc.c
@@ -623,21 +623,22 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
/* Only handles OTG mode switch event, system suspend event will be done in bus suspend */
if (pdata->pmflags == 0) {
printk(KERN_DEBUG "%s, pm event \n", __func__);
+ /* Need open clock for register access */
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+ fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
+
ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd),
device_may_wakeup(&(pdev->dev)));
if (!host_can_wakeup_system(pdev)) {
int mask;
- /* Need open clock for register access */
- if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
- fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
mask = ehci_readl(ehci, &ehci->regs->intr_enable);
mask &= ~STS_PCD;
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
usb_host_set_wakeup(hcd->self.controller, false);
- fsl_usb_clk_gate(hcd->self.controller->platform_data, false);
}
+ fsl_usb_clk_gate(hcd->self.controller->platform_data, false);
printk(KERN_DEBUG "host suspend ends\n");
return 0;
}
@@ -724,17 +725,17 @@ static int ehci_fsl_drv_resume(struct platform_device *pdev)
if (pdata->pmflags == 0) {
printk(KERN_DEBUG "%s,pm event, wait for wakeup irq if needed\n", __func__);
wait_event_interruptible(wake_up_pdata->wq, !wake_up_pdata->usb_wakeup_is_pending);
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+ fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
+ }
if (!host_can_wakeup_system(pdev)) {
- if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
- fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
- }
usb_host_set_wakeup(hcd->self.controller, true);
- if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
- fsl_usb_clk_gate(hcd->self.controller->platform_data, false);
- }
}
ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd));
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+ fsl_usb_clk_gate(hcd->self.controller->platform_data, false);
+ }
return 0;
}
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {