diff options
-rw-r--r-- | drivers/mmc/core/core.c | 22 | ||||
-rw-r--r-- | include/linux/mmc/core.h | 13 |
2 files changed, 28 insertions, 7 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b8f27e5ade97..d1e4b0849e39 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) | |||
273 | EXPORT_SYMBOL(mmc_set_data_timeout); | 273 | EXPORT_SYMBOL(mmc_set_data_timeout); |
274 | 274 | ||
275 | /** | 275 | /** |
276 | * mmc_claim_host - exclusively claim a host | 276 | * __mmc_claim_host - exclusively claim a host |
277 | * @host: mmc host to claim | 277 | * @host: mmc host to claim |
278 | * @abort: whether or not the operation should be aborted | ||
278 | * | 279 | * |
279 | * Claim a host for a set of operations. | 280 | * Claim a host for a set of operations. If @abort is non null and |
281 | * dereference a non-zero value then this will return prematurely with | ||
282 | * that non-zero value without acquiring the lock. Returns zero | ||
283 | * with the lock held otherwise. | ||
280 | */ | 284 | */ |
281 | void mmc_claim_host(struct mmc_host *host) | 285 | int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) |
282 | { | 286 | { |
283 | DECLARE_WAITQUEUE(wait, current); | 287 | DECLARE_WAITQUEUE(wait, current); |
284 | unsigned long flags; | 288 | unsigned long flags; |
289 | int stop; | ||
285 | 290 | ||
286 | might_sleep(); | 291 | might_sleep(); |
287 | 292 | ||
@@ -289,19 +294,24 @@ void mmc_claim_host(struct mmc_host *host) | |||
289 | spin_lock_irqsave(&host->lock, flags); | 294 | spin_lock_irqsave(&host->lock, flags); |
290 | while (1) { | 295 | while (1) { |
291 | set_current_state(TASK_UNINTERRUPTIBLE); | 296 | set_current_state(TASK_UNINTERRUPTIBLE); |
292 | if (!host->claimed) | 297 | stop = abort ? atomic_read(abort) : 0; |
298 | if (stop || !host->claimed) | ||
293 | break; | 299 | break; |
294 | spin_unlock_irqrestore(&host->lock, flags); | 300 | spin_unlock_irqrestore(&host->lock, flags); |
295 | schedule(); | 301 | schedule(); |
296 | spin_lock_irqsave(&host->lock, flags); | 302 | spin_lock_irqsave(&host->lock, flags); |
297 | } | 303 | } |
298 | set_current_state(TASK_RUNNING); | 304 | set_current_state(TASK_RUNNING); |
299 | host->claimed = 1; | 305 | if (!stop) |
306 | host->claimed = 1; | ||
307 | else | ||
308 | wake_up(&host->wq); | ||
300 | spin_unlock_irqrestore(&host->lock, flags); | 309 | spin_unlock_irqrestore(&host->lock, flags); |
301 | remove_wait_queue(&host->wq, &wait); | 310 | remove_wait_queue(&host->wq, &wait); |
311 | return stop; | ||
302 | } | 312 | } |
303 | 313 | ||
304 | EXPORT_SYMBOL(mmc_claim_host); | 314 | EXPORT_SYMBOL(__mmc_claim_host); |
305 | 315 | ||
306 | /** | 316 | /** |
307 | * mmc_release_host - release a host | 317 | * mmc_release_host - release a host |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 43a92736be63..8945da9b54fa 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 *, | |||
114 | 114 | ||
115 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); | 115 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); |
116 | 116 | ||
117 | extern void mmc_claim_host(struct mmc_host *host); | 117 | extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); |
118 | extern void mmc_release_host(struct mmc_host *host); | 118 | extern void mmc_release_host(struct mmc_host *host); |
119 | 119 | ||
120 | /** | ||
121 | * mmc_claim_host - exclusively claim a host | ||
122 | * @host: mmc host to claim | ||
123 | * | ||
124 | * Claim a host for a set of operations. | ||
125 | */ | ||
126 | static inline void mmc_claim_host(struct mmc_host *host) | ||
127 | { | ||
128 | __mmc_claim_host(host, NULL); | ||
129 | } | ||
130 | |||
120 | #endif | 131 | #endif |