From: yangkai Date: Thu, 5 May 2011 08:57:23 +0000 (+0800) Subject: reconnect to PC if usb config change X-Git-Tag: firefly_0821_release~10357 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5f245d22092781a6d6b5901fda14b26c3004fd81;p=firefly-linux-kernel-4.4.55.git reconnect to PC if usb config change --- diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index 6c1f1d720c18..4df9ff25b86c 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -567,8 +567,8 @@ static int dwc_otg_pcd_ep_queue(struct usb_ep *_ep, ep = container_of(_ep, dwc_otg_pcd_ep_t, ep); request_done(ep, req, -ECONNABORTED); DWC_PRINT("%s::ep %s req not empty,done it error!\n" , __func__, _ep->name); - return -EINVAL; } + return -EINVAL; } ep = container_of(_ep, dwc_otg_pcd_ep_t, ep); @@ -999,10 +999,42 @@ static int dwc_otg_pcd_wakeup(struct usb_gadget *_gadget) return 0; } +static int dwc_otg_pcd_pullup(struct usb_gadget *_gadget, int is_on) +{ + unsigned long flags; + dwc_otg_pcd_t *pcd; + dctl_data_t dctl = {.d32=0}; + dwc_otg_core_if_t *core_if; + DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _gadget); + + if (_gadget == 0) + { + return -ENODEV; + } + else + { + pcd = container_of(_gadget, dwc_otg_pcd_t, gadget); + core_if = GET_CORE_IF(pcd); + } + if(is_on) //connect + { + dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); + dctl.b.sftdiscon = 0; + dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); + } + else //disconnect + { + dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); + dctl.b.sftdiscon = 1; + dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); + } +} + static const struct usb_gadget_ops dwc_otg_pcd_ops = { .get_frame = dwc_otg_pcd_get_frame, .wakeup = dwc_otg_pcd_wakeup, + .pullup = dwc_otg_pcd_pullup, // current versions must always be self-powered }; @@ -1619,7 +1651,6 @@ static void dwc_phy_reconnect(struct work_struct *work) core_if = GET_CORE_IF(pcd); gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); if( gctrl.b.bsesvld ) { - dwc_otg_msc_lock(pcd); pcd->conn_status++; dwc_pcd_reset(pcd); /* @@ -1649,24 +1680,25 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) if( gctrl.b.bsesvld ) { /* if usb not connect before ,then start connect */ if( _pcd->vbus_status == 0 ) { + dwc_otg_msc_lock(_pcd); DWC_PRINT("********vbus detect*********************************************\n"); - _pcd->vbus_status = 1; - /* soft disconnect */ - dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); - dctl.b.sftdiscon = 1; - dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); - /* Clear any pending interrupts */ - dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); - if(_pcd->conn_en) - { - schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ - _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ - } + _pcd->vbus_status = 1; + /* soft disconnect */ + dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); + dctl.b.sftdiscon = 1; + dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); + /* Clear any pending interrupts */ + dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); + if(_pcd->conn_en) + { + schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ + _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ + } } else if((_pcd->conn_status>0)&&(_pcd->conn_status <3)) { - dwc_otg_msc_unlock(_pcd); + //dwc_otg_msc_unlock(_pcd); DWC_PRINT("********soft reconnect******************************************\n"); - _pcd->vbus_status =0; + //_pcd->vbus_status =0; /* soft disconnect */ dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); @@ -1674,6 +1706,11 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); + if(_pcd->conn_en) + { + schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ + _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ + } } else if((_pcd->conn_en)&&(_pcd->conn_status == 0)) { @@ -1722,7 +1759,7 @@ void dwc_otg_pcd_start_vbus_timer( dwc_otg_pcd_t * _pcd ) * when receive reset int,the vbus state may not be update,so * always start timer here. */ - mod_timer( vbus_timer , jiffies + (HZ<<2)); + mod_timer( vbus_timer , jiffies + (HZ)); } /* diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c old mode 100644 new mode 100755 index c6ab4d1b206c..140fafed70a1 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -113,7 +113,7 @@ void usb_composite_force_reset(struct usb_composite_dev *cdev) if (cdev && cdev->gadget && cdev->gadget->speed != USB_SPEED_UNKNOWN) { /* avoid sending a disconnect switch event until after we disconnect */ - cdev->mute_switch = 1; +// cdev->mute_switch = 1;// yk 20110505 rk29 don't need to mute switch spin_unlock_irqrestore(&cdev->lock, flags); usb_gadget_disconnect(cdev->gadget);