1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-18 10:35:55 +00:00

Poll VBUS status every second, hence the AT91 GPIO library doesn't support

registering interrupt handlers yet for GPIO events.
This commit is contained in:
Hans Petter Selasky 2012-09-10 13:50:34 +00:00
parent 460febc7be
commit e828eaabf4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=240314
2 changed files with 15 additions and 51 deletions

View File

@ -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

View File

@ -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()