Commit | Line | Data |
---|---|---|
5c4e6f13 PO |
1 | /* |
2 | * linux/drivers/mmc/sdio.c | |
3 | * | |
4 | * Copyright 2006-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 | ||
12 | #include <linux/err.h> | |
13 | ||
14 | #include <linux/mmc/host.h> | |
15 | #include <linux/mmc/card.h> | |
35c66c19 | 16 | #include <linux/mmc/sdio.h> |
e29a7d73 | 17 | #include <linux/mmc/sdio_func.h> |
5c4e6f13 PO |
18 | |
19 | #include "core.h" | |
20 | #include "bus.h" | |
71578a1e | 21 | #include "sd.h" |
e29a7d73 | 22 | #include "sdio_bus.h" |
5c4e6f13 PO |
23 | #include "mmc_ops.h" |
24 | #include "sd_ops.h" | |
25 | #include "sdio_ops.h" | |
b7261261 | 26 | #include "sdio_cis.h" |
5c4e6f13 | 27 | |
0597007f PO |
28 | static int sdio_read_fbr(struct sdio_func *func) |
29 | { | |
30 | int ret; | |
31 | unsigned char data; | |
32 | ||
33 | ret = mmc_io_rw_direct(func->card, 0, 0, | |
7616ee95 | 34 | SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data); |
0597007f PO |
35 | if (ret) |
36 | goto out; | |
37 | ||
38 | data &= 0x0f; | |
39 | ||
40 | if (data == 0x0f) { | |
41 | ret = mmc_io_rw_direct(func->card, 0, 0, | |
7616ee95 | 42 | SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data); |
0597007f PO |
43 | if (ret) |
44 | goto out; | |
45 | } | |
46 | ||
47 | func->class = data; | |
48 | ||
49 | out: | |
50 | return ret; | |
51 | } | |
52 | ||
e29a7d73 PO |
53 | static int sdio_init_func(struct mmc_card *card, unsigned int fn) |
54 | { | |
0597007f | 55 | int ret; |
e29a7d73 PO |
56 | struct sdio_func *func; |
57 | ||
58 | BUG_ON(fn > SDIO_MAX_FUNCS); | |
59 | ||
60 | func = sdio_alloc_func(card); | |
61 | if (IS_ERR(func)) | |
62 | return PTR_ERR(func); | |
63 | ||
64 | func->num = fn; | |
65 | ||
0597007f PO |
66 | ret = sdio_read_fbr(func); |
67 | if (ret) | |
68 | goto fail; | |
69 | ||
1a632f8c | 70 | ret = sdio_read_func_cis(func); |
b7261261 NP |
71 | if (ret) |
72 | goto fail; | |
73 | ||
e29a7d73 PO |
74 | card->sdio_func[fn - 1] = func; |
75 | ||
76 | return 0; | |
0597007f PO |
77 | |
78 | fail: | |
79 | /* | |
80 | * It is okay to remove the function here even though we hold | |
81 | * the host lock as we haven't registered the device yet. | |
82 | */ | |
83 | sdio_remove_func(func); | |
84 | return ret; | |
e29a7d73 PO |
85 | } |
86 | ||
35c66c19 PO |
87 | static int sdio_read_cccr(struct mmc_card *card) |
88 | { | |
89 | int ret; | |
90 | int cccr_vsn; | |
91 | unsigned char data; | |
92 | ||
93 | memset(&card->cccr, 0, sizeof(struct sdio_cccr)); | |
94 | ||
95 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data); | |
96 | if (ret) | |
97 | goto out; | |
98 | ||
99 | cccr_vsn = data & 0x0f; | |
100 | ||
101 | if (cccr_vsn > SDIO_CCCR_REV_1_20) { | |
102 | printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n", | |
103 | mmc_hostname(card->host), cccr_vsn); | |
104 | return -EINVAL; | |
105 | } | |
106 | ||
107 | card->cccr.sdio_vsn = (data & 0xf0) >> 4; | |
108 | ||
109 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data); | |
110 | if (ret) | |
111 | goto out; | |
112 | ||
113 | if (data & SDIO_CCCR_CAP_SMB) | |
114 | card->cccr.multi_block = 1; | |
115 | if (data & SDIO_CCCR_CAP_LSC) | |
116 | card->cccr.low_speed = 1; | |
117 | if (data & SDIO_CCCR_CAP_4BLS) | |
118 | card->cccr.wide_bus = 1; | |
119 | ||
120 | if (cccr_vsn >= SDIO_CCCR_REV_1_10) { | |
121 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data); | |
122 | if (ret) | |
123 | goto out; | |
124 | ||
125 | if (data & SDIO_POWER_SMPC) | |
126 | card->cccr.high_power = 1; | |
127 | } | |
128 | ||
129 | if (cccr_vsn >= SDIO_CCCR_REV_1_20) { | |
130 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); | |
131 | if (ret) | |
132 | goto out; | |
133 | ||
134 | if (data & SDIO_SPEED_SHS) | |
135 | card->cccr.high_speed = 1; | |
136 | } | |
137 | ||
138 | out: | |
139 | return ret; | |
140 | } | |
141 | ||
4ff6471c PO |
142 | static int sdio_enable_wide(struct mmc_card *card) |
143 | { | |
144 | int ret; | |
145 | u8 ctrl; | |
146 | ||
147 | if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) | |
148 | return 0; | |
149 | ||
150 | if (card->cccr.low_speed && !card->cccr.wide_bus) | |
151 | return 0; | |
152 | ||
153 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); | |
154 | if (ret) | |
155 | return ret; | |
156 | ||
157 | ctrl |= SDIO_BUS_WIDTH_4BIT; | |
158 | ||
159 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); | |
160 | if (ret) | |
161 | return ret; | |
162 | ||
7310ece8 | 163 | return 1; |
4ff6471c PO |
164 | } |
165 | ||
006ebd5d OBC |
166 | /* |
167 | * If desired, disconnect the pull-up resistor on CD/DAT[3] (pin 1) | |
168 | * of the card. This may be required on certain setups of boards, | |
169 | * controllers and embedded sdio device which do not need the card's | |
170 | * pull-up. As a result, card detection is disabled and power is saved. | |
171 | */ | |
172 | static int sdio_disable_cd(struct mmc_card *card) | |
173 | { | |
174 | int ret; | |
175 | u8 ctrl; | |
176 | ||
177 | if (!card->cccr.disable_cd) | |
178 | return 0; | |
179 | ||
180 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); | |
181 | if (ret) | |
182 | return ret; | |
183 | ||
184 | ctrl |= SDIO_BUS_CD_DISABLE; | |
185 | ||
186 | return mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); | |
187 | } | |
188 | ||
6b5eda36 DD |
189 | /* |
190 | * Devices that remain active during a system suspend are | |
191 | * put back into 1-bit mode. | |
192 | */ | |
193 | static int sdio_disable_wide(struct mmc_card *card) | |
194 | { | |
195 | int ret; | |
196 | u8 ctrl; | |
197 | ||
198 | if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) | |
199 | return 0; | |
200 | ||
201 | if (card->cccr.low_speed && !card->cccr.wide_bus) | |
202 | return 0; | |
203 | ||
204 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); | |
205 | if (ret) | |
206 | return ret; | |
207 | ||
208 | if (!(ctrl & SDIO_BUS_WIDTH_4BIT)) | |
209 | return 0; | |
210 | ||
211 | ctrl &= ~SDIO_BUS_WIDTH_4BIT; | |
212 | ctrl |= SDIO_BUS_ASYNC_INT; | |
213 | ||
214 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); | |
215 | if (ret) | |
216 | return ret; | |
217 | ||
218 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1); | |
219 | ||
220 | return 0; | |
221 | } | |
222 | ||
7310ece8 MM |
223 | |
224 | static int sdio_enable_4bit_bus(struct mmc_card *card) | |
225 | { | |
226 | int err; | |
227 | ||
228 | if (card->type == MMC_TYPE_SDIO) | |
229 | return sdio_enable_wide(card); | |
230 | ||
231 | if ((card->host->caps & MMC_CAP_4_BIT_DATA) && | |
232 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | |
233 | err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); | |
234 | if (err) | |
235 | return err; | |
236 | } else | |
237 | return 0; | |
238 | ||
239 | err = sdio_enable_wide(card); | |
240 | if (err <= 0) | |
241 | mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1); | |
242 | ||
243 | return err; | |
244 | } | |
245 | ||
246 | ||
d16f5770 PO |
247 | /* |
248 | * Test if the card supports high-speed mode and, if so, switch to it. | |
249 | */ | |
7310ece8 | 250 | static int mmc_sdio_switch_hs(struct mmc_card *card, int enable) |
d16f5770 PO |
251 | { |
252 | int ret; | |
253 | u8 speed; | |
254 | ||
255 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | |
256 | return 0; | |
257 | ||
258 | if (!card->cccr.high_speed) | |
259 | return 0; | |
260 | ||
261 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); | |
262 | if (ret) | |
263 | return ret; | |
264 | ||
7310ece8 MM |
265 | if (enable) |
266 | speed |= SDIO_SPEED_EHS; | |
267 | else | |
268 | speed &= ~SDIO_SPEED_EHS; | |
d16f5770 PO |
269 | |
270 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); | |
271 | if (ret) | |
272 | return ret; | |
273 | ||
71578a1e MM |
274 | return 1; |
275 | } | |
d16f5770 | 276 | |
7310ece8 MM |
277 | /* |
278 | * Enable SDIO/combo card's high-speed mode. Return 0/1 if [not]supported. | |
279 | */ | |
280 | static int sdio_enable_hs(struct mmc_card *card) | |
281 | { | |
282 | int ret; | |
283 | ||
284 | ret = mmc_sdio_switch_hs(card, true); | |
285 | if (ret <= 0 || card->type == MMC_TYPE_SDIO) | |
286 | return ret; | |
287 | ||
288 | ret = mmc_sd_switch_hs(card); | |
289 | if (ret <= 0) | |
290 | mmc_sdio_switch_hs(card, false); | |
291 | ||
292 | return ret; | |
293 | } | |
294 | ||
71578a1e MM |
295 | static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) |
296 | { | |
297 | unsigned max_dtr; | |
298 | ||
299 | if (mmc_card_highspeed(card)) { | |
300 | /* | |
301 | * The SDIO specification doesn't mention how | |
302 | * the CIS transfer speed register relates to | |
303 | * high-speed, but it seems that 50 MHz is | |
304 | * mandatory. | |
305 | */ | |
306 | max_dtr = 50000000; | |
307 | } else { | |
308 | max_dtr = card->cis.max_dtr; | |
309 | } | |
310 | ||
7310ece8 MM |
311 | if (card->type == MMC_TYPE_SD_COMBO) |
312 | max_dtr = min(max_dtr, mmc_sd_get_max_clock(card)); | |
313 | ||
71578a1e | 314 | return max_dtr; |
d16f5770 PO |
315 | } |
316 | ||
17d33e14 NP |
317 | /* |
318 | * Handle the detection and initialisation of a card. | |
319 | * | |
320 | * In the case of a resume, "oldcard" will contain the card | |
321 | * we're trying to reinitialise. | |
322 | */ | |
323 | static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |
3bca4cf7 | 324 | struct mmc_card *oldcard, int powered_resume) |
17d33e14 NP |
325 | { |
326 | struct mmc_card *card; | |
327 | int err; | |
328 | ||
329 | BUG_ON(!host); | |
330 | WARN_ON(!host->claimed); | |
331 | ||
332 | /* | |
333 | * Inform the card of the voltage | |
334 | */ | |
3bca4cf7 CB |
335 | if (!powered_resume) { |
336 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); | |
337 | if (err) | |
338 | goto err; | |
339 | } | |
17d33e14 NP |
340 | |
341 | /* | |
342 | * For SPI, enable CRC as appropriate. | |
343 | */ | |
344 | if (mmc_host_is_spi(host)) { | |
345 | err = mmc_spi_set_crc(host, use_spi_crc); | |
346 | if (err) | |
347 | goto err; | |
348 | } | |
349 | ||
350 | /* | |
351 | * Allocate card structure. | |
352 | */ | |
353 | card = mmc_alloc_card(host, NULL); | |
354 | if (IS_ERR(card)) { | |
355 | err = PTR_ERR(card); | |
356 | goto err; | |
357 | } | |
358 | ||
7310ece8 MM |
359 | err = mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid); |
360 | ||
361 | if (!err) { | |
362 | card->type = MMC_TYPE_SD_COMBO; | |
363 | ||
364 | if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || | |
365 | memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) { | |
366 | mmc_remove_card(card); | |
367 | return -ENOENT; | |
368 | } | |
369 | } else { | |
370 | card->type = MMC_TYPE_SDIO; | |
371 | ||
372 | if (oldcard && oldcard->type != MMC_TYPE_SDIO) { | |
373 | mmc_remove_card(card); | |
374 | return -ENOENT; | |
375 | } | |
376 | } | |
17d33e14 | 377 | |
3fcb027d DM |
378 | /* |
379 | * Call the optional HC's init_card function to handle quirks. | |
380 | */ | |
381 | if (host->ops->init_card) | |
382 | host->ops->init_card(host, card); | |
383 | ||
17d33e14 NP |
384 | /* |
385 | * For native busses: set card RCA and quit open drain mode. | |
386 | */ | |
3bca4cf7 | 387 | if (!powered_resume && !mmc_host_is_spi(host)) { |
17d33e14 NP |
388 | err = mmc_send_relative_addr(host, &card->rca); |
389 | if (err) | |
390 | goto remove; | |
391 | ||
392 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | |
393 | } | |
394 | ||
7310ece8 MM |
395 | /* |
396 | * Read CSD, before selecting the card | |
397 | */ | |
398 | if (!oldcard && card->type == MMC_TYPE_SD_COMBO) { | |
399 | err = mmc_sd_get_csd(host, card); | |
400 | if (err) | |
401 | return err; | |
402 | ||
403 | mmc_decode_cid(card); | |
404 | } | |
405 | ||
17d33e14 NP |
406 | /* |
407 | * Select card, as all following commands rely on that. | |
408 | */ | |
3bca4cf7 | 409 | if (!powered_resume && !mmc_host_is_spi(host)) { |
17d33e14 NP |
410 | err = mmc_select_card(card); |
411 | if (err) | |
412 | goto remove; | |
413 | } | |
414 | ||
415 | /* | |
416 | * Read the common registers. | |
417 | */ | |
418 | err = sdio_read_cccr(card); | |
419 | if (err) | |
420 | goto remove; | |
421 | ||
422 | /* | |
423 | * Read the common CIS tuples. | |
424 | */ | |
425 | err = sdio_read_common_cis(card); | |
426 | if (err) | |
427 | goto remove; | |
428 | ||
429 | if (oldcard) { | |
430 | int same = (card->cis.vendor == oldcard->cis.vendor && | |
431 | card->cis.device == oldcard->cis.device); | |
432 | mmc_remove_card(card); | |
7310ece8 MM |
433 | if (!same) |
434 | return -ENOENT; | |
435 | ||
17d33e14 | 436 | card = oldcard; |
95cdfb72 | 437 | return 0; |
17d33e14 NP |
438 | } |
439 | ||
7310ece8 MM |
440 | if (card->type == MMC_TYPE_SD_COMBO) { |
441 | err = mmc_sd_setup_card(host, card, oldcard != NULL); | |
442 | /* handle as SDIO-only card if memory init failed */ | |
443 | if (err) { | |
444 | mmc_go_idle(host); | |
445 | if (mmc_host_is_spi(host)) | |
446 | /* should not fail, as it worked previously */ | |
447 | mmc_spi_set_crc(host, use_spi_crc); | |
448 | card->type = MMC_TYPE_SDIO; | |
449 | } else | |
450 | card->dev.type = &sd_type; | |
451 | } | |
452 | ||
453 | /* | |
454 | * If needed, disconnect card detection pull-up resistor. | |
455 | */ | |
456 | err = sdio_disable_cd(card); | |
457 | if (err) | |
458 | goto remove; | |
459 | ||
17d33e14 NP |
460 | /* |
461 | * Switch to high-speed (if supported). | |
462 | */ | |
463 | err = sdio_enable_hs(card); | |
71578a1e MM |
464 | if (err > 0) |
465 | mmc_sd_go_highspeed(card); | |
466 | else if (err) | |
17d33e14 NP |
467 | goto remove; |
468 | ||
469 | /* | |
470 | * Change to the card's maximum speed. | |
471 | */ | |
71578a1e | 472 | mmc_set_clock(host, mmc_sdio_get_max_clock(card)); |
17d33e14 NP |
473 | |
474 | /* | |
475 | * Switch to wider bus (if supported). | |
476 | */ | |
7310ece8 MM |
477 | err = sdio_enable_4bit_bus(card); |
478 | if (err > 0) | |
479 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | |
480 | else if (err) | |
17d33e14 NP |
481 | goto remove; |
482 | ||
483 | if (!oldcard) | |
484 | host->card = card; | |
485 | return 0; | |
486 | ||
487 | remove: | |
488 | if (!oldcard) | |
489 | mmc_remove_card(card); | |
490 | ||
491 | err: | |
492 | return err; | |
493 | } | |
494 | ||
5c4e6f13 PO |
495 | /* |
496 | * Host is being removed. Free up the current card. | |
497 | */ | |
498 | static void mmc_sdio_remove(struct mmc_host *host) | |
499 | { | |
e29a7d73 PO |
500 | int i; |
501 | ||
5c4e6f13 PO |
502 | BUG_ON(!host); |
503 | BUG_ON(!host->card); | |
504 | ||
e29a7d73 PO |
505 | for (i = 0;i < host->card->sdio_funcs;i++) { |
506 | if (host->card->sdio_func[i]) { | |
507 | sdio_remove_func(host->card->sdio_func[i]); | |
508 | host->card->sdio_func[i] = NULL; | |
509 | } | |
510 | } | |
511 | ||
5c4e6f13 PO |
512 | mmc_remove_card(host->card); |
513 | host->card = NULL; | |
514 | } | |
515 | ||
516 | /* | |
517 | * Card detection callback from host. | |
518 | */ | |
519 | static void mmc_sdio_detect(struct mmc_host *host) | |
520 | { | |
521 | int err; | |
522 | ||
523 | BUG_ON(!host); | |
524 | BUG_ON(!host->card); | |
525 | ||
526 | mmc_claim_host(host); | |
527 | ||
528 | /* | |
529 | * Just check if our card has been removed. | |
530 | */ | |
531 | err = mmc_select_card(host->card); | |
532 | ||
533 | mmc_release_host(host); | |
534 | ||
535 | if (err) { | |
536 | mmc_sdio_remove(host); | |
537 | ||
538 | mmc_claim_host(host); | |
539 | mmc_detach_bus(host); | |
540 | mmc_release_host(host); | |
541 | } | |
542 | } | |
543 | ||
17d33e14 NP |
544 | /* |
545 | * SDIO suspend. We need to suspend all functions separately. | |
546 | * Therefore all registered functions must have drivers with suspend | |
547 | * and resume methods. Failing that we simply remove the whole card. | |
548 | */ | |
95cdfb72 | 549 | static int mmc_sdio_suspend(struct mmc_host *host) |
17d33e14 | 550 | { |
95cdfb72 | 551 | int i, err = 0; |
17d33e14 | 552 | |
17d33e14 NP |
553 | for (i = 0; i < host->card->sdio_funcs; i++) { |
554 | struct sdio_func *func = host->card->sdio_func[i]; | |
555 | if (func && sdio_func_present(func) && func->dev.driver) { | |
556 | const struct dev_pm_ops *pmops = func->dev.driver->pm; | |
557 | if (!pmops || !pmops->suspend || !pmops->resume) { | |
95cdfb72 NP |
558 | /* force removal of entire card in that case */ |
559 | err = -ENOSYS; | |
560 | } else | |
561 | err = pmops->suspend(&func->dev); | |
562 | if (err) | |
563 | break; | |
17d33e14 NP |
564 | } |
565 | } | |
95cdfb72 | 566 | while (err && --i >= 0) { |
17d33e14 NP |
567 | struct sdio_func *func = host->card->sdio_func[i]; |
568 | if (func && sdio_func_present(func) && func->dev.driver) { | |
569 | const struct dev_pm_ops *pmops = func->dev.driver->pm; | |
95cdfb72 | 570 | pmops->resume(&func->dev); |
17d33e14 NP |
571 | } |
572 | } | |
95cdfb72 | 573 | |
6b5eda36 DD |
574 | if (!err && host->pm_flags & MMC_PM_KEEP_POWER) { |
575 | mmc_claim_host(host); | |
576 | sdio_disable_wide(host->card); | |
577 | mmc_release_host(host); | |
578 | } | |
579 | ||
95cdfb72 | 580 | return err; |
17d33e14 NP |
581 | } |
582 | ||
95cdfb72 | 583 | static int mmc_sdio_resume(struct mmc_host *host) |
17d33e14 NP |
584 | { |
585 | int i, err; | |
586 | ||
587 | BUG_ON(!host); | |
588 | BUG_ON(!host->card); | |
589 | ||
95cdfb72 | 590 | /* Basic card reinitialization. */ |
17d33e14 | 591 | mmc_claim_host(host); |
3bca4cf7 CB |
592 | err = mmc_sdio_init_card(host, host->ocr, host->card, |
593 | (host->pm_flags & MMC_PM_KEEP_POWER)); | |
7310ece8 | 594 | if (!err) { |
6b5eda36 | 595 | /* We may have switched to 1-bit mode during suspend. */ |
7310ece8 MM |
596 | err = sdio_enable_4bit_bus(host->card); |
597 | if (err > 0) { | |
598 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | |
599 | err = 0; | |
600 | } | |
601 | } | |
40216842 NP |
602 | if (!err && host->sdio_irqs) |
603 | mmc_signal_sdio_irq(host); | |
17d33e14 | 604 | mmc_release_host(host); |
17d33e14 | 605 | |
95cdfb72 NP |
606 | /* |
607 | * If the card looked to be the same as before suspending, then | |
608 | * we proceed to resume all card functions. If one of them returns | |
609 | * an error then we simply return that error to the core and the | |
610 | * card will be redetected as new. It is the responsibility of | |
611 | * the function driver to perform further tests with the extra | |
612 | * knowledge it has of the card to confirm the card is indeed the | |
613 | * same as before suspending (same MAC address for network cards, | |
614 | * etc.) and return an error otherwise. | |
615 | */ | |
616 | for (i = 0; !err && i < host->card->sdio_funcs; i++) { | |
17d33e14 NP |
617 | struct sdio_func *func = host->card->sdio_func[i]; |
618 | if (func && sdio_func_present(func) && func->dev.driver) { | |
619 | const struct dev_pm_ops *pmops = func->dev.driver->pm; | |
95cdfb72 | 620 | err = pmops->resume(&func->dev); |
17d33e14 NP |
621 | } |
622 | } | |
95cdfb72 NP |
623 | |
624 | return err; | |
17d33e14 | 625 | } |
5c4e6f13 PO |
626 | |
627 | static const struct mmc_bus_ops mmc_sdio_ops = { | |
628 | .remove = mmc_sdio_remove, | |
629 | .detect = mmc_sdio_detect, | |
17d33e14 NP |
630 | .suspend = mmc_sdio_suspend, |
631 | .resume = mmc_sdio_resume, | |
5c4e6f13 PO |
632 | }; |
633 | ||
634 | ||
635 | /* | |
636 | * Starting point for SDIO card init. | |
637 | */ | |
638 | int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |
639 | { | |
640 | int err; | |
e29a7d73 | 641 | int i, funcs; |
5c4e6f13 PO |
642 | struct mmc_card *card; |
643 | ||
644 | BUG_ON(!host); | |
d84075c8 | 645 | WARN_ON(!host->claimed); |
5c4e6f13 PO |
646 | |
647 | mmc_attach_bus(host, &mmc_sdio_ops); | |
648 | ||
649 | /* | |
650 | * Sanity check the voltages that the card claims to | |
651 | * support. | |
652 | */ | |
653 | if (ocr & 0x7F) { | |
654 | printk(KERN_WARNING "%s: card claims to support voltages " | |
655 | "below the defined range. These will be ignored.\n", | |
656 | mmc_hostname(host)); | |
657 | ocr &= ~0x7F; | |
658 | } | |
659 | ||
5c4e6f13 PO |
660 | host->ocr = mmc_select_voltage(host, ocr); |
661 | ||
662 | /* | |
663 | * Can we support the voltage(s) of the card(s)? | |
664 | */ | |
665 | if (!host->ocr) { | |
666 | err = -EINVAL; | |
667 | goto err; | |
668 | } | |
669 | ||
670 | /* | |
17d33e14 | 671 | * Detect and init the card. |
5c4e6f13 | 672 | */ |
3bca4cf7 | 673 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); |
5c4e6f13 PO |
674 | if (err) |
675 | goto err; | |
17d33e14 | 676 | card = host->card; |
af517150 | 677 | |
5c4e6f13 PO |
678 | /* |
679 | * The number of functions on the card is encoded inside | |
680 | * the ocr. | |
681 | */ | |
e8812793 MF |
682 | funcs = (ocr & 0x70000000) >> 28; |
683 | card->sdio_funcs = 0; | |
4ff6471c | 684 | |
e29a7d73 PO |
685 | /* |
686 | * Initialize (but don't add) all present functions. | |
687 | */ | |
e8812793 | 688 | for (i = 0; i < funcs; i++, card->sdio_funcs++) { |
e29a7d73 PO |
689 | err = sdio_init_func(host->card, i + 1); |
690 | if (err) | |
691 | goto remove; | |
692 | } | |
5c4e6f13 PO |
693 | |
694 | mmc_release_host(host); | |
695 | ||
e29a7d73 PO |
696 | /* |
697 | * First add the card to the driver model... | |
698 | */ | |
5c4e6f13 PO |
699 | err = mmc_add_card(host->card); |
700 | if (err) | |
e29a7d73 PO |
701 | goto remove_added; |
702 | ||
703 | /* | |
704 | * ...then the SDIO functions. | |
705 | */ | |
706 | for (i = 0;i < funcs;i++) { | |
707 | err = sdio_add_func(host->card->sdio_func[i]); | |
708 | if (err) | |
709 | goto remove_added; | |
710 | } | |
5c4e6f13 PO |
711 | |
712 | return 0; | |
713 | ||
e29a7d73 PO |
714 | |
715 | remove_added: | |
716 | /* Remove without lock if the device has been added. */ | |
717 | mmc_sdio_remove(host); | |
5c4e6f13 | 718 | mmc_claim_host(host); |
e29a7d73 PO |
719 | remove: |
720 | /* And with lock if it hasn't been added. */ | |
721 | if (host->card) | |
722 | mmc_sdio_remove(host); | |
5c4e6f13 PO |
723 | err: |
724 | mmc_detach_bus(host); | |
725 | mmc_release_host(host); | |
726 | ||
727 | printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n", | |
728 | mmc_hostname(host), err); | |
729 | ||
730 | return err; | |
731 | } | |
732 |