Commit 8c4fc031954b4eb72daf13d3c907a985a3eee208
Committed by
Greg Kroah-Hartman
1 parent
984f753cf1
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
USB: chipidea: add vbus detect for udc
Using vbus valid interrupt to detect vbus. Tested-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Tested-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Richard Zhao <richard.zhao@freescale.com> Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 2 changed files with 39 additions and 1 deletions Side-by-side Diff
drivers/usb/chipidea/ci.h
drivers/usb/chipidea/udc.c
... | ... | @@ -305,6 +305,18 @@ |
305 | 305 | return reg; |
306 | 306 | } |
307 | 307 | |
308 | +static void hw_enable_vbus_intr(struct ci13xxx *ci) | |
309 | +{ | |
310 | + hw_write(ci, OP_OTGSC, OTGSC_AVVIS, OTGSC_AVVIS); | |
311 | + hw_write(ci, OP_OTGSC, OTGSC_AVVIE, OTGSC_AVVIE); | |
312 | + queue_work(ci->wq, &ci->vbus_work); | |
313 | +} | |
314 | + | |
315 | +static void hw_disable_vbus_intr(struct ci13xxx *ci) | |
316 | +{ | |
317 | + hw_write(ci, OP_OTGSC, OTGSC_AVVIE, 0); | |
318 | +} | |
319 | + | |
308 | 320 | /** |
309 | 321 | * hw_test_and_clear_setup_guard: test & clear setup guard (execute without |
310 | 322 | * interruption) |
... | ... | @@ -371,6 +383,16 @@ |
371 | 383 | return 0; |
372 | 384 | } |
373 | 385 | |
386 | +static void vbus_work(struct work_struct *work) | |
387 | +{ | |
388 | + struct ci13xxx *ci = container_of(work, struct ci13xxx, vbus_work); | |
389 | + | |
390 | + if (hw_read(ci, OP_OTGSC, OTGSC_AVV)) | |
391 | + usb_gadget_vbus_connect(&ci->gadget); | |
392 | + else | |
393 | + usb_gadget_vbus_disconnect(&ci->gadget); | |
394 | +} | |
395 | + | |
374 | 396 | /****************************************************************************** |
375 | 397 | * UTIL block |
376 | 398 | *****************************************************************************/ |
... | ... | @@ -1370,6 +1392,7 @@ |
1370 | 1392 | if (is_active) { |
1371 | 1393 | pm_runtime_get_sync(&_gadget->dev); |
1372 | 1394 | hw_device_reset(ci, USBMODE_CM_DC); |
1395 | + hw_enable_vbus_intr(ci); | |
1373 | 1396 | hw_device_state(ci, ci->ep0out->qh.dma); |
1374 | 1397 | } else { |
1375 | 1398 | hw_device_state(ci, 0); |
1376 | 1399 | |
... | ... | @@ -1544,8 +1567,10 @@ |
1544 | 1567 | pm_runtime_get_sync(&ci->gadget.dev); |
1545 | 1568 | if (ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS) { |
1546 | 1569 | if (ci->vbus_active) { |
1547 | - if (ci->platdata->flags & CI13XXX_REGS_SHARED) | |
1570 | + if (ci->platdata->flags & CI13XXX_REGS_SHARED) { | |
1548 | 1571 | hw_device_reset(ci, USBMODE_CM_DC); |
1572 | + hw_enable_vbus_intr(ci); | |
1573 | + } | |
1549 | 1574 | } else { |
1550 | 1575 | pm_runtime_put_sync(&ci->gadget.dev); |
1551 | 1576 | goto done; |
... | ... | @@ -1651,6 +1676,13 @@ |
1651 | 1676 | } else { |
1652 | 1677 | retval = IRQ_NONE; |
1653 | 1678 | } |
1679 | + | |
1680 | + intr = hw_read(ci, OP_OTGSC, ~0); | |
1681 | + hw_write(ci, OP_OTGSC, ~0, intr); | |
1682 | + | |
1683 | + if (intr & (OTGSC_AVVIE & OTGSC_AVVIS)) | |
1684 | + queue_work(ci->wq, &ci->vbus_work); | |
1685 | + | |
1654 | 1686 | spin_unlock(&ci->lock); |
1655 | 1687 | |
1656 | 1688 | return retval; |
... | ... | @@ -1726,6 +1758,7 @@ |
1726 | 1758 | retval = hw_device_reset(ci, USBMODE_CM_DC); |
1727 | 1759 | if (retval) |
1728 | 1760 | goto put_transceiver; |
1761 | + hw_enable_vbus_intr(ci); | |
1729 | 1762 | } |
1730 | 1763 | |
1731 | 1764 | retval = device_register(&ci->gadget.dev); |
... | ... | @@ -1788,6 +1821,9 @@ |
1788 | 1821 | if (ci == NULL) |
1789 | 1822 | return; |
1790 | 1823 | |
1824 | + hw_disable_vbus_intr(ci); | |
1825 | + cancel_work_sync(&ci->vbus_work); | |
1826 | + | |
1791 | 1827 | usb_del_gadget_udc(&ci->gadget); |
1792 | 1828 | |
1793 | 1829 | destroy_eps(ci); |
... | ... | @@ -1828,6 +1864,7 @@ |
1828 | 1864 | rdrv->irq = udc_irq; |
1829 | 1865 | rdrv->name = "gadget"; |
1830 | 1866 | ci->roles[CI_ROLE_GADGET] = rdrv; |
1867 | + INIT_WORK(&ci->vbus_work, vbus_work); | |
1831 | 1868 | |
1832 | 1869 | return 0; |
1833 | 1870 | } |