Loading drivers/mmc/core/core.c +7 −3 Original line number Diff line number Diff line Loading @@ -4706,9 +4706,11 @@ static int mmc_pm_notify(struct notifier_block *notify_block, int err = 0; switch (mode) { case PM_RESTORE_PREPARE: case PM_HIBERNATION_PREPARE: if (host->bus_ops && host->bus_ops->pre_hibernate) host->bus_ops->pre_hibernate(host); case PM_SUSPEND_PREPARE: case PM_RESTORE_PREPARE: spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 1; spin_unlock_irqrestore(&host->lock, flags); Loading Loading @@ -4740,9 +4742,11 @@ static int mmc_pm_notify(struct notifier_block *notify_block, host->pm_flags = 0; break; case PM_POST_SUSPEND: case PM_POST_HIBERNATION: case PM_POST_RESTORE: case PM_POST_HIBERNATION: if (host->bus_ops && host->bus_ops->post_hibernate) host->bus_ops->post_hibernate(host); case PM_POST_SUSPEND: spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 0; Loading drivers/mmc/core/mmc.c +69 −0 Original line number Diff line number Diff line Loading @@ -3058,6 +3058,73 @@ static int mmc_shutdown(struct mmc_host *host) return 0; } static int mmc_pre_hibernate(struct mmc_host *host) { int ret = 0; mmc_get_card(host->card); host->cached_caps2 = host->caps2; /* * Increase usage_count of card and host device till * hibernation is over. This will ensure they will not runtime suspend. */ pm_runtime_get_noresume(mmc_dev(host)); pm_runtime_get_noresume(&host->card->dev); if (!mmc_can_scale_clk(host)) goto out; /* * Suspend clock scaling and mask host capability so that * we will run in max frequency during: * 1. Hibernation preparation and image creation * 2. After finding hibernation image during reboot * 3. Once hibernation image is loaded and till hibernation * restore is complete. */ if (host->clk_scaling.enable) mmc_suspend_clk_scaling(host); host->caps2 &= ~MMC_CAP2_CLK_SCALE; host->clk_scaling.state = MMC_LOAD_HIGH; ret = mmc_clk_update_freq(host, host->card->clk_scaling_highest, host->clk_scaling.state); if (ret) pr_err("%s: %s: Setting clk frequency to max failed: %d\n", mmc_hostname(host), __func__, ret); out: mmc_host_clk_hold(host); mmc_put_card(host->card); return ret; } static int mmc_post_hibernate(struct mmc_host *host) { int ret = 0; mmc_get_card(host->card); if (!(host->cached_caps2 & MMC_CAP2_CLK_SCALE)) goto enable_pm; /* Enable the clock scaling and set the host capability */ host->caps2 |= MMC_CAP2_CLK_SCALE; if (!host->clk_scaling.enable) ret = mmc_resume_clk_scaling(host); if (ret) pr_err("%s: %s: Resuming clk scaling failed: %d\n", mmc_hostname(host), __func__, ret); enable_pm: /* * Reduce usage count of card and host device so that they may * runtime suspend. */ pm_runtime_put_noidle(&host->card->dev); pm_runtime_put_noidle(mmc_dev(host)); mmc_host_clk_release(host); mmc_put_card(host->card); return ret; } static const struct mmc_bus_ops mmc_ops = { .remove = mmc_remove, .detect = mmc_detect, Loading @@ -3069,6 +3136,8 @@ static const struct mmc_bus_ops mmc_ops = { .change_bus_speed = mmc_change_bus_speed, .reset = mmc_reset, .shutdown = mmc_shutdown, .pre_hibernate = mmc_pre_hibernate, .post_hibernate = mmc_post_hibernate }; /* Loading include/linux/mmc/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,8 @@ struct mmc_bus_ops { int (*shutdown)(struct mmc_host *); int (*reset)(struct mmc_host *); int (*change_bus_speed)(struct mmc_host *, unsigned long *); int (*pre_hibernate)(struct mmc_host *); int (*post_hibernate)(struct mmc_host *); }; struct mmc_card; Loading include/linux/mmc/host.h +1 −0 Original line number Diff line number Diff line Loading @@ -454,6 +454,7 @@ struct mmc_host { #define MMC_CAP_HW_RESET (1 << 31) /* Hardware reset */ u32 caps2; /* More host capabilities */ u32 cached_caps2; #define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */ #define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */ Loading Loading
drivers/mmc/core/core.c +7 −3 Original line number Diff line number Diff line Loading @@ -4706,9 +4706,11 @@ static int mmc_pm_notify(struct notifier_block *notify_block, int err = 0; switch (mode) { case PM_RESTORE_PREPARE: case PM_HIBERNATION_PREPARE: if (host->bus_ops && host->bus_ops->pre_hibernate) host->bus_ops->pre_hibernate(host); case PM_SUSPEND_PREPARE: case PM_RESTORE_PREPARE: spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 1; spin_unlock_irqrestore(&host->lock, flags); Loading Loading @@ -4740,9 +4742,11 @@ static int mmc_pm_notify(struct notifier_block *notify_block, host->pm_flags = 0; break; case PM_POST_SUSPEND: case PM_POST_HIBERNATION: case PM_POST_RESTORE: case PM_POST_HIBERNATION: if (host->bus_ops && host->bus_ops->post_hibernate) host->bus_ops->post_hibernate(host); case PM_POST_SUSPEND: spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 0; Loading
drivers/mmc/core/mmc.c +69 −0 Original line number Diff line number Diff line Loading @@ -3058,6 +3058,73 @@ static int mmc_shutdown(struct mmc_host *host) return 0; } static int mmc_pre_hibernate(struct mmc_host *host) { int ret = 0; mmc_get_card(host->card); host->cached_caps2 = host->caps2; /* * Increase usage_count of card and host device till * hibernation is over. This will ensure they will not runtime suspend. */ pm_runtime_get_noresume(mmc_dev(host)); pm_runtime_get_noresume(&host->card->dev); if (!mmc_can_scale_clk(host)) goto out; /* * Suspend clock scaling and mask host capability so that * we will run in max frequency during: * 1. Hibernation preparation and image creation * 2. After finding hibernation image during reboot * 3. Once hibernation image is loaded and till hibernation * restore is complete. */ if (host->clk_scaling.enable) mmc_suspend_clk_scaling(host); host->caps2 &= ~MMC_CAP2_CLK_SCALE; host->clk_scaling.state = MMC_LOAD_HIGH; ret = mmc_clk_update_freq(host, host->card->clk_scaling_highest, host->clk_scaling.state); if (ret) pr_err("%s: %s: Setting clk frequency to max failed: %d\n", mmc_hostname(host), __func__, ret); out: mmc_host_clk_hold(host); mmc_put_card(host->card); return ret; } static int mmc_post_hibernate(struct mmc_host *host) { int ret = 0; mmc_get_card(host->card); if (!(host->cached_caps2 & MMC_CAP2_CLK_SCALE)) goto enable_pm; /* Enable the clock scaling and set the host capability */ host->caps2 |= MMC_CAP2_CLK_SCALE; if (!host->clk_scaling.enable) ret = mmc_resume_clk_scaling(host); if (ret) pr_err("%s: %s: Resuming clk scaling failed: %d\n", mmc_hostname(host), __func__, ret); enable_pm: /* * Reduce usage count of card and host device so that they may * runtime suspend. */ pm_runtime_put_noidle(&host->card->dev); pm_runtime_put_noidle(mmc_dev(host)); mmc_host_clk_release(host); mmc_put_card(host->card); return ret; } static const struct mmc_bus_ops mmc_ops = { .remove = mmc_remove, .detect = mmc_detect, Loading @@ -3069,6 +3136,8 @@ static const struct mmc_bus_ops mmc_ops = { .change_bus_speed = mmc_change_bus_speed, .reset = mmc_reset, .shutdown = mmc_shutdown, .pre_hibernate = mmc_pre_hibernate, .post_hibernate = mmc_post_hibernate }; /* Loading
include/linux/mmc/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,8 @@ struct mmc_bus_ops { int (*shutdown)(struct mmc_host *); int (*reset)(struct mmc_host *); int (*change_bus_speed)(struct mmc_host *, unsigned long *); int (*pre_hibernate)(struct mmc_host *); int (*post_hibernate)(struct mmc_host *); }; struct mmc_card; Loading
include/linux/mmc/host.h +1 −0 Original line number Diff line number Diff line Loading @@ -454,6 +454,7 @@ struct mmc_host { #define MMC_CAP_HW_RESET (1 << 31) /* Hardware reset */ u32 caps2; /* More host capabilities */ u32 cached_caps2; #define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */ #define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */ Loading