mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-06-30 22:23:49 +08:00
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.
This commit is contained in:
parent
f9d4e1d8c1
commit
1e77a45d54
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user