]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/mmc/core/sdio_bus.c
mmc: basic SDIO device model
[linux-2.6-omap-h63xx.git] / drivers / mmc / core / sdio_bus.c
1 /*
2  *  linux/drivers/mmc/core/sdio_bus.c
3  *
4  *  Copyright 2007 Pierre Ossman
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or (at
9  * your option) any later version.
10  *
11  * SDIO function driver model
12  */
13
14 #include <linux/device.h>
15 #include <linux/err.h>
16
17 #include <linux/mmc/card.h>
18 #include <linux/mmc/sdio_func.h>
19
20 #include "sdio_bus.h"
21
22 #define dev_to_sdio_func(d)     container_of(d, struct sdio_func, dev)
23
24 /*
25  * This currently matches any SDIO function to any driver in order
26  * to help initial development and testing.
27  */
28 static int sdio_bus_match(struct device *dev, struct device_driver *drv)
29 {
30         return 1;
31 }
32
33 static int
34 sdio_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
35                 int buf_size)
36 {
37         envp[0] = NULL;
38
39         return 0;
40 }
41
42 static int sdio_bus_probe(struct device *dev)
43 {
44         return -ENODEV;
45 }
46
47 static int sdio_bus_remove(struct device *dev)
48 {
49         return 0;
50 }
51
52 static struct bus_type sdio_bus_type = {
53         .name           = "sdio",
54         .match          = sdio_bus_match,
55         .uevent         = sdio_bus_uevent,
56         .probe          = sdio_bus_probe,
57         .remove         = sdio_bus_remove,
58 };
59
60 int sdio_register_bus(void)
61 {
62         return bus_register(&sdio_bus_type);
63 }
64
65 void sdio_unregister_bus(void)
66 {
67         bus_unregister(&sdio_bus_type);
68 }
69
70 static void sdio_release_func(struct device *dev)
71 {
72         struct sdio_func *func = dev_to_sdio_func(dev);
73
74         kfree(func);
75 }
76
77 /*
78  * Allocate and initialise a new SDIO function structure.
79  */
80 struct sdio_func *sdio_alloc_func(struct mmc_card *card)
81 {
82         struct sdio_func *func;
83
84         func = kmalloc(sizeof(struct sdio_func), GFP_KERNEL);
85         if (!func)
86                 return ERR_PTR(-ENOMEM);
87
88         memset(func, 0, sizeof(struct sdio_func));
89
90         func->card = card;
91
92         device_initialize(&func->dev);
93
94         func->dev.parent = &card->dev;
95         func->dev.bus = &sdio_bus_type;
96         func->dev.release = sdio_release_func;
97
98         return func;
99 }
100
101 /*
102  * Register a new SDIO function with the driver model.
103  */
104 int sdio_add_func(struct sdio_func *func)
105 {
106         int ret;
107
108         snprintf(func->dev.bus_id, sizeof(func->dev.bus_id),
109                  "%s:%d", mmc_card_id(func->card), func->num);
110
111         ret = device_add(&func->dev);
112         if (ret == 0)
113                 sdio_func_set_present(func);
114
115         return ret;
116 }
117
118 /*
119  * Unregister a SDIO function with the driver model, and
120  * (eventually) free it.
121  */
122 void sdio_remove_func(struct sdio_func *func)
123 {
124         if (sdio_func_present(func))
125                 device_del(&func->dev);
126
127         put_device(&func->dev);
128 }
129