diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/card/block.c | 4 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 51 | ||||
-rw-r--r-- | drivers/mmc/core/debugfs.c | 11 | ||||
-rw-r--r-- | drivers/mmc/core/host.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 10 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 5 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-iproc.c | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-msm.c | 70 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-msm.h | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 30 |
10 files changed, 137 insertions, 52 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 69e51cc96303..01e5502917f7 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1017,7 +1017,7 @@ static int mmc_blk_ioctl_rpmb_cmd(struct block_device *bdev, { struct mmc_blk_ioc_rpmb_data *idata; struct mmc_blk_data *md; - struct mmc_card *card; + struct mmc_card *card = NULL; struct mmc_command cmd = {0}; struct mmc_data data = {0}; struct mmc_request mrq = {NULL}; @@ -1701,7 +1701,7 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, mmc_retune_recheck(card->host); prev_cmd_status_valid = false; - pr_err("%s: error %d sending status command, %sing\n", + pr_err_ratelimited("%s: error %d sending status command, %sing\n", req->rq_disk->disk_name, err, retry ? "retry" : "abort"); } diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 63f7bf87843f..0da9c5caea13 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -487,12 +487,17 @@ static int mmc_devfreq_set_target(struct device *dev, struct mmc_devfeq_clk_scaling *clk_scaling; int err = 0; int abort; + unsigned long pflags = current->flags; + + /* Ensure scaling would happen even in memory pressure conditions */ + current->flags |= PF_MEMALLOC; if (!(host && freq)) { pr_err("%s: unexpected host/freq parameter\n", __func__); err = -EINVAL; goto out; } + clk_scaling = &host->clk_scaling; if (!clk_scaling->enable) @@ -551,6 +556,7 @@ static int mmc_devfreq_set_target(struct device *dev, rel_host: mmc_release_host(host); out: + tsk_restore_flags(current, pflags, PF_MEMALLOC); return err; } @@ -616,17 +622,39 @@ static int mmc_devfreq_create_freq_table(struct mmc_host *host) host->card->clk_scaling_lowest, host->card->clk_scaling_highest); + /* + * Create the frequency table and initialize it with default values. + * Initialize it with platform specific frequencies if the frequency + * table supplied by platform driver is present, otherwise initialize + * it with min and max frequencies supported by the card. + */ if (!clk_scaling->freq_table) { - pr_debug("%s: no frequency table defined - setting default\n", - mmc_hostname(host)); + if (clk_scaling->pltfm_freq_table_sz) + clk_scaling->freq_table_sz = + clk_scaling->pltfm_freq_table_sz; + else + clk_scaling->freq_table_sz = 2; + clk_scaling->freq_table = kzalloc( - 2*sizeof(*(clk_scaling->freq_table)), GFP_KERNEL); + (clk_scaling->freq_table_sz * + sizeof(*(clk_scaling->freq_table))), GFP_KERNEL); if (!clk_scaling->freq_table) return -ENOMEM; - clk_scaling->freq_table[0] = host->card->clk_scaling_lowest; - clk_scaling->freq_table[1] = host->card->clk_scaling_highest; - clk_scaling->freq_table_sz = 2; - goto out; + + if (clk_scaling->pltfm_freq_table) { + memcpy(clk_scaling->freq_table, + clk_scaling->pltfm_freq_table, + (clk_scaling->pltfm_freq_table_sz * + sizeof(*(clk_scaling->pltfm_freq_table)))); + } else { + pr_debug("%s: no frequency table defined - setting default\n", + mmc_hostname(host)); + clk_scaling->freq_table[0] = + host->card->clk_scaling_lowest; + clk_scaling->freq_table[1] = + host->card->clk_scaling_highest; + goto out; + } } if (host->card->clk_scaling_lowest > @@ -835,7 +863,7 @@ int mmc_resume_clk_scaling(struct mmc_host *host) devfreq_min_clk = host->clk_scaling.freq_table[0]; host->clk_scaling.curr_freq = devfreq_max_clk; - if (host->ios.clock < host->card->clk_scaling_highest) + if (host->ios.clock < host->clk_scaling.freq_table[max_clk_idx]) host->clk_scaling.curr_freq = devfreq_min_clk; host->clk_scaling.clk_scaling_in_progress = false; @@ -895,6 +923,10 @@ int mmc_exit_clk_scaling(struct mmc_host *host) host->clk_scaling.devfreq = NULL; atomic_set(&host->clk_scaling.devfreq_abort, 1); + + kfree(host->clk_scaling.freq_table); + host->clk_scaling.freq_table = NULL; + pr_debug("%s: devfreq was removed\n", mmc_hostname(host)); return 0; @@ -1709,7 +1741,6 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, struct mmc_async_req *areq, int *error) { int err = 0; - int start_err = 0; struct mmc_async_req *data = host->areq; /* Prepare a new request */ @@ -1758,7 +1789,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, trace_mmc_blk_rw_start(areq->mrq->cmd->opcode, areq->mrq->cmd->arg, areq->mrq->data); - start_err = __mmc_start_data_req(host, areq->mrq); + __mmc_start_data_req(host, areq->mrq); } if (host->areq) diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 594fba08e623..72bfdd835178 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -337,10 +337,15 @@ static int mmc_force_err_set(void *data, u64 val) { struct mmc_host *host = data; - if (host && host->ops && host->ops->force_err_irq) { - mmc_host_clk_hold(host); + if (host && host->card && host->ops && + host->ops->force_err_irq) { + /* + * To access the force error irq reg, we need to make + * sure the host is powered up and host clock is ticking. + */ + mmc_get_card(host->card); host->ops->force_err_irq(host, val); - mmc_host_clk_release(host); + mmc_put_card(host->card); } return 0; diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 9ca73a2b86db..ae54302be8fd 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -327,6 +327,7 @@ void mmc_retune_enable(struct mmc_host *host) mod_timer(&host->retune_timer, jiffies + host->retune_period * HZ); } +EXPORT_SYMBOL(mmc_retune_enable); void mmc_retune_disable(struct mmc_host *host) { @@ -335,6 +336,7 @@ void mmc_retune_disable(struct mmc_host *host) host->retune_now = 0; host->need_retune = 0; } +EXPORT_SYMBOL(mmc_retune_disable); void mmc_retune_timer_stop(struct mmc_host *host) { diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index df60774b02af..a28d6b98a042 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1323,10 +1323,6 @@ int mmc_hs400_to_hs200(struct mmc_card *card) if (host->caps & MMC_CAP_WAIT_WHILE_BUSY) send_status = false; - /* Reduce frequency to HS */ - max_dtr = card->ext_csd.hs_max_dtr; - mmc_set_clock(host, max_dtr); - /* Switch HS400 to HS DDR */ val = EXT_CSD_TIMING_HS; err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, @@ -1337,6 +1333,10 @@ int mmc_hs400_to_hs200(struct mmc_card *card) mmc_set_timing(host, MMC_TIMING_MMC_DDR52); + /* Reduce frequency to HS */ + max_dtr = card->ext_csd.hs_max_dtr; + mmc_set_clock(host, max_dtr); + if (!send_status) { err = mmc_switch_status(card, false); if (err) @@ -2849,6 +2849,7 @@ static int mmc_runtime_suspend(struct mmc_host *host) return -EBUSY; } + MMC_TRACE(host, "%s\n", __func__); err = _mmc_suspend(host, true); if (err) pr_err("%s: error %d doing aggressive suspend\n", @@ -2870,6 +2871,7 @@ static int mmc_runtime_resume(struct mmc_host *host) if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME))) return 0; + MMC_TRACE(host, "%s\n", __func__); err = _mmc_resume(host); if (err) pr_err("%s: error %d doing aggressive resume\n", diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 5b4d5d74fe55..5033107f6e26 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1283,6 +1283,11 @@ static int _mmc_sd_resume(struct mmc_host *host) #else err = mmc_sd_init_card(host, host->card->ocr, host->card); #endif + if (err) { + pr_err("%s: %s: mmc_sd_init_card_failed (%d)\n", + mmc_hostname(host), __func__, err); + goto out; + } mmc_card_clr_suspended(host->card); if (host->card->sdr104_blocked) diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c index 3b423b0ad8e7..f280744578e4 100644 --- a/drivers/mmc/host/sdhci-iproc.c +++ b/drivers/mmc/host/sdhci-iproc.c @@ -156,7 +156,8 @@ static const struct sdhci_ops sdhci_iproc_ops = { }; static const struct sdhci_pltfm_data sdhci_iproc_pltfm_data = { - .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, + .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | + SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN, .ops = &sdhci_iproc_ops, }; diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index ca72ebfd55a3..7aefeb037ef4 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1823,7 +1823,7 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev, } pdata->status_gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags); - if (gpio_is_valid(pdata->status_gpio) & !(flags & OF_GPIO_ACTIVE_LOW)) + if (gpio_is_valid(pdata->status_gpio) && !(flags & OF_GPIO_ACTIVE_LOW)) pdata->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; of_property_read_u32(np, "qcom,bus-width", &bus_width); @@ -1837,13 +1837,13 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev, } if (sdhci_msm_dt_get_array(dev, "qcom,devfreq,freq-table", - &msm_host->mmc->clk_scaling.freq_table, - &msm_host->mmc->clk_scaling.freq_table_sz, 0)) + &msm_host->mmc->clk_scaling.pltfm_freq_table, + &msm_host->mmc->clk_scaling.pltfm_freq_table_sz, 0)) pr_debug("%s: no clock scaling frequencies were supplied\n", dev_name(dev)); - else if (!msm_host->mmc->clk_scaling.freq_table || - !msm_host->mmc->clk_scaling.freq_table_sz) - dev_err(dev, "bad dts clock scaling frequencies\n"); + else if (!msm_host->mmc->clk_scaling.pltfm_freq_table || + !msm_host->mmc->clk_scaling.pltfm_freq_table_sz) + dev_err(dev, "bad dts clock scaling frequencies\n"); /* * Few hosts can support DDR52 mode at the same lower @@ -1958,7 +1958,7 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev, sdhci_msm_pm_qos_parse(dev, pdata); if (of_get_property(np, "qcom,core_3_0v_support", NULL)) - pdata->core_3_0v_support = true; + msm_host->core_3_0v_support = true; pdata->sdr104_wa = of_property_read_bool(np, "qcom,sdr104-wa"); @@ -2366,21 +2366,6 @@ out: return ret; } -/* - * Reset vreg by ensuring it is off during probe. A call - * to enable vreg is needed to balance disable vreg - */ -static int sdhci_msm_vreg_reset(struct sdhci_msm_pltfm_data *pdata) -{ - int ret; - - ret = sdhci_msm_setup_vreg(pdata, 1, true); - if (ret) - return ret; - ret = sdhci_msm_setup_vreg(pdata, 0, true); - return ret; -} - /* This init function should be called only once for each SDHC slot */ static int sdhci_msm_vreg_init(struct device *dev, struct sdhci_msm_pltfm_data *pdata, @@ -2415,7 +2400,7 @@ static int sdhci_msm_vreg_init(struct device *dev, if (ret) goto vdd_reg_deinit; } - ret = sdhci_msm_vreg_reset(pdata); + if (ret) dev_err(dev, "vreg reset failed (%d)\n", ret); goto out; @@ -2509,15 +2494,30 @@ void sdhci_msm_dump_pwr_ctrl_regs(struct sdhci_host *host) struct sdhci_msm_host *msm_host = pltfm_host->priv; const struct sdhci_msm_offset *msm_host_offset = msm_host->offset; + unsigned int irq_flags = 0; + struct irq_desc *pwr_irq_desc = irq_to_desc(msm_host->pwr_irq); + + if (pwr_irq_desc) + irq_flags = pwr_irq_desc->irq_data.common->state_use_accessors; - pr_err("%s: PWRCTL_STATUS: 0x%08x | PWRCTL_MASK: 0x%08x | PWRCTL_CTL: 0x%08x\n", + pr_err("%s: PWRCTL_STATUS: 0x%08x | PWRCTL_MASK: 0x%08x | PWRCTL_CTL: 0x%08x, pwr isr state=0x%x\n", mmc_hostname(host->mmc), sdhci_msm_readl_relaxed(host, msm_host_offset->CORE_PWRCTL_STATUS), sdhci_msm_readl_relaxed(host, msm_host_offset->CORE_PWRCTL_MASK), sdhci_msm_readl_relaxed(host, - msm_host_offset->CORE_PWRCTL_CTL)); + msm_host_offset->CORE_PWRCTL_CTL), irq_flags); + + MMC_TRACE(host->mmc, + "%s: Sts: 0x%08x | Mask: 0x%08x | Ctrl: 0x%08x, pwr isr state=0x%x\n", + __func__, + sdhci_msm_readb_relaxed(host, + msm_host_offset->CORE_PWRCTL_STATUS), + sdhci_msm_readb_relaxed(host, + msm_host_offset->CORE_PWRCTL_MASK), + sdhci_msm_readb_relaxed(host, + msm_host_offset->CORE_PWRCTL_CTL), irq_flags); } static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) @@ -2592,7 +2592,9 @@ static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) io_level = REQ_IO_HIGH; } if (irq_status & CORE_PWRCTL_BUS_OFF) { - ret = sdhci_msm_setup_vreg(msm_host->pdata, false, false); + if (msm_host->pltfm_init_done) + ret = sdhci_msm_setup_vreg(msm_host->pdata, + false, false); if (!ret) { ret = sdhci_msm_setup_pins(msm_host->pdata, false); ret |= sdhci_msm_set_vdd_io_vol(msm_host->pdata, @@ -2639,7 +2641,9 @@ static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) */ mb(); - if ((io_level & REQ_IO_HIGH) && (msm_host->caps_0 & CORE_3_0V_SUPPORT)) + if ((io_level & REQ_IO_HIGH) && + (msm_host->caps_0 & CORE_3_0V_SUPPORT) && + !msm_host->core_3_0v_support) writel_relaxed((readl_relaxed(host->ioaddr + msm_host_offset->CORE_VENDOR_SPEC) & ~CORE_IO_PAD_PWR_SWITCH), host->ioaddr + @@ -2786,10 +2790,14 @@ static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type) if (done) init_completion(&msm_host->pwr_irq_completion); else if (!wait_for_completion_timeout(&msm_host->pwr_irq_completion, - msecs_to_jiffies(MSM_PWR_IRQ_TIMEOUT_MS))) + msecs_to_jiffies(MSM_PWR_IRQ_TIMEOUT_MS))) { __WARN_printf("%s: request(%d) timed out waiting for pwr_irq\n", mmc_hostname(host->mmc), req_type); - + MMC_TRACE(host->mmc, + "%s: request(%d) timed out waiting for pwr_irq\n", + __func__, req_type); + sdhci_msm_dump_pwr_ctrl_regs(host); + } pr_debug("%s: %s: request %d done\n", mmc_hostname(host->mmc), __func__, req_type); } @@ -4133,7 +4141,7 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host, msm_host->use_14lpp_dll = true; /* Fake 3.0V support for SDIO devices which requires such voltage */ - if (msm_host->pdata->core_3_0v_support) { + if (msm_host->core_3_0v_support) { caps |= CORE_3_0V_SUPPORT; writel_relaxed((readl_relaxed(host->ioaddr + SDHCI_CAPABILITIES) | caps), host->ioaddr + @@ -4666,6 +4674,8 @@ static int sdhci_msm_probe(struct platform_device *pdev) goto vreg_deinit; } + msm_host->pltfm_init_done = true; + pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, MSM_AUTOSUSPEND_DELAY_MS); diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h index 92f61708001e..79949c2c537f 100644 --- a/drivers/mmc/host/sdhci-msm.h +++ b/drivers/mmc/host/sdhci-msm.h @@ -152,7 +152,6 @@ struct sdhci_msm_pltfm_data { u32 ice_clk_max; u32 ice_clk_min; struct sdhci_msm_pm_qos_data pm_qos_data; - bool core_3_0v_support; bool sdr104_wa; }; @@ -226,6 +225,8 @@ struct sdhci_msm_host { bool tuning_in_progress; bool mci_removed; const struct sdhci_msm_offset *offset; + bool core_3_0v_support; + bool pltfm_init_done; }; extern char *saved_command_line; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 40a34c283955..a5ff9f73dfbc 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -255,6 +255,8 @@ retry_reset: if (timeout == 0) { pr_err("%s: Reset 0x%x never completed.\n", mmc_hostname(host->mmc), (int)mask); + MMC_TRACE(host->mmc, "%s: Reset 0x%x never completed\n", + __func__, (int)mask); if ((host->quirks2 & SDHCI_QUIRK2_USE_RESET_WORKAROUND) && host->ops->reset_workaround) { if (!host->reset_wa_applied) { @@ -1178,6 +1180,9 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) if (timeout == 0) { pr_err("%s: Controller never released " "inhibit bit(s).\n", mmc_hostname(host->mmc)); + MMC_TRACE(host->mmc, + "%s :Controller never released inhibit bit(s)\n", + __func__); sdhci_dumpregs(host); cmd->error = -EIO; tasklet_schedule(&host->finish_tasklet); @@ -1233,12 +1238,12 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) if (cmd->data) host->data_start_time = ktime_get(); trace_mmc_cmd_rw_start(cmd->opcode, cmd->arg, cmd->flags); + sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); MMC_TRACE(host->mmc, "%s: updated 0x8=0x%08x 0xC=0x%08x 0xE=0x%08x\n", __func__, sdhci_readl(host, SDHCI_ARGUMENT), sdhci_readw(host, SDHCI_TRANSFER_MODE), sdhci_readw(host, SDHCI_COMMAND)); - sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); } EXPORT_SYMBOL_GPL(sdhci_send_command); @@ -1434,6 +1439,8 @@ clock_set: if (timeout == 0) { pr_err("%s: Internal clock never " "stabilised.\n", mmc_hostname(host->mmc)); + MMC_TRACE(host->mmc, + "%s: Internal clock never stabilised.\n", __func__); sdhci_dumpregs(host); return; } @@ -1777,6 +1784,7 @@ end_req: if (mrq->data) mrq->data->error = -EIO; host->mrq = NULL; + MMC_TRACE(host->mmc, "Request failed due to ice config\n"); sdhci_dumpregs(host); mmc_request_done(host->mmc, mrq); sdhci_runtime_pm_put(host); @@ -2418,7 +2426,13 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) if (host->ops->platform_execute_tuning) { spin_unlock_irqrestore(&host->lock, flags); + /* + * Make sure re-tuning won't get triggered for the CRC errors + * occurred while executing tuning + */ + mmc_retune_disable(mmc); err = host->ops->platform_execute_tuning(host, opcode); + mmc_retune_enable(mmc); sdhci_runtime_pm_put(host); return err; } @@ -2840,6 +2854,7 @@ static void sdhci_timeout_timer(unsigned long data) if (host->mrq) { pr_err("%s: Timeout waiting for hardware " "interrupt.\n", mmc_hostname(host->mmc)); + MMC_TRACE(host->mmc, "Timeout waiting for h/w interrupt\n"); sdhci_dumpregs(host); if (host->data) { @@ -2879,6 +2894,9 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *mask) pr_err("%s: Got command interrupt 0x%08x even " "though no command operation was in progress.\n", mmc_hostname(host->mmc), (unsigned)intmask); + MMC_TRACE(host->mmc, + "Got command interrupt 0x%08x even though no command operation was in progress.\n", + (unsigned)intmask); sdhci_dumpregs(host); return; } @@ -3048,6 +3066,9 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) pr_err("%s: Got data interrupt 0x%08x even " "though no data operation was in progress.\n", mmc_hostname(host->mmc), (unsigned)intmask); + MMC_TRACE(host->mmc, + "Got data interrupt 0x%08x even though no data operation was in progress.\n", + (unsigned)intmask); sdhci_dumpregs(host); return; @@ -3083,6 +3104,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) mmc_hostname(host->mmc), intmask, host->data->error, ktime_to_ms(ktime_sub( ktime_get(), host->data_start_time))); + MMC_TRACE(host->mmc, + "data txfr (0x%08x) error: %d after %lld ms\n", + intmask, host->data->error, + ktime_to_ms(ktime_sub(ktime_get(), + host->data_start_time))); if (!host->mmc->sdr104_wa || (host->mmc->ios.timing != MMC_TIMING_UHS_SDR104)) @@ -3334,6 +3360,8 @@ out: if (unexpected) { pr_err("%s: Unexpected interrupt 0x%08x.\n", mmc_hostname(host->mmc), unexpected); + MMC_TRACE(host->mmc, "Unexpected interrupt 0x%08x.\n", + unexpected); sdhci_dumpregs(host); } |