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:
parent
460febc7be
commit
e828eaabf4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=240314
@ -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
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user