diff options
author | hselasky <hselasky@FreeBSD.org> | 2012-09-10 13:50:34 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2012-09-10 13:50:34 +0000 |
commit | d6420ed47c240aed3849f8f82d7c8468fbb49622 (patch) | |
tree | ac16bd2b6eb408a501a3498bc10777b40dd6a361 | |
parent | 3467c1af7a81e2a8c9aa8b461eeebc4fe5cf7b0d (diff) | |
download | FreeBSD-src-d6420ed47c240aed3849f8f82d7c8468fbb49622.zip FreeBSD-src-d6420ed47c240aed3849f8f82d7c8468fbb49622.tar.gz |
Poll VBUS status every second, hence the AT91 GPIO library doesn't support
registering interrupt handlers yet for GPIO events.
-rw-r--r-- | sys/dev/usb/controller/at91dci.c | 2 | ||||
-rw-r--r-- | sys/dev/usb/controller/at91dci_atmelarm.c | 64 |
2 files changed, 15 insertions, 51 deletions
diff --git a/sys/dev/usb/controller/at91dci.c b/sys/dev/usb/controller/at91dci.c index 8468e6f..8d3c1cb 100644 --- a/sys/dev/usb/controller/at91dci.c +++ b/sys/dev/usb/controller/at91dci.c @@ -740,7 +740,6 @@ at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on) { DPRINTFN(5, "vbus = %u\n", is_on); - USB_BUS_LOCK(&sc->sc_bus); if (is_on) { if (!sc->sc_flags.status_vbus) { sc->sc_flags.status_vbus = 1; @@ -760,7 +759,6 @@ at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on) at91dci_root_intr(sc); } } - USB_BUS_UNLOCK(&sc->sc_bus); } void diff --git a/sys/dev/usb/controller/at91dci_atmelarm.c b/sys/dev/usb/controller/at91dci_atmelarm.c index be3d7d8..678ad48 100644 --- a/sys/dev/usb/controller/at91dci_atmelarm.c +++ b/sys/dev/usb/controller/at91dci_atmelarm.c @@ -83,24 +83,18 @@ struct at91_udp_softc { struct at91_pmc_clock *sc_mclk; struct at91_pmc_clock *sc_iclk; struct at91_pmc_clock *sc_fclk; - struct resource *sc_vbus_irq_res; - void *sc_vbus_intr_hdl; + struct callout sc_vbus; }; static void at91_vbus_poll(struct at91_udp_softc *sc) { - uint32_t temp; uint8_t vbus_val; - /* XXX temporary clear interrupts here */ - - temp = at91_pio_gpio_clear_interrupt(VBUS_BASE); - - /* just forward it */ - vbus_val = at91_pio_gpio_get(VBUS_BASE, VBUS_MASK); at91dci_vbus_interrupt(&sc->sc_dci, vbus_val); + + callout_reset(&sc->sc_vbus, hz, (void *)&at91_vbus_poll, sc); } static void @@ -168,6 +162,8 @@ at91_udp_attach(device_t dev) USB_GET_DMA_TAG(dev), NULL)) { return (ENOMEM); } + callout_init_mtx(&sc->sc_vbus, &sc->sc_dci.sc_bus.bus_mtx, 0); + /* * configure VBUS input pin, enable deglitch and enable * interrupt : @@ -175,7 +171,7 @@ at91_udp_attach(device_t dev) at91_pio_use_gpio(VBUS_BASE, VBUS_MASK); at91_pio_gpio_input(VBUS_BASE, VBUS_MASK); at91_pio_gpio_set_deglitch(VBUS_BASE, VBUS_MASK, 1); - at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 1); + at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0); /* * configure PULLUP output pin : @@ -210,13 +206,6 @@ at91_udp_attach(device_t dev) if (!(sc->sc_dci.sc_irq_res)) { goto error; } - rid = 1; - sc->sc_vbus_irq_res = - bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (sc->sc_vbus_irq_res == NULL) { - at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0); - device_printf(dev, "No VBUS IRQ!\n"); - } sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1); if (!(sc->sc_dci.sc_bus.bdev)) { goto error; @@ -234,25 +223,7 @@ at91_udp_attach(device_t dev) sc->sc_dci.sc_intr_hdl = NULL; goto error; } -#if (__FreeBSD_version >= 700031) - if (sc->sc_vbus_irq_res != NULL) { - err = bus_setup_intr(dev, sc->sc_vbus_irq_res, - INTR_TYPE_BIO | INTR_MPSAFE, - NULL, (driver_intr_t *)at91_vbus_poll, sc, - &sc->sc_vbus_intr_hdl); - } -#else - if (sc->sc_vbus_irq_res != NULL) { - err = bus_setup_intr(dev, sc->sc_vbus_irq_res, - INTR_TYPE_BIO | INTR_MPSAFE, - (driver_intr_t *)at91_vbus_poll, sc, - &sc->sc_vbus_intr_hdl); - } -#endif - if (err) { - sc->sc_vbus_intr_hdl = NULL; - goto error; - } + err = at91dci_init(&sc->sc_dci); if (!err) { err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev); @@ -261,7 +232,9 @@ at91_udp_attach(device_t dev) goto error; } else { /* poll VBUS one time */ + USB_BUS_LOCK(&sc->sc_dci.sc_bus); at91_vbus_poll(sc); + USB_BUS_UNLOCK(&sc->sc_dci.sc_bus); } return (0); @@ -285,6 +258,12 @@ at91_udp_detach(device_t dev) /* during module unload there are lots of children leftover */ device_delete_children(dev); + USB_BUS_LOCK(&sc->sc_dci.sc_bus); + callout_stop(&sc->sc_vbus); + USB_BUS_UNLOCK(&sc->sc_dci.sc_bus); + + callout_drain(&sc->sc_vbus); + /* disable Transceiver */ AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS); @@ -292,19 +271,6 @@ at91_udp_detach(device_t dev) AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_IDR, 0xFFFFFFFF); AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_ICR, 0xFFFFFFFF); - /* disable VBUS interrupt */ - at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0); - - if (sc->sc_vbus_irq_res && sc->sc_vbus_intr_hdl) { - err = bus_teardown_intr(dev, sc->sc_vbus_irq_res, - sc->sc_vbus_intr_hdl); - sc->sc_vbus_intr_hdl = NULL; - } - if (sc->sc_vbus_irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 1, - sc->sc_vbus_irq_res); - sc->sc_vbus_irq_res = NULL; - } if (sc->sc_dci.sc_irq_res && sc->sc_dci.sc_intr_hdl) { /* * only call at91_udp_uninit() after at91_udp_init() |