aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/mmc.c29
-rw-r--r--drivers/mmc/mmc.h5
-rw-r--r--drivers/mmc/mmc_sysfs.c90
-rw-r--r--drivers/mmc/mmci.c4
-rw-r--r--drivers/mmc/wbsd.c2
5 files changed, 109 insertions, 21 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index eeb9f6668e69..3c5904834fe8 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -361,7 +361,7 @@ static void mmc_decode_cid(struct mmc_card *card)
361 361
362 default: 362 default:
363 printk("%s: card has unknown MMCA version %d\n", 363 printk("%s: card has unknown MMCA version %d\n",
364 card->host->host_name, card->csd.mmca_vsn); 364 mmc_hostname(card->host), card->csd.mmca_vsn);
365 mmc_card_set_bad(card); 365 mmc_card_set_bad(card);
366 break; 366 break;
367 } 367 }
@@ -383,7 +383,7 @@ static void mmc_decode_csd(struct mmc_card *card)
383 csd_struct = UNSTUFF_BITS(resp, 126, 2); 383 csd_struct = UNSTUFF_BITS(resp, 126, 2);
384 if (csd_struct != 1 && csd_struct != 2) { 384 if (csd_struct != 1 && csd_struct != 2) {
385 printk("%s: unrecognised CSD structure version %d\n", 385 printk("%s: unrecognised CSD structure version %d\n",
386 card->host->host_name, csd_struct); 386 mmc_hostname(card->host), csd_struct);
387 mmc_card_set_bad(card); 387 mmc_card_set_bad(card);
388 return; 388 return;
389 } 389 }
@@ -551,7 +551,7 @@ static void mmc_discover_cards(struct mmc_host *host)
551 } 551 }
552 if (err != MMC_ERR_NONE) { 552 if (err != MMC_ERR_NONE) {
553 printk(KERN_ERR "%s: error requesting CID: %d\n", 553 printk(KERN_ERR "%s: error requesting CID: %d\n",
554 host->host_name, err); 554 mmc_hostname(host), err);
555 break; 555 break;
556 } 556 }
557 557
@@ -796,17 +796,13 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
796{ 796{
797 struct mmc_host *host; 797 struct mmc_host *host;
798 798
799 host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); 799 host = mmc_alloc_host_sysfs(extra, dev);
800 if (host) { 800 if (host) {
801 memset(host, 0, sizeof(struct mmc_host) + extra);
802
803 spin_lock_init(&host->lock); 801 spin_lock_init(&host->lock);
804 init_waitqueue_head(&host->wq); 802 init_waitqueue_head(&host->wq);
805 INIT_LIST_HEAD(&host->cards); 803 INIT_LIST_HEAD(&host->cards);
806 INIT_WORK(&host->detect, mmc_rescan, host); 804 INIT_WORK(&host->detect, mmc_rescan, host);
807 805
808 host->dev = dev;
809
810 /* 806 /*
811 * By default, hosts do not support SGIO or large requests. 807 * By default, hosts do not support SGIO or large requests.
812 * They have to set these according to their abilities. 808 * They have to set these according to their abilities.
@@ -828,15 +824,15 @@ EXPORT_SYMBOL(mmc_alloc_host);
828 */ 824 */
829int mmc_add_host(struct mmc_host *host) 825int mmc_add_host(struct mmc_host *host)
830{ 826{
831 static unsigned int host_num; 827 int ret;
832 828
833 snprintf(host->host_name, sizeof(host->host_name), 829 ret = mmc_add_host_sysfs(host);
834 "mmc%d", host_num++); 830 if (ret == 0) {
835 831 mmc_power_off(host);
836 mmc_power_off(host); 832 mmc_detect_change(host);
837 mmc_detect_change(host); 833 }
838 834
839 return 0; 835 return ret;
840} 836}
841 837
842EXPORT_SYMBOL(mmc_add_host); 838EXPORT_SYMBOL(mmc_add_host);
@@ -859,6 +855,7 @@ void mmc_remove_host(struct mmc_host *host)
859 } 855 }
860 856
861 mmc_power_off(host); 857 mmc_power_off(host);
858 mmc_remove_host_sysfs(host);
862} 859}
863 860
864EXPORT_SYMBOL(mmc_remove_host); 861EXPORT_SYMBOL(mmc_remove_host);
@@ -872,7 +869,7 @@ EXPORT_SYMBOL(mmc_remove_host);
872void mmc_free_host(struct mmc_host *host) 869void mmc_free_host(struct mmc_host *host)
873{ 870{
874 flush_scheduled_work(); 871 flush_scheduled_work();
875 kfree(host); 872 mmc_free_host_sysfs(host);
876} 873}
877 874
878EXPORT_SYMBOL(mmc_free_host); 875EXPORT_SYMBOL(mmc_free_host);
diff --git a/drivers/mmc/mmc.h b/drivers/mmc/mmc.h
index b498dffe0b11..97bae00292fa 100644
--- a/drivers/mmc/mmc.h
+++ b/drivers/mmc/mmc.h
@@ -13,4 +13,9 @@
13void mmc_init_card(struct mmc_card *card, struct mmc_host *host); 13void mmc_init_card(struct mmc_card *card, struct mmc_host *host);
14int mmc_register_card(struct mmc_card *card); 14int mmc_register_card(struct mmc_card *card);
15void mmc_remove_card(struct mmc_card *card); 15void mmc_remove_card(struct mmc_card *card);
16
17struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev);
18int mmc_add_host_sysfs(struct mmc_host *host);
19void mmc_remove_host_sysfs(struct mmc_host *host);
20void mmc_free_host_sysfs(struct mmc_host *host);
16#endif 21#endif
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index 5556cd3b5559..ad8949810fc5 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -12,6 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/idr.h>
15 16
16#include <linux/mmc/card.h> 17#include <linux/mmc/card.h>
17#include <linux/mmc/host.h> 18#include <linux/mmc/host.h>
@@ -20,6 +21,7 @@
20 21
21#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) 22#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev)
22#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) 23#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
24#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
23 25
24#define MMC_ATTR(name, fmt, args...) \ 26#define MMC_ATTR(name, fmt, args...) \
25static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ 27static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
@@ -206,7 +208,7 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host)
206int mmc_register_card(struct mmc_card *card) 208int mmc_register_card(struct mmc_card *card)
207{ 209{
208 snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), 210 snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
209 "%s:%04x", card->host->host_name, card->rca); 211 "%s:%04x", mmc_hostname(card->host), card->rca);
210 212
211 return device_add(&card->dev); 213 return device_add(&card->dev);
212} 214}
@@ -224,13 +226,97 @@ void mmc_remove_card(struct mmc_card *card)
224} 226}
225 227
226 228
229static void mmc_host_classdev_release(struct class_device *dev)
230{
231 struct mmc_host *host = cls_dev_to_mmc_host(dev);
232 kfree(host);
233}
234
235static struct class mmc_host_class = {
236 .name = "mmc_host",
237 .release = mmc_host_classdev_release,
238};
239
240static DEFINE_IDR(mmc_host_idr);
241static DEFINE_SPINLOCK(mmc_host_lock);
242
243/*
244 * Internal function. Allocate a new MMC host.
245 */
246struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev)
247{
248 struct mmc_host *host;
249
250 host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
251 if (host) {
252 memset(host, 0, sizeof(struct mmc_host) + extra);
253
254 host->dev = dev;
255 host->class_dev.dev = host->dev;
256 host->class_dev.class = &mmc_host_class;
257 class_device_initialize(&host->class_dev);
258 }
259
260 return host;
261}
262
263/*
264 * Internal function. Register a new MMC host with the MMC class.
265 */
266int mmc_add_host_sysfs(struct mmc_host *host)
267{
268 int err;
269
270 if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
271 return -ENOMEM;
272
273 spin_lock(&mmc_host_lock);
274 err = idr_get_new(&mmc_host_idr, host, &host->index);
275 spin_unlock(&mmc_host_lock);
276 if (err)
277 return err;
278
279 snprintf(host->class_dev.class_id, BUS_ID_SIZE,
280 "mmc%d", host->index);
281
282 return class_device_add(&host->class_dev);
283}
284
285/*
286 * Internal function. Unregister a MMC host with the MMC class.
287 */
288void mmc_remove_host_sysfs(struct mmc_host *host)
289{
290 class_device_del(&host->class_dev);
291
292 spin_lock(&mmc_host_lock);
293 idr_remove(&mmc_host_idr, host->index);
294 spin_unlock(&mmc_host_lock);
295}
296
297/*
298 * Internal function. Free a MMC host.
299 */
300void mmc_free_host_sysfs(struct mmc_host *host)
301{
302 class_device_put(&host->class_dev);
303}
304
305
227static int __init mmc_init(void) 306static int __init mmc_init(void)
228{ 307{
229 return bus_register(&mmc_bus_type); 308 int ret = bus_register(&mmc_bus_type);
309 if (ret == 0) {
310 ret = class_register(&mmc_host_class);
311 if (ret)
312 bus_unregister(&mmc_bus_type);
313 }
314 return ret;
230} 315}
231 316
232static void __exit mmc_exit(void) 317static void __exit mmc_exit(void)
233{ 318{
319 class_unregister(&mmc_host_class);
234 bus_unregister(&mmc_bus_type); 320 bus_unregister(&mmc_bus_type);
235} 321}
236 322
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 7a42966d755b..716c4ef4faf6 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -34,7 +34,7 @@
34 34
35#ifdef CONFIG_MMC_DEBUG 35#ifdef CONFIG_MMC_DEBUG
36#define DBG(host,fmt,args...) \ 36#define DBG(host,fmt,args...) \
37 pr_debug("%s: %s: " fmt, host->mmc->host_name, __func__ , args) 37 pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
38#else 38#else
39#define DBG(host,fmt,args...) do { } while (0) 39#define DBG(host,fmt,args...) do { } while (0)
40#endif 40#endif
@@ -541,7 +541,7 @@ static int mmci_probe(struct amba_device *dev, void *id)
541 mmc_add_host(mmc); 541 mmc_add_host(mmc);
542 542
543 printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n", 543 printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n",
544 mmc->host_name, amba_rev(dev), amba_config(dev), 544 mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
545 dev->res.start, dev->irq[0], dev->irq[1]); 545 dev->res.start, dev->irq[0], dev->irq[1]);
546 546
547 init_timer(&host->timer); 547 init_timer(&host->timer);
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 974f2f36bdbe..402c2d661fb2 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1796,7 +1796,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
1796 1796
1797 mmc_add_host(mmc); 1797 mmc_add_host(mmc);
1798 1798
1799 printk(KERN_INFO "%s: W83L51xD", mmc->host_name); 1799 printk(KERN_INFO "%s: W83L51xD", mmc_hostname(mmc));
1800 if (host->chip_id != 0) 1800 if (host->chip_id != 0)
1801 printk(" id %x", (int)host->chip_id); 1801 printk(" id %x", (int)host->chip_id);
1802 printk(" at 0x%x irq %d", (int)host->base, (int)host->irq); 1802 printk(" at 0x%x irq %d", (int)host->base, (int)host->irq);