Skip to content

Commit

Permalink
mmc: allow host claim / release nesting
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Adrian Hunter authored and Linus Torvalds committed Sep 23, 2009
1 parent 8ea926b commit 319a3f1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 9 deletions.
34 changes: 25 additions & 9 deletions drivers/mmc/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,16 +461,18 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
stop = abort ? atomic_read(abort) : 0;
if (stop || !host->claimed)
if (stop || !host->claimed || host->claimer == current)
break;
spin_unlock_irqrestore(&host->lock, flags);
schedule();
spin_lock_irqsave(&host->lock, flags);
}
set_current_state(TASK_RUNNING);
if (!stop)
if (!stop) {
host->claimed = 1;
else
host->claimer = current;
host->claim_cnt += 1;
} else
wake_up(&host->wq);
spin_unlock_irqrestore(&host->lock, flags);
remove_wait_queue(&host->wq, &wait);
Expand All @@ -481,29 +483,43 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)

EXPORT_SYMBOL(__mmc_claim_host);

static int mmc_try_claim_host(struct mmc_host *host)
/**
* mmc_try_claim_host - try exclusively to claim a host
* @host: mmc host to claim
*
* Returns %1 if the host is claimed, %0 otherwise.
*/
int mmc_try_claim_host(struct mmc_host *host)
{
int claimed_host = 0;
unsigned long flags;

spin_lock_irqsave(&host->lock, flags);
if (!host->claimed) {
if (!host->claimed || host->claimer == current) {
host->claimed = 1;
host->claimer = current;
host->claim_cnt += 1;
claimed_host = 1;
}
spin_unlock_irqrestore(&host->lock, flags);
return claimed_host;
}
EXPORT_SYMBOL(mmc_try_claim_host);

static void mmc_do_release_host(struct mmc_host *host)
{
unsigned long flags;

spin_lock_irqsave(&host->lock, flags);
host->claimed = 0;
spin_unlock_irqrestore(&host->lock, flags);

wake_up(&host->wq);
if (--host->claim_cnt) {
/* Release for nested claim */
spin_unlock_irqrestore(&host->lock, flags);
} else {
host->claimed = 0;
host->claimer = NULL;
spin_unlock_irqrestore(&host->lock, flags);
wake_up(&host->wq);
}
}

void mmc_host_deeper_disable(struct work_struct *work)
Expand Down
1 change: 1 addition & 0 deletions include/linux/mmc/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int);

extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
extern void mmc_release_host(struct mmc_host *host);
extern int mmc_try_claim_host(struct mmc_host *host);

/**
* mmc_claim_host - exclusively claim a host
Expand Down
2 changes: 2 additions & 0 deletions include/linux/mmc/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ struct mmc_host {
struct mmc_card *card; /* device attached to this host */

wait_queue_head_t wq;
struct task_struct *claimer; /* task that has host claimed */
int claim_cnt; /* "claim" nesting count */

struct delayed_work detect;

Expand Down

0 comments on commit 319a3f1

Please sign in to comment.