diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-10-04 12:06:44 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-10-04 14:14:51 +0200 |
commit | 1e77a45d54bfc52eb76453f3e1327645acc8f77b (patch) | |
tree | e06ee24573a7e7b1e29f830bd9662427b504946e /freebsd/sys | |
parent | rtwn: Align mbuf to avoid realignment in rx path (diff) | |
download | rtems-libbsd-1e77a45d54bfc52eb76453f3e1327645acc8f77b.tar.bz2 |
saf1761_otg: Use real interrupt handler
The USB_BUS_SPIN_LOCK() is only used internally to the bus driver.
Replace the mutex with an interrupt disable/enable section. Execute the
interrupt filter in a real interrupt context and forward the interrupt
handler to the interrupt server if necessary.
Diffstat (limited to 'freebsd/sys')
-rw-r--r-- | freebsd/sys/dev/usb/controller/saf1761_otg.c | 25 | ||||
-rw-r--r-- | freebsd/sys/dev/usb/controller/saf1761_otg.h | 6 | ||||
-rw-r--r-- | freebsd/sys/dev/usb/controller/saf1761_otg_fdt.c | 28 |
3 files changed, 53 insertions, 6 deletions
diff --git a/freebsd/sys/dev/usb/controller/saf1761_otg.c b/freebsd/sys/dev/usb/controller/saf1761_otg.c index e1ce5eb6..cb9e50cf 100644 --- a/freebsd/sys/dev/usb/controller/saf1761_otg.c +++ b/freebsd/sys/dev/usb/controller/saf1761_otg.c @@ -88,6 +88,15 @@ #ifdef LIBBSP_ARM_ATSAM_BSP_H #include <bsp/pin-config.h> #endif /* LIBBSP_ARM_ATSAM_BSP_H */ +#undef USB_BUS_SPIN_LOCK +#undef USB_BUS_SPIN_UNLOCK +#define USB_BUS_SPIN_LOCK(_b) \ + do { \ + rtems_interrupt_level usb_bus_spin_lock; \ + rtems_interrupt_disable(usb_bus_spin_lock) +#define USB_BUS_SPIN_UNLOCK(_b) \ + rtems_interrupt_enable(usb_bus_spin_lock); \ + } while (0) #endif /* __rtems__ */ #define SAF1761_OTG_BUS2SC(bus) \ @@ -1668,6 +1677,7 @@ saf1761_otg_interrupt(void *arg) { struct saf1761_otg_softc *sc = arg; uint32_t status; + bool xfer_complete; USB_BUS_LOCK(&sc->sc_bus); USB_BUS_SPIN_LOCK(&sc->sc_bus); @@ -1735,13 +1745,16 @@ saf1761_otg_interrupt(void *arg) } } - if (sc->sc_xfer_complete != 0) { + xfer_complete = (sc->sc_xfer_complete != 0); + if (xfer_complete) sc->sc_xfer_complete = 0; + USB_BUS_SPIN_UNLOCK(&sc->sc_bus); + + if (xfer_complete) /* complete FIFOs, if any */ saf1761_otg_interrupt_complete_locked(sc); - } - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); + USB_BUS_UNLOCK(&sc->sc_bus); } @@ -2232,10 +2245,10 @@ saf1761_otg_device_done(struct usb_xfer *xfer, usb_error_t error) saf1761_host_channel_free(sc, td); } + USB_BUS_SPIN_UNLOCK(&sc->sc_bus); + /* dequeue transfer and start next transfer */ usbd_transfer_done(xfer, error); - - USB_BUS_SPIN_UNLOCK(&sc->sc_bus); } static void @@ -2600,8 +2613,8 @@ saf1761_otg_do_poll(struct usb_bus *bus) USB_BUS_LOCK(&sc->sc_bus); USB_BUS_SPIN_LOCK(&sc->sc_bus); saf1761_otg_interrupt_poll_locked(sc); - saf1761_otg_interrupt_complete_locked(sc); USB_BUS_SPIN_UNLOCK(&sc->sc_bus); + saf1761_otg_interrupt_complete_locked(sc); USB_BUS_UNLOCK(&sc->sc_bus); } diff --git a/freebsd/sys/dev/usb/controller/saf1761_otg.h b/freebsd/sys/dev/usb/controller/saf1761_otg.h index 4ab9b629..afee30bc 100644 --- a/freebsd/sys/dev/usb/controller/saf1761_otg.h +++ b/freebsd/sys/dev/usb/controller/saf1761_otg.h @@ -32,6 +32,9 @@ #ifndef _SAF1761_OTG_H_ #define _SAF1761_OTG_H_ +#ifdef __rtems__ +#include <rtems/irq-extension.h> +#endif /* __rtems__ */ #define SOTG_MAX_DEVICES MIN(USB_MAX_DEVICES, 32) #define SOTG_FS_MAX_PACKET_SIZE 64 #define SOTG_HS_MAX_PACKET_SIZE 512 @@ -163,6 +166,9 @@ struct saf1761_otg_softc { uint8_t sc_hub_idata[1]; struct saf1761_otg_flags sc_flags; +#ifdef __rtems__ + rtems_interrupt_server_request sc_irq_srv_req; +#endif /* __rtems__ */ }; /* prototypes */ diff --git a/freebsd/sys/dev/usb/controller/saf1761_otg_fdt.c b/freebsd/sys/dev/usb/controller/saf1761_otg_fdt.c index 32b6b92c..c088716a 100644 --- a/freebsd/sys/dev/usb/controller/saf1761_otg_fdt.c +++ b/freebsd/sys/dev/usb/controller/saf1761_otg_fdt.c @@ -135,6 +135,19 @@ saf1761_otg_fdt_probe(device_t dev) return (0); } +#ifdef __rtems__ +static void +saf1761_otg_filter_interrupt_wrapper(void *arg) +{ + struct saf1761_otg_softc *sc = arg; + int status; + + status = saf1761_otg_filter_interrupt(sc); + if ((status & FILTER_SCHEDULE_THREAD) != 0) { + rtems_interrupt_server_request_submit(&sc->sc_irq_srv_req); + } +} +#endif /* __rtems__ */ static int saf1761_otg_fdt_attach(device_t dev) { @@ -142,6 +155,9 @@ saf1761_otg_fdt_attach(device_t dev) char param[24]; int err; int rid; +#ifdef __rtems__ + rtems_status_code status; +#endif /* __rtems__ */ #ifndef __rtems__ /* get configuration from FDT */ @@ -243,8 +259,20 @@ saf1761_otg_fdt_attach(device_t dev) PIO_EnableIt(&saf_irq); #endif /* LIBBSP_ARM_ATSAM_BSP_H */ #endif /* __rtems__ */ +#ifndef __rtems__ err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE, &saf1761_otg_filter_interrupt, &saf1761_otg_interrupt, sc, &sc->sc_intr_hdl); +#else /* __rtems__ */ + rtems_interrupt_server_request_initialize( + RTEMS_INTERRUPT_SERVER_DEFAULT, &sc->sc_irq_srv_req, + saf1761_otg_interrupt, sc); + rtems_interrupt_server_request_set_vector(&sc->sc_irq_srv_req, + rman_get_start(sc->sc_irq_res)); + status = rtems_interrupt_handler_install( + rman_get_start(sc->sc_irq_res), device_get_nameunit(dev), + RTEMS_INTERRUPT_SHARED, saf1761_otg_filter_interrupt_wrapper, sc); + err = (status == RTEMS_SUCCESSFUL) ? 0 : EINVAL; +#endif /* __rtems__ */ if (err) { sc->sc_intr_hdl = NULL; goto error; |