diff options
-rw-r--r-- | drivers/mmc/core/core.c | 24 | ||||
-rw-r--r-- | include/linux/mmc/host.h | 1 |
2 files changed, 22 insertions, 3 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index faa0af10d334..436409f7f7bd 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -2121,18 +2121,36 @@ int _mmc_detect_card_removed(struct mmc_host *host) | |||
2121 | int mmc_detect_card_removed(struct mmc_host *host) | 2121 | int mmc_detect_card_removed(struct mmc_host *host) |
2122 | { | 2122 | { |
2123 | struct mmc_card *card = host->card; | 2123 | struct mmc_card *card = host->card; |
2124 | int ret; | ||
2124 | 2125 | ||
2125 | WARN_ON(!host->claimed); | 2126 | WARN_ON(!host->claimed); |
2127 | |||
2128 | if (!card) | ||
2129 | return 1; | ||
2130 | |||
2131 | ret = mmc_card_removed(card); | ||
2126 | /* | 2132 | /* |
2127 | * The card will be considered unchanged unless we have been asked to | 2133 | * The card will be considered unchanged unless we have been asked to |
2128 | * detect a change or host requires polling to provide card detection. | 2134 | * detect a change or host requires polling to provide card detection. |
2129 | */ | 2135 | */ |
2130 | if (card && !host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL)) | 2136 | if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) && |
2131 | return mmc_card_removed(card); | 2137 | !(host->caps2 & MMC_CAP2_DETECT_ON_ERR)) |
2138 | return ret; | ||
2132 | 2139 | ||
2133 | host->detect_change = 0; | 2140 | host->detect_change = 0; |
2141 | if (!ret) { | ||
2142 | ret = _mmc_detect_card_removed(host); | ||
2143 | if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) { | ||
2144 | /* | ||
2145 | * Schedule a detect work as soon as possible to let a | ||
2146 | * rescan handle the card removal. | ||
2147 | */ | ||
2148 | cancel_delayed_work(&host->detect); | ||
2149 | mmc_detect_change(host, 0); | ||
2150 | } | ||
2151 | } | ||
2134 | 2152 | ||
2135 | return _mmc_detect_card_removed(host); | 2153 | return ret; |
2136 | } | 2154 | } |
2137 | EXPORT_SYMBOL(mmc_detect_card_removed); | 2155 | EXPORT_SYMBOL(mmc_detect_card_removed); |
2138 | 2156 | ||
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index ee2b0363c040..d1d3743fde90 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -258,6 +258,7 @@ struct mmc_host { | |||
258 | #define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \ | 258 | #define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \ |
259 | MMC_CAP2_HS200_1_2V_SDR) | 259 | MMC_CAP2_HS200_1_2V_SDR) |
260 | #define MMC_CAP2_BROKEN_VOLTAGE (1 << 7) /* Use the broken voltage */ | 260 | #define MMC_CAP2_BROKEN_VOLTAGE (1 << 7) /* Use the broken voltage */ |
261 | #define MMC_CAP2_DETECT_ON_ERR (1 << 8) /* On I/O err check card removal */ | ||
261 | 262 | ||
262 | mmc_pm_flag_t pm_caps; /* supported pm features */ | 263 | mmc_pm_flag_t pm_caps; /* supported pm features */ |
263 | unsigned int power_notify_type; | 264 | unsigned int power_notify_type; |