[rtems-libbsd commit] saf1761_otg: Use real interrupt handler

Sebastian Huber sebh at rtems.org
Thu Oct 4 12:19:36 UTC 2018


Module:    rtems-libbsd
Branch:    master
Commit:    1e77a45d54bfc52eb76453f3e1327645acc8f77b
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=1e77a45d54bfc52eb76453f3e1327645acc8f77b

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Oct  4 12:06:44 2018 +0200

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.

---

 freebsd/sys/dev/usb/controller/saf1761_otg.c     | 25 ++++++++++++++++-----
 freebsd/sys/dev/usb/controller/saf1761_otg.h     |  6 +++++
 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 e1ce5eb..cb9e50c 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 4ab9b62..afee30b 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 32b6b92..c088716 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;




More information about the vc mailing list