Branch data Line data Source code
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 : : #include <linux/export.h>
17 : : #include <linux/slab.h>
18 : : #include <linux/pm_runtime.h>
19 : : #include <linux/acpi.h>
20 : :
21 : : #include <linux/mmc/card.h>
22 : : #include <linux/mmc/host.h>
23 : : #include <linux/mmc/sdio_func.h>
24 : :
25 : : #include "sdio_cis.h"
26 : : #include "sdio_bus.h"
27 : :
28 : : #ifdef CONFIG_MMC_EMBEDDED_SDIO
29 : : #include <linux/mmc/host.h>
30 : : #endif
31 : :
32 : : /* show configuration fields */
33 : : #define sdio_config_attr(field, format_string) \
34 : : static ssize_t \
35 : : field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
36 : : { \
37 : : struct sdio_func *func; \
38 : : \
39 : : func = dev_to_sdio_func (dev); \
40 : : return sprintf (buf, format_string, func->field); \
41 : : } \
42 : : static DEVICE_ATTR_RO(field)
43 : :
44 : 0 : sdio_config_attr(class, "0x%02x\n");
45 : 0 : sdio_config_attr(vendor, "0x%04x\n");
46 : 0 : sdio_config_attr(device, "0x%04x\n");
47 : :
48 : 0 : static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
49 : : {
50 : : struct sdio_func *func = dev_to_sdio_func (dev);
51 : :
52 : 0 : return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n",
53 : 0 : func->class, func->vendor, func->device);
54 : : }
55 : : static DEVICE_ATTR_RO(modalias);
56 : :
57 : : static struct attribute *sdio_dev_attrs[] = {
58 : : &dev_attr_class.attr,
59 : : &dev_attr_vendor.attr,
60 : : &dev_attr_device.attr,
61 : : &dev_attr_modalias.attr,
62 : : NULL,
63 : : };
64 : : ATTRIBUTE_GROUPS(sdio_dev);
65 : :
66 : : static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,
67 : : const struct sdio_device_id *id)
68 : : {
69 [ # # ][ # # ]: 0 : if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class)
70 : : return NULL;
71 [ # # ][ # # ]: 0 : if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor)
72 : : return NULL;
73 [ # # ][ # # ]: 0 : if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device)
74 : : return NULL;
75 : : return id;
76 : : }
77 : :
78 : 0 : static const struct sdio_device_id *sdio_match_device(struct sdio_func *func,
79 : : struct sdio_driver *sdrv)
80 : : {
81 : : const struct sdio_device_id *ids;
82 : :
83 : 0 : ids = sdrv->id_table;
84 : :
85 [ # # ]: 0 : if (ids) {
86 [ # # ][ # # ]: 0 : while (ids->class || ids->vendor || ids->device) {
87 [ # # ]: 0 : if (sdio_match_one(func, ids))
88 : : return ids;
89 : 0 : ids++;
90 : : }
91 : : }
92 : :
93 : : return NULL;
94 : : }
95 : :
96 : 0 : static int sdio_bus_match(struct device *dev, struct device_driver *drv)
97 : : {
98 : 0 : struct sdio_func *func = dev_to_sdio_func(dev);
99 : 0 : struct sdio_driver *sdrv = to_sdio_driver(drv);
100 : :
101 [ # # ]: 0 : if (sdio_match_device(func, sdrv))
102 : : return 1;
103 : :
104 : 0 : return 0;
105 : : }
106 : :
107 : : static int
108 : 0 : sdio_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
109 : : {
110 : : struct sdio_func *func = dev_to_sdio_func(dev);
111 : :
112 [ # # ]: 0 : if (add_uevent_var(env,
113 : 0 : "SDIO_CLASS=%02X", func->class))
114 : : return -ENOMEM;
115 : :
116 [ # # ]: 0 : if (add_uevent_var(env,
117 : 0 : "SDIO_ID=%04X:%04X", func->vendor, func->device))
118 : : return -ENOMEM;
119 : :
120 [ # # ]: 0 : if (add_uevent_var(env,
121 : : "MODALIAS=sdio:c%02Xv%04Xd%04X",
122 : 0 : func->class, func->vendor, func->device))
123 : : return -ENOMEM;
124 : :
125 : 0 : return 0;
126 : : }
127 : :
128 : 0 : static int sdio_bus_probe(struct device *dev)
129 : : {
130 : 0 : struct sdio_driver *drv = to_sdio_driver(dev->driver);
131 : 0 : struct sdio_func *func = dev_to_sdio_func(dev);
132 : : const struct sdio_device_id *id;
133 : : int ret;
134 : :
135 : 0 : id = sdio_match_device(func, drv);
136 [ # # ]: 0 : if (!id)
137 : : return -ENODEV;
138 : :
139 : : /* Unbound SDIO functions are always suspended.
140 : : * During probe, the function is set active and the usage count
141 : : * is incremented. If the driver supports runtime PM,
142 : : * it should call pm_runtime_put_noidle() in its probe routine and
143 : : * pm_runtime_get_noresume() in its remove routine.
144 : : */
145 : : if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
146 : : ret = pm_runtime_get_sync(dev);
147 : : if (ret < 0)
148 : : goto disable_runtimepm;
149 : : }
150 : :
151 : : /* Set the default block size so the driver is sure it's something
152 : : * sensible. */
153 : 0 : sdio_claim_host(func);
154 : 0 : ret = sdio_set_block_size(func, 0);
155 : 0 : sdio_release_host(func);
156 [ # # ]: 0 : if (ret)
157 : : goto disable_runtimepm;
158 : :
159 : 0 : ret = drv->probe(func, id);
160 [ # # ]: 0 : if (ret)
161 : : goto disable_runtimepm;
162 : :
163 : : return 0;
164 : :
165 : : disable_runtimepm:
166 : : if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
167 : : pm_runtime_put_noidle(dev);
168 : 0 : return ret;
169 : : }
170 : :
171 : 0 : static int sdio_bus_remove(struct device *dev)
172 : : {
173 : 0 : struct sdio_driver *drv = to_sdio_driver(dev->driver);
174 : 0 : struct sdio_func *func = dev_to_sdio_func(dev);
175 : : int ret = 0;
176 : :
177 : : /* Make sure card is powered before invoking ->remove() */
178 : : if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
179 : : pm_runtime_get_sync(dev);
180 : :
181 : 0 : drv->remove(func);
182 : :
183 [ # # ]: 0 : if (func->irq_handler) {
184 : 0 : pr_warning("WARNING: driver %s did not remove "
185 : : "its interrupt handler!\n", drv->name);
186 : 0 : sdio_claim_host(func);
187 : 0 : sdio_release_irq(func);
188 : 0 : sdio_release_host(func);
189 : : }
190 : :
191 : : /* First, undo the increment made directly above */
192 : : if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
193 : : pm_runtime_put_noidle(dev);
194 : :
195 : : /* Then undo the runtime PM settings in sdio_bus_probe() */
196 : : if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
197 : : pm_runtime_put_sync(dev);
198 : :
199 : 0 : return ret;
200 : : }
201 : :
202 : : #ifdef CONFIG_PM
203 : :
204 : : #ifdef CONFIG_PM_SLEEP
205 : 0 : static int pm_no_operation(struct device *dev)
206 : : {
207 : : /*
208 : : * Prevent the PM core from calling SDIO device drivers' suspend
209 : : * callback routines, which it is not supposed to do, by using this
210 : : * empty function as the bus type suspend callaback for SDIO.
211 : : */
212 : 0 : return 0;
213 : : }
214 : : #endif
215 : :
216 : : static const struct dev_pm_ops sdio_bus_pm_ops = {
217 : : SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
218 : : SET_RUNTIME_PM_OPS(
219 : : pm_generic_runtime_suspend,
220 : : pm_generic_runtime_resume,
221 : : NULL
222 : : )
223 : : };
224 : :
225 : : #define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops)
226 : :
227 : : #else /* !CONFIG_PM */
228 : :
229 : : #define SDIO_PM_OPS_PTR NULL
230 : :
231 : : #endif /* !CONFIG_PM */
232 : :
233 : : static struct bus_type sdio_bus_type = {
234 : : .name = "sdio",
235 : : .dev_groups = sdio_dev_groups,
236 : : .match = sdio_bus_match,
237 : : .uevent = sdio_bus_uevent,
238 : : .probe = sdio_bus_probe,
239 : : .remove = sdio_bus_remove,
240 : : .pm = SDIO_PM_OPS_PTR,
241 : : };
242 : :
243 : 0 : int sdio_register_bus(void)
244 : : {
245 : 0 : return bus_register(&sdio_bus_type);
246 : : }
247 : :
248 : 0 : void sdio_unregister_bus(void)
249 : : {
250 : 0 : bus_unregister(&sdio_bus_type);
251 : 0 : }
252 : :
253 : : /**
254 : : * sdio_register_driver - register a function driver
255 : : * @drv: SDIO function driver
256 : : */
257 : 0 : int sdio_register_driver(struct sdio_driver *drv)
258 : : {
259 : 0 : drv->drv.name = drv->name;
260 : 0 : drv->drv.bus = &sdio_bus_type;
261 : 0 : return driver_register(&drv->drv);
262 : : }
263 : : EXPORT_SYMBOL_GPL(sdio_register_driver);
264 : :
265 : : /**
266 : : * sdio_unregister_driver - unregister a function driver
267 : : * @drv: SDIO function driver
268 : : */
269 : 0 : void sdio_unregister_driver(struct sdio_driver *drv)
270 : : {
271 : 0 : drv->drv.bus = &sdio_bus_type;
272 : 0 : driver_unregister(&drv->drv);
273 : 0 : }
274 : : EXPORT_SYMBOL_GPL(sdio_unregister_driver);
275 : :
276 : 0 : static void sdio_release_func(struct device *dev)
277 : : {
278 : 0 : struct sdio_func *func = dev_to_sdio_func(dev);
279 : :
280 : : #ifdef CONFIG_MMC_EMBEDDED_SDIO
281 : : /*
282 : : * If this device is embedded then we never allocated
283 : : * cis tables for this func
284 : : */
285 : : if (!func->card->host->embedded_sdio_data.funcs)
286 : : #endif
287 : 0 : sdio_free_func_cis(func);
288 : :
289 : 0 : kfree(func->info);
290 : :
291 : 0 : kfree(func);
292 : 0 : }
293 : :
294 : : /*
295 : : * Allocate and initialise a new SDIO function structure.
296 : : */
297 : 0 : struct sdio_func *sdio_alloc_func(struct mmc_card *card)
298 : : {
299 : : struct sdio_func *func;
300 : :
301 : : func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL);
302 [ # # ]: 0 : if (!func)
303 : : return ERR_PTR(-ENOMEM);
304 : :
305 : 0 : func->card = card;
306 : :
307 : 0 : device_initialize(&func->dev);
308 : :
309 : 0 : func->dev.parent = &card->dev;
310 : 0 : func->dev.bus = &sdio_bus_type;
311 : 0 : func->dev.release = sdio_release_func;
312 : :
313 : 0 : return func;
314 : : }
315 : :
316 : : #ifdef CONFIG_ACPI
317 : : static void sdio_acpi_set_handle(struct sdio_func *func)
318 : : {
319 : : struct mmc_host *host = func->card->host;
320 : : u64 addr = (host->slotno << 16) | func->num;
321 : :
322 : : acpi_preset_companion(&func->dev, ACPI_HANDLE(host->parent), addr);
323 : : }
324 : : #else
325 : : static inline void sdio_acpi_set_handle(struct sdio_func *func) {}
326 : : #endif
327 : :
328 : : /*
329 : : * Register a new SDIO function with the driver model.
330 : : */
331 : 0 : int sdio_add_func(struct sdio_func *func)
332 : : {
333 : : int ret;
334 : :
335 : 0 : dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);
336 : :
337 : : sdio_acpi_set_handle(func);
338 : 0 : ret = device_add(&func->dev);
339 [ # # ]: 0 : if (ret == 0) {
340 : 0 : sdio_func_set_present(func);
341 : : acpi_dev_pm_attach(&func->dev, false);
342 : : }
343 : :
344 : 0 : return ret;
345 : : }
346 : :
347 : : /*
348 : : * Unregister a SDIO function with the driver model, and
349 : : * (eventually) free it.
350 : : * This function can be called through error paths where sdio_add_func() was
351 : : * never executed (because a failure occurred at an earlier point).
352 : : */
353 : 0 : void sdio_remove_func(struct sdio_func *func)
354 : : {
355 [ # # ]: 0 : if (!sdio_func_present(func))
356 : 0 : return;
357 : :
358 : : acpi_dev_pm_detach(&func->dev, false);
359 : 0 : device_del(&func->dev);
360 : 0 : put_device(&func->dev);
361 : : }
362 : :
|