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:
parent
954eba2546
commit
65dee48836
3 changed files with 9 additions and 5 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *,
|
||||
|
|
Loading…
Add table
Reference in a new issue