summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/sdhci/sdhci.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-20 15:53:03 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:39 +0200
commit18fa92c2dcc6c52e0bf27d214d80f0c25a89b47d (patch)
treea3020ac5b1f366f2f0920941b589808e435dbcee /freebsd/sys/dev/sdhci/sdhci.c
parentUpdate to FreeBSD head 2017-12-01 (diff)
downloadrtems-libbsd-18fa92c2dcc6c52e0bf27d214d80f0c25a89b47d.tar.bz2
Update to FreeBSD head 2018-02-01
Git mirror commit d079ae0442af8fa3cfd6d7ede190d04e64a2c0d4. Update #3472.
Diffstat (limited to 'freebsd/sys/dev/sdhci/sdhci.c')
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c
index 496e8fac..39b9dc91 100644
--- a/freebsd/sys/dev/sdhci/sdhci.c
+++ b/freebsd/sys/dev/sdhci/sdhci.c
@@ -275,7 +275,7 @@ sdhci_tuning_intmask(struct sdhci_slot *slot)
uint32_t intmask;
intmask = 0;
- if (slot->opt & SDHCI_TUNING_SUPPORTED) {
+ if (slot->opt & SDHCI_TUNING_ENABLED) {
intmask |= SDHCI_INT_TUNEERR;
if (slot->retune_mode == SDHCI_RETUNE_MODE_2 ||
slot->retune_mode == SDHCI_RETUNE_MODE_3)
@@ -303,7 +303,7 @@ sdhci_init(struct sdhci_slot *slot)
slot->intmask |= SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
}
- WR4(slot, SDHCI_INT_ENABLE, slot->intmask | sdhci_tuning_intmask(slot));
+ WR4(slot, SDHCI_INT_ENABLE, slot->intmask);
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
}
@@ -656,6 +656,7 @@ sdhci_card_task(void *arg, int pending __unused)
xpt_rescan(ccb);
#else
slot->intmask &= ~sdhci_tuning_intmask(slot);
+ WR4(slot, SDHCI_INT_ENABLE, slot->intmask);
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
slot->opt &= ~SDHCI_TUNING_ENABLED;
SDHCI_UNLOCK(slot);
@@ -1340,6 +1341,7 @@ sdhci_generic_tune(device_t brdev __unused, device_t reqdev, bool hs400)
if (err == 0) {
slot->opt |= SDHCI_TUNING_ENABLED;
slot->intmask |= sdhci_tuning_intmask(slot);
+ WR4(slot, SDHCI_INT_ENABLE, slot->intmask);
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
if (slot->retune_ticks) {
callout_reset(&slot->retune_callout, slot->retune_ticks,
@@ -1408,6 +1410,7 @@ sdhci_exec_tuning(struct sdhci_slot *slot, bool reset)
*/
intmask = slot->intmask;
slot->intmask = SDHCI_INT_DATA_AVAIL;
+ WR4(slot, SDHCI_INT_ENABLE, SDHCI_INT_DATA_AVAIL);
WR4(slot, SDHCI_SIGNAL_ENABLE, SDHCI_INT_DATA_AVAIL);
hostctrl2 = RD2(slot, SDHCI_HOST_CONTROL2);
@@ -1447,8 +1450,17 @@ sdhci_exec_tuning(struct sdhci_slot *slot, bool reset)
DELAY(1000);
}
+ /*
+ * Restore DMA usage and interrupts.
+ * Note that the interrupt aggregation code might have cleared
+ * SDHCI_INT_DMA_END and/or SDHCI_INT_RESPONSE in slot->intmask
+ * and SDHCI_SIGNAL_ENABLE respectively so ensure SDHCI_INT_ENABLE
+ * doesn't lose these.
+ */
slot->opt = opt;
slot->intmask = intmask;
+ WR4(slot, SDHCI_INT_ENABLE, intmask | SDHCI_INT_DMA_END |
+ SDHCI_INT_RESPONSE);
WR4(slot, SDHCI_SIGNAL_ENABLE, intmask);
if ((hostctrl2 & (SDHCI_CTRL2_EXEC_TUNING |