Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / drivers / mmc / core / bus.c
index 7cd9749..af8dc6a 100644 (file)
@@ -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>
 #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);
        }