aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@stericsson.com>2012-04-19 05:55:25 -0400
committerChris Ball <cjb@laptop.org>2012-04-20 21:52:13 -0400
commit7c5709194096beea1ab6e6db46768d70a068efb0 (patch)
tree4f41be93cdcbaaeb32869c1a1e5e60f3597a6261 /drivers
parente1631f989e0c6c8d9b43a2dbdd1097f70da603a5 (diff)
mmc: core: Do not pre-claim host in suspend
Since SDIO drivers may want to do some SDIO operations in their suspend callback functions, we must not keep the host claimed when calling them. Daniel Drake reported that libertas_sdio encountered a deadlock in its suspend function. Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> Tested-by: Daniel Drake <dsd@laptop.org> [stable@: please apply to 3.2-stable and 3.3-stable] Cc: stable <stable@vger.kernel.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/core/core.c55
1 files changed, 20 insertions, 35 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index e541efbf325..ba821fe70bc 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2238,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
2238 mmc_card_is_removable(host)) 2238 mmc_card_is_removable(host))
2239 return err; 2239 return err;
2240 2240
2241 mmc_claim_host(host);
2241 if (card && mmc_card_mmc(card) && 2242 if (card && mmc_card_mmc(card) &&
2242 (card->ext_csd.cache_size > 0)) { 2243 (card->ext_csd.cache_size > 0)) {
2243 enable = !!enable; 2244 enable = !!enable;
@@ -2255,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
2255 card->ext_csd.cache_ctrl = enable; 2256 card->ext_csd.cache_ctrl = enable;
2256 } 2257 }
2257 } 2258 }
2259 mmc_release_host(host);
2258 2260
2259 return err; 2261 return err;
2260} 2262}
@@ -2272,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host)
2272 2274
2273 cancel_delayed_work(&host->detect); 2275 cancel_delayed_work(&host->detect);
2274 mmc_flush_scheduled_work(); 2276 mmc_flush_scheduled_work();
2275 if (mmc_try_claim_host(host)) {
2276 err = mmc_cache_ctrl(host, 0);
2277 mmc_release_host(host);
2278 } else {
2279 err = -EBUSY;
2280 }
2281 2277
2278 err = mmc_cache_ctrl(host, 0);
2282 if (err) 2279 if (err)
2283 goto out; 2280 goto out;
2284 2281
2285 mmc_bus_get(host); 2282 mmc_bus_get(host);
2286 if (host->bus_ops && !host->bus_dead) { 2283 if (host->bus_ops && !host->bus_dead) {
2287 2284
2288 /* 2285 if (host->bus_ops->suspend)
2289 * A long response time is not acceptable for device drivers 2286 err = host->bus_ops->suspend(host);
2290 * when doing suspend. Prevent mmc_claim_host in the suspend
2291 * sequence, to potentially wait "forever" by trying to
2292 * pre-claim the host.
2293 */
2294 if (mmc_try_claim_host(host)) {
2295 if (host->bus_ops->suspend) {
2296 err = host->bus_ops->suspend(host);
2297 }
2298 mmc_release_host(host);
2299 2287
2300 if (err == -ENOSYS || !host->bus_ops->resume) { 2288 if (err == -ENOSYS || !host->bus_ops->resume) {
2301 /* 2289 /*
2302 * We simply "remove" the card in this case. 2290 * We simply "remove" the card in this case.
2303 * It will be redetected on resume. (Calling 2291 * It will be redetected on resume. (Calling
2304 * bus_ops->remove() with a claimed host can 2292 * bus_ops->remove() with a claimed host can
2305 * deadlock.) 2293 * deadlock.)
2306 */ 2294 */
2307 if (host->bus_ops->remove) 2295 if (host->bus_ops->remove)
2308 host->bus_ops->remove(host); 2296 host->bus_ops->remove(host);
2309 mmc_claim_host(host); 2297 mmc_claim_host(host);
2310 mmc_detach_bus(host); 2298 mmc_detach_bus(host);
2311 mmc_power_off(host); 2299 mmc_power_off(host);
2312 mmc_release_host(host); 2300 mmc_release_host(host);
2313 host->pm_flags = 0; 2301 host->pm_flags = 0;
2314 err = 0; 2302 err = 0;
2315 }
2316 } else {
2317 err = -EBUSY;
2318 } 2303 }
2319 } 2304 }
2320 mmc_bus_put(host); 2305 mmc_bus_put(host);