diff options
author | Peter Chen <peter.chen@freescale.com> | 2013-04-12 16:04:37 +0800 |
---|---|---|
committer | Peter Chen <peter.chen@freescale.com> | 2013-04-24 09:22:00 +0800 |
commit | 8086df3040dcac95688cecbeed3de052fe33ea2e (patch) | |
tree | 165288bde331147996873d72fd0157386890c269 | |
parent | 72c86f0b9a953e91bb1ed31021b71f337050bc28 (diff) |
ENGR00258491-1 usb: host: fix error at unload module path
- When take the PHY out of low power mode, it needs to
call PHY's API, only set controller register is
not enough for some platforms
- usb_put_hcd will free hcd, all hcd related operation should
be prior to it.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
-rwxr-xr-x | drivers/usb/host/ehci-arc.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c index 1dbe54f2b183..4a63faefe83b 100755 --- a/drivers/usb/host/ehci-arc.c +++ b/drivers/usb/host/ehci-arc.c @@ -333,7 +333,6 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - u32 tmp; if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { /* Need open clock for register access */ @@ -343,31 +342,35 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, /*disable the wakeup to avoid an abnormal wakeup interrupt*/ usb_host_set_wakeup(hcd->self.controller, false); - tmp = ehci_readl(ehci, &ehci->regs->port_status[0]); - if (tmp & PORT_PTS_PHCD) { - tmp &= ~PORT_PTS_PHCD; - ehci_writel(ehci, tmp, &ehci->regs->port_status[0]); - msleep(100); - } + /* Put the PHY out of low power mode */ + fsl_usb_lowpower_mode(pdata, false); } + /* disable the host wakeup */ + usb_host_set_wakeup(hcd->self.controller, false); + /*free the ehci_fsl_pre_irq */ + free_irq(hcd->irq, (void *)pdev); + + usb_remove_hcd(hcd); + + ehci_port_power(ehci, 0); + + iounmap(hcd->regs); + if (ehci->transceiver) { (void)otg_set_host(ehci->transceiver, 0); otg_put_transceiver(ehci->transceiver); } else { release_mem_region(hcd->rsrc_start, hcd->rsrc_len); } - /*disable the host wakeup and put phy to low power mode */ - usb_host_set_wakeup(hcd->self.controller, false); - /*free the ehci_fsl_pre_irq */ - free_irq(hcd->irq, (void *)pdev); - usb_remove_hcd(hcd); + usb_put_hcd(hcd); fsl_usb_lowpower_mode(pdata, true); - /* DDD shouldn't we turn off the power here? */ - fsl_platform_set_vbus_power(pdata, 0); + /* Close the VBUS */ + if (pdata->xcvr_ops && pdata->xcvr_ops->set_vbus_power) + pdata->xcvr_ops->set_vbus_power(pdata->xcvr_ops, pdata, 0); /* * do platform specific un-initialization: @@ -375,8 +378,6 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, */ if (pdata->exit && pdata->pdev) pdata->exit(pdata->pdev); - - iounmap(hcd->regs); } static void fsl_setup_phy(struct ehci_hcd *ehci, |