mmc: block: fix the block driver shutdown

mmc_queue_suspend() function returns the -EBUSY error if the MMC request
queue is not empty as this function was getting called from the system
suspend path which enforces time limit on the completion of the driver
suspend callback.

But recently the driver shutdown routine also started using
mmc_queue_suspend() function but in shutdown case, we would really want
to wait for the MMC request queue to be empty.

To fix above issue, this change have added new argument named "wait" to
mmc_queue_suspend() function which would tell whether it needs to wait
for the MMC request queue to be empty or not. Driver shutdown callback
will tell the mmc_queue_suspend() to wait but suspend callback won't.

CRs-Fixed: 503227
Change-Id: I86f32d68ec4c4799648785681c5776f090ea6e36
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
Subhash Jadavani 2013-06-20 18:15:50 +05:30
parent 954eba2546
commit 65dee48836
3 changed files with 9 additions and 5 deletions

View file

@ -3180,11 +3180,11 @@ static int _mmc_blk_suspend(struct mmc_card *card)
int rc = 0;
if (md) {
rc = mmc_queue_suspend(&md->queue);
rc = mmc_queue_suspend(&md->queue, 0);
if (rc)
goto out;
list_for_each_entry(part_md, &md->part, part) {
rc = mmc_queue_suspend(&part_md->queue);
rc = mmc_queue_suspend(&part_md->queue, 0);
if (rc)
goto out_resume;
}

View file

@ -421,12 +421,13 @@ void mmc_packed_clean(struct mmc_queue *mq)
/**
* mmc_queue_suspend - suspend a MMC request queue
* @mq: MMC queue to suspend
* @wait: Wait till MMC request queue is empty
*
* Stop the block request queue, and wait for our thread to
* complete any outstanding requests. This ensures that we
* won't suspend while a request is being processed.
*/
int mmc_queue_suspend(struct mmc_queue *mq)
int mmc_queue_suspend(struct mmc_queue *mq, int wait)
{
struct request_queue *q = mq->queue;
unsigned long flags;
@ -440,7 +441,7 @@ int mmc_queue_suspend(struct mmc_queue *mq)
spin_unlock_irqrestore(q->queue_lock, flags);
rc = down_trylock(&mq->thread_sem);
if (rc) {
if (rc && !wait) {
/*
* Failed to take the lock so better to abort the
* suspend because mmcqd thread is processing requests.
@ -450,6 +451,9 @@ int mmc_queue_suspend(struct mmc_queue *mq)
blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
rc = -EBUSY;
} else if (rc && wait) {
down(&mq->thread_sem);
rc = 0;
}
}
return rc;

View file

@ -69,7 +69,7 @@ struct mmc_queue {
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
const char *);
extern void mmc_cleanup_queue(struct mmc_queue *);
extern int mmc_queue_suspend(struct mmc_queue *);
extern int mmc_queue_suspend(struct mmc_queue *, int);
extern void mmc_queue_resume(struct mmc_queue *);
extern unsigned int mmc_queue_map_sg(struct mmc_queue *,