From 74506a87359b9fe29171b505628502e1c05afbe2 Mon Sep 17 00:00:00 2001 From: yangkai Date: Mon, 26 Mar 2012 21:53:51 +0800 Subject: [PATCH] fix some bug with spin_lock in usb pcd --- drivers/usb/dwc_otg/dwc_otg_cil.c | 128 ++++++----------------- drivers/usb/dwc_otg/dwc_otg_cil.h | 2 +- drivers/usb/dwc_otg/dwc_otg_pcd.c | 24 ++--- drivers/usb/dwc_otg/linux/dwc_otg_plat.h | 12 ++- 4 files changed, 53 insertions(+), 113 deletions(-) diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c index a259a6923ec3..8fc8441718bb 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c @@ -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; } diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.h b/drivers/usb/dwc_otg/dwc_otg_cil.h index a93555ed306a..6dadebf09ad8 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.h +++ b/drivers/usb/dwc_otg/dwc_otg_cil.h @@ -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 diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index 1749a24f2590..36eb032a96d8 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -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; diff --git a/drivers/usb/dwc_otg/linux/dwc_otg_plat.h b/drivers/usb/dwc_otg/linux/dwc_otg_plat.h index 6460005e97c3..1425ca691f84 100755 --- a/drivers/usb/dwc_otg/linux/dwc_otg_plat.h +++ b/drivers/usb/dwc_otg/linux/dwc_otg_plat.h @@ -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); } /** -- 2.34.1