summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/core/core.c22
-rw-r--r--include/linux/mmc/core.h13
2 files changed, 28 insertions, 7 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index b8f27e5ade9..d1e4b0849e3 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -273,15 +273,20 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
EXPORT_SYMBOL(mmc_set_data_timeout);
/**
- * mmc_claim_host - exclusively claim a host
+ * __mmc_claim_host - exclusively claim a host
* @host: mmc host to claim
+ * @abort: whether or not the operation should be aborted
*
- * Claim a host for a set of operations.
+ * Claim a host for a set of operations. If @abort is non null and
+ * dereference a non-zero value then this will return prematurely with
+ * that non-zero value without acquiring the lock. Returns zero
+ * with the lock held otherwise.
*/
-void mmc_claim_host(struct mmc_host *host)
+int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
+ int stop;
might_sleep();
@@ -289,19 +294,24 @@ void mmc_claim_host(struct mmc_host *host)
spin_lock_irqsave(&host->lock, flags);
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
- if (!host->claimed)
+ stop = abort ? atomic_read(abort) : 0;
+ if (stop || !host->claimed)
break;
spin_unlock_irqrestore(&host->lock, flags);
schedule();
spin_lock_irqsave(&host->lock, flags);
}
set_current_state(TASK_RUNNING);
- host->claimed = 1;
+ if (!stop)
+ host->claimed = 1;
+ else
+ wake_up(&host->wq);
spin_unlock_irqrestore(&host->lock, flags);
remove_wait_queue(&host->wq, &wait);
+ return stop;
}
-EXPORT_SYMBOL(mmc_claim_host);
+EXPORT_SYMBOL(__mmc_claim_host);
/**
* mmc_release_host - release a host
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 43a92736be6..8945da9b54f 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -114,7 +114,18 @@ extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *);
-extern void mmc_claim_host(struct mmc_host *host);
+extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
extern void mmc_release_host(struct mmc_host *host);
+/**
+ * mmc_claim_host - exclusively claim a host
+ * @host: mmc host to claim
+ *
+ * Claim a host for a set of operations.
+ */
+static inline void mmc_claim_host(struct mmc_host *host)
+{
+ __mmc_claim_host(host, NULL);
+}
+
#endif