#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/idr.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
card->raw_cid[2], card->raw_cid[3]);
MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
card->raw_csd[2], card->raw_csd[3]);
+MMC_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]);
MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
__ATTR_NULL
};
+static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr);
+
static void mmc_release_card(struct device *dev)
{
}
static int
-mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
+mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
int buf_size)
{
struct mmc_card *card = dev_to_mmc_card(dev);
return ret;
}
-static struct bus_type mmc_bus_type = {
- .name = "mmc",
- .dev_attrs = mmc_dev_attrs,
- .match = mmc_bus_match,
- .hotplug = mmc_bus_hotplug,
- .suspend = mmc_bus_suspend,
- .resume = mmc_bus_resume,
-};
-
-
-static int mmc_drv_probe(struct device *dev)
+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);
return drv->probe(card);
}
-static int mmc_drv_remove(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);
return 0;
}
+static struct bus_type mmc_bus_type = {
+ .name = "mmc",
+ .dev_attrs = mmc_dev_attrs,
+ .match = mmc_bus_match,
+ .uevent = mmc_bus_uevent,
+ .probe = mmc_bus_probe,
+ .remove = mmc_bus_remove,
+ .suspend = mmc_bus_suspend,
+ .resume = mmc_bus_resume,
+};
/**
* mmc_register_driver - register a media driver
int mmc_register_driver(struct mmc_driver *drv)
{
drv->drv.bus = &mmc_bus_type;
- drv->drv.probe = mmc_drv_probe;
- drv->drv.remove = mmc_drv_remove;
return driver_register(&drv->drv);
}
*/
int mmc_register_card(struct mmc_card *card)
{
+ int ret;
+
snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
"%s:%04x", mmc_hostname(card->host), card->rca);
- return device_add(&card->dev);
+ ret = device_add(&card->dev);
+ if (ret == 0) {
+ if (mmc_card_sd(card)) {
+ ret = device_create_file(&card->dev, &mmc_dev_attr_scr);
+ if (ret)
+ device_del(&card->dev);
+ }
+ }
+ return ret;
}
/*
*/
void mmc_remove_card(struct mmc_card *card)
{
- if (mmc_card_present(card))
+ if (mmc_card_present(card)) {
+ if (mmc_card_sd(card))
+ device_remove_file(&card->dev, &mmc_dev_attr_scr);
+
device_del(&card->dev);
+ }
put_device(&card->dev);
}
.release = mmc_host_classdev_release,
};
+static DEFINE_IDR(mmc_host_idr);
+static DEFINE_SPINLOCK(mmc_host_lock);
+
/*
* Internal function. Allocate a new MMC host.
*/
*/
int mmc_add_host_sysfs(struct mmc_host *host)
{
- static unsigned int host_num;
+ int err;
+
+ if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
+ return -ENOMEM;
+
+ spin_lock(&mmc_host_lock);
+ err = idr_get_new(&mmc_host_idr, host, &host->index);
+ spin_unlock(&mmc_host_lock);
+ if (err)
+ return err;
snprintf(host->class_dev.class_id, BUS_ID_SIZE,
- "mmc%d", host_num++);
+ "mmc%d", host->index);
return class_device_add(&host->class_dev);
}
void mmc_remove_host_sysfs(struct mmc_host *host)
{
class_device_del(&host->class_dev);
+
+ spin_lock(&mmc_host_lock);
+ idr_remove(&mmc_host_idr, host->index);
+ spin_unlock(&mmc_host_lock);
}
/*