Skip to content

Commit

Permalink
ENGR00234722 USB: fix Kernel dump issue after USB driver loadable
Browse files Browse the repository at this point in the history
- It is better to disable otgsc and wake up interrupt to avoid an
  abnormal interrupt happen during USB driver being removed.
- If the USB host is already at low power mode, only need turn on
  the clock, no need turn off the clock.
- Need discharge dp and dm during USB driver being removed ,in order
  to avoid a wakeup interrupt happen. And if the USB otg is in host
  mode, we should clear discharge dp and dm in fsl_otg_set_host()
  during system boot up.

Signed-off-by: make shi <b15407@freescale.com>
  • Loading branch information
make shi committed Dec 3, 2012
1 parent 812b6f8 commit 7395b05
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 4 deletions.
9 changes: 8 additions & 1 deletion drivers/usb/gadget/arcotg_udc.c
Expand Up @@ -3248,7 +3248,7 @@ static int __devinit fsl_udc_probe(struct platform_device *pdev)
static int fsl_udc_remove(struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;

u32 temp;
DECLARE_COMPLETION(done);

if (!udc_controller)
Expand All @@ -3258,6 +3258,13 @@ static int fsl_udc_remove(struct platform_device *pdev)
if (udc_controller->stopped)
dr_clk_gate(true);

/* disable wake up and otgsc interrupt for safely remove udc driver*/
temp = fsl_readl(&dr_regs->otgsc);
temp &= ~(0x7f << 24);
fsl_writel(temp, &dr_regs->otgsc);
dr_wake_up_enable(udc_controller, false);

dr_discharge_line(pdata, true);
/* DR has been stopped in usb_gadget_unregister_driver() */
remove_proc_file();

Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/host/ehci-arc.c
Expand Up @@ -339,14 +339,14 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
if (pdata->usb_clock_for_pm)
pdata->usb_clock_for_pm(true);

/*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);

if (pdata->usb_clock_for_pm)
pdata->usb_clock_for_pm(false);
}
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/usb/otg/fsl_otg.c
Expand Up @@ -607,6 +607,9 @@ int fsl_otg_start_gadget(struct otg_fsm *fsm, int on)
static int fsl_otg_set_host(struct otg_transceiver *otg_p, struct usb_bus *host)
{
struct fsl_otg *otg_dev = container_of(otg_p, struct fsl_otg, otg);
struct fsl_usb2_platform_data *pdata;

pdata = otg_dev->otg.dev->platform_data;

if (!otg_p || otg_dev != fsl_otg_dev)
return -ENODEV;
Expand All @@ -633,6 +636,8 @@ static int fsl_otg_set_host(struct otg_transceiver *otg_p, struct usb_bus *host)
else {
/* if the device is already at the port */
otg_drv_vbus(&otg_dev->fsm, 1);
if (pdata->dr_discharge_line)
pdata->dr_discharge_line(false);
fsl_otg_wait_stable_vbus(true);
b_session_irq_enable(false);
fsl_otg_start_host(&otg_dev->fsm, 1);
Expand Down

0 comments on commit 7395b05

Please sign in to comment.