From 4e5824f8cebb5dee2cb57d784129f056126e2f1b Mon Sep 17 00:00:00 2001 From: Sujith Reddy Thumma Date: Thu, 17 Feb 2011 21:37:48 +0530 Subject: [PATCH] mmc: core: Fix race between runtime PM suspend and block requests There is a possible race with mmc_claim_host() in mmc_sd_suspend()/ mmc_suspend() and mmc_claim_host() in mmc_blk_issue_rq() when runtime pm is enabled. Fix this by blocking processing of requests until the previous runtime suspend is processed and then resume as part of msmsdcc_enable(). Previous fix has card detection failure as a side effect during resume. Change-Id: I9cb31269638d9db4e630eb22b973a5335af1bda4 Signed-off-by: Sujith Reddy Thumma [sboyd: Dropped msm driver change] Signed-off-by: Stephen Boyd --- drivers/mmc/core/core.c | 9 +++++++++ include/linux/mmc/host.h | 1 + 2 files changed, 10 insertions(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8ece791f7b0..8b05245d3af 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -643,6 +644,14 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) might_sleep(); add_wait_queue(&host->wq, &wait); +#ifdef CONFIG_PM_RUNTIME + while (mmc_dev(host)->power.runtime_status == RPM_SUSPENDING) { + if (host->suspend_task == current) + break; + msleep(15); + } +#endif + spin_lock_irqsave(&host->lock, flags); while (1) { set_current_state(TASK_UNINTERRUPTIBLE); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 390b3a1676b..6a4025e74c0 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -287,6 +287,7 @@ struct mmc_host { wait_queue_head_t wq; struct task_struct *claimer; /* task that has host claimed */ + struct task_struct *suspend_task; int claim_cnt; /* "claim" nesting count */ struct delayed_work detect;