diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/host.c | 39 |
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 | */ |
58 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | 58 | struct 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 | |||
102 | free: | ||
103 | kfree(host); | ||
104 | return NULL; | ||
88 | } | 105 | } |
89 | 106 | ||
90 | EXPORT_SYMBOL(mmc_alloc_host); | 107 | EXPORT_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 | ||
153 | EXPORT_SYMBOL(mmc_remove_host); | 154 | EXPORT_SYMBOL(mmc_remove_host); |
@@ -160,6 +161,10 @@ EXPORT_SYMBOL(mmc_remove_host); | |||
160 | */ | 161 | */ |
161 | void mmc_free_host(struct mmc_host *host) | 162 | void 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 | ||