fix some bug with spin_lock in usb pcd
authoryangkai <yk@rock-chips.com>
Mon, 26 Mar 2012 13:53:51 +0000 (21:53 +0800)
committeryangkai <yk@rock-chips.com>
Mon, 26 Mar 2012 13:53:51 +0000 (21:53 +0800)
drivers/usb/dwc_otg/dwc_otg_cil.c
drivers/usb/dwc_otg/dwc_otg_cil.h
drivers/usb/dwc_otg/dwc_otg_pcd.c
drivers/usb/dwc_otg/linux/dwc_otg_plat.h

index a259a6923ec3d854820b1f321a08f22d7ac31a15..8fc8441718bb4e5497022c4ff73e02494a3b4199 100755 (executable)
@@ -3002,6 +3002,10 @@ extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if,
 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *_core_if)
 {
        volatile uint32_t *addr;
+       uint32_t hwcfg1;
+       int i;
+
+       hwcfg1 = ~_core_if->core_global_regs->ghwcfg1;
        
        DWC_PRINT("Device Global Registers\n");
        addr=&_core_if->dev_if->dev_global_regs->dcfg;
@@ -3045,101 +3049,35 @@ void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *_core_if)
                DWC_PRINT("DTKNQR4       @0x%08X : 0x%08X\n",
                                  (uint32_t)addr, dwc_read_reg32(addr));
        }
-       DWC_PRINT("Device IN EP 0 Registers\n");
-       addr=&_core_if->dev_if->in_ep_regs[0]->diepctl;
-       DWC_PRINT("DIEPCTL0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[0]->diepint;
-       DWC_PRINT("DIEPINT0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[0]->dieptsiz;
-       DWC_PRINT("DIETSIZ0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[0]->diepdma;
-       DWC_PRINT("DIEPDMA0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[0]->dtxfsts;
-       DWC_PRINT("DTXFSTS0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-
-       DWC_PRINT("Device OUT EP 0 Registers\n");
-       addr=&_core_if->dev_if->out_ep_regs[0]->doepctl;
-       DWC_PRINT("DOEPCTL0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[0]->doepfn;
-       DWC_PRINT("DOEPFN0       @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[0]->doepint;
-       DWC_PRINT("DOEPINT0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[0]->doeptsiz;
-       DWC_PRINT("DOETSIZ0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[0]->doepdma;
-       DWC_PRINT("DOEPDMA0      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-
-       DWC_PRINT("Device IN EP 1 Registers\n");
-       addr=&_core_if->dev_if->in_ep_regs[1]->diepctl;
-       DWC_PRINT("DIEPCTL1      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[1]->diepint;
-       DWC_PRINT("DIEPINT1      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[1]->dieptsiz;
-       DWC_PRINT("DIETSIZ1      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[1]->diepdma;
-       DWC_PRINT("DIEPDMA1      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[1]->dtxfsts;
-       DWC_PRINT("DTXFSTS1      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-
-       DWC_PRINT("Device OUT EP 2 Registers\n");
-       addr=&_core_if->dev_if->out_ep_regs[2]->doepctl;
-       DWC_PRINT("DOEPCTL2      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[2]->doepfn;
-       DWC_PRINT("DOEPFN2       @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[2]->doepint;
-       DWC_PRINT("DOEPINT2      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[2]->doeptsiz;
-       DWC_PRINT("DOETSIZ2      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[2]->doepdma;
-       DWC_PRINT("DOEPDMA2      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       
-       DWC_PRINT("Device IN EP 3 Registers\n");
-       addr=&_core_if->dev_if->in_ep_regs[3]->diepctl;
-       DWC_PRINT("DIEPCTL3      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[3]->diepint;
-       DWC_PRINT("DIEPINT3      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[3]->dieptsiz;
-       DWC_PRINT("DIETSIZ3      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[3]->diepdma;
-       DWC_PRINT("DIEPDMA3      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[3]->dtxfsts;
-       DWC_PRINT("DTXFSTS3      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-
-       DWC_PRINT("Device OUT EP 4 Registers\n");
-       addr=&_core_if->dev_if->out_ep_regs[4]->doepctl;
-       DWC_PRINT("DOEPCTL4      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[4]->doepfn;
-       DWC_PRINT("DOEPFN4       @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[4]->doepint;
-       DWC_PRINT("DOEPINT4      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[4]->doeptsiz;
-       DWC_PRINT("DOETSIZ4      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[4]->doepdma;
-       DWC_PRINT("DOEPDMA4      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       
-       DWC_PRINT("Device IN EP 5 Registers\n");
-       addr=&_core_if->dev_if->in_ep_regs[5]->diepctl;
-       DWC_PRINT("DIEPCTL5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[5]->diepint;
-       DWC_PRINT("DIEPINT5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[5]->dieptsiz;
-       DWC_PRINT("DIETSIZ5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[5]->diepdma;
-       DWC_PRINT("DIEPDMA5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->in_ep_regs[5]->dtxfsts;
-       DWC_PRINT("DTXFSTS5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-
-       DWC_PRINT("Device OUT EP 6 Registers\n");
-       addr=&_core_if->dev_if->out_ep_regs[6]->doepctl;
-       DWC_PRINT("DOEPCTL6      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[6]->doepfn;
-       DWC_PRINT("DOEPFN6       @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[6]->doepint;
-       DWC_PRINT("DOEPINT6      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[6]->doeptsiz;
-       DWC_PRINT("DOETSIZ6      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
-       addr=&_core_if->dev_if->out_ep_regs[6]->doepdma;
-       DWC_PRINT("DOEPDMA6      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+       for (i=0; i<_core_if->core_params->dev_endpoints; i++) 
+       {
+           if(hwcfg1 & (2<<(i<<1))){
+               DWC_PRINT("Device IN EP %d Registers\n", i);
+               addr=&_core_if->dev_if->in_ep_regs[i]->diepctl;
+               DWC_PRINT("DIEPCTL5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+               addr=&_core_if->dev_if->in_ep_regs[i]->diepint;
+               DWC_PRINT("DIEPINT5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+               addr=&_core_if->dev_if->in_ep_regs[i]->dieptsiz;
+               DWC_PRINT("DIETSIZ5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+               addr=&_core_if->dev_if->in_ep_regs[i]->diepdma;
+               DWC_PRINT("DIEPDMA5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+               addr=&_core_if->dev_if->in_ep_regs[i]->dtxfsts;
+               DWC_PRINT("DTXFSTS5      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+           }
+           if(hwcfg1 & (1<<(i<<1))){
+               DWC_PRINT("Device OUT EP %d Registers\n", i);
+               addr=&_core_if->dev_if->out_ep_regs[i]->doepctl;
+               DWC_PRINT("DOEPCTL6      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+               addr=&_core_if->dev_if->out_ep_regs[i]->doepfn;
+               DWC_PRINT("DOEPFN6       @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+               addr=&_core_if->dev_if->out_ep_regs[i]->doepint;
+               DWC_PRINT("DOEPINT6      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+               addr=&_core_if->dev_if->out_ep_regs[i]->doeptsiz;
+               DWC_PRINT("DOETSIZ6      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+               addr=&_core_if->dev_if->out_ep_regs[i]->doepdma;
+               DWC_PRINT("DOEPDMA6      @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
+           }
+       }
 
        return;
 }
index a93555ed306adf72be20c5597cbfad1f888a285f..6dadebf09ad876ac564620d60290adc622caef08 100755 (executable)
@@ -438,7 +438,7 @@ typedef struct dwc_otg_core_params
         * endpoints in addition to EP0.
         */
        int32_t dev_endpoints;
-#define dwc_param_dev_endpoints_default 6
+#define dwc_param_dev_endpoints_default 10
 
                /** 
                 * Specifies the type of PHY interface to use. By default, the driver
index 1749a24f2590ba821e134b9b3a17fb2d2f9d1a40..36eb032a96d876eeb04968fdf8af8020dfedee8d 100755 (executable)
@@ -286,7 +286,8 @@ static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep,
                return -ESHUTDOWN;
        }
 
-       SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
+       local_irq_save(flags);
+//     SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
                
        ep->desc = _desc;
        ep->ep.maxpacket = le16_to_cpu (_desc->wMaxPacketSize);
@@ -352,7 +353,8 @@ static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep,
                                        ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc );
                
        dwc_otg_ep_activate( GET_CORE_IF(pcd), &ep->dwc_ep );
-       SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
+//     SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
+    local_irq_restore(flags);
        return 0;
 }
 
@@ -379,7 +381,8 @@ static int dwc_otg_pcd_ep_disable(struct usb_ep *_ep)
                return -EINVAL;
        }
                
-       SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
+//     SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
+    local_irq_save(flags);
        request_nuke( ep );                
 
        dwc_otg_ep_deactivate( GET_CORE_IF(ep->pcd), &ep->dwc_ep );
@@ -392,7 +395,8 @@ static int dwc_otg_pcd_ep_disable(struct usb_ep *_ep)
                release_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
        }       
        
-       SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
+//     SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
+    local_irq_restore(flags);
 
        DWC_DEBUGPL(DBG_PCD, "%s disabled\n", _ep->name);
        return 0;
@@ -1649,20 +1653,18 @@ void dwc_otg_msc_lock(dwc_otg_pcd_t *pcd)
 {
        unsigned long           flags;
 
-       spin_lock_irqsave(&pcd->lock, flags);
-
+       local_irq_save(flags);
     wake_lock(&pcd->wake_lock);
-
-       spin_unlock_irqrestore(&pcd->lock, flags);
+    local_irq_restore(flags);
 
 }
 
 void dwc_otg_msc_unlock(dwc_otg_pcd_t *pcd)
 {
        unsigned long           flags;
-       spin_lock_irqsave(&pcd->lock, flags);
+       local_irq_save(flags);
        wake_unlock(&pcd->wake_lock);
-    spin_unlock_irqrestore(&pcd->lock, flags);
+       local_irq_restore(flags);
 }
 static void dwc_phy_reconnect(struct work_struct *work)
 {
@@ -1826,13 +1828,11 @@ int dwc_otg_pcd_init(struct device *dev)
        
        memset( pcd, 0, sizeof(dwc_otg_pcd_t));
        spin_lock_init( &pcd->lock );
-       spin_lock(&pcd->lock);
        otg_dev->pcd = pcd;
        s_pcd = pcd;
        pcd->gadget.name = pcd_name;
        //strcpy(pcd->gadget.dev.bus_id, "gadget");
        
-       spin_unlock(&pcd->lock);
        pcd->otg_dev = otg_dev;
        
        pcd->gadget.dev.parent = dev;
index 6460005e97c3054404e8ea95e95958b051a75a30..1425ca691f84bd875bfbab22ec130d39be800a08 100755 (executable)
@@ -89,7 +89,7 @@
  */
 static __inline__ uint32_t dwc_read_reg32( volatile uint32_t *_reg) 
 {
-        return readl(_reg);
+        return readl_relaxed(_reg);
 };
 
 /** 
@@ -103,7 +103,8 @@ static __inline__ uint32_t dwc_read_reg32( volatile uint32_t *_reg)
  */
 static __inline__ void dwc_write_reg32( volatile uint32_t *_reg, const uint32_t _value) 
 {
-        writel( _value, _reg );
+        writel_relaxed( _value, _reg );
+        dsb();
 };
 
 /**  
@@ -122,7 +123,8 @@ static __inline__ void dwc_write_reg32( volatile uint32_t *_reg, const uint32_t
 static __inline__
  void dwc_modify_reg32( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask) 
 {
-        writel( (readl(_reg) & ~_clear_mask) | _set_mask, _reg );  
+        writel_relaxed( (readl_relaxed(_reg) & ~_clear_mask) | _set_mask, _reg );  
+        dsb();
 };
 
 
@@ -152,7 +154,7 @@ static __inline__ void MDELAY( const uint32_t _msecs )
  */
 static __inline__ void SPIN_LOCK( spinlock_t *_lock )  
 {
-        spin_lock(_lock);
+//        spin_lock(_lock);
 }
 
 /**
@@ -163,7 +165,7 @@ static __inline__ void SPIN_LOCK( spinlock_t *_lock )
  */
 static __inline__ void SPIN_UNLOCK( spinlock_t *_lock )     
 { 
-        spin_unlock(_lock);
+//        spin_unlock(_lock);
 }
 
 /**