bcm2835_sdhci: roll back r354823
r354823 kicked DATA_END handling out of the DMA interrupt path "to make things easy", but this was likely a mistake -- if we know we're done after we've finished pending DMA operations, we should go ahead and acknowledge it rather than waiting for the controller to finalize it. If it's not ready, we'll simply re-enable interrupts and wait for it anyways, to be re-entered in sdhci_data_intr.
This commit is contained in:
parent
691bc5f6fa
commit
78cbd2b0bd
@ -87,6 +87,7 @@ __FBSDID("$FreeBSD$");
|
||||
rounddown(BCM_SDHCI_SLOT_LEFT(slot), BCM_SDHCI_BUFFER_SIZE))
|
||||
|
||||
#define DATA_PENDING_MASK (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)
|
||||
#define DATA_XFER_MASK (DATA_PENDING_MASK | SDHCI_INT_DATA_END)
|
||||
|
||||
#ifdef DEBUG
|
||||
static int bcm2835_sdhci_debug = 0;
|
||||
@ -579,7 +580,7 @@ bcm_sdhci_start_dma_seg(struct bcm_sdhci_softc *sc)
|
||||
if (idx == 0) {
|
||||
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op);
|
||||
|
||||
slot->intmask &= ~DATA_PENDING_MASK;
|
||||
slot->intmask &= ~DATA_XFER_MASK;
|
||||
bcm_sdhci_write_4(sc->sc_dev, slot, SDHCI_SIGNAL_ENABLE,
|
||||
slot->intmask);
|
||||
}
|
||||
@ -600,7 +601,7 @@ bcm_sdhci_dma_exit(struct bcm_sdhci_softc *sc)
|
||||
mtx_assert(&slot->mtx, MA_OWNED);
|
||||
|
||||
/* Re-enable interrupts */
|
||||
slot->intmask |= DATA_PENDING_MASK;
|
||||
slot->intmask |= DATA_XFER_MASK;
|
||||
bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
|
||||
slot->intmask);
|
||||
}
|
||||
@ -625,6 +626,8 @@ bcm_sdhci_dma_intr(int ch, void *arg)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sc->dmamap_seg_count == 0)
|
||||
return;
|
||||
if ((slot->curcmd->data->flags & MMC_DATA_READ) != 0)
|
||||
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
@ -654,6 +657,12 @@ bcm_sdhci_dma_intr(int ch, void *arg)
|
||||
sdhci_finish_data(slot);
|
||||
bcm_sdhci_dma_exit(sc);
|
||||
}
|
||||
} else if ((reg & SDHCI_INT_DATA_END) != 0) {
|
||||
bcm_sdhci_dma_exit(sc);
|
||||
bcm_sdhci_write_4(slot->bus, slot, SDHCI_INT_STATUS,
|
||||
reg);
|
||||
slot->flags &= ~PLATFORM_DATA_STARTED;
|
||||
sdhci_finish_data(slot);
|
||||
} else {
|
||||
bcm_sdhci_dma_exit(sc);
|
||||
}
|
||||
@ -732,7 +741,11 @@ bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
|
||||
{
|
||||
struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
|
||||
|
||||
/* Clean up */
|
||||
/*
|
||||
* Clean up. Interrupts are clearly enabled, because we received an
|
||||
* SDHCI_INT_DATA_END to get this far -- just make sure we don't leave
|
||||
* anything laying around.
|
||||
*/
|
||||
if (sc->dmamap_seg_count != 0) {
|
||||
/*
|
||||
* Our segment math should have worked out such that we would
|
||||
@ -753,7 +766,6 @@ bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
|
||||
sc->dmamap_seg_index = 0;
|
||||
}
|
||||
|
||||
bcm_sdhci_dma_exit(sc);
|
||||
sdhci_finish_data(slot);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user