aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2013-02-08 08:24:04 -0500
committerFelipe Balbi <balbi@ti.com>2013-03-18 05:17:00 -0400
commit8698e2acf3a5e8d6f260ca7675f94e5087df5ae8 (patch)
tree7e18c79a0f72c410d9af65841aed9af42d9fe81f /drivers/usb/dwc3/gadget.c
parentf122d33e4b0045a42238b9a4c3943adf7e8313c1 (diff)
usb: dwc3: gadget: introduce and use enable/disable irq methods
we don't need to enable IRQs until we have a gadget driver loaded and ready to work, so let's delay IRQ enable to ->udc_start() and IRQ disable to ->udc_stop(). While at that, also move the related use of request_irq() and free_irq(). Tested-by: Vivek Gautam <gautam.vivek@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c80
1 files changed, 45 insertions, 35 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 65493b6cd5a6..db2031725abc 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1469,6 +1469,32 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
1469 return ret; 1469 return ret;
1470} 1470}
1471 1471
1472static void dwc3_gadget_enable_irq(struct dwc3 *dwc)
1473{
1474 u32 reg;
1475
1476 /* Enable all but Start and End of Frame IRQs */
1477 reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN |
1478 DWC3_DEVTEN_EVNTOVERFLOWEN |
1479 DWC3_DEVTEN_CMDCMPLTEN |
1480 DWC3_DEVTEN_ERRTICERREN |
1481 DWC3_DEVTEN_WKUPEVTEN |
1482 DWC3_DEVTEN_ULSTCNGEN |
1483 DWC3_DEVTEN_CONNECTDONEEN |
1484 DWC3_DEVTEN_USBRSTEN |
1485 DWC3_DEVTEN_DISCONNEVTEN);
1486
1487 dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
1488}
1489
1490static void dwc3_gadget_disable_irq(struct dwc3 *dwc)
1491{
1492 /* mask all interrupts */
1493 dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
1494}
1495
1496static irqreturn_t dwc3_interrupt(int irq, void *_dwc);
1497
1472static int dwc3_gadget_start(struct usb_gadget *g, 1498static int dwc3_gadget_start(struct usb_gadget *g,
1473 struct usb_gadget_driver *driver) 1499 struct usb_gadget_driver *driver)
1474{ 1500{
@@ -1476,6 +1502,7 @@ static int dwc3_gadget_start(struct usb_gadget *g,
1476 struct dwc3_ep *dep; 1502 struct dwc3_ep *dep;
1477 unsigned long flags; 1503 unsigned long flags;
1478 int ret = 0; 1504 int ret = 0;
1505 int irq;
1479 u32 reg; 1506 u32 reg;
1480 1507
1481 spin_lock_irqsave(&dwc->lock, flags); 1508 spin_lock_irqsave(&dwc->lock, flags);
@@ -1536,6 +1563,17 @@ static int dwc3_gadget_start(struct usb_gadget *g,
1536 dwc->ep0state = EP0_SETUP_PHASE; 1563 dwc->ep0state = EP0_SETUP_PHASE;
1537 dwc3_ep0_out_start(dwc); 1564 dwc3_ep0_out_start(dwc);
1538 1565
1566 irq = platform_get_irq(to_platform_device(dwc->dev), 0);
1567 ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED,
1568 "dwc3", dwc);
1569 if (ret) {
1570 dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
1571 irq, ret);
1572 goto err1;
1573 }
1574
1575 dwc3_gadget_enable_irq(dwc);
1576
1539 spin_unlock_irqrestore(&dwc->lock, flags); 1577 spin_unlock_irqrestore(&dwc->lock, flags);
1540 1578
1541 return 0; 1579 return 0;
@@ -1554,9 +1592,14 @@ static int dwc3_gadget_stop(struct usb_gadget *g,
1554{ 1592{
1555 struct dwc3 *dwc = gadget_to_dwc(g); 1593 struct dwc3 *dwc = gadget_to_dwc(g);
1556 unsigned long flags; 1594 unsigned long flags;
1595 int irq;
1557 1596
1558 spin_lock_irqsave(&dwc->lock, flags); 1597 spin_lock_irqsave(&dwc->lock, flags);
1559 1598
1599 dwc3_gadget_disable_irq(dwc);
1600 irq = platform_get_irq(to_platform_device(dwc->dev), 0);
1601 free_irq(irq, dwc);
1602
1560 __dwc3_gadget_ep_disable(dwc->eps[0]); 1603 __dwc3_gadget_ep_disable(dwc->eps[0]);
1561 __dwc3_gadget_ep_disable(dwc->eps[1]); 1604 __dwc3_gadget_ep_disable(dwc->eps[1]);
1562 1605
@@ -2454,7 +2497,6 @@ int dwc3_gadget_init(struct dwc3 *dwc)
2454{ 2497{
2455 u32 reg; 2498 u32 reg;
2456 int ret; 2499 int ret;
2457 int irq;
2458 2500
2459 dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req), 2501 dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
2460 &dwc->ctrl_req_addr, GFP_KERNEL); 2502 &dwc->ctrl_req_addr, GFP_KERNEL);
@@ -2510,33 +2552,11 @@ int dwc3_gadget_init(struct dwc3 *dwc)
2510 if (ret) 2552 if (ret)
2511 goto err4; 2553 goto err4;
2512 2554
2513 irq = platform_get_irq(to_platform_device(dwc->dev), 0);
2514
2515 ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED,
2516 "dwc3", dwc);
2517 if (ret) {
2518 dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
2519 irq, ret);
2520 goto err5;
2521 }
2522
2523 reg = dwc3_readl(dwc->regs, DWC3_DCFG); 2555 reg = dwc3_readl(dwc->regs, DWC3_DCFG);
2524 reg |= DWC3_DCFG_LPM_CAP; 2556 reg |= DWC3_DCFG_LPM_CAP;
2525 dwc3_writel(dwc->regs, DWC3_DCFG, reg); 2557 dwc3_writel(dwc->regs, DWC3_DCFG, reg);
2526 2558
2527 /* Enable all but Start and End of Frame IRQs */ 2559 /* Enable USB2 LPM and automatic phy suspend only on recent versions */
2528 reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN |
2529 DWC3_DEVTEN_EVNTOVERFLOWEN |
2530 DWC3_DEVTEN_CMDCMPLTEN |
2531 DWC3_DEVTEN_ERRTICERREN |
2532 DWC3_DEVTEN_WKUPEVTEN |
2533 DWC3_DEVTEN_ULSTCNGEN |
2534 DWC3_DEVTEN_CONNECTDONEEN |
2535 DWC3_DEVTEN_USBRSTEN |
2536 DWC3_DEVTEN_DISCONNEVTEN);
2537 dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
2538
2539 /* automatic phy suspend only on recent versions */
2540 if (dwc->revision >= DWC3_REVISION_194A) { 2560 if (dwc->revision >= DWC3_REVISION_194A) {
2541 dwc3_gadget_usb2_phy_suspend(dwc, false); 2561 dwc3_gadget_usb2_phy_suspend(dwc, false);
2542 dwc3_gadget_usb3_phy_suspend(dwc, false); 2562 dwc3_gadget_usb3_phy_suspend(dwc, false);
@@ -2545,15 +2565,11 @@ int dwc3_gadget_init(struct dwc3 *dwc)
2545 ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); 2565 ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
2546 if (ret) { 2566 if (ret) {
2547 dev_err(dwc->dev, "failed to register udc\n"); 2567 dev_err(dwc->dev, "failed to register udc\n");
2548 goto err6; 2568 goto err5;
2549 } 2569 }
2550 2570
2551 return 0; 2571 return 0;
2552 2572
2553err6:
2554 dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
2555 free_irq(irq, dwc);
2556
2557err5: 2573err5:
2558 dwc3_gadget_free_endpoints(dwc); 2574 dwc3_gadget_free_endpoints(dwc);
2559 2575
@@ -2578,13 +2594,7 @@ err0:
2578 2594
2579void dwc3_gadget_exit(struct dwc3 *dwc) 2595void dwc3_gadget_exit(struct dwc3 *dwc)
2580{ 2596{
2581 int irq;
2582
2583 usb_del_gadget_udc(&dwc->gadget); 2597 usb_del_gadget_udc(&dwc->gadget);
2584 irq = platform_get_irq(to_platform_device(dwc->dev), 0);
2585
2586 dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
2587 free_irq(irq, dwc);
2588 2598
2589 dwc3_gadget_free_endpoints(dwc); 2599 dwc3_gadget_free_endpoints(dwc);
2590 2600