diff options
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r-- | drivers/mmc/core/core.c | 64 |
1 files changed, 26 insertions, 38 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7474c47b9c08..ba821fe70bca 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -1409,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, | |||
1409 | { | 1409 | { |
1410 | unsigned int erase_timeout; | 1410 | unsigned int erase_timeout; |
1411 | 1411 | ||
1412 | if (card->ext_csd.erase_group_def & 1) { | 1412 | if (arg == MMC_DISCARD_ARG || |
1413 | (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { | ||
1414 | erase_timeout = card->ext_csd.trim_timeout; | ||
1415 | } else if (card->ext_csd.erase_group_def & 1) { | ||
1413 | /* High Capacity Erase Group Size uses HC timeouts */ | 1416 | /* High Capacity Erase Group Size uses HC timeouts */ |
1414 | if (arg == MMC_TRIM_ARG) | 1417 | if (arg == MMC_TRIM_ARG) |
1415 | erase_timeout = card->ext_csd.trim_timeout; | 1418 | erase_timeout = card->ext_csd.trim_timeout; |
@@ -1681,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card) | |||
1681 | { | 1684 | { |
1682 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) | 1685 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) |
1683 | return 1; | 1686 | return 1; |
1684 | if (mmc_can_discard(card)) | ||
1685 | return 1; | ||
1686 | return 0; | 1687 | return 0; |
1687 | } | 1688 | } |
1688 | EXPORT_SYMBOL(mmc_can_trim); | 1689 | EXPORT_SYMBOL(mmc_can_trim); |
@@ -1701,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard); | |||
1701 | 1702 | ||
1702 | int mmc_can_sanitize(struct mmc_card *card) | 1703 | int mmc_can_sanitize(struct mmc_card *card) |
1703 | { | 1704 | { |
1705 | if (!mmc_can_trim(card) && !mmc_can_erase(card)) | ||
1706 | return 0; | ||
1704 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) | 1707 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) |
1705 | return 1; | 1708 | return 1; |
1706 | return 0; | 1709 | return 0; |
@@ -2235,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | |||
2235 | mmc_card_is_removable(host)) | 2238 | mmc_card_is_removable(host)) |
2236 | return err; | 2239 | return err; |
2237 | 2240 | ||
2241 | mmc_claim_host(host); | ||
2238 | if (card && mmc_card_mmc(card) && | 2242 | if (card && mmc_card_mmc(card) && |
2239 | (card->ext_csd.cache_size > 0)) { | 2243 | (card->ext_csd.cache_size > 0)) { |
2240 | enable = !!enable; | 2244 | enable = !!enable; |
@@ -2252,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | |||
2252 | card->ext_csd.cache_ctrl = enable; | 2256 | card->ext_csd.cache_ctrl = enable; |
2253 | } | 2257 | } |
2254 | } | 2258 | } |
2259 | mmc_release_host(host); | ||
2255 | 2260 | ||
2256 | return err; | 2261 | return err; |
2257 | } | 2262 | } |
@@ -2269,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host) | |||
2269 | 2274 | ||
2270 | cancel_delayed_work(&host->detect); | 2275 | cancel_delayed_work(&host->detect); |
2271 | mmc_flush_scheduled_work(); | 2276 | mmc_flush_scheduled_work(); |
2272 | if (mmc_try_claim_host(host)) { | ||
2273 | err = mmc_cache_ctrl(host, 0); | ||
2274 | mmc_release_host(host); | ||
2275 | } else { | ||
2276 | err = -EBUSY; | ||
2277 | } | ||
2278 | 2277 | ||
2278 | err = mmc_cache_ctrl(host, 0); | ||
2279 | if (err) | 2279 | if (err) |
2280 | goto out; | 2280 | goto out; |
2281 | 2281 | ||
2282 | mmc_bus_get(host); | 2282 | mmc_bus_get(host); |
2283 | if (host->bus_ops && !host->bus_dead) { | 2283 | if (host->bus_ops && !host->bus_dead) { |
2284 | 2284 | ||
2285 | /* | 2285 | if (host->bus_ops->suspend) |
2286 | * A long response time is not acceptable for device drivers | 2286 | err = host->bus_ops->suspend(host); |
2287 | * when doing suspend. Prevent mmc_claim_host in the suspend | ||
2288 | * sequence, to potentially wait "forever" by trying to | ||
2289 | * pre-claim the host. | ||
2290 | */ | ||
2291 | if (mmc_try_claim_host(host)) { | ||
2292 | if (host->bus_ops->suspend) { | ||
2293 | err = host->bus_ops->suspend(host); | ||
2294 | } | ||
2295 | mmc_release_host(host); | ||
2296 | 2287 | ||
2297 | if (err == -ENOSYS || !host->bus_ops->resume) { | 2288 | if (err == -ENOSYS || !host->bus_ops->resume) { |
2298 | /* | 2289 | /* |
2299 | * We simply "remove" the card in this case. | 2290 | * We simply "remove" the card in this case. |
2300 | * It will be redetected on resume. (Calling | 2291 | * It will be redetected on resume. (Calling |
2301 | * bus_ops->remove() with a claimed host can | 2292 | * bus_ops->remove() with a claimed host can |
2302 | * deadlock.) | 2293 | * deadlock.) |
2303 | */ | 2294 | */ |
2304 | if (host->bus_ops->remove) | 2295 | if (host->bus_ops->remove) |
2305 | host->bus_ops->remove(host); | 2296 | host->bus_ops->remove(host); |
2306 | mmc_claim_host(host); | 2297 | mmc_claim_host(host); |
2307 | mmc_detach_bus(host); | 2298 | mmc_detach_bus(host); |
2308 | mmc_power_off(host); | 2299 | mmc_power_off(host); |
2309 | mmc_release_host(host); | 2300 | mmc_release_host(host); |
2310 | host->pm_flags = 0; | 2301 | host->pm_flags = 0; |
2311 | err = 0; | 2302 | err = 0; |
2312 | } | ||
2313 | } else { | ||
2314 | err = -EBUSY; | ||
2315 | } | 2303 | } |
2316 | } | 2304 | } |
2317 | mmc_bus_put(host); | 2305 | mmc_bus_put(host); |