diff --git a/sys/arch/arm/omap/tiotg.c b/sys/arch/arm/omap/tiotg.c index da82f7691379..04425978268f 100644 --- a/sys/arch/arm/omap/tiotg.c +++ b/sys/arch/arm/omap/tiotg.c @@ -1,4 +1,4 @@ -/* $NetBSD: tiotg.c,v 1.1 2014/07/16 18:27:19 bouyer Exp $ */ +/* $NetBSD: tiotg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $ */ /* * Copyright (c) 2013 Manuel Bouyer. All rights reserved. * @@ -24,7 +24,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tiotg.c,v 1.1 2014/07/16 18:27:19 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tiotg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $"); #include "opt_omap.h" #include "locators.h" @@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: tiotg.c,v 1.1 2014/07/16 18:27:19 bouyer Exp $"); #include #include #include +#include #include #define MOTG_DEBUG @@ -376,27 +377,42 @@ ti_motg_intr(void *v) { struct ti_motg_softc *sc = v; uint32_t stat, stat0, stat1; - int vbus = 0; int rv = 0; + int i; mutex_spin_enter(&sc->sc_motg.sc_intr_lock); stat = TIOTG_USBC_READ4(sc, USBCTRL_STAT); stat0 = TIOTG_USBC_READ4(sc, USBCTRL_IRQ_STAT0); stat1 = TIOTG_USBC_READ4(sc, USBCTRL_IRQ_STAT1); - DPRINTF(("USB %d 0x%x 0x%x stat %d\n", sc->sc_ctrlport, stat0, stat1, stat)); + DPRINTF(("USB %d 0x%x 0x%x stat %d\n", + sc->sc_ctrlport, stat0, stat1, stat)); + /* try to deal with vbus errors */ + if (stat1 & MUSB2_MASK_IVBUSERR ) { + stat1 &= ~MUSB2_MASK_IVBUSERR; + for (i = 0; i < 1000; i++) { + TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT1, + MUSB2_MASK_IVBUSERR); + motg_intr_vbus(&sc->sc_motg, stat & 0x1); + delay(1000); + stat = TIOTG_USBC_READ4(sc, USBCTRL_STAT); + if (stat & 0x1) + break; + } + } if (stat0) { TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT0, stat0); } if (stat1) { TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT1, stat1); } - if (stat1 & USBCTRL_IRQ_STAT1_DRVVBUS) { - vbus = ((stat & 0x1) ? 1 : 0); - DPRINTF(("USB %d stat %d\n", sc->sc_ctrlport, stat)); + if ((stat & 0x1) == 0) { + mutex_spin_exit(&sc->sc_motg.sc_intr_lock); + aprint_error_dev(sc->sc_motg.sc_dev, ": vbus error\n"); + return 1; } - if (stat0 != 0 || stat1 != 0 || stat != 0) { + if (stat0 != 0 || stat1 != 0) { rv = motg_intr(&sc->sc_motg, ((stat0 >> 16) & 0xffff), - stat0 & 0xffff, stat1 & 0xff, vbus); + stat0 & 0xffff, stat1 & 0xff); } mutex_spin_exit(&sc->sc_motg.sc_intr_lock); return rv; diff --git a/sys/dev/usb/motg.c b/sys/dev/usb/motg.c index 81133a142886..2047f0463952 100644 --- a/sys/dev/usb/motg.c +++ b/sys/dev/usb/motg.c @@ -1,4 +1,4 @@ -/* $NetBSD: motg.c,v 1.1 2014/07/16 18:22:23 bouyer Exp $ */ +/* $NetBSD: motg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $ */ /* * Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc. @@ -40,7 +40,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.1 2014/07/16 18:22:23 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $"); #include #include @@ -464,10 +464,6 @@ motg_open(usbd_pipe_handle pipe) struct motg_softc *sc = pipe->device->bus->hci_private; struct motg_pipe *otgpipe = (struct motg_pipe *)pipe; usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; -#if 0 - usbd_status err = USBD_NOMEM; - int ival; -#endif DPRINTF(("motg_open: pipe=%p, addr=%d, endpt=%d (%d)\n", pipe, pipe->device->address, @@ -660,7 +656,7 @@ motg_poll(struct usbd_bus *bus) int motg_intr(struct motg_softc *sc, uint16_t rx_ep, uint16_t tx_ep, - uint8_t ctrl, int vbus) + uint8_t ctrl) { KASSERT(mutex_owned(&sc->sc_intr_lock)); sc->sc_intr_tx_ep = tx_ep; @@ -674,6 +670,20 @@ motg_intr(struct motg_softc *sc, uint16_t rx_ep, uint16_t tx_ep, return 1; } +int +motg_intr_vbus(struct motg_softc *sc, int vbus) +{ + uint8_t val; + if (sc->sc_mode == MOTG_MODE_HOST && vbus == 0) { + DPRINTF(("motg_intr_vbus: vbus down, try to re-enable\n")); + /* try to re-enter session for Host mode */ + val = UREAD1(sc, MUSB2_REG_DEVCTL); + val |= MUSB2_MASK_SESS; + UWRITE1(sc, MUSB2_REG_DEVCTL, val); + } + return 1; +} + usbd_status motg_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) { diff --git a/sys/dev/usb/motgvar.h b/sys/dev/usb/motgvar.h index cd277b7c1d54..8a24b0ca647a 100644 --- a/sys/dev/usb/motgvar.h +++ b/sys/dev/usb/motgvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: motgvar.h,v 1.1 2014/07/16 18:22:23 bouyer Exp $ */ +/* $NetBSD: motgvar.h,v 1.2 2014/07/17 19:58:18 bouyer Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -121,7 +121,8 @@ struct motg_xfer { usbd_status motg_init(struct motg_softc *); -int motg_intr(struct motg_softc *, uint16_t, uint16_t, uint8_t, int); +int motg_intr(struct motg_softc *, uint16_t, uint16_t, uint8_t); +int motg_intr_vbus(struct motg_softc *, int); int motg_detach(struct motg_softc *, int); void motg_childdet(device_t, device_t); int motg_activate(device_t, enum devact);