{
        struct mmc_host *host;
 
-       host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
+       host = mmc_alloc_host_sysfs(extra, dev);
        if (host) {
-               memset(host, 0, sizeof(struct mmc_host) + extra);
-
                spin_lock_init(&host->lock);
                init_waitqueue_head(&host->wq);
                INIT_LIST_HEAD(&host->cards);
                INIT_WORK(&host->detect, mmc_rescan, host);
 
-               host->dev = dev;
-
                /*
                 * By default, hosts do not support SGIO or large requests.
                 * They have to set these according to their abilities.
  */
 int mmc_add_host(struct mmc_host *host)
 {
-       static unsigned int host_num;
+       int ret;
 
-       snprintf(host->host_name, sizeof(host->host_name),
-                "mmc%d", host_num++);
-
-       mmc_power_off(host);
-       mmc_detect_change(host);
+       ret = mmc_add_host_sysfs(host);
+       if (ret == 0) {
+               mmc_power_off(host);
+               mmc_detect_change(host);
+       }
 
-       return 0;
+       return ret;
 }
 
 EXPORT_SYMBOL(mmc_add_host);
        }
 
        mmc_power_off(host);
+       mmc_remove_host_sysfs(host);
 }
 
 EXPORT_SYMBOL(mmc_remove_host);
 void mmc_free_host(struct mmc_host *host)
 {
        flush_scheduled_work();
-       kfree(host);
+       mmc_free_host_sysfs(host);
 }
 
 EXPORT_SYMBOL(mmc_free_host);
 
 void mmc_init_card(struct mmc_card *card, struct mmc_host *host);
 int mmc_register_card(struct mmc_card *card);
 void mmc_remove_card(struct mmc_card *card);
+
+struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev);
+int mmc_add_host_sysfs(struct mmc_host *host);
+void mmc_remove_host_sysfs(struct mmc_host *host);
+void mmc_free_host_sysfs(struct mmc_host *host);
 #endif
 
 
 #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)
+#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
 
 #define MMC_ATTR(name, fmt, args...)                                   \
 static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf)        \
 }
 
 
+static void mmc_host_classdev_release(struct class_device *dev)
+{
+       struct mmc_host *host = cls_dev_to_mmc_host(dev);
+       kfree(host);
+}
+
+static struct class mmc_host_class = {
+       .name           = "mmc_host",
+       .release        = mmc_host_classdev_release,
+};
+
+/*
+ * Internal function. Allocate a new MMC host.
+ */
+struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev)
+{
+       struct mmc_host *host;
+
+       host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
+       if (host) {
+               memset(host, 0, sizeof(struct mmc_host) + extra);
+
+               host->dev = dev;
+               host->class_dev.dev = host->dev;
+               host->class_dev.class = &mmc_host_class;
+               class_device_initialize(&host->class_dev);
+       }
+
+       return host;
+}
+
+/*
+ * Internal function. Register a new MMC host with the MMC class.
+ */
+int mmc_add_host_sysfs(struct mmc_host *host)
+{
+       static unsigned int host_num;
+
+       snprintf(host->host_name, sizeof(host->host_name),
+                "mmc%d", host_num++);
+
+       strlcpy(host->class_dev.class_id, host->host_name, BUS_ID_SIZE);
+       return class_device_add(&host->class_dev);
+}
+
+/*
+ * Internal function. Unregister a MMC host with the MMC class.
+ */
+void mmc_remove_host_sysfs(struct mmc_host *host)
+{
+       class_device_del(&host->class_dev);
+}
+
+/*
+ * Internal function. Free a MMC host.
+ */
+void mmc_free_host_sysfs(struct mmc_host *host)
+{
+       class_device_put(&host->class_dev);
+}
+
+
 static int __init mmc_init(void)
 {
-       return bus_register(&mmc_bus_type);
+       int ret = bus_register(&mmc_bus_type);
+       if (ret == 0) {
+               ret = class_register(&mmc_host_class);
+               if (ret)
+                       bus_unregister(&mmc_bus_type);
+       }
+       return ret;
 }
 
 static void __exit mmc_exit(void)
 {
+       class_unregister(&mmc_host_class);
        bus_unregister(&mmc_bus_type);
 }