[rtems-libbsd commit] at91_mci: Use real interrupt

Sebastian Huber sebh at rtems.org
Fri Apr 27 11:30:36 UTC 2018


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Apr 26 15:23:08 2018 +0200

at91_mci: Use real interrupt

Execute at91_mci_intr() in interrupt context.  Synchronize MMC requests
via RTEMS interrupt lock.

---

 freebsd/sys/arm/at91/at91_mci.c | 51 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/freebsd/sys/arm/at91/at91_mci.c b/freebsd/sys/arm/at91/at91_mci.c
index 44499bf..82041da 100644
--- a/freebsd/sys/arm/at91/at91_mci.c
+++ b/freebsd/sys/arm/at91/at91_mci.c
@@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
 #endif /* __rtems__ */
 #if defined(__rtems__) && defined(LIBBSP_ARM_ATSAM_BSP_H)
 #ifdef __rtems__
+#include <rtems/irq-extension.h>
 #include <libchip/chip.h>
 
 #define AT91_MCI_HAS_4WIRE 1
@@ -150,7 +151,11 @@ static sXdmad *pXdmad = &XDMAD_Instance;
  * original driver. But that would need some rework. */
 #endif /* __rtems__ */
 
+#ifndef __rtems__
 static int mci_debug;
+#else /* __rtems__ */
+#define	mci_debug 0
+#endif /* __rtems__ */
 
 struct at91_mci_softc {
 	void *intrhand;			/* Interrupt handle */
@@ -169,6 +174,9 @@ struct at91_mci_softc {
 	struct resource *irq_res;	/* IRQ resource */
 	struct resource	*mem_res;	/* Memory resource */
 	struct mtx sc_mtx;
+#ifdef __rtems__
+	RTEMS_INTERRUPT_LOCK_MEMBER(sc_lock)
+#endif /* __rtems__ */
 	bus_dma_tag_t dmatag;
 	struct mmc_host host;
 	int bus_busy;
@@ -204,6 +212,7 @@ static void at91_mci_read_done(struct at91_mci_softc *sc, uint32_t sr);
 static void at91_mci_write_done(struct at91_mci_softc *sc, uint32_t sr);
 #endif /* __rtems__ */
 
+#ifndef __rtems__
 #define AT91_MCI_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
 #define	AT91_MCI_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
 #define AT91_MCI_LOCK_INIT(_sc) \
@@ -212,6 +221,23 @@ static void at91_mci_write_done(struct at91_mci_softc *sc, uint32_t sr);
 #define AT91_MCI_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
 #define AT91_MCI_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
 #define AT91_MCI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+#else /* __rtems__ */
+#define AT91_MCI_LOCK(_sc) \
+	rtems_interrupt_lock_context at91_mci_lock_context; \
+	rtems_interrupt_lock_acquire(&(_sc)->sc_lock, &at91_mci_lock_context)
+#define	AT91_MCI_UNLOCK(_sc) \
+	rtems_interrupt_lock_release(&(_sc)->sc_lock, &at91_mci_lock_context)
+#define AT91_MCI_LOCK_INIT(_sc) \
+	rtems_interrupt_lock_initialize(&(_sc)->sc_lock, \
+	    device_get_nameunit((_sc)->dev))
+#define AT91_MCI_LOCK_DESTROY(_sc) \
+	rtems_interrupt_lock_destroy(&(_sc)->sc_mtx)
+#define AT91_MCI_BUS_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	AT91_MCI_BUS_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define AT91_MCI_BUS_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->dev), \
+	    "mci", MTX_DEF)
+#endif /* __rtems__ */
 
 static inline uint32_t
 RD4(struct at91_mci_softc *sc, bus_size_t off)
@@ -482,6 +508,7 @@ at91_mci_attach(device_t dev)
 	if (rc != XDMAD_OK)
 		goto out;
 
+	AT91_MCI_BUS_LOCK_INIT(sc);
 #endif /* __rtems__ */
 	AT91_MCI_LOCK_INIT(sc);
 
@@ -516,8 +543,14 @@ at91_mci_attach(device_t dev)
 	/*
 	 * Activate the interrupt
 	 */
+#ifndef __rtems__
 	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
 	    NULL, at91_mci_intr, sc, &sc->intrhand);
+#else /* __rtems__ */
+	err = rtems_interrupt_handler_install(rman_get_start(sc->irq_res),
+	    device_get_nameunit(dev), RTEMS_INTERRUPT_SHARED, at91_mci_intr,
+	    sc);
+#endif /* __rtems__ */
 	if (err) {
 		AT91_MCI_LOCK_DESTROY(sc);
 		goto out;
@@ -545,8 +578,10 @@ at91_mci_attach(device_t dev)
 	    CTLFLAG_RW, &sc->allow_overclock, 0,
 	    "Allow up to 30MHz clock for 25MHz request when next highest speed 15MHz or less.");
 
+#ifndef __rtems__
 	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "debug",
 	    CTLFLAG_RWTUN, &mci_debug, 0, "enable debug output");
+#endif /* __rtems__ */
 
 	/*
 	 * Our real min freq is master_clock/512, but upper driver layers are
@@ -1119,11 +1154,19 @@ at91_mci_acquire_host(device_t brdev, device_t reqdev)
 	struct at91_mci_softc *sc = device_get_softc(brdev);
 	int err = 0;
 
+#ifndef __rtems__
 	AT91_MCI_LOCK(sc);
+#else /* __rtems__ */
+	AT91_MCI_BUS_LOCK(sc);
+#endif /* __rtems__ */
 	while (sc->bus_busy)
 		msleep(sc, &sc->sc_mtx, PZERO, "mciah", hz / 5);
 	sc->bus_busy++;
+#ifndef __rtems__
 	AT91_MCI_UNLOCK(sc);
+#else /* __rtems__ */
+	AT91_MCI_BUS_UNLOCK(sc);
+#endif /* __rtems__ */
 	return (err);
 }
 
@@ -1132,10 +1175,18 @@ at91_mci_release_host(device_t brdev, device_t reqdev)
 {
 	struct at91_mci_softc *sc = device_get_softc(brdev);
 
+#ifndef __rtems__
 	AT91_MCI_LOCK(sc);
+#else /* __rtems__ */
+	AT91_MCI_BUS_LOCK(sc);
+#endif /* __rtems__ */
 	sc->bus_busy--;
 	wakeup(sc);
+#ifndef __rtems__
 	AT91_MCI_UNLOCK(sc);
+#else /* __rtems__ */
+	AT91_MCI_BUS_UNLOCK(sc);
+#endif /* __rtems__ */
 	return (0);
 }
 



More information about the vc mailing list