aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/mmc_sysfs.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-08-19 04:41:24 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-08-19 04:41:24 -0400
commit00b137cfda5276b3d2c87d44236fe4c5ee68b405 (patch)
tree2ecf68ba041d4cb94be9bf6b5e640a94ee0974a2 /drivers/mmc/mmc_sysfs.c
parentd366b6436386875b1310ce8f70e3f9dea4647bac (diff)
[MMC] Add MMC class devices
Create a mmc_host class to allow enumeration of MMC host controllers even though they have no card(s) inserted. Patch based on work by Pierre Ossman. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc/mmc_sysfs.c')
-rw-r--r--drivers/mmc/mmc_sysfs.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index 3a6b325a9149..96c192057df3 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -20,6 +20,7 @@
20 20
21#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) 21#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) 22#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
23#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
23 24
24#define MMC_ATTR(name, fmt, args...) \ 25#define MMC_ATTR(name, fmt, args...) \
25static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ 26static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
@@ -224,13 +225,82 @@ void mmc_remove_card(struct mmc_card *card)
224} 225}
225 226
226 227
228static void mmc_host_classdev_release(struct class_device *dev)
229{
230 struct mmc_host *host = cls_dev_to_mmc_host(dev);
231 kfree(host);
232}
233
234static struct class mmc_host_class = {
235 .name = "mmc_host",
236 .release = mmc_host_classdev_release,
237};
238
239/*
240 * Internal function. Allocate a new MMC host.
241 */
242struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev)
243{
244 struct mmc_host *host;
245
246 host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
247 if (host) {
248 memset(host, 0, sizeof(struct mmc_host) + extra);
249
250 host->dev = dev;
251 host->class_dev.dev = host->dev;
252 host->class_dev.class = &mmc_host_class;
253 class_device_initialize(&host->class_dev);
254 }
255
256 return host;
257}
258
259/*
260 * Internal function. Register a new MMC host with the MMC class.
261 */
262int mmc_add_host_sysfs(struct mmc_host *host)
263{
264 static unsigned int host_num;
265
266 snprintf(host->host_name, sizeof(host->host_name),
267 "mmc%d", host_num++);
268
269 strlcpy(host->class_dev.class_id, host->host_name, BUS_ID_SIZE);
270 return class_device_add(&host->class_dev);
271}
272
273/*
274 * Internal function. Unregister a MMC host with the MMC class.
275 */
276void mmc_remove_host_sysfs(struct mmc_host *host)
277{
278 class_device_del(&host->class_dev);
279}
280
281/*
282 * Internal function. Free a MMC host.
283 */
284void mmc_free_host_sysfs(struct mmc_host *host)
285{
286 class_device_put(&host->class_dev);
287}
288
289
227static int __init mmc_init(void) 290static int __init mmc_init(void)
228{ 291{
229 return bus_register(&mmc_bus_type); 292 int ret = bus_register(&mmc_bus_type);
293 if (ret == 0) {
294 ret = class_register(&mmc_host_class);
295 if (ret)
296 bus_unregister(&mmc_bus_type);
297 }
298 return ret;
230} 299}
231 300
232static void __exit mmc_exit(void) 301static void __exit mmc_exit(void)
233{ 302{
303 class_unregister(&mmc_host_class);
234 bus_unregister(&mmc_bus_type); 304 bus_unregister(&mmc_bus_type);
235} 305}
236 306