mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-01 04:22:13 +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
|
#ifdef LIBBSP_ARM_ATSAM_BSP_H
|
||||||
#include <bsp/pin-config.h>
|
#include <bsp/pin-config.h>
|
||||||
#endif /* LIBBSP_ARM_ATSAM_BSP_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__ */
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
#define SAF1761_OTG_BUS2SC(bus) \
|
#define SAF1761_OTG_BUS2SC(bus) \
|
||||||
@ -1668,6 +1677,7 @@ saf1761_otg_interrupt(void *arg)
|
|||||||
{
|
{
|
||||||
struct saf1761_otg_softc *sc = arg;
|
struct saf1761_otg_softc *sc = arg;
|
||||||
uint32_t status;
|
uint32_t status;
|
||||||
|
bool xfer_complete;
|
||||||
|
|
||||||
USB_BUS_LOCK(&sc->sc_bus);
|
USB_BUS_LOCK(&sc->sc_bus);
|
||||||
USB_BUS_SPIN_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;
|
sc->sc_xfer_complete = 0;
|
||||||
|
|
||||||
|
USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
|
||||||
|
|
||||||
|
if (xfer_complete)
|
||||||
/* complete FIFOs, if any */
|
/* complete FIFOs, if any */
|
||||||
saf1761_otg_interrupt_complete_locked(sc);
|
saf1761_otg_interrupt_complete_locked(sc);
|
||||||
}
|
|
||||||
USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
|
|
||||||
USB_BUS_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);
|
saf1761_host_channel_free(sc, td);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
|
||||||
|
|
||||||
/* dequeue transfer and start next transfer */
|
/* dequeue transfer and start next transfer */
|
||||||
usbd_transfer_done(xfer, error);
|
usbd_transfer_done(xfer, error);
|
||||||
|
|
||||||
USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2600,8 +2613,8 @@ saf1761_otg_do_poll(struct usb_bus *bus)
|
|||||||
USB_BUS_LOCK(&sc->sc_bus);
|
USB_BUS_LOCK(&sc->sc_bus);
|
||||||
USB_BUS_SPIN_LOCK(&sc->sc_bus);
|
USB_BUS_SPIN_LOCK(&sc->sc_bus);
|
||||||
saf1761_otg_interrupt_poll_locked(sc);
|
saf1761_otg_interrupt_poll_locked(sc);
|
||||||
saf1761_otg_interrupt_complete_locked(sc);
|
|
||||||
USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
|
USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
|
||||||
|
saf1761_otg_interrupt_complete_locked(sc);
|
||||||
USB_BUS_UNLOCK(&sc->sc_bus);
|
USB_BUS_UNLOCK(&sc->sc_bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
#ifndef _SAF1761_OTG_H_
|
#ifndef _SAF1761_OTG_H_
|
||||||
#define _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_MAX_DEVICES MIN(USB_MAX_DEVICES, 32)
|
||||||
#define SOTG_FS_MAX_PACKET_SIZE 64
|
#define SOTG_FS_MAX_PACKET_SIZE 64
|
||||||
#define SOTG_HS_MAX_PACKET_SIZE 512
|
#define SOTG_HS_MAX_PACKET_SIZE 512
|
||||||
@ -163,6 +166,9 @@ struct saf1761_otg_softc {
|
|||||||
uint8_t sc_hub_idata[1];
|
uint8_t sc_hub_idata[1];
|
||||||
|
|
||||||
struct saf1761_otg_flags sc_flags;
|
struct saf1761_otg_flags sc_flags;
|
||||||
|
#ifdef __rtems__
|
||||||
|
rtems_interrupt_server_request sc_irq_srv_req;
|
||||||
|
#endif /* __rtems__ */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
|
@ -135,6 +135,19 @@ saf1761_otg_fdt_probe(device_t dev)
|
|||||||
return (0);
|
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
|
static int
|
||||||
saf1761_otg_fdt_attach(device_t dev)
|
saf1761_otg_fdt_attach(device_t dev)
|
||||||
{
|
{
|
||||||
@ -142,6 +155,9 @@ saf1761_otg_fdt_attach(device_t dev)
|
|||||||
char param[24];
|
char param[24];
|
||||||
int err;
|
int err;
|
||||||
int rid;
|
int rid;
|
||||||
|
#ifdef __rtems__
|
||||||
|
rtems_status_code status;
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
#ifndef __rtems__
|
#ifndef __rtems__
|
||||||
/* get configuration from FDT */
|
/* get configuration from FDT */
|
||||||
@ -243,8 +259,20 @@ saf1761_otg_fdt_attach(device_t dev)
|
|||||||
PIO_EnableIt(&saf_irq);
|
PIO_EnableIt(&saf_irq);
|
||||||
#endif /* LIBBSP_ARM_ATSAM_BSP_H */
|
#endif /* LIBBSP_ARM_ATSAM_BSP_H */
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
|
#ifndef __rtems__
|
||||||
err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE,
|
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);
|
&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) {
|
if (err) {
|
||||||
sc->sc_intr_hdl = NULL;
|
sc->sc_intr_hdl = NULL;
|
||||||
goto error;
|
goto error;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user