diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 48bda70145ee6..018b77ade4c69 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -272,7 +272,7 @@ EXPORT_SYMBOL(mmc_of_parse_clk_phase); int mmc_of_parse(struct mmc_host *host) { struct device *dev = host->parent; - u32 bus_width, drv_type, cd_debounce_delay_ms; + u32 bus_width, drv_type, cd_debounce_delay_ms, cq_allow; int ret; if (!dev || !dev_fwnode(dev)) @@ -407,6 +407,15 @@ int mmc_of_parse(struct mmc_host *host) host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V | MMC_CAP2_HS400_ES); + cq_allow = 0; + /* + * Downstream property - if a u32 and 2 instead of a bool, + * trust most A2 SD cards claiming CQ support. + */ + device_property_read_u32(dev, "supports-cqe", &cq_allow); + if (cq_allow == 2) + host->caps2 |= MMC_CAP2_SD_CQE_PERMISSIVE; + /* Must be after "non-removable" check */ if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) { if (host->caps & MMC_CAP_NONREMOVABLE) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index ece494e6c078a..ea42fa2ef4a6e 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1501,8 +1501,8 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, goto free_card; } - /* Disallow command queueing on unvetted cards */ - if (!mmc_card_working_sd_cq(card)) + /* Disallow command queueing on unvetted cards unless overridden */ + if (!(host->caps2 & MMC_CAP2_SD_CQE_PERMISSIVE) && !mmc_card_working_sd_cq(card)) card->ext_csd.cmdq_support = false; /* Enable command queueing if supported */ diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c index 9743d6cf921b8..1f267c9336d46 100644 --- a/drivers/mmc/host/sdhci-brcmstb.c +++ b/drivers/mmc/host/sdhci-brcmstb.c @@ -571,7 +571,7 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host; const struct of_device_id *match; struct sdhci_brcmstb_priv *priv; - u32 actual_clock_mhz; + u32 actual_clock_mhz, cqe; struct sdhci_host *host; struct resource *iomem; bool no_pinctrl = false; @@ -600,7 +600,9 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) pltfm_host->clk = clk; priv = sdhci_pltfm_priv(pltfm_host); - if (device_property_read_bool(&pdev->dev, "supports-cqe")) { + cqe = 0; + device_property_read_u32(&pdev->dev, "supports-cqe", &cqe); + if (cqe > 0) { priv->flags |= BRCMSTB_PRIV_FLAGS_HAS_CQE; match_priv->ops->irq = sdhci_brcmstb_cqhci_irq; } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 8fc2b328ec4d1..b89232b091b63 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -404,6 +404,7 @@ struct mmc_host { #define MMC_CAP2_CRYPTO 0 #endif #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28) /* Host with eMMC that has GPT entry at a non-standard location */ +#define MMC_CAP2_SD_CQE_PERMISSIVE (1 << 31) /* Ignore allow-list for CQ capable SD card detection */ int fixed_drv_type; /* fixed driver type for non-removable media */