1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/device.h>
15#include <linux/err.h>
16#include <linux/export.h>
17#include <linux/slab.h>
18#include <linux/pm_runtime.h>
19#include <linux/pm_domain.h>
20#include <linux/acpi.h>
21
22#include <linux/mmc/card.h>
23#include <linux/mmc/host.h>
24#include <linux/mmc/sdio_func.h>
25
26#include "sdio_cis.h"
27#include "sdio_bus.h"
28
29#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv)
30
31
32#define sdio_config_attr(field, format_string) \
33static ssize_t \
34field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
35{ \
36 struct sdio_func *func; \
37 \
38 func = dev_to_sdio_func (dev); \
39 return sprintf (buf, format_string, func->field); \
40} \
41static DEVICE_ATTR_RO(field)
42
43sdio_config_attr(class, "0x%02x\n");
44sdio_config_attr(vendor, "0x%04x\n");
45sdio_config_attr(device, "0x%04x\n");
46
47static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
48{
49 struct sdio_func *func = dev_to_sdio_func (dev);
50
51 return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n",
52 func->class, func->vendor, func->device);
53}
54static DEVICE_ATTR_RO(modalias);
55
56static struct attribute *sdio_dev_attrs[] = {
57 &dev_attr_class.attr,
58 &dev_attr_vendor.attr,
59 &dev_attr_device.attr,
60 &dev_attr_modalias.attr,
61 NULL,
62};
63ATTRIBUTE_GROUPS(sdio_dev);
64
65static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,
66 const struct sdio_device_id *id)
67{
68 if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class)
69 return NULL;
70 if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor)
71 return NULL;
72 if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device)
73 return NULL;
74 return id;
75}
76
77static const struct sdio_device_id *sdio_match_device(struct sdio_func *func,
78 struct sdio_driver *sdrv)
79{
80 const struct sdio_device_id *ids;
81
82 ids = sdrv->id_table;
83
84 if (ids) {
85 while (ids->class || ids->vendor || ids->device) {
86 if (sdio_match_one(func, ids))
87 return ids;
88 ids++;
89 }
90 }
91
92 return NULL;
93}
94
95static int sdio_bus_match(struct device *dev, struct device_driver *drv)
96{
97 struct sdio_func *func = dev_to_sdio_func(dev);
98 struct sdio_driver *sdrv = to_sdio_driver(drv);
99
100 if (sdio_match_device(func, sdrv))
101 return 1;
102
103 return 0;
104}
105
106static int
107sdio_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
108{
109 struct sdio_func *func = dev_to_sdio_func(dev);
110
111 if (add_uevent_var(env,
112 "SDIO_CLASS=%02X", func->class))
113 return -ENOMEM;
114
115 if (add_uevent_var(env,
116 "SDIO_ID=%04X:%04X", func->vendor, func->device))
117 return -ENOMEM;
118
119 if (add_uevent_var(env,
120 "MODALIAS=sdio:c%02Xv%04Xd%04X",
121 func->class, func->vendor, func->device))
122 return -ENOMEM;
123
124 return 0;
125}
126
127static int sdio_bus_probe(struct device *dev)
128{
129 struct sdio_driver *drv = to_sdio_driver(dev->driver);
130 struct sdio_func *func = dev_to_sdio_func(dev);
131 const struct sdio_device_id *id;
132 int ret;
133
134 id = sdio_match_device(func, drv);
135 if (!id)
136 return -ENODEV;
137
138
139
140
141
142
143
144 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
145 ret = pm_runtime_get_sync(dev);
146 if (ret < 0)
147 goto disable_runtimepm;
148 }
149
150
151
152 sdio_claim_host(func);
153 ret = sdio_set_block_size(func, 0);
154 sdio_release_host(func);
155 if (ret)
156 goto disable_runtimepm;
157
158 ret = drv->probe(func, id);
159 if (ret)
160 goto disable_runtimepm;
161
162 return 0;
163
164disable_runtimepm:
165 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
166 pm_runtime_put_noidle(dev);
167 return ret;
168}
169
170static int sdio_bus_remove(struct device *dev)
171{
172 struct sdio_driver *drv = to_sdio_driver(dev->driver);
173 struct sdio_func *func = dev_to_sdio_func(dev);
174 int ret = 0;
175
176
177 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
178 pm_runtime_get_sync(dev);
179
180 drv->remove(func);
181
182 if (func->irq_handler) {
183 pr_warn("WARNING: driver %s did not remove its interrupt handler!\n",
184 drv->name);
185 sdio_claim_host(func);
186 sdio_release_irq(func);
187 sdio_release_host(func);
188 }
189
190
191 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
192 pm_runtime_put_noidle(dev);
193
194
195 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
196 pm_runtime_put_sync(dev);
197
198 return ret;
199}
200
201static const struct dev_pm_ops sdio_bus_pm_ops = {
202 SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume)
203 SET_RUNTIME_PM_OPS(
204 pm_generic_runtime_suspend,
205 pm_generic_runtime_resume,
206 NULL
207 )
208};
209
210static struct bus_type sdio_bus_type = {
211 .name = "sdio",
212 .dev_groups = sdio_dev_groups,
213 .match = sdio_bus_match,
214 .uevent = sdio_bus_uevent,
215 .probe = sdio_bus_probe,
216 .remove = sdio_bus_remove,
217 .pm = &sdio_bus_pm_ops,
218};
219
220int sdio_register_bus(void)
221{
222 return bus_register(&sdio_bus_type);
223}
224
225void sdio_unregister_bus(void)
226{
227 bus_unregister(&sdio_bus_type);
228}
229
230
231
232
233
234int sdio_register_driver(struct sdio_driver *drv)
235{
236 drv->drv.name = drv->name;
237 drv->drv.bus = &sdio_bus_type;
238 return driver_register(&drv->drv);
239}
240EXPORT_SYMBOL_GPL(sdio_register_driver);
241
242
243
244
245
246void sdio_unregister_driver(struct sdio_driver *drv)
247{
248 drv->drv.bus = &sdio_bus_type;
249 driver_unregister(&drv->drv);
250}
251EXPORT_SYMBOL_GPL(sdio_unregister_driver);
252
253static void sdio_release_func(struct device *dev)
254{
255 struct sdio_func *func = dev_to_sdio_func(dev);
256
257 sdio_free_func_cis(func);
258
259 kfree(func->info);
260
261 kfree(func);
262}
263
264
265
266
267struct sdio_func *sdio_alloc_func(struct mmc_card *card)
268{
269 struct sdio_func *func;
270
271 func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL);
272 if (!func)
273 return ERR_PTR(-ENOMEM);
274
275 func->card = card;
276
277 device_initialize(&func->dev);
278
279 func->dev.parent = &card->dev;
280 func->dev.bus = &sdio_bus_type;
281 func->dev.release = sdio_release_func;
282
283 return func;
284}
285
286#ifdef CONFIG_ACPI
287static void sdio_acpi_set_handle(struct sdio_func *func)
288{
289 struct mmc_host *host = func->card->host;
290 u64 addr = ((u64)host->slotno << 16) | func->num;
291
292 acpi_preset_companion(&func->dev, ACPI_COMPANION(host->parent), addr);
293}
294#else
295static inline void sdio_acpi_set_handle(struct sdio_func *func) {}
296#endif
297
298
299
300
301int sdio_add_func(struct sdio_func *func)
302{
303 int ret;
304
305 dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);
306
307 sdio_acpi_set_handle(func);
308 ret = device_add(&func->dev);
309 if (ret == 0) {
310 sdio_func_set_present(func);
311 dev_pm_domain_attach(&func->dev, false);
312 }
313
314 return ret;
315}
316
317
318
319
320
321
322
323void sdio_remove_func(struct sdio_func *func)
324{
325 if (!sdio_func_present(func))
326 return;
327
328 dev_pm_domain_detach(&func->dev, false);
329 device_del(&func->dev);
330 put_device(&func->dev);
331}
332
333