MMC core:

- Fix HW busy detection support for host controllers requiring the
    MMC_RSP_BUSY response flag (R1B) to be set for the command. In
    particular for CMD6 (eMMC), erase/trim/discard (SD/eMMC) and CMD5
    (eMMC sleep).
 
 MMC host:
  - sdhci-omap|tegra: Fix support for HW busy detection
 -----BEGIN PGP SIGNATURE-----
 
 iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAl5rfBwXHHVsZi5oYW5z
 c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjClhrA/+MlUKdgTL1MoySMU3xKDUslgx
 Nq+ZzAnSESPMRqGaUkZ/V5ctwXUTQEa1rB8NSWlh/0qerdB+Llt8wnU8YiExBUnK
 LeV0qZlmDv6OPBEVcVT2NyQgWmQDzd1BYXHbOyAhRTXJiSQ9RXiL/DK4Vbu+zikw
 TIe4DUgzaOzzoFU8ohL9nRRJcoIG6L7jw8GT2hUWnJYM56qhpjnibrr62y4qQmSQ
 pwPZ83Z3SYL5EIw/1QYN0swFluaOZCGjiaxC8JAK53SNJzDGLR1LDufw8y1PMwkb
 huvq/lsOEZkUOiIiPwsPTBZul10p4kDC6FkqApd6zlItlT6K3M4vGfgQT5gv7Ke0
 4Zd+gNDBVndwp4AgRgZa785n8F39QILkMSpB4KJ9YkfKKFI8+fm/Nzf8oyrLVmSD
 Xg28TG470fRZtb4YxYVFCbJ+CZW9Czf5cAyY0RmDBkbFQzWt76w+RFxTLWFLU5U0
 LZMLxjQo5oQ9TM7N4wzgoj4OQTE39xGFv3iXIrOW21sbjAMKrvqFSoJEZJxOyHZM
 WMMHFfuiXacfXAHRkGiORRZwtMmoZpyp44/BMprYyVrM616z8RwYEs715QwFkvlP
 8lx9Xtxx0ABgiWBa9C0TgLr/vOeXIJGvJuxv5f1oBnyyXhLzeeaTmg4QhHMt2Ti+
 0UhVxVYQQ3XEpkEgz6Y=
 =3dnT
 -----END PGP SIGNATURE-----

Merge tag 'mmc-v5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC core:

   - Fix HW busy detection support for host controllers requiring the
     MMC_RSP_BUSY response flag (R1B) to be set for the command. In
     particular for CMD6 (eMMC), erase/trim/discard (SD/eMMC) and CMD5
     (eMMC sleep).

  MMC host:

   - sdhci-omap|tegra: Fix support for HW busy detection"

* tag 'mmc-v5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for eMMC sleep command
  mmc: sdhci-tegra: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY
  mmc: sdhci-omap: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY
  mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for erase/trim/discard
  mmc: core: Allow host controllers to require R1B for CMD6
pull/774/merge
Linus Torvalds 2020-03-13 12:21:10 -07:00
commit d36561296b
6 changed files with 20 additions and 5 deletions

View File

@ -1732,8 +1732,11 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
* the erase operation does not exceed the max_busy_timeout, we should * the erase operation does not exceed the max_busy_timeout, we should
* use R1B response. Or we need to prevent the host from doing hw busy * use R1B response. Or we need to prevent the host from doing hw busy
* detection, which is done by converting to a R1 response instead. * detection, which is done by converting to a R1 response instead.
* Note, some hosts requires R1B, which also means they are on their own
* when it comes to deal with the busy timeout.
*/ */
if (card->host->max_busy_timeout && if (!(card->host->caps & MMC_CAP_NEED_RSP_BUSY) &&
card->host->max_busy_timeout &&
busy_timeout > card->host->max_busy_timeout) { busy_timeout > card->host->max_busy_timeout) {
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
} else { } else {

View File

@ -1910,9 +1910,12 @@ static int mmc_sleep(struct mmc_host *host)
* If the max_busy_timeout of the host is specified, validate it against * If the max_busy_timeout of the host is specified, validate it against
* the sleep cmd timeout. A failure means we need to prevent the host * the sleep cmd timeout. A failure means we need to prevent the host
* from doing hw busy detection, which is done by converting to a R1 * from doing hw busy detection, which is done by converting to a R1
* response instead of a R1B. * response instead of a R1B. Note, some hosts requires R1B, which also
* means they are on their own when it comes to deal with the busy
* timeout.
*/ */
if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
(timeout_ms > host->max_busy_timeout)) {
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
} else { } else {
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;

View File

@ -542,9 +542,11 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
* If the max_busy_timeout of the host is specified, make sure it's * If the max_busy_timeout of the host is specified, make sure it's
* enough to fit the used timeout_ms. In case it's not, let's instruct * enough to fit the used timeout_ms. In case it's not, let's instruct
* the host to avoid HW busy detection, by converting to a R1 response * the host to avoid HW busy detection, by converting to a R1 response
* instead of a R1B. * instead of a R1B. Note, some hosts requires R1B, which also means
* they are on their own when it comes to deal with the busy timeout.
*/ */
if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout &&
(timeout_ms > host->max_busy_timeout))
use_r1b_resp = false; use_r1b_resp = false;
cmd.opcode = MMC_SWITCH; cmd.opcode = MMC_SWITCH;

View File

@ -1192,6 +1192,9 @@ static int sdhci_omap_probe(struct platform_device *pdev)
if (of_find_property(dev->of_node, "dmas", NULL)) if (of_find_property(dev->of_node, "dmas", NULL))
sdhci_switch_external_dma(host, true); sdhci_switch_external_dma(host, true);
/* R1B responses is required to properly manage HW busy detection. */
mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
ret = sdhci_setup_host(host); ret = sdhci_setup_host(host);
if (ret) if (ret)
goto err_put_sync; goto err_put_sync;

View File

@ -1552,6 +1552,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50)
host->mmc->caps |= MMC_CAP_1_8V_DDR; host->mmc->caps |= MMC_CAP_1_8V_DDR;
/* R1B responses is required to properly manage HW busy detection. */
host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
tegra_sdhci_parse_dt(host); tegra_sdhci_parse_dt(host);
tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power",

View File

@ -333,6 +333,7 @@ struct mmc_host {
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \
MMC_CAP_UHS_DDR50) MMC_CAP_UHS_DDR50)
#define MMC_CAP_SYNC_RUNTIME_PM (1 << 21) /* Synced runtime PM suspends. */ #define MMC_CAP_SYNC_RUNTIME_PM (1 << 21) /* Synced runtime PM suspends. */
#define MMC_CAP_NEED_RSP_BUSY (1 << 22) /* Commands with R1B can't use R1. */
#define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */
#define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */
#define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */