Merge "mmc: core: Fix deadlock in suspend & rescan path"

This commit is contained in:
Linux Build Service Account 2017-02-21 05:33:14 -08:00 committed by Gerrit - the friendly Code Review server
commit abe0d1ce01

View file

@ -3095,7 +3095,6 @@ int mmc_resume_bus(struct mmc_host *host)
pr_debug("%s: Starting deferred resume\n", mmc_hostname(host));
spin_lock_irqsave(&host->lock, flags);
host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
host->rescan_disable = 0;
spin_unlock_irqrestore(&host->lock, flags);
mmc_bus_get(host);
@ -4041,6 +4040,7 @@ EXPORT_SYMBOL(mmc_detect_card_removed);
void mmc_rescan(struct work_struct *work)
{
unsigned long flags;
struct mmc_host *host =
container_of(work, struct mmc_host, detect.work);
@ -4049,8 +4049,12 @@ void mmc_rescan(struct work_struct *work)
host->trigger_card_event = false;
}
if (host->rescan_disable)
spin_lock_irqsave(&host->lock, flags);
if (host->rescan_disable) {
spin_unlock_irqrestore(&host->lock, flags);
return;
}
spin_unlock_irqrestore(&host->lock, flags);
/* If there is a non-removable card registered, only scan once */
if ((host->caps & MMC_CAP_NONREMOVABLE) && host->rescan_entered)
@ -4297,10 +4301,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
case PM_SUSPEND_PREPARE:
case PM_RESTORE_PREPARE:
spin_lock_irqsave(&host->lock, flags);
if (mmc_bus_needs_resume(host)) {
spin_unlock_irqrestore(&host->lock, flags);
break;
}
host->rescan_disable = 1;
spin_unlock_irqrestore(&host->lock, flags);
cancel_delayed_work_sync(&host->detect);