diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 06748b32d5d4..c3abd5c6ce52 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -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; } diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index de3c1dd0a569..4756193e9a0f 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -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; diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 900137715ceb..2e23b6d849ae 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -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 *,