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 6f8ebd6caa4ca224d5e0dd9ca849b1ff668fa77d..915b58f9bfc50de66168909ca7c364921bb10a14 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 baf3d5da4ccbbc344a05ae1438be03b11926ba56..7f87a5354f9f33f0a9fdfe3593ee8c12aca15088 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 24b510b743da0c4a5a91b9cf599f315e7e748c4d..87e53a721a100b5775c6e267122713ff97b8d591 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 85146235231edf4f0d8c747f69a89a3bb2bf3d8a..7c6eaf63f5ce71a4029c76db6576a00172807f0b 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 */