Loading drivers/mmc/core/bus.c +14 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,8 @@ static int mmc_bus_suspend(struct device *dev) return ret; } if (mmc_bus_needs_resume(host)) return 0; ret = host->bus_ops->suspend(host); return ret; } Loading @@ -177,11 +179,17 @@ static int mmc_bus_resume(struct device *dev) struct mmc_host *host = card->host; int ret; if (host->bus_resume_flags & MMC_BUSRESUME_MANUAL_RESUME) { host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME; goto skip_full_resume; } ret = host->bus_ops->resume(host); if (ret) pr_warn("%s: error %d during resume (card was removed?)\n", mmc_hostname(host), ret); skip_full_resume: if (dev->driver && drv->resume) ret = drv->resume(card); Loading @@ -195,6 +203,9 @@ static int mmc_runtime_suspend(struct device *dev) struct mmc_card *card = mmc_dev_to_card(dev); struct mmc_host *host = card->host; if (mmc_bus_needs_resume(host)) return 0; return host->bus_ops->runtime_suspend(host); } Loading @@ -203,6 +214,9 @@ static int mmc_runtime_resume(struct device *dev) struct mmc_card *card = mmc_dev_to_card(dev); struct mmc_host *host = card->host; if (mmc_bus_needs_resume(host)) host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME; return host->bus_ops->runtime_resume(host); } Loading drivers/mmc/core/core.c +23 −0 Original line number Diff line number Diff line Loading @@ -2762,6 +2762,29 @@ static inline void mmc_bus_put(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); } int mmc_resume_bus(struct mmc_host *host) { if (!mmc_bus_needs_resume(host)) return -EINVAL; pr_debug("%s: Starting deferred resume\n", mmc_hostname(host)); host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME; mmc_bus_get(host); if (host->bus_ops && !host->bus_dead && host->card) { mmc_power_up(host, host->card->ocr); BUG_ON(!host->bus_ops->resume); host->bus_ops->resume(host); } if (host->bus_ops->detect && !host->bus_dead) host->bus_ops->detect(host); mmc_bus_put(host); pr_debug("%s: Deferred resume completed\n", mmc_hostname(host)); return 0; } EXPORT_SYMBOL(mmc_resume_bus); /* * Assign a mmc bus handler to a host. Only one bus handler may control a * host at any given time. Loading include/linux/mmc/host.h +16 −0 Original line number Diff line number Diff line Loading @@ -497,6 +497,10 @@ struct mmc_host { const struct mmc_bus_ops *bus_ops; /* current bus driver */ unsigned int bus_refs; /* reference counter */ unsigned int bus_resume_flags; #define MMC_BUSRESUME_MANUAL_RESUME (1 << 0) #define MMC_BUSRESUME_NEEDS_RESUME (1 << 1) unsigned int sdio_irqs; struct task_struct *sdio_irq_thread; bool sdio_irq_pending; Loading Loading @@ -600,6 +604,18 @@ static inline void *mmc_cmdq_private(struct mmc_host *host) #define mmc_dev(x) ((x)->parent) #define mmc_classdev(x) (&(x)->class_dev) #define mmc_hostname(x) (dev_name(&(x)->class_dev)) #define mmc_bus_needs_resume(host) ((host)->bus_resume_flags & \ MMC_BUSRESUME_NEEDS_RESUME) static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual) { if (manual) host->bus_resume_flags |= MMC_BUSRESUME_MANUAL_RESUME; else host->bus_resume_flags &= ~MMC_BUSRESUME_MANUAL_RESUME; } extern int mmc_resume_bus(struct mmc_host *host); int mmc_power_save_host(struct mmc_host *host); int mmc_power_restore_host(struct mmc_host *host); Loading Loading
drivers/mmc/core/bus.c +14 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,8 @@ static int mmc_bus_suspend(struct device *dev) return ret; } if (mmc_bus_needs_resume(host)) return 0; ret = host->bus_ops->suspend(host); return ret; } Loading @@ -177,11 +179,17 @@ static int mmc_bus_resume(struct device *dev) struct mmc_host *host = card->host; int ret; if (host->bus_resume_flags & MMC_BUSRESUME_MANUAL_RESUME) { host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME; goto skip_full_resume; } ret = host->bus_ops->resume(host); if (ret) pr_warn("%s: error %d during resume (card was removed?)\n", mmc_hostname(host), ret); skip_full_resume: if (dev->driver && drv->resume) ret = drv->resume(card); Loading @@ -195,6 +203,9 @@ static int mmc_runtime_suspend(struct device *dev) struct mmc_card *card = mmc_dev_to_card(dev); struct mmc_host *host = card->host; if (mmc_bus_needs_resume(host)) return 0; return host->bus_ops->runtime_suspend(host); } Loading @@ -203,6 +214,9 @@ static int mmc_runtime_resume(struct device *dev) struct mmc_card *card = mmc_dev_to_card(dev); struct mmc_host *host = card->host; if (mmc_bus_needs_resume(host)) host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME; return host->bus_ops->runtime_resume(host); } Loading
drivers/mmc/core/core.c +23 −0 Original line number Diff line number Diff line Loading @@ -2762,6 +2762,29 @@ static inline void mmc_bus_put(struct mmc_host *host) spin_unlock_irqrestore(&host->lock, flags); } int mmc_resume_bus(struct mmc_host *host) { if (!mmc_bus_needs_resume(host)) return -EINVAL; pr_debug("%s: Starting deferred resume\n", mmc_hostname(host)); host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME; mmc_bus_get(host); if (host->bus_ops && !host->bus_dead && host->card) { mmc_power_up(host, host->card->ocr); BUG_ON(!host->bus_ops->resume); host->bus_ops->resume(host); } if (host->bus_ops->detect && !host->bus_dead) host->bus_ops->detect(host); mmc_bus_put(host); pr_debug("%s: Deferred resume completed\n", mmc_hostname(host)); return 0; } EXPORT_SYMBOL(mmc_resume_bus); /* * Assign a mmc bus handler to a host. Only one bus handler may control a * host at any given time. Loading
include/linux/mmc/host.h +16 −0 Original line number Diff line number Diff line Loading @@ -497,6 +497,10 @@ struct mmc_host { const struct mmc_bus_ops *bus_ops; /* current bus driver */ unsigned int bus_refs; /* reference counter */ unsigned int bus_resume_flags; #define MMC_BUSRESUME_MANUAL_RESUME (1 << 0) #define MMC_BUSRESUME_NEEDS_RESUME (1 << 1) unsigned int sdio_irqs; struct task_struct *sdio_irq_thread; bool sdio_irq_pending; Loading Loading @@ -600,6 +604,18 @@ static inline void *mmc_cmdq_private(struct mmc_host *host) #define mmc_dev(x) ((x)->parent) #define mmc_classdev(x) (&(x)->class_dev) #define mmc_hostname(x) (dev_name(&(x)->class_dev)) #define mmc_bus_needs_resume(host) ((host)->bus_resume_flags & \ MMC_BUSRESUME_NEEDS_RESUME) static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual) { if (manual) host->bus_resume_flags |= MMC_BUSRESUME_MANUAL_RESUME; else host->bus_resume_flags &= ~MMC_BUSRESUME_MANUAL_RESUME; } extern int mmc_resume_bus(struct mmc_host *host); int mmc_power_save_host(struct mmc_host *host); int mmc_power_restore_host(struct mmc_host *host); Loading