aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/core.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@nokia.com>2009-09-22 19:44:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:33 -0400
commit319a3f1429c91147058ac26c5f5bac8ec1730bc6 (patch)
tree4a39ff034f7e9b57b903997f818eee5304657991 /drivers/mmc/core/core.c
parent8ea926b22e2d13238e4d65d8f61c48fe424e6f4f (diff)
mmc: allow host claim / release nesting
This change allows the MMC host to be claimed in situations where the host may or may not have already been claimed. Also 'mmc_try_claim_host()' is now exported. Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com> Acked-by: Matt Fleming <matt@console-pimps.org> Cc: Ian Molton <ian@mnementh.co.uk> Cc: "Roberto A. Foglietta" <roberto.foglietta@gmail.com> Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com> Cc: Denis Karpov <ext-denis.2.karpov@nokia.com> Cc: Pierre Ossman <pierre@ossman.eu> Cc: Philip Langdale <philipl@overt.org> Cc: "Madhusudhan" <madhu.cr@ti.com> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r--drivers/mmc/core/core.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index fb24a096dba..02f2b1871a3 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -461,16 +461,18 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
461 while (1) { 461 while (1) {
462 set_current_state(TASK_UNINTERRUPTIBLE); 462 set_current_state(TASK_UNINTERRUPTIBLE);
463 stop = abort ? atomic_read(abort) : 0; 463 stop = abort ? atomic_read(abort) : 0;
464 if (stop || !host->claimed) 464 if (stop || !host->claimed || host->claimer == current)
465 break; 465 break;
466 spin_unlock_irqrestore(&host->lock, flags); 466 spin_unlock_irqrestore(&host->lock, flags);
467 schedule(); 467 schedule();
468 spin_lock_irqsave(&host->lock, flags); 468 spin_lock_irqsave(&host->lock, flags);
469 } 469 }
470 set_current_state(TASK_RUNNING); 470 set_current_state(TASK_RUNNING);
471 if (!stop) 471 if (!stop) {
472 host->claimed = 1; 472 host->claimed = 1;
473 else 473 host->claimer = current;
474 host->claim_cnt += 1;
475 } else
474 wake_up(&host->wq); 476 wake_up(&host->wq);
475 spin_unlock_irqrestore(&host->lock, flags); 477 spin_unlock_irqrestore(&host->lock, flags);
476 remove_wait_queue(&host->wq, &wait); 478 remove_wait_queue(&host->wq, &wait);
@@ -481,29 +483,43 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
481 483
482EXPORT_SYMBOL(__mmc_claim_host); 484EXPORT_SYMBOL(__mmc_claim_host);
483 485
484static int mmc_try_claim_host(struct mmc_host *host) 486/**
487 * mmc_try_claim_host - try exclusively to claim a host
488 * @host: mmc host to claim
489 *
490 * Returns %1 if the host is claimed, %0 otherwise.
491 */
492int mmc_try_claim_host(struct mmc_host *host)
485{ 493{
486 int claimed_host = 0; 494 int claimed_host = 0;
487 unsigned long flags; 495 unsigned long flags;
488 496
489 spin_lock_irqsave(&host->lock, flags); 497 spin_lock_irqsave(&host->lock, flags);
490 if (!host->claimed) { 498 if (!host->claimed || host->claimer == current) {
491 host->claimed = 1; 499 host->claimed = 1;
500 host->claimer = current;
501 host->claim_cnt += 1;
492 claimed_host = 1; 502 claimed_host = 1;
493 } 503 }
494 spin_unlock_irqrestore(&host->lock, flags); 504 spin_unlock_irqrestore(&host->lock, flags);
495 return claimed_host; 505 return claimed_host;
496} 506}
507EXPORT_SYMBOL(mmc_try_claim_host);
497 508
498static void mmc_do_release_host(struct mmc_host *host) 509static void mmc_do_release_host(struct mmc_host *host)
499{ 510{
500 unsigned long flags; 511 unsigned long flags;
501 512
502 spin_lock_irqsave(&host->lock, flags); 513 spin_lock_irqsave(&host->lock, flags);
503 host->claimed = 0; 514 if (--host->claim_cnt) {
504 spin_unlock_irqrestore(&host->lock, flags); 515 /* Release for nested claim */
505 516 spin_unlock_irqrestore(&host->lock, flags);
506 wake_up(&host->wq); 517 } else {
518 host->claimed = 0;
519 host->claimer = NULL;
520 spin_unlock_irqrestore(&host->lock, flags);
521 wake_up(&host->wq);
522 }
507} 523}
508 524
509void mmc_host_deeper_disable(struct work_struct *work) 525void mmc_host_deeper_disable(struct work_struct *work)