+static void rk_ehci_hcd_enable(struct work_struct *work)
+{
+ struct rk_ehci_hcd *rk_ehci;
+ struct usb_hcd *hcd;
+ struct rkehci_platform_data *pldata;
+ struct ehci_hcd *ehci;
+
+ rk_ehci = container_of(work, struct rk_ehci_hcd, host_enable_work.work);
+ pldata = rk_ehci->pldata;
+ ehci = rk_ehci->ehci;
+ hcd = ehci_to_hcd(ehci);
+
+ if(rk_ehci->host_enabled == rk_ehci->host_setenable){
+ printk("%s, enable flag %d\n", __func__, rk_ehci->host_setenable);
+ goto out;
+ }
+
+ if(rk_ehci->host_setenable == 2){// enable -> disable
+ if(pldata->get_status(USB_STATUS_DPDM)){// usb device connected
+ rk_ehci->host_setenable = 1;
+ goto out;
+ }
+
+ printk("%s, disable host controller\n", __func__);
+ ehci_port_power(ehci, 0);
+ usb_remove_hcd(hcd);
+
+ /* reset cru and reinitialize EHCI controller */
+ pldata->soft_reset();
+ usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
+ if(pldata->phy_suspend)
+ pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
+ /* do not disable EHCI clk, otherwise RK3288
+ * host1(DWC_OTG) can't work normally.
+ */
+ //pldata->clock_enable(pldata, 0);
+ }else if(rk_ehci->host_setenable == 1){
+ //pldata->clock_enable(pldata, 1);
+ if(pldata->phy_suspend)
+ pldata->phy_suspend(pldata, USB_PHY_ENABLED);
+ mdelay(5);
+ ehci_port_power(ehci, 1);
+ printk("%s, enable host controller\n", __func__);
+ }
+ rk_ehci->host_enabled = rk_ehci->host_setenable;
+
+out:
+ return;
+}
+
+static void rk_ehci_hcd_connect_detect(unsigned long pdata)
+{
+ struct rk_ehci_hcd *rk_ehci= (struct rk_ehci_hcd*)pdata;
+ struct ehci_hcd *ehci = rk_ehci->ehci;
+ struct rkehci_platform_data *pldata;
+ uint32_t status;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ pldata = rk_ehci->pldata;
+
+ if(pldata->get_status(USB_STATUS_DPDM)){
+ // usb device connected
+ rk_ehci->host_setenable = 1;
+ }else{
+ // no device, suspend host
+ status = readl(&ehci->regs->port_status[0]);
+ if(!(status & PORT_CONNECT)){
+ rk_ehci->host_setenable = 2;
+ }
+ }
+
+ if((rk_ehci->host_enabled) && (rk_ehci->host_setenable != rk_ehci->host_enabled)){
+ schedule_delayed_work(&rk_ehci->host_enable_work, 1);
+ }
+
+ mod_timer(&rk_ehci->connect_detect_timer,jiffies + (HZ<<1));
+
+ local_irq_restore(flags);
+ return;
+}
+