Loading drivers/mmc/core/block.c +0 −4 Original line number Diff line number Diff line Loading @@ -3002,9 +3002,7 @@ static int mmc_blk_probe(struct mmc_card *card) dev_set_drvdata(&card->dev, md); #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME mmc_set_bus_resume_policy(card->host, 1); #endif if (mmc_add_disk(md)) goto out; Loading Loading @@ -3053,9 +3051,7 @@ static void mmc_blk_remove(struct mmc_card *card) pm_runtime_put_noidle(&card->dev); mmc_blk_remove_req(md); dev_set_drvdata(&card->dev, NULL); #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME mmc_set_bus_resume_policy(card->host, 0); #endif destroy_workqueue(card->complete_wq); } Loading drivers/mmc/core/core.c +31 −23 Original line number Diff line number Diff line Loading @@ -1496,10 +1496,9 @@ EXPORT_SYMBOL(mmc_is_req_done); */ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) { #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME if (mmc_bus_needs_resume(host)) mmc_resume_bus(host); #endif __mmc_start_req(host, mrq); if (!mrq->cap_cmd_during_tfr) Loading Loading @@ -1789,10 +1788,9 @@ void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx) { pm_runtime_get_sync(&card->dev); __mmc_claim_host(card->host, ctx, NULL); #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME if (mmc_bus_needs_resume(card->host)) mmc_resume_bus(card->host); #endif } EXPORT_SYMBOL(mmc_get_card); Loading Loading @@ -2658,6 +2656,7 @@ int mmc_resume_bus(struct mmc_host *host) { unsigned long flags; int err = 0; int card_present = true; if (!mmc_bus_needs_resume(host)) return -EINVAL; Loading @@ -2668,23 +2667,29 @@ int mmc_resume_bus(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); mmc_bus_get(host); if (host->bus_ops && !host->bus_dead && host->card) { if (host->ops->get_cd) { card_present = host->ops->get_cd(host); if (!card_present) { pr_err("%s: Card removed - card_present:%d\n", mmc_hostname(host), card_present); mmc_card_set_removed(host->card); } } if (host->bus_ops && !host->bus_dead && host->card && card_present) { mmc_power_up(host, host->card->ocr); BUG_ON(!host->bus_ops->deferred_resume); err = host->bus_ops->deferred_resume(host); if (err && (err != -ENOMEDIUM)) { pr_err("%s: bus resume: failed: %d\n", mmc_hostname(host), err); err = mmc_hw_reset(host); if (err) { pr_err("%s: %s: resume failed: %d\n", mmc_hostname(host), __func__, err); /* * If we have cd-gpio based detection mechanism and * deferred resume is supported, we will not detect * card removal event when system is suspended. So if * resume fails after a system suspend/resume, * schedule the work to detect card presence. */ if (mmc_card_is_removable(host) && !(host->caps & MMC_CAP_NEEDS_POLL)) { mmc_detect_change(host, 0); pr_err("%s: reset: failed: %d\n", mmc_hostname(host), err); goto err_reset; } else { mmc_card_clr_suspended(host->card); } } if (host->card->ext_csd.cmdq_en && !host->cqe_enabled) { Loading @@ -2693,14 +2698,13 @@ int mmc_resume_bus(struct mmc_host *host) if (err) pr_err("%s: %s: cqe enable failed: %d\n", mmc_hostname(host), __func__, err); else mmc_card_clr_suspended(host->card); } } err_reset: mmc_bus_put(host); pr_debug("%s: Deferred resume completed\n", mmc_hostname(host)); return 0; return err; } EXPORT_SYMBOL(mmc_resume_bus); Loading Loading @@ -3717,7 +3721,7 @@ static int mmc_pm_notify(struct notifier_block *notify_block, struct mmc_host *host = container_of( notify_block, struct mmc_host, pm_notify); unsigned long flags; int err = 0; int err = 0, present = 0; switch (mode) { case PM_HIBERNATION_PREPARE: Loading Loading @@ -3760,8 +3764,12 @@ static int mmc_pm_notify(struct notifier_block *notify_block, spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 0; if (host->ops->get_cd) present = host->ops->get_cd(host); if (mmc_bus_manual_resume(host) && !host->ignore_bus_resume_flags) { !host->ignore_bus_resume_flags && present) { spin_unlock_irqrestore(&host->lock, flags); break; } Loading drivers/mmc/core/host.c +19 −0 Original line number Diff line number Diff line Loading @@ -47,9 +47,28 @@ static void mmc_host_classdev_release(struct device *dev) kfree(host); } static int mmc_host_prepare(struct device *dev) { /* * Since mmc_host is a virtual device, we don't have to do anything. * If we return a positive value, the pm framework will consider that * the runtime suspend and system suspend of this device is same and * will set direct_complete flag as true. We don't want this as the * mmc_host always has positive disable_depth and setting the flag * will not speed up the suspend process. * So return 0. */ return 0; } static const struct dev_pm_ops mmc_pm_ops = { .prepare = mmc_host_prepare, }; static struct class mmc_host_class = { .name = "mmc_host", .dev_release = mmc_host_classdev_release, .pm = &mmc_pm_ops, }; int mmc_register_host_class(void) Loading drivers/mmc/core/mmc.c +4 −0 Original line number Diff line number Diff line Loading @@ -2755,6 +2755,10 @@ static int _mmc_hw_reset(struct mmc_host *host) mmc_hostname(host), __func__, ret); return ret; } if (host->inlinecrypt_support) host->inlinecrypt_reset_needed = true; ret = mmc_init_card(host, host->card->ocr, host->card); if (ret) { pr_err("%s: %s: mmc_init_card failed (%d)\n", Loading drivers/mmc/core/sd.c +41 −8 Original line number Diff line number Diff line Loading @@ -1208,6 +1208,9 @@ static void mmc_sd_remove(struct mmc_host *host) */ static int mmc_sd_alive(struct mmc_host *host) { if (host->ops->get_cd && !host->ops->get_cd(host)) return -ENOMEDIUM; return mmc_send_status(host->card, NULL); } Loading @@ -1220,11 +1223,19 @@ static void mmc_sd_detect(struct mmc_host *host) mmc_get_card(host->card, NULL); if (host->ops->get_cd && !host->ops->get_cd(host)) { err = -ENOMEDIUM; mmc_card_set_removed(host->card); mmc_card_clr_suspended(host->card); goto out; } /* * Just check if our card has been removed. */ err = _mmc_detect_card_removed(host); out: mmc_put_card(host->card, NULL); if (err) { Loading Loading @@ -1300,6 +1311,12 @@ static int _mmc_sd_resume(struct mmc_host *host) if (!mmc_card_suspended(host->card)) goto out; if (host->ops->get_cd && !host->ops->get_cd(host)) { err = -ENOMEDIUM; mmc_card_clr_suspended(host->card); goto out; } mmc_power_up(host, host->card->ocr); err = mmc_sd_init_card(host, host->card->ocr, host->card); if (err == -ENOENT) { Loading Loading @@ -1361,12 +1378,23 @@ static int mmc_sd_resume(struct mmc_host *host) { int err = 0; mmc_log_string(host, "enter\n"); err = _mmc_sd_resume(host); if (err) { pr_err("%s: sd resume err: %d\n", mmc_hostname(host), err); if (host->ops->get_cd && !host->ops->get_cd(host)) { err = -ENOMEDIUM; mmc_card_set_removed(host->card); } } if (err != -ENOMEDIUM) { pm_runtime_set_active(&host->card->dev); pm_runtime_mark_last_busy(&host->card->dev); pm_runtime_enable(&host->card->dev); mmc_log_string(host, "done\n"); } mmc_log_string(host, "done err=%d\n", err); return err; } Loading Loading @@ -1410,18 +1438,23 @@ static int mmc_sd_runtime_suspend(struct mmc_host *host) */ static int mmc_sd_runtime_resume(struct mmc_host *host) { int err; int err = 0; err = _mmc_sd_resume(host); if (err && err != -ENOMEDIUM) if (err) { pr_err("%s: error %d doing runtime resume\n", mmc_hostname(host), err); return 0; if (err == -ENOMEDIUM) mmc_card_set_removed(host->card); } return err; } static int mmc_sd_hw_reset(struct mmc_host *host) { if (host->ops->get_cd && !host->ops->get_cd(host)) return -ENOMEDIUM; mmc_power_cycle(host, host->card->ocr); return mmc_sd_init_card(host, host->card->ocr, host->card); } Loading Loading
drivers/mmc/core/block.c +0 −4 Original line number Diff line number Diff line Loading @@ -3002,9 +3002,7 @@ static int mmc_blk_probe(struct mmc_card *card) dev_set_drvdata(&card->dev, md); #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME mmc_set_bus_resume_policy(card->host, 1); #endif if (mmc_add_disk(md)) goto out; Loading Loading @@ -3053,9 +3051,7 @@ static void mmc_blk_remove(struct mmc_card *card) pm_runtime_put_noidle(&card->dev); mmc_blk_remove_req(md); dev_set_drvdata(&card->dev, NULL); #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME mmc_set_bus_resume_policy(card->host, 0); #endif destroy_workqueue(card->complete_wq); } Loading
drivers/mmc/core/core.c +31 −23 Original line number Diff line number Diff line Loading @@ -1496,10 +1496,9 @@ EXPORT_SYMBOL(mmc_is_req_done); */ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) { #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME if (mmc_bus_needs_resume(host)) mmc_resume_bus(host); #endif __mmc_start_req(host, mrq); if (!mrq->cap_cmd_during_tfr) Loading Loading @@ -1789,10 +1788,9 @@ void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx) { pm_runtime_get_sync(&card->dev); __mmc_claim_host(card->host, ctx, NULL); #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME if (mmc_bus_needs_resume(card->host)) mmc_resume_bus(card->host); #endif } EXPORT_SYMBOL(mmc_get_card); Loading Loading @@ -2658,6 +2656,7 @@ int mmc_resume_bus(struct mmc_host *host) { unsigned long flags; int err = 0; int card_present = true; if (!mmc_bus_needs_resume(host)) return -EINVAL; Loading @@ -2668,23 +2667,29 @@ int mmc_resume_bus(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); mmc_bus_get(host); if (host->bus_ops && !host->bus_dead && host->card) { if (host->ops->get_cd) { card_present = host->ops->get_cd(host); if (!card_present) { pr_err("%s: Card removed - card_present:%d\n", mmc_hostname(host), card_present); mmc_card_set_removed(host->card); } } if (host->bus_ops && !host->bus_dead && host->card && card_present) { mmc_power_up(host, host->card->ocr); BUG_ON(!host->bus_ops->deferred_resume); err = host->bus_ops->deferred_resume(host); if (err && (err != -ENOMEDIUM)) { pr_err("%s: bus resume: failed: %d\n", mmc_hostname(host), err); err = mmc_hw_reset(host); if (err) { pr_err("%s: %s: resume failed: %d\n", mmc_hostname(host), __func__, err); /* * If we have cd-gpio based detection mechanism and * deferred resume is supported, we will not detect * card removal event when system is suspended. So if * resume fails after a system suspend/resume, * schedule the work to detect card presence. */ if (mmc_card_is_removable(host) && !(host->caps & MMC_CAP_NEEDS_POLL)) { mmc_detect_change(host, 0); pr_err("%s: reset: failed: %d\n", mmc_hostname(host), err); goto err_reset; } else { mmc_card_clr_suspended(host->card); } } if (host->card->ext_csd.cmdq_en && !host->cqe_enabled) { Loading @@ -2693,14 +2698,13 @@ int mmc_resume_bus(struct mmc_host *host) if (err) pr_err("%s: %s: cqe enable failed: %d\n", mmc_hostname(host), __func__, err); else mmc_card_clr_suspended(host->card); } } err_reset: mmc_bus_put(host); pr_debug("%s: Deferred resume completed\n", mmc_hostname(host)); return 0; return err; } EXPORT_SYMBOL(mmc_resume_bus); Loading Loading @@ -3717,7 +3721,7 @@ static int mmc_pm_notify(struct notifier_block *notify_block, struct mmc_host *host = container_of( notify_block, struct mmc_host, pm_notify); unsigned long flags; int err = 0; int err = 0, present = 0; switch (mode) { case PM_HIBERNATION_PREPARE: Loading Loading @@ -3760,8 +3764,12 @@ static int mmc_pm_notify(struct notifier_block *notify_block, spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 0; if (host->ops->get_cd) present = host->ops->get_cd(host); if (mmc_bus_manual_resume(host) && !host->ignore_bus_resume_flags) { !host->ignore_bus_resume_flags && present) { spin_unlock_irqrestore(&host->lock, flags); break; } Loading
drivers/mmc/core/host.c +19 −0 Original line number Diff line number Diff line Loading @@ -47,9 +47,28 @@ static void mmc_host_classdev_release(struct device *dev) kfree(host); } static int mmc_host_prepare(struct device *dev) { /* * Since mmc_host is a virtual device, we don't have to do anything. * If we return a positive value, the pm framework will consider that * the runtime suspend and system suspend of this device is same and * will set direct_complete flag as true. We don't want this as the * mmc_host always has positive disable_depth and setting the flag * will not speed up the suspend process. * So return 0. */ return 0; } static const struct dev_pm_ops mmc_pm_ops = { .prepare = mmc_host_prepare, }; static struct class mmc_host_class = { .name = "mmc_host", .dev_release = mmc_host_classdev_release, .pm = &mmc_pm_ops, }; int mmc_register_host_class(void) Loading
drivers/mmc/core/mmc.c +4 −0 Original line number Diff line number Diff line Loading @@ -2755,6 +2755,10 @@ static int _mmc_hw_reset(struct mmc_host *host) mmc_hostname(host), __func__, ret); return ret; } if (host->inlinecrypt_support) host->inlinecrypt_reset_needed = true; ret = mmc_init_card(host, host->card->ocr, host->card); if (ret) { pr_err("%s: %s: mmc_init_card failed (%d)\n", Loading
drivers/mmc/core/sd.c +41 −8 Original line number Diff line number Diff line Loading @@ -1208,6 +1208,9 @@ static void mmc_sd_remove(struct mmc_host *host) */ static int mmc_sd_alive(struct mmc_host *host) { if (host->ops->get_cd && !host->ops->get_cd(host)) return -ENOMEDIUM; return mmc_send_status(host->card, NULL); } Loading @@ -1220,11 +1223,19 @@ static void mmc_sd_detect(struct mmc_host *host) mmc_get_card(host->card, NULL); if (host->ops->get_cd && !host->ops->get_cd(host)) { err = -ENOMEDIUM; mmc_card_set_removed(host->card); mmc_card_clr_suspended(host->card); goto out; } /* * Just check if our card has been removed. */ err = _mmc_detect_card_removed(host); out: mmc_put_card(host->card, NULL); if (err) { Loading Loading @@ -1300,6 +1311,12 @@ static int _mmc_sd_resume(struct mmc_host *host) if (!mmc_card_suspended(host->card)) goto out; if (host->ops->get_cd && !host->ops->get_cd(host)) { err = -ENOMEDIUM; mmc_card_clr_suspended(host->card); goto out; } mmc_power_up(host, host->card->ocr); err = mmc_sd_init_card(host, host->card->ocr, host->card); if (err == -ENOENT) { Loading Loading @@ -1361,12 +1378,23 @@ static int mmc_sd_resume(struct mmc_host *host) { int err = 0; mmc_log_string(host, "enter\n"); err = _mmc_sd_resume(host); if (err) { pr_err("%s: sd resume err: %d\n", mmc_hostname(host), err); if (host->ops->get_cd && !host->ops->get_cd(host)) { err = -ENOMEDIUM; mmc_card_set_removed(host->card); } } if (err != -ENOMEDIUM) { pm_runtime_set_active(&host->card->dev); pm_runtime_mark_last_busy(&host->card->dev); pm_runtime_enable(&host->card->dev); mmc_log_string(host, "done\n"); } mmc_log_string(host, "done err=%d\n", err); return err; } Loading Loading @@ -1410,18 +1438,23 @@ static int mmc_sd_runtime_suspend(struct mmc_host *host) */ static int mmc_sd_runtime_resume(struct mmc_host *host) { int err; int err = 0; err = _mmc_sd_resume(host); if (err && err != -ENOMEDIUM) if (err) { pr_err("%s: error %d doing runtime resume\n", mmc_hostname(host), err); return 0; if (err == -ENOMEDIUM) mmc_card_set_removed(host->card); } return err; } static int mmc_sd_hw_reset(struct mmc_host *host) { if (host->ops->get_cd && !host->ops->get_cd(host)) return -ENOMEDIUM; mmc_power_cycle(host, host->card->ocr); return mmc_sd_init_card(host, host->card->ocr, host->card); } Loading