|
@@ -1581,6 +1581,37 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|
|
sdhci_runtime_pm_put(host);
|
|
|
}
|
|
|
|
|
|
+static int sdhci_do_get_cd(struct sdhci_host *host)
|
|
|
+{
|
|
|
+ int gpio_cd = mmc_gpio_get_cd(host->mmc);
|
|
|
+
|
|
|
+ if (host->flags & SDHCI_DEVICE_DEAD)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /* If polling/nonremovable, assume that the card is always present. */
|
|
|
+ if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
|
|
|
+ (host->mmc->caps & MMC_CAP_NONREMOVABLE))
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ /* Try slot gpio detect */
|
|
|
+ if (!IS_ERR_VALUE(gpio_cd))
|
|
|
+ return !!gpio_cd;
|
|
|
+
|
|
|
+ /* Host native card detect */
|
|
|
+ return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
|
|
|
+}
|
|
|
+
|
|
|
+static int sdhci_get_cd(struct mmc_host *mmc)
|
|
|
+{
|
|
|
+ struct sdhci_host *host = mmc_priv(mmc);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ sdhci_runtime_pm_get(host);
|
|
|
+ ret = sdhci_do_get_cd(host);
|
|
|
+ sdhci_runtime_pm_put(host);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static int sdhci_check_ro(struct sdhci_host *host)
|
|
|
{
|
|
|
unsigned long flags;
|
|
@@ -2038,6 +2069,7 @@ static void sdhci_card_event(struct mmc_host *mmc)
|
|
|
static const struct mmc_host_ops sdhci_ops = {
|
|
|
.request = sdhci_request,
|
|
|
.set_ios = sdhci_set_ios,
|
|
|
+ .get_cd = sdhci_get_cd,
|
|
|
.get_ro = sdhci_get_ro,
|
|
|
.hw_reset = sdhci_hw_reset,
|
|
|
.enable_sdio_irq = sdhci_enable_sdio_irq,
|