aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorThomas Dahlmann <dahlmann.thomas@arcor.de>2009-11-17 17:18:27 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-11-30 19:43:15 -0500
commitc5deb832d7a3f9618b09e6eeaa91a1a845c90c65 (patch)
tree7676793d67592bac01c7605e4b37e26a63a27e9e /drivers/usb
parent0de6ab8b91f2e1e8e7fc66a8b5c5e8ca82ea16b7 (diff)
usb: amd5536udc: fixed shared interrupt bug and warning oops
- fixed shared interrupt bug reported by Vadim Lobanov - fixed possible warning oops on driver unload when connected - prevent interrupt flood in PIO mode ("modprobe amd5536udc use_dma=0") when using gadget ether Signed-off-by: Thomas Dahlmann <dahlmann.thomas@arcor.de> Cc: Robert Richter <robert.richter@amd.com> Cc: David Brownell <david-b@pacbell.net> Cc: stable <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/amd5536udc.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index d5b65962dd36..731150d4b1d9 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -1213,7 +1213,12 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp)
1213 tmp &= AMD_UNMASK_BIT(ep->num); 1213 tmp &= AMD_UNMASK_BIT(ep->num);
1214 writel(tmp, &dev->regs->ep_irqmsk); 1214 writel(tmp, &dev->regs->ep_irqmsk);
1215 } 1215 }
1216 } 1216 } else if (ep->in) {
1217 /* enable ep irq */
1218 tmp = readl(&dev->regs->ep_irqmsk);
1219 tmp &= AMD_UNMASK_BIT(ep->num);
1220 writel(tmp, &dev->regs->ep_irqmsk);
1221 }
1217 1222
1218 } else if (ep->dma) { 1223 } else if (ep->dma) {
1219 1224
@@ -2005,18 +2010,17 @@ __acquires(dev->lock)
2005{ 2010{
2006 int tmp; 2011 int tmp;
2007 2012
2008 /* empty queues and init hardware */
2009 udc_basic_init(dev);
2010 for (tmp = 0; tmp < UDC_EP_NUM; tmp++) {
2011 empty_req_queue(&dev->ep[tmp]);
2012 }
2013
2014 if (dev->gadget.speed != USB_SPEED_UNKNOWN) { 2013 if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
2015 spin_unlock(&dev->lock); 2014 spin_unlock(&dev->lock);
2016 driver->disconnect(&dev->gadget); 2015 driver->disconnect(&dev->gadget);
2017 spin_lock(&dev->lock); 2016 spin_lock(&dev->lock);
2018 } 2017 }
2019 /* init */ 2018
2019 /* empty queues and init hardware */
2020 udc_basic_init(dev);
2021 for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
2022 empty_req_queue(&dev->ep[tmp]);
2023
2020 udc_setup_endpoints(dev); 2024 udc_setup_endpoints(dev);
2021} 2025}
2022 2026
@@ -2472,6 +2476,13 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix)
2472 } 2476 }
2473 } 2477 }
2474 2478
2479 } else if (!use_dma && ep->in) {
2480 /* disable interrupt */
2481 tmp = readl(
2482 &dev->regs->ep_irqmsk);
2483 tmp |= AMD_BIT(ep->num);
2484 writel(tmp,
2485 &dev->regs->ep_irqmsk);
2475 } 2486 }
2476 } 2487 }
2477 /* clear status bits */ 2488 /* clear status bits */
@@ -3279,6 +3290,17 @@ static int udc_pci_probe(
3279 goto finished; 3290 goto finished;
3280 } 3291 }
3281 3292
3293 spin_lock_init(&dev->lock);
3294 /* udc csr registers base */
3295 dev->csr = dev->virt_addr + UDC_CSR_ADDR;
3296 /* dev registers base */
3297 dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
3298 /* ep registers base */
3299 dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
3300 /* fifo's base */
3301 dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
3302 dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
3303
3282 if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { 3304 if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
3283 dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); 3305 dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
3284 kfree(dev); 3306 kfree(dev);
@@ -3331,7 +3353,6 @@ static int udc_probe(struct udc *dev)
3331 udc_pollstall_timer.data = 0; 3353 udc_pollstall_timer.data = 0;
3332 3354
3333 /* device struct setup */ 3355 /* device struct setup */
3334 spin_lock_init(&dev->lock);
3335 dev->gadget.ops = &udc_ops; 3356 dev->gadget.ops = &udc_ops;
3336 3357
3337 dev_set_name(&dev->gadget.dev, "gadget"); 3358 dev_set_name(&dev->gadget.dev, "gadget");
@@ -3340,16 +3361,6 @@ static int udc_probe(struct udc *dev)
3340 dev->gadget.name = name; 3361 dev->gadget.name = name;
3341 dev->gadget.is_dualspeed = 1; 3362 dev->gadget.is_dualspeed = 1;
3342 3363
3343 /* udc csr registers base */
3344 dev->csr = dev->virt_addr + UDC_CSR_ADDR;
3345 /* dev registers base */
3346 dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
3347 /* ep registers base */
3348 dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
3349 /* fifo's base */
3350 dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
3351 dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
3352
3353 /* init registers, interrupts, ... */ 3364 /* init registers, interrupts, ... */
3354 startup_registers(dev); 3365 startup_registers(dev);
3355 3366