mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-14 07:19:36 +08:00
at91_mci: Use real interrupt
Execute at91_mci_intr() in interrupt context. Synchronize MMC requests via RTEMS interrupt lock.
This commit is contained in:
parent
c7e162abd8
commit
3fac9e9cd4
@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
#if defined(__rtems__) && defined(LIBBSP_ARM_ATSAM_BSP_H)
|
#if defined(__rtems__) && defined(LIBBSP_ARM_ATSAM_BSP_H)
|
||||||
#ifdef __rtems__
|
#ifdef __rtems__
|
||||||
|
#include <rtems/irq-extension.h>
|
||||||
#include <libchip/chip.h>
|
#include <libchip/chip.h>
|
||||||
|
|
||||||
#define AT91_MCI_HAS_4WIRE 1
|
#define AT91_MCI_HAS_4WIRE 1
|
||||||
@ -150,7 +151,11 @@ static sXdmad *pXdmad = &XDMAD_Instance;
|
|||||||
* original driver. But that would need some rework. */
|
* original driver. But that would need some rework. */
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
static int mci_debug;
|
static int mci_debug;
|
||||||
|
#else /* __rtems__ */
|
||||||
|
#define mci_debug 0
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
struct at91_mci_softc {
|
struct at91_mci_softc {
|
||||||
void *intrhand; /* Interrupt handle */
|
void *intrhand; /* Interrupt handle */
|
||||||
@ -169,6 +174,9 @@ struct at91_mci_softc {
|
|||||||
struct resource *irq_res; /* IRQ resource */
|
struct resource *irq_res; /* IRQ resource */
|
||||||
struct resource *mem_res; /* Memory resource */
|
struct resource *mem_res; /* Memory resource */
|
||||||
struct mtx sc_mtx;
|
struct mtx sc_mtx;
|
||||||
|
#ifdef __rtems__
|
||||||
|
RTEMS_INTERRUPT_LOCK_MEMBER(sc_lock)
|
||||||
|
#endif /* __rtems__ */
|
||||||
bus_dma_tag_t dmatag;
|
bus_dma_tag_t dmatag;
|
||||||
struct mmc_host host;
|
struct mmc_host host;
|
||||||
int bus_busy;
|
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);
|
static void at91_mci_write_done(struct at91_mci_softc *sc, uint32_t sr);
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
#define AT91_MCI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
#define AT91_MCI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
||||||
#define AT91_MCI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
|
#define AT91_MCI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
|
||||||
#define AT91_MCI_LOCK_INIT(_sc) \
|
#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_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_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
|
||||||
#define AT91_MCI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
|
#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
|
static inline uint32_t
|
||||||
RD4(struct at91_mci_softc *sc, bus_size_t off)
|
RD4(struct at91_mci_softc *sc, bus_size_t off)
|
||||||
@ -482,6 +508,7 @@ at91_mci_attach(device_t dev)
|
|||||||
if (rc != XDMAD_OK)
|
if (rc != XDMAD_OK)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
AT91_MCI_BUS_LOCK_INIT(sc);
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
AT91_MCI_LOCK_INIT(sc);
|
AT91_MCI_LOCK_INIT(sc);
|
||||||
|
|
||||||
@ -516,8 +543,14 @@ at91_mci_attach(device_t dev)
|
|||||||
/*
|
/*
|
||||||
* Activate the interrupt
|
* Activate the interrupt
|
||||||
*/
|
*/
|
||||||
|
#ifndef __rtems__
|
||||||
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
|
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
|
||||||
NULL, at91_mci_intr, sc, &sc->intrhand);
|
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) {
|
if (err) {
|
||||||
AT91_MCI_LOCK_DESTROY(sc);
|
AT91_MCI_LOCK_DESTROY(sc);
|
||||||
goto out;
|
goto out;
|
||||||
@ -545,8 +578,10 @@ at91_mci_attach(device_t dev)
|
|||||||
CTLFLAG_RW, &sc->allow_overclock, 0,
|
CTLFLAG_RW, &sc->allow_overclock, 0,
|
||||||
"Allow up to 30MHz clock for 25MHz request when next highest speed 15MHz or less.");
|
"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",
|
SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "debug",
|
||||||
CTLFLAG_RWTUN, &mci_debug, 0, "enable debug output");
|
CTLFLAG_RWTUN, &mci_debug, 0, "enable debug output");
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our real min freq is master_clock/512, but upper driver layers are
|
* 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);
|
struct at91_mci_softc *sc = device_get_softc(brdev);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
AT91_MCI_LOCK(sc);
|
AT91_MCI_LOCK(sc);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
AT91_MCI_BUS_LOCK(sc);
|
||||||
|
#endif /* __rtems__ */
|
||||||
while (sc->bus_busy)
|
while (sc->bus_busy)
|
||||||
msleep(sc, &sc->sc_mtx, PZERO, "mciah", hz / 5);
|
msleep(sc, &sc->sc_mtx, PZERO, "mciah", hz / 5);
|
||||||
sc->bus_busy++;
|
sc->bus_busy++;
|
||||||
|
#ifndef __rtems__
|
||||||
AT91_MCI_UNLOCK(sc);
|
AT91_MCI_UNLOCK(sc);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
AT91_MCI_BUS_UNLOCK(sc);
|
||||||
|
#endif /* __rtems__ */
|
||||||
return (err);
|
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);
|
struct at91_mci_softc *sc = device_get_softc(brdev);
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
AT91_MCI_LOCK(sc);
|
AT91_MCI_LOCK(sc);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
AT91_MCI_BUS_LOCK(sc);
|
||||||
|
#endif /* __rtems__ */
|
||||||
sc->bus_busy--;
|
sc->bus_busy--;
|
||||||
wakeup(sc);
|
wakeup(sc);
|
||||||
|
#ifndef __rtems__
|
||||||
AT91_MCI_UNLOCK(sc);
|
AT91_MCI_UNLOCK(sc);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
AT91_MCI_BUS_UNLOCK(sc);
|
||||||
|
#endif /* __rtems__ */
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user