aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/host.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index c65d203a846d..1d795c5379b5 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -2,7 +2,7 @@
2 * linux/drivers/mmc/core/host.c 2 * linux/drivers/mmc/core/host.c
3 * 3 *
4 * Copyright (C) 2003 Russell King, All Rights Reserved. 4 * Copyright (C) 2003 Russell King, All Rights Reserved.
5 * Copyright (C) 2007 Pierre Ossman 5 * Copyright (C) 2007-2008 Pierre Ossman
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -57,12 +57,25 @@ static DEFINE_SPINLOCK(mmc_host_lock);
57 */ 57 */
58struct mmc_host *mmc_alloc_host(int extra, struct device *dev) 58struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
59{ 59{
60 int err;
60 struct mmc_host *host; 61 struct mmc_host *host;
61 62
63 if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
64 return NULL;
65
62 host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); 66 host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
63 if (!host) 67 if (!host)
64 return NULL; 68 return NULL;
65 69
70 spin_lock(&mmc_host_lock);
71 err = idr_get_new(&mmc_host_idr, host, &host->index);
72 spin_unlock(&mmc_host_lock);
73 if (err)
74 goto free;
75
76 snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
77 "mmc%d", host->index);
78
66 host->parent = dev; 79 host->parent = dev;
67 host->class_dev.parent = dev; 80 host->class_dev.parent = dev;
68 host->class_dev.class = &mmc_host_class; 81 host->class_dev.class = &mmc_host_class;
@@ -85,6 +98,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
85 host->max_blk_count = PAGE_CACHE_SIZE / 512; 98 host->max_blk_count = PAGE_CACHE_SIZE / 512;
86 99
87 return host; 100 return host;
101
102free:
103 kfree(host);
104 return NULL;
88} 105}
89 106
90EXPORT_SYMBOL(mmc_alloc_host); 107EXPORT_SYMBOL(mmc_alloc_host);
@@ -104,18 +121,6 @@ int mmc_add_host(struct mmc_host *host)
104 WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && 121 WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
105 !host->ops->enable_sdio_irq); 122 !host->ops->enable_sdio_irq);
106 123
107 if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
108 return -ENOMEM;
109
110 spin_lock(&mmc_host_lock);
111 err = idr_get_new(&mmc_host_idr, host, &host->index);
112 spin_unlock(&mmc_host_lock);
113 if (err)
114 return err;
115
116 snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
117 "mmc%d", host->index);
118
119 led_trigger_register_simple(host->class_dev.bus_id, &host->led); 124 led_trigger_register_simple(host->class_dev.bus_id, &host->led);
120 125
121 err = device_add(&host->class_dev); 126 err = device_add(&host->class_dev);
@@ -144,10 +149,6 @@ void mmc_remove_host(struct mmc_host *host)
144 device_del(&host->class_dev); 149 device_del(&host->class_dev);
145 150
146 led_trigger_unregister_simple(host->led); 151 led_trigger_unregister_simple(host->led);
147
148 spin_lock(&mmc_host_lock);
149 idr_remove(&mmc_host_idr, host->index);
150 spin_unlock(&mmc_host_lock);
151} 152}
152 153
153EXPORT_SYMBOL(mmc_remove_host); 154EXPORT_SYMBOL(mmc_remove_host);
@@ -160,6 +161,10 @@ EXPORT_SYMBOL(mmc_remove_host);
160 */ 161 */
161void mmc_free_host(struct mmc_host *host) 162void mmc_free_host(struct mmc_host *host)
162{ 163{
164 spin_lock(&mmc_host_lock);
165 idr_remove(&mmc_host_idr, host->index);
166 spin_unlock(&mmc_host_lock);
167
163 put_device(&host->class_dev); 168 put_device(&host->class_dev);
164} 169}
165 170