mmc: tmio: add hook for custom busy_wait calculation
authorWolfram Sang <wsa+renesas@sang-engineering.com>
Wed, 25 Nov 2020 21:30:00 +0000 (22:30 +0100)
committerUlf Hansson <ulf.hansson@linaro.org>
Fri, 4 Dec 2020 12:30:04 +0000 (13:30 +0100)
Newer SDHI variants can 'wait while busy' longer than the generic TMIO.
Provide a hook to get the maximum cycle count to wait for. If the hook
is not populated, fall back to a generic version which works well with
all older TMIO/SDHI variants.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Link: https://lore.kernel.org/r/20201125213001.15003-3-wsa+renesas@sang-engineering.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/tmio_mmc.h
drivers/mmc/host/tmio_mmc_core.c

index 819198af17f4c7dad2f5324c4cb9e45c11e49ac2..f60559bc413a4755ad8f2af05bfa905cb1772ba0 100644 (file)
@@ -181,6 +181,7 @@ struct tmio_mmc_host {
        void (*reset)(struct tmio_mmc_host *host);
        bool (*check_retune)(struct tmio_mmc_host *host);
        void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
+       unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host);
 
        void (*prepare_hs400_tuning)(struct tmio_mmc_host *host);
        void (*hs400_downgrade)(struct tmio_mmc_host *host);
index 7d2da5befe6b3edf530ea92d1d3908ad44dcbacd..942b8375179c929b47d3b34c1b4ac84b2ad81647 100644 (file)
@@ -887,16 +887,20 @@ static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host,
        sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg);
 }
 
-static void tmio_mmc_max_busy_timeout(struct tmio_mmc_host *host)
+static unsigned int tmio_mmc_get_timeout_cycles(struct tmio_mmc_host *host)
 {
        u16 val = sd_ctrl_read16(host, CTL_SD_MEM_CARD_OPT);
-       unsigned int clk_rate = host->mmc->actual_clock ?: host->mmc->f_max;
-       unsigned int cycles;
 
        val = (val & CARD_OPT_TOP_MASK) >> CARD_OPT_TOP_SHIFT;
-       cycles = 1 << (13 + val);
+       return 1 << (13 + val);
+}
+
+static void tmio_mmc_max_busy_timeout(struct tmio_mmc_host *host)
+{
+       unsigned int clk_rate = host->mmc->actual_clock ?: host->mmc->f_max;
 
-       host->mmc->max_busy_timeout = cycles / (clk_rate / MSEC_PER_SEC);
+       host->mmc->max_busy_timeout = host->get_timeout_cycles(host) /
+                                     (clk_rate / MSEC_PER_SEC);
 }
 
 /* Set MMC clock / power.
@@ -1116,6 +1120,9 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
        if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT))
                _host->write16_hook = NULL;
 
+       if (pdata->flags & TMIO_MMC_USE_BUSY_TIMEOUT && !_host->get_timeout_cycles)
+               _host->get_timeout_cycles = tmio_mmc_get_timeout_cycles;
+
        _host->set_pwr = pdata->set_pwr;
 
        ret = tmio_mmc_init_ocr(_host);