Commit 2342f332 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Pierre Ossman

sdio: allow for mmc_claim_host to be aborted

It is sometimes necessary to give up on trying to claim the host lock,
especially if that happens in a thread that has to be stopped.

While at it, fix the description for mmc_claim_host() which was wrong.
Signed-off-by: default avatarNicolas Pitre <npitre@mvista.com>
Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent 55fe77a0
...@@ -273,15 +273,20 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) ...@@ -273,15 +273,20 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
EXPORT_SYMBOL(mmc_set_data_timeout); 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 * @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); DECLARE_WAITQUEUE(wait, current);
unsigned long flags; unsigned long flags;
int stop;
might_sleep(); might_sleep();
...@@ -289,19 +294,24 @@ void mmc_claim_host(struct mmc_host *host) ...@@ -289,19 +294,24 @@ void mmc_claim_host(struct mmc_host *host)
spin_lock_irqsave(&host->lock, flags); spin_lock_irqsave(&host->lock, flags);
while (1) { while (1) {
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
if (!host->claimed) stop = abort ? atomic_read(abort) : 0;
if (stop || !host->claimed)
break; break;
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
schedule(); schedule();
spin_lock_irqsave(&host->lock, flags); spin_lock_irqsave(&host->lock, flags);
} }
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
if (!stop)
host->claimed = 1; host->claimed = 1;
else
wake_up(&host->wq);
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
remove_wait_queue(&host->wq, &wait); remove_wait_queue(&host->wq, &wait);
return stop;
} }
EXPORT_SYMBOL(mmc_claim_host); EXPORT_SYMBOL(__mmc_claim_host);
/** /**
* mmc_release_host - release a host * mmc_release_host - release a host
......
...@@ -114,7 +114,18 @@ extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, ...@@ -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_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); 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 #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment