diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-09-28 07:24:47 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-09-28 07:24:47 -0700 |
commit | 0c72b292de0b2865f21e5ffc9bed2b36b8c8e693 (patch) | |
tree | 544ebd035faafd6238e67ceb685eb8f9d72500e5 /drivers | |
parent | 0513e464f9007b70b96740271a948ca5ab6e7dd7 (diff) | |
parent | b81bede4d138ce62f7342e27bf55ac93c8071818 (diff) |
Merge tag 'mmc-v5.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC fixes from Ulf Hansson:
- renesas_sdhi: Fix regression with hard reset on old SDHIs
- dw_mmc: Only inject fault before done/error
* tag 'mmc-v5.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
mmc: renesas_sdhi: fix regression with hard reset on old SDHIs
mmc: dw_mmc: Only inject fault before done/error
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 15 | ||||
-rw-r--r-- | drivers/mmc/host/renesas_sdhi_core.c | 2 |
2 files changed, 14 insertions, 3 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 6578cc64ae9e..380f9aa56eb2 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1802,10 +1802,15 @@ static enum hrtimer_restart dw_mci_fault_timer(struct hrtimer *t) spin_lock_irqsave(&host->irq_lock, flags); - if (!host->data_status) + /* + * Only inject an error if we haven't already got an error or data over + * interrupt. + */ + if (!host->data_status) { host->data_status = SDMMC_INT_DCRC; - set_bit(EVENT_DATA_ERROR, &host->pending_events); - tasklet_schedule(&host->tasklet); + set_bit(EVENT_DATA_ERROR, &host->pending_events); + tasklet_schedule(&host->tasklet); + } spin_unlock_irqrestore(&host->irq_lock, flags); @@ -2721,12 +2726,16 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) } if (pending & DW_MCI_DATA_ERROR_FLAGS) { + spin_lock(&host->irq_lock); + /* if there is an error report DATA_ERROR */ mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); host->data_status = pending; smp_wmb(); /* drain writebuffer */ set_bit(EVENT_DATA_ERROR, &host->pending_events); tasklet_schedule(&host->tasklet); + + spin_unlock(&host->irq_lock); } if (pending & SDMMC_INT_DATA_OVER) { diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 6fc4cf3c9dce..a4407f391f66 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -561,6 +561,8 @@ static void renesas_sdhi_reset(struct tmio_mmc_host *host) /* Unknown why but without polling reset status, it will hang */ read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100, false, priv->rstc); + /* At least SDHI_VER_GEN2_SDR50 needs manual release of reset */ + sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); priv->needs_adjust_hs400 = false; renesas_sdhi_set_clock(host, host->clk_cache); } else if (priv->scc_ctl) { |