add usb buffer cache maintaince
authoryangkai <yk@rock-chips.com>
Sat, 31 Mar 2012 07:54:42 +0000 (15:54 +0800)
committeryangkai <yk@rock-chips.com>
Sat, 31 Mar 2012 07:54:42 +0000 (15:54 +0800)
drivers/usb/dwc_otg/dwc_otg_pcd.c
drivers/usb/dwc_otg/dwc_otg_pcd_intr.c

index 76099b51e4a5f6a586ff4448f31c5d1dc5fe3ec1..4e9c2e574e56566ad5e3427fdb46506ba7e9cc69 100755 (executable)
@@ -118,22 +118,21 @@ void request_done(dwc_otg_pcd_ep_t *_ep, dwc_otg_pcd_request_t *_req,
        {       
                _status = _req->req.status;
        }
-#if 0
-
-               if (_req->mapped) {
-                       dma_unmap_single(_ep->pcd->gadget.dev.parent,
-                               _req->req.dma, _req->req.length,
-                               _ep->dwc_ep.is_in
-                                       ? DMA_TO_DEVICE
-                                       : DMA_FROM_DEVICE);
-                       _req->req.dma = DMA_ADDR_INVALID;
-                       _req->mapped = 0;
-               } else
-                       dma_sync_single_for_cpu(_ep->pcd->gadget.dev.parent,
-                               _req->req.dma, _req->req.length,
-                               _ep->dwc_ep.is_in
-                                       ? DMA_TO_DEVICE
-                                       : DMA_FROM_DEVICE);
+#if 1
+       if (_req->mapped) {
+               dma_unmap_single(_ep->pcd->gadget.dev.parent,
+                       _req->req.dma, _req->req.length,
+                       _ep->dwc_ep.is_in
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+               _req->req.dma = DMA_ADDR_INVALID;
+               _req->mapped = 0;
+       } else
+               dma_sync_single_for_cpu(_ep->pcd->gadget.dev.parent,
+                       _req->req.dma, _req->req.length,
+                       _ep->dwc_ep.is_in
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
 #endif
        /* don't modify queue heads during completion callback */
        _ep->stopped = 1;
@@ -1149,9 +1148,9 @@ static int32_t dwc_otg_pcd_suspend_cb( void *_p ,int suspend)
 //#endif               
        if (pcd->driver && pcd->driver->resume) 
        {
-//             SPIN_UNLOCK(&pcd->lock);
+               SPIN_UNLOCK(&pcd->lock);
                pcd->driver->suspend(&pcd->gadget);
-//             SPIN_LOCK(&pcd->lock);
+               SPIN_LOCK(&pcd->lock);
        }
        return 1;
 }
@@ -1706,7 +1705,7 @@ static void dwc_phy_reconnect(struct work_struct *work)
         DWC_PRINT("********soft connect!!!*****************************************\n");
     } 
 }
-
+#ifdef CONFIG_ARCH_RK29
 static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
 {
     dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
@@ -1793,6 +1792,85 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
     add_timer(&_pcd->check_vbus_timer); 
        local_irq_restore(flags);
 }
+#endif
+#ifdef CONFIG_ARCH_RK30
+static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
+{
+    dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd);
+    gotgctl_data_t    gctrl;
+    dctl_data_t dctl = {.d32=0};
+    //dsts_data_t           gsts;
+       unsigned long flags;
+#ifdef CONFIG_ARCH_RK30
+    unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);
+#endif
+    _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
+       if(usbgrf_status &0x20000){  // bvalid
+        /* 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;
+            if(_pcd->conn_en)
+           {
+                   if( _pcd->phy_suspend  == 1 ) { 
+//                     rk28_usb_suspend( 1 );
+                }
+                   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_PRINT("********soft reconnect******************************************\n");
+            //_pcd->vbus_status =0;
+            
+            /* 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_en)&&(_pcd->conn_status == 0))
+        {
+            DWC_PRINT("********vbus detect ccccc*********************************************\n");
+       
+           schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
+                    _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
+        }
+        else if(_pcd->conn_status ==3)
+        {
+                       //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
+            dwc_otg_msc_unlock(_pcd);
+            _pcd->conn_status++;
+            if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
+                _pcd->vbus_status = 2;
+        }
+       }else {
+        //DWC_PRINT("new vbus=%d,old vbus=%d\n" , gctrl.b.bsesvld , _pcd->vbus_status );
+       DWC_PRINT("********vbus 0******************************************\n");
+        _pcd->vbus_status = 0;
+        if(_pcd->conn_status)
+        {
+             _pcd->conn_status = 0;
+             dwc_otg_msc_unlock(_pcd);
+        }
+        /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
+        if( _pcd->phy_suspend == 0 ) 
+                /* no vbus detect here , close usb phy  */
+             rk28_usb_suspend( 0 );
+    }
+    add_timer(&_pcd->check_vbus_timer); 
+}
+
+#endif
 #ifdef CONFIG_ARCH_RK29
 /*
  * This function can be only called in charge mode.
index 7db4671907e0a4352318c298857d3059884537f1..85bd8491128110056f94f702214faff189032fc6 100755 (executable)
@@ -606,9 +606,9 @@ void dwc_otg_pcd_stop(dwc_otg_pcd_t *_pcd)
        /* report disconnect; the driver is already quiesced */
        if (_pcd->driver && _pcd->driver->disconnect) 
        {
-//             SPIN_UNLOCK(&_pcd->lock);
+               SPIN_UNLOCK(&_pcd->lock);
                _pcd->driver->disconnect(&_pcd->gadget);
-//             SPIN_LOCK(&_pcd->lock);
+               SPIN_LOCK(&_pcd->lock);
        }
 }
 
@@ -947,6 +947,7 @@ int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *_pcd)
     dwc_write_reg32( &GET_CORE_IF(_pcd)->dev_if->out_ep_regs[2]->doepctl, depctl.d32 );
     dwc_write_reg32( &GET_CORE_IF(_pcd)->dev_if->out_ep_regs[4]->doepctl, depctl.d32 );
     dwc_write_reg32( &GET_CORE_IF(_pcd)->dev_if->out_ep_regs[6]->doepctl, depctl.d32 );
+    dwc_write_reg32( &GET_CORE_IF(_pcd)->dev_if->out_ep_regs[8]->doepctl, depctl.d32 );
        return 1;
 }