Merge tag 'mmc-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Apr 2022 16:37:11 +0000 (06:37 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Apr 2022 16:37:11 +0000 (06:37 -1000)
Pull MMC updates from Ulf Hansson:
 "MMC core:
   - Improve API to make it clear that mmc_hw_reset() is for cards
   - Fixup support for writeback-cache for eMMC and SD
   - Check for errors after writes on SPI

  MMC host:
   - renesas_sdhi: A couple of fixes of TAP settings for eMMC HS400 mode
   - mmci_stm32: Fixup check of all elements in sg list
   - sdhci-xenon: Revert unnecessary fix for annoying 1.8V regulator warning"

* tag 'mmc-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: core: improve API to make clear mmc_hw_reset is for cards
  mmc: renesas_sdhi: don't overwrite TAP settings when HS400 tuning is complete
  mmc: renesas_sdhi: special 4tap settings only apply to HS400
  mmc: core: Fixup support for writeback-cache for eMMC and SD
  mmc: block: Check for errors after write on SPI
  mmc: mmci: stm32: correctly check all elements of sg list
  Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning"

drivers/mmc/core/block.c
drivers/mmc/core/core.c
drivers/mmc/core/mmc_test.c
drivers/mmc/host/mmci_stm32_sdmmc.c
drivers/mmc/host/renesas_sdhi_core.c
drivers/mmc/host/sdhci-xenon.c
drivers/net/wireless/ath/ath10k/sdio.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/marvell/mwifiex/sdio.c
drivers/net/wireless/ti/wlcore/sdio.c
include/linux/mmc/core.h

index 4e67c14..506dc90 100644 (file)
@@ -993,7 +993,7 @@ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
                return -EEXIST;
 
        md->reset_done |= type;
-       err = mmc_hw_reset(host);
+       err = mmc_hw_reset(host->card);
        /* Ensure we switch back to the correct partition */
        if (err) {
                struct mmc_blk_data *main_md =
@@ -1880,6 +1880,31 @@ static inline bool mmc_blk_rq_error(struct mmc_blk_request *brq)
               brq->data.error || brq->cmd.resp[0] & CMD_ERRORS;
 }
 
+static int mmc_spi_err_check(struct mmc_card *card)
+{
+       u32 status = 0;
+       int err;
+
+       /*
+        * SPI does not have a TRAN state we have to wait on, instead the
+        * card is ready again when it no longer holds the line LOW.
+        * We still have to ensure two things here before we know the write
+        * was successful:
+        * 1. The card has not disconnected during busy and we actually read our
+        * own pull-up, thinking it was still connected, so ensure it
+        * still responds.
+        * 2. Check for any error bits, in particular R1_SPI_IDLE to catch a
+        * just reconnected card after being disconnected during busy.
+        */
+       err = __mmc_send_status(card, &status, 0);
+       if (err)
+               return err;
+       /* All R1 and R2 bits of SPI are errors in our case */
+       if (status)
+               return -EIO;
+       return 0;
+}
+
 static int mmc_blk_busy_cb(void *cb_data, bool *busy)
 {
        struct mmc_blk_busy_data *data = cb_data;
@@ -1903,9 +1928,16 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req)
        struct mmc_blk_busy_data cb_data;
        int err;
 
-       if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ)
+       if (rq_data_dir(req) == READ)
                return 0;
 
+       if (mmc_host_is_spi(card->host)) {
+               err = mmc_spi_err_check(card);
+               if (err)
+                       mqrq->brq.data.bytes_xfered = 0;
+               return err;
+       }
+
        cb_data.card = card;
        cb_data.status = 0;
        err = __mmc_poll_for_busy(card->host, 0, MMC_BLK_TIMEOUT_MS,
@@ -2350,6 +2382,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
        struct mmc_blk_data *md;
        int devidx, ret;
        char cap_str[10];
+       bool cache_enabled = false;
+       bool fua_enabled = false;
 
        devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL);
        if (devidx < 0) {
@@ -2429,13 +2463,17 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
                        md->flags |= MMC_BLK_CMD23;
        }
 
-       if (mmc_card_mmc(card) &&
-           md->flags & MMC_BLK_CMD23 &&
+       if (md->flags & MMC_BLK_CMD23 &&
            ((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) ||
             card->ext_csd.rel_sectors)) {
                md->flags |= MMC_BLK_REL_WR;
-               blk_queue_write_cache(md->queue.queue, true, true);
+               fua_enabled = true;
+               cache_enabled = true;
        }
+       if (mmc_cache_enabled(card->host))
+               cache_enabled  = true;
+
+       blk_queue_write_cache(md->queue.queue, cache_enabled, fua_enabled);
 
        string_get_size((u64)size, 512, STRING_UNITS_2,
                        cap_str, sizeof(cap_str));
index 368f104..c6ae16d 100644 (file)
@@ -1995,7 +1995,7 @@ static void mmc_hw_reset_for_init(struct mmc_host *host)
 
 /**
  * mmc_hw_reset - reset the card in hardware
- * @host: MMC host to which the card is attached
+ * @card: card to be reset
  *
  * Hard reset the card. This function is only for upper layers, like the
  * block layer or card drivers. You cannot use it in host drivers (struct
@@ -2003,8 +2003,9 @@ static void mmc_hw_reset_for_init(struct mmc_host *host)
  *
  * Return: 0 on success, -errno on failure
  */
-int mmc_hw_reset(struct mmc_host *host)
+int mmc_hw_reset(struct mmc_card *card)
 {
+       struct mmc_host *host = card->host;
        int ret;
 
        ret = host->bus_ops->hw_reset(host);
index e6a2fd2..8d9bcee 100644 (file)
@@ -2325,10 +2325,9 @@ static int mmc_test_profile_sglen_r_nonblock_perf(struct mmc_test_card *test)
 static int mmc_test_reset(struct mmc_test_card *test)
 {
        struct mmc_card *card = test->card;
-       struct mmc_host *host = card->host;
        int err;
 
-       err = mmc_hw_reset(host);
+       err = mmc_hw_reset(card);
        if (!err) {
                /*
                 * Reset will re-enable the card's command queue, but tests
index 9c13f2c..4566d7f 100644 (file)
@@ -62,8 +62,8 @@ static int sdmmc_idma_validate_data(struct mmci_host *host,
         * excepted the last element which has no constraint on idmasize
         */
        for_each_sg(data->sg, sg, data->sg_len - 1, i) {
-               if (!IS_ALIGNED(data->sg->offset, sizeof(u32)) ||
-                   !IS_ALIGNED(data->sg->length, SDMMC_IDMA_BURST)) {
+               if (!IS_ALIGNED(sg->offset, sizeof(u32)) ||
+                   !IS_ALIGNED(sg->length, SDMMC_IDMA_BURST)) {
                        dev_err(mmc_dev(host->mmc),
                                "unaligned scatterlist: ofst:%x length:%d\n",
                                data->sg->offset, data->sg->length);
@@ -71,7 +71,7 @@ static int sdmmc_idma_validate_data(struct mmci_host *host,
                }
        }
 
-       if (!IS_ALIGNED(data->sg->offset, sizeof(u32))) {
+       if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
                dev_err(mmc_dev(host->mmc),
                        "unaligned last scatterlist: ofst:%x length:%d\n",
                        data->sg->offset, data->sg->length);
index 2797a9c..ddb5ca2 100644 (file)
@@ -144,9 +144,9 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
                return clk_get_rate(priv->clk);
 
        if (priv->clkh) {
+               /* HS400 with 4TAP needs different clock settings */
                bool use_4tap = priv->quirks && priv->quirks->hs400_4taps;
-               bool need_slow_clkh = (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104) ||
-                                     (host->mmc->ios.timing == MMC_TIMING_MMC_HS400);
+               bool need_slow_clkh = host->mmc->ios.timing == MMC_TIMING_MMC_HS400;
                clkh_shift = use_4tap && need_slow_clkh ? 1 : 2;
                ref_clk = priv->clkh;
        }
@@ -396,10 +396,10 @@ static void renesas_sdhi_hs400_complete(struct mmc_host *mmc)
                        SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) |
                        sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
 
-       /* Set the sampling clock selection range of HS400 mode */
        sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
                       SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN |
-                      0x4 << SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT);
+                      sd_scc_read32(host, priv,
+                                    SH_MOBILE_SDHI_SCC_DTCNTL));
 
        /* Avoid bad TAP */
        if (bad_taps & BIT(priv->tap_set)) {
index 666cee4..08e8384 100644 (file)
@@ -241,16 +241,6 @@ static void xenon_voltage_switch(struct sdhci_host *host)
 {
        /* Wait for 5ms after set 1.8V signal enable bit */
        usleep_range(5000, 5500);
-
-       /*
-        * For some reason the controller's Host Control2 register reports
-        * the bit representing 1.8V signaling as 0 when read after it was
-        * written as 1. Subsequent read reports 1.
-        *
-        * Since this may cause some issues, do an empty read of the Host
-        * Control2 register here to circumvent this.
-        */
-       sdhci_readw(host, SDHCI_HOST_CONTROL2);
 }
 
 static unsigned int xenon_get_max_clock(struct sdhci_host *host)
index 63e1c2d..73693c6 100644 (file)
@@ -1633,7 +1633,7 @@ static void ath10k_sdio_hif_power_down(struct ath10k *ar)
                return;
        }
 
-       ret = mmc_hw_reset(ar_sdio->func->card->host);
+       ret = mmc_hw_reset(ar_sdio->func->card);
        if (ret)
                ath10k_warn(ar, "unable to reset sdio: %d\n", ret);
 
index ba3c159..55285ca 100644 (file)
@@ -4165,7 +4165,7 @@ static int brcmf_sdio_bus_reset(struct device *dev)
 
        /* reset the adapter */
        sdio_claim_host(sdiodev->func1);
-       mmc_hw_reset(sdiodev->func1->card->host);
+       mmc_hw_reset(sdiodev->func1->card);
        sdio_release_host(sdiodev->func1);
 
        brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
index bde9e4b..4f3238d 100644 (file)
@@ -2639,7 +2639,7 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
 
        /* Run a HW reset of the SDIO interface. */
        sdio_claim_host(func);
-       ret = mmc_hw_reset(func->card->host);
+       ret = mmc_hw_reset(func->card);
        sdio_release_host(func);
 
        switch (ret) {
index 72fc41a..9140b01 100644 (file)
@@ -146,7 +146,7 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
         * To guarantee that the SDIO card is power cycled, as required to make
         * the FW programming to succeed, let's do a brute force HW reset.
         */
-       mmc_hw_reset(card->host);
+       mmc_hw_reset(card);
 
        sdio_enable_func(func);
        sdio_release_host(func);
index 71101d1..de5c64b 100644 (file)
@@ -175,7 +175,7 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq);
 int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd,
                int retries);
 
-int mmc_hw_reset(struct mmc_host *host);
+int mmc_hw_reset(struct mmc_card *card);
 int mmc_sw_reset(struct mmc_host *host);
 void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card);