diff options
author | Kevin Liu <kliu5@marvell.com> | 2013-02-28 04:35:53 -0500 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-03-22 12:24:50 -0400 |
commit | 94144a465dd0b34b3249f988a09472d0f57ad2b7 (patch) | |
tree | 207bb564e0a1f6a0a4762f579dc09c7f119c86f1 | |
parent | 1450734ec61cda7bbb77afc8cb412b9d64c62d9a (diff) |
mmc: sdhci: add get_cd() implementation
1. mmc_rescan will call get_cd to know whether the card is present
before mmc_rescan_try_freq to avoid useless trials during
card removal or start host is called when card is not present.
2. get_cd needs to be checked to resolve slow card removal issue.
Signed-off-by: Kevin Liu <kliu5@marvell.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | drivers/mmc/host/sdhci.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 51bbba486f38..81d52942677c 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1581,6 +1581,37 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1581 | sdhci_runtime_pm_put(host); | 1581 | sdhci_runtime_pm_put(host); |
1582 | } | 1582 | } |
1583 | 1583 | ||
1584 | static int sdhci_do_get_cd(struct sdhci_host *host) | ||
1585 | { | ||
1586 | int gpio_cd = mmc_gpio_get_cd(host->mmc); | ||
1587 | |||
1588 | if (host->flags & SDHCI_DEVICE_DEAD) | ||
1589 | return 0; | ||
1590 | |||
1591 | /* If polling/nonremovable, assume that the card is always present. */ | ||
1592 | if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || | ||
1593 | (host->mmc->caps & MMC_CAP_NONREMOVABLE)) | ||
1594 | return 1; | ||
1595 | |||
1596 | /* Try slot gpio detect */ | ||
1597 | if (!IS_ERR_VALUE(gpio_cd)) | ||
1598 | return !!gpio_cd; | ||
1599 | |||
1600 | /* Host native card detect */ | ||
1601 | return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); | ||
1602 | } | ||
1603 | |||
1604 | static int sdhci_get_cd(struct mmc_host *mmc) | ||
1605 | { | ||
1606 | struct sdhci_host *host = mmc_priv(mmc); | ||
1607 | int ret; | ||
1608 | |||
1609 | sdhci_runtime_pm_get(host); | ||
1610 | ret = sdhci_do_get_cd(host); | ||
1611 | sdhci_runtime_pm_put(host); | ||
1612 | return ret; | ||
1613 | } | ||
1614 | |||
1584 | static int sdhci_check_ro(struct sdhci_host *host) | 1615 | static int sdhci_check_ro(struct sdhci_host *host) |
1585 | { | 1616 | { |
1586 | unsigned long flags; | 1617 | unsigned long flags; |
@@ -2038,6 +2069,7 @@ static void sdhci_card_event(struct mmc_host *mmc) | |||
2038 | static const struct mmc_host_ops sdhci_ops = { | 2069 | static const struct mmc_host_ops sdhci_ops = { |
2039 | .request = sdhci_request, | 2070 | .request = sdhci_request, |
2040 | .set_ios = sdhci_set_ios, | 2071 | .set_ios = sdhci_set_ios, |
2072 | .get_cd = sdhci_get_cd, | ||
2041 | .get_ro = sdhci_get_ro, | 2073 | .get_ro = sdhci_get_ro, |
2042 | .hw_reset = sdhci_hw_reset, | 2074 | .hw_reset = sdhci_hw_reset, |
2043 | .enable_sdio_irq = sdhci_enable_sdio_irq, | 2075 | .enable_sdio_irq = sdhci_enable_sdio_irq, |