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)
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();
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);
}
}
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;
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);