mmc: core: Add capability to avoid 3.3V signaling
authorKyle Roeschley <kyle.roeschley@ni.com>
Fri, 13 Apr 2018 21:54:57 +0000 (16:54 -0500)
committerUlf Hansson <ulf.hansson@linaro.org>
Wed, 2 May 2018 13:08:44 +0000 (15:08 +0200)
Some SD host controllers cannot handle extended use of 3.3V signaling.
To accommodate these controllers, add a capability that requires us to
negotiate the voltage down from 3.3V during card initialization.

Signed-off-by: Kyle Roeschley <kyle.roeschley@ni.com>
Signed-off-by: Jennifer Dahm <jennifer.dahm@ni.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/core/mmc.c
drivers/mmc/core/sd.c
drivers/mmc/core/sdio.c
include/linux/mmc/host.h

index 6f8ebd6..915b58f 100644 (file)
@@ -1830,6 +1830,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                }
        }
 
+       if (host->caps2 & MMC_CAP2_AVOID_3_3V &&
+           host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+               pr_err("%s: Host failed to negotiate down from 3.3V\n",
+                       mmc_hostname(host));
+               err = -EINVAL;
+               goto free_card;
+       }
+
        if (!oldcard)
                host->card = card;
 
index baf3d5d..7f87a53 100644 (file)
@@ -1058,6 +1058,14 @@ retry:
                        mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
                }
        }
+
+       if (host->caps2 & MMC_CAP2_AVOID_3_3V &&
+           host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+               pr_err("%s: Host failed to negotiate down from 3.3V\n",
+                       mmc_hostname(host));
+               err = -EINVAL;
+               goto free_card;
+       }
 done:
        host->card = card;
        return 0;
index 24b510b..87e53a7 100644 (file)
@@ -792,6 +792,14 @@ try_again:
                if (err)
                        goto remove;
        }
+
+       if (host->caps2 & MMC_CAP2_AVOID_3_3V &&
+           host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+               pr_err("%s: Host failed to negotiate down from 3.3V\n",
+                       mmc_hostname(host));
+               err = -EINVAL;
+               goto remove;
+       }
 finish:
        if (!oldcard)
                host->card = card;
index 8514623..7c6eaf6 100644 (file)
@@ -354,6 +354,7 @@ struct mmc_host {
 #define MMC_CAP2_NO_MMC                (1 << 22)       /* Do not send (e)MMC commands during initialization */
 #define MMC_CAP2_CQE           (1 << 23)       /* Has eMMC command queue engine */
 #define MMC_CAP2_CQE_DCMD      (1 << 24)       /* CQE can issue a direct command */
+#define MMC_CAP2_AVOID_3_3V    (1 << 25)       /* Host must negotiate down from 3.3V */
 
        int                     fixed_drv_type; /* fixed driver type for non-removable media */