diff options
Diffstat (limited to 'drivers/mmc/core/bus.c')
-rw-r--r-- | drivers/mmc/core/bus.c | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 7cd9749dc21d..af8dc6a2a317 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -14,6 +14,7 @@ #include <linux/device.h> #include <linux/err.h> #include <linux/slab.h> +#include <linux/pm_runtime.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> @@ -22,13 +23,12 @@ #include "sdio_cis.h" #include "bus.h" -#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) static ssize_t mmc_type_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct mmc_card *card = dev_to_mmc_card(dev); + struct mmc_card *card = mmc_dev_to_card(dev); switch (card->type) { case MMC_TYPE_MMC: @@ -62,7 +62,7 @@ static int mmc_bus_match(struct device *dev, struct device_driver *drv) static int mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) { - struct mmc_card *card = dev_to_mmc_card(dev); + struct mmc_card *card = mmc_dev_to_card(dev); const char *type; int retval = 0; @@ -105,7 +105,7 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) static int mmc_bus_probe(struct device *dev) { struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = dev_to_mmc_card(dev); + struct mmc_card *card = mmc_dev_to_card(dev); return drv->probe(card); } @@ -113,7 +113,7 @@ static int mmc_bus_probe(struct device *dev) static int mmc_bus_remove(struct device *dev) { struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = dev_to_mmc_card(dev); + struct mmc_card *card = mmc_dev_to_card(dev); drv->remove(card); @@ -123,7 +123,7 @@ static int mmc_bus_remove(struct device *dev) static int mmc_bus_suspend(struct device *dev, pm_message_t state) { struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = dev_to_mmc_card(dev); + struct mmc_card *card = mmc_dev_to_card(dev); int ret = 0; if (dev->driver && drv->suspend) @@ -134,7 +134,7 @@ static int mmc_bus_suspend(struct device *dev, pm_message_t state) static int mmc_bus_resume(struct device *dev) { struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = dev_to_mmc_card(dev); + struct mmc_card *card = mmc_dev_to_card(dev); int ret = 0; if (dev->driver && drv->resume) @@ -142,6 +142,41 @@ static int mmc_bus_resume(struct device *dev) return ret; } +#ifdef CONFIG_PM_RUNTIME + +static int mmc_runtime_suspend(struct device *dev) +{ + struct mmc_card *card = mmc_dev_to_card(dev); + + return mmc_power_save_host(card->host); +} + +static int mmc_runtime_resume(struct device *dev) +{ + struct mmc_card *card = mmc_dev_to_card(dev); + + return mmc_power_restore_host(card->host); +} + +static int mmc_runtime_idle(struct device *dev) +{ + return pm_runtime_suspend(dev); +} + +static const struct dev_pm_ops mmc_bus_pm_ops = { + .runtime_suspend = mmc_runtime_suspend, + .runtime_resume = mmc_runtime_resume, + .runtime_idle = mmc_runtime_idle, +}; + +#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops) + +#else /* !CONFIG_PM_RUNTIME */ + +#define MMC_PM_OPS_PTR NULL + +#endif /* !CONFIG_PM_RUNTIME */ + static struct bus_type mmc_bus_type = { .name = "mmc", .dev_attrs = mmc_dev_attrs, @@ -151,6 +186,7 @@ static struct bus_type mmc_bus_type = { .remove = mmc_bus_remove, .suspend = mmc_bus_suspend, .resume = mmc_bus_resume, + .pm = MMC_PM_OPS_PTR, }; int mmc_register_bus(void) @@ -189,7 +225,7 @@ EXPORT_SYMBOL(mmc_unregister_driver); static void mmc_release_card(struct device *dev) { - struct mmc_card *card = dev_to_mmc_card(dev); + struct mmc_card *card = mmc_dev_to_card(dev); sdio_free_common_cis(card); @@ -254,14 +290,16 @@ int mmc_add_card(struct mmc_card *card) } if (mmc_host_is_spi(card->host)) { - printk(KERN_INFO "%s: new %s%s card on SPI\n", + printk(KERN_INFO "%s: new %s%s%s card on SPI\n", mmc_hostname(card->host), mmc_card_highspeed(card) ? "high speed " : "", + mmc_card_ddr_mode(card) ? "DDR " : "", type); } else { - printk(KERN_INFO "%s: new %s%s card at address %04x\n", + printk(KERN_INFO "%s: new %s%s%s card at address %04x\n", mmc_hostname(card->host), mmc_card_highspeed(card) ? "high speed " : "", + mmc_card_ddr_mode(card) ? "DDR " : "", type, card->rca); } |