X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmmc%2Fmmc_sysfs.c;h=a2a35fd946eecf8a2b9fc585b2687f39e2806e82;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=29a56e9cd5b3a5ad35e879845930143475130c4e;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c index 29a56e9cd..a2a35fd94 100644 --- a/drivers/mmc/mmc_sysfs.c +++ b/drivers/mmc/mmc_sysfs.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -20,9 +21,10 @@ #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, char *buf) \ +static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct mmc_card *card = dev_to_mmc_card(dev); \ return sprintf(buf, fmt, args); \ @@ -32,6 +34,7 @@ MMC_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], 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); @@ -55,6 +58,8 @@ static struct device_attribute mmc_dev_attrs[] = { __ATTR_NULL }; +static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr); + static void mmc_release_card(struct device *dev) { @@ -75,7 +80,7 @@ static int mmc_bus_match(struct device *dev, struct device_driver *drv) } 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); @@ -131,17 +136,7 @@ static int mmc_bus_resume(struct device *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); @@ -149,7 +144,7 @@ static int mmc_drv_probe(struct device *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); @@ -159,6 +154,16 @@ static int mmc_drv_remove(struct device *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 @@ -167,8 +172,6 @@ static int mmc_drv_remove(struct device *dev) 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); } @@ -205,10 +208,20 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host) */ int mmc_register_card(struct mmc_card *card) { - snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), - "%s:%04x", card->host->host_name, card->rca); + int ret; - return device_add(&card->dev); + snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), + "%s:%04x", mmc_hostname(card->host), card->rca); + + 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; } /* @@ -217,20 +230,108 @@ int mmc_register_card(struct mmc_card *card) */ 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); } +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, +}; + +static DEFINE_IDR(mmc_host_idr); +static DEFINE_SPINLOCK(mmc_host_lock); + +/* + * 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) +{ + 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->index); + + 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); + + spin_lock(&mmc_host_lock); + idr_remove(&mmc_host_idr, host->index); + spin_unlock(&mmc_host_lock); +} + +/* + * 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); }