aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/mmc/core
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/Kconfig4
-rw-r--r--drivers/mmc/core/bus.c1
-rw-r--r--drivers/mmc/core/core.c29
-rw-r--r--drivers/mmc/core/core.h2
-rw-r--r--drivers/mmc/core/debugfs.c1
-rw-r--r--drivers/mmc/core/host.c1
-rw-r--r--drivers/mmc/core/mmc.c29
-rw-r--r--drivers/mmc/core/mmc_ops.c1
-rw-r--r--drivers/mmc/core/sd.c22
-rw-r--r--drivers/mmc/core/sdio.c69
-rw-r--r--drivers/mmc/core/sdio_bus.c8
-rw-r--r--drivers/mmc/core/sdio_cis.c168
-rw-r--r--drivers/mmc/core/sdio_io.c56
-rw-r--r--drivers/mmc/core/sdio_ops.c36
-rw-r--r--drivers/mmc/core/sdio_ops.h1
15 files changed, 286 insertions, 142 deletions
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index ab37a6d9d32a..bb22ffd76ef8 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -3,7 +3,7 @@
3# 3#
4 4
5config MMC_UNSAFE_RESUME 5config MMC_UNSAFE_RESUME
6 bool "Allow unsafe resume (DANGEROUS)" 6 bool "Assume MMC/SD cards are non-removable (DANGEROUS)"
7 help 7 help
8 If you say Y here, the MMC layer will assume that all cards 8 If you say Y here, the MMC layer will assume that all cards
9 stayed in their respective slots during the suspend. The 9 stayed in their respective slots during the suspend. The
@@ -14,3 +14,5 @@ config MMC_UNSAFE_RESUME
14 This option is usually just for embedded systems which use 14 This option is usually just for embedded systems which use
15 a MMC/SD card for rootfs. Most people should say N here. 15 a MMC/SD card for rootfs. Most people should say N here.
16 16
17 This option sets a default which can be overridden by the
18 module parameter "removable=0" or "removable=1".
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index bdb165f93046..49d9dcaeca49 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/slab.h>
16 17
17#include <linux/mmc/card.h> 18#include <linux/mmc/card.h>
18#include <linux/mmc/host.h> 19#include <linux/mmc/host.h>
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7dab2e5f4bc9..3168ebd616b2 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -48,6 +48,22 @@ int use_spi_crc = 1;
48module_param(use_spi_crc, bool, 0); 48module_param(use_spi_crc, bool, 0);
49 49
50/* 50/*
51 * We normally treat cards as removed during suspend if they are not
52 * known to be on a non-removable bus, to avoid the risk of writing
53 * back data to a different card after resume. Allow this to be
54 * overridden if necessary.
55 */
56#ifdef CONFIG_MMC_UNSAFE_RESUME
57int mmc_assume_removable;
58#else
59int mmc_assume_removable = 1;
60#endif
61module_param_named(removable, mmc_assume_removable, bool, 0644);
62MODULE_PARM_DESC(
63 removable,
64 "MMC/SD cards are removable and may be removed during suspend");
65
66/*
51 * Internal function. Schedule delayed work in the MMC work queue. 67 * Internal function. Schedule delayed work in the MMC work queue.
52 */ 68 */
53static int mmc_schedule_delayed_work(struct delayed_work *work, 69static int mmc_schedule_delayed_work(struct delayed_work *work,
@@ -1073,6 +1089,7 @@ void mmc_rescan(struct work_struct *work)
1073 mmc_claim_host(host); 1089 mmc_claim_host(host);
1074 1090
1075 mmc_power_up(host); 1091 mmc_power_up(host);
1092 sdio_reset(host);
1076 mmc_go_idle(host); 1093 mmc_go_idle(host);
1077 1094
1078 mmc_send_if_cond(host, host->ocr_avail); 1095 mmc_send_if_cond(host, host->ocr_avail);
@@ -1135,6 +1152,9 @@ void mmc_stop_host(struct mmc_host *host)
1135 cancel_delayed_work(&host->detect); 1152 cancel_delayed_work(&host->detect);
1136 mmc_flush_scheduled_work(); 1153 mmc_flush_scheduled_work();
1137 1154
1155 /* clear pm flags now and let card drivers set them as needed */
1156 host->pm_flags = 0;
1157
1138 mmc_bus_get(host); 1158 mmc_bus_get(host);
1139 if (host->bus_ops && !host->bus_dead) { 1159 if (host->bus_ops && !host->bus_dead) {
1140 if (host->bus_ops->remove) 1160 if (host->bus_ops->remove)
@@ -1257,12 +1277,13 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
1257 mmc_claim_host(host); 1277 mmc_claim_host(host);
1258 mmc_detach_bus(host); 1278 mmc_detach_bus(host);
1259 mmc_release_host(host); 1279 mmc_release_host(host);
1280 host->pm_flags = 0;
1260 err = 0; 1281 err = 0;
1261 } 1282 }
1262 } 1283 }
1263 mmc_bus_put(host); 1284 mmc_bus_put(host);
1264 1285
1265 if (!err) 1286 if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
1266 mmc_power_off(host); 1287 mmc_power_off(host);
1267 1288
1268 return err; 1289 return err;
@@ -1280,8 +1301,10 @@ int mmc_resume_host(struct mmc_host *host)
1280 1301
1281 mmc_bus_get(host); 1302 mmc_bus_get(host);
1282 if (host->bus_ops && !host->bus_dead) { 1303 if (host->bus_ops && !host->bus_dead) {
1283 mmc_power_up(host); 1304 if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
1284 mmc_select_voltage(host, host->ocr); 1305 mmc_power_up(host);
1306 mmc_select_voltage(host, host->ocr);
1307 }
1285 BUG_ON(!host->bus_ops->resume); 1308 BUG_ON(!host->bus_ops->resume);
1286 err = host->bus_ops->resume(host); 1309 err = host->bus_ops->resume(host);
1287 if (err) { 1310 if (err) {
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 67ae6abc4230..a811c52a1659 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -54,7 +54,9 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr);
54int mmc_attach_sd(struct mmc_host *host, u32 ocr); 54int mmc_attach_sd(struct mmc_host *host, u32 ocr);
55int mmc_attach_sdio(struct mmc_host *host, u32 ocr); 55int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
56 56
57/* Module parameters */
57extern int use_spi_crc; 58extern int use_spi_crc;
59extern int mmc_assume_removable;
58 60
59/* Debugfs information for hosts and cards */ 61/* Debugfs information for hosts and cards */
60void mmc_add_host_debugfs(struct mmc_host *host); 62void mmc_add_host_debugfs(struct mmc_host *host);
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 96d10f40fb23..53cb380c0987 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -10,6 +10,7 @@
10#include <linux/debugfs.h> 10#include <linux/debugfs.h>
11#include <linux/fs.h> 11#include <linux/fs.h>
12#include <linux/seq_file.h> 12#include <linux/seq_file.h>
13#include <linux/slab.h>
13#include <linux/stat.h> 14#include <linux/stat.h>
14 15
15#include <linux/mmc/card.h> 16#include <linux/mmc/card.h>
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index a268d12f1af0..47353909e345 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -16,6 +16,7 @@
16#include <linux/idr.h> 16#include <linux/idr.h>
17#include <linux/pagemap.h> 17#include <linux/pagemap.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19#include <linux/slab.h>
19 20
20#include <linux/mmc/host.h> 21#include <linux/mmc/host.h>
21 22
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index bfefce365ae7..89f7a25b7ac1 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/slab.h>
14 15
15#include <linux/mmc/host.h> 16#include <linux/mmc/host.h>
16#include <linux/mmc/card.h> 17#include <linux/mmc/card.h>
@@ -207,7 +208,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
207 } 208 }
208 209
209 card->ext_csd.rev = ext_csd[EXT_CSD_REV]; 210 card->ext_csd.rev = ext_csd[EXT_CSD_REV];
210 if (card->ext_csd.rev > 3) { 211 if (card->ext_csd.rev > 5) {
211 printk(KERN_ERR "%s: unrecognised EXT_CSD structure " 212 printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
212 "version %d\n", mmc_hostname(card->host), 213 "version %d\n", mmc_hostname(card->host),
213 card->ext_csd.rev); 214 card->ext_csd.rev);
@@ -225,7 +226,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
225 mmc_card_set_blockaddr(card); 226 mmc_card_set_blockaddr(card);
226 } 227 }
227 228
228 switch (ext_csd[EXT_CSD_CARD_TYPE]) { 229 switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
229 case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: 230 case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
230 card->ext_csd.hs_max_dtr = 52000000; 231 card->ext_csd.hs_max_dtr = 52000000;
231 break; 232 break;
@@ -237,7 +238,6 @@ static int mmc_read_ext_csd(struct mmc_card *card)
237 printk(KERN_WARNING "%s: card is mmc v4 but doesn't " 238 printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
238 "support any high-speed modes.\n", 239 "support any high-speed modes.\n",
239 mmc_hostname(card->host)); 240 mmc_hostname(card->host));
240 goto out;
241 } 241 }
242 242
243 if (card->ext_csd.rev >= 3) { 243 if (card->ext_csd.rev >= 3) {
@@ -602,25 +602,6 @@ static int mmc_awake(struct mmc_host *host)
602 return err; 602 return err;
603} 603}
604 604
605#ifdef CONFIG_MMC_UNSAFE_RESUME
606
607static const struct mmc_bus_ops mmc_ops = {
608 .awake = mmc_awake,
609 .sleep = mmc_sleep,
610 .remove = mmc_remove,
611 .detect = mmc_detect,
612 .suspend = mmc_suspend,
613 .resume = mmc_resume,
614 .power_restore = mmc_power_restore,
615};
616
617static void mmc_attach_bus_ops(struct mmc_host *host)
618{
619 mmc_attach_bus(host, &mmc_ops);
620}
621
622#else
623
624static const struct mmc_bus_ops mmc_ops = { 605static const struct mmc_bus_ops mmc_ops = {
625 .awake = mmc_awake, 606 .awake = mmc_awake,
626 .sleep = mmc_sleep, 607 .sleep = mmc_sleep,
@@ -645,15 +626,13 @@ static void mmc_attach_bus_ops(struct mmc_host *host)
645{ 626{
646 const struct mmc_bus_ops *bus_ops; 627 const struct mmc_bus_ops *bus_ops;
647 628
648 if (host->caps & MMC_CAP_NONREMOVABLE) 629 if (host->caps & MMC_CAP_NONREMOVABLE || !mmc_assume_removable)
649 bus_ops = &mmc_ops_unsafe; 630 bus_ops = &mmc_ops_unsafe;
650 else 631 else
651 bus_ops = &mmc_ops; 632 bus_ops = &mmc_ops;
652 mmc_attach_bus(host, bus_ops); 633 mmc_attach_bus(host, bus_ops);
653} 634}
654 635
655#endif
656
657/* 636/*
658 * Starting point for MMC card init. 637 * Starting point for MMC card init.
659 */ 638 */
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index d2cb5c634392..326447c9ede8 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -9,6 +9,7 @@
9 * your option) any later version. 9 * your option) any later version.
10 */ 10 */
11 11
12#include <linux/slab.h>
12#include <linux/types.h> 13#include <linux/types.h>
13#include <linux/scatterlist.h> 14#include <linux/scatterlist.h>
14 15
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 10b2a4d20f5a..5eac21df4809 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/slab.h>
14 15
15#include <linux/mmc/host.h> 16#include <linux/mmc/host.h>
16#include <linux/mmc/card.h> 17#include <linux/mmc/card.h>
@@ -606,23 +607,6 @@ static void mmc_sd_power_restore(struct mmc_host *host)
606 mmc_release_host(host); 607 mmc_release_host(host);
607} 608}
608 609
609#ifdef CONFIG_MMC_UNSAFE_RESUME
610
611static const struct mmc_bus_ops mmc_sd_ops = {
612 .remove = mmc_sd_remove,
613 .detect = mmc_sd_detect,
614 .suspend = mmc_sd_suspend,
615 .resume = mmc_sd_resume,
616 .power_restore = mmc_sd_power_restore,
617};
618
619static void mmc_sd_attach_bus_ops(struct mmc_host *host)
620{
621 mmc_attach_bus(host, &mmc_sd_ops);
622}
623
624#else
625
626static const struct mmc_bus_ops mmc_sd_ops = { 610static const struct mmc_bus_ops mmc_sd_ops = {
627 .remove = mmc_sd_remove, 611 .remove = mmc_sd_remove,
628 .detect = mmc_sd_detect, 612 .detect = mmc_sd_detect,
@@ -643,15 +627,13 @@ static void mmc_sd_attach_bus_ops(struct mmc_host *host)
643{ 627{
644 const struct mmc_bus_ops *bus_ops; 628 const struct mmc_bus_ops *bus_ops;
645 629
646 if (host->caps & MMC_CAP_NONREMOVABLE) 630 if (host->caps & MMC_CAP_NONREMOVABLE || !mmc_assume_removable)
647 bus_ops = &mmc_sd_ops_unsafe; 631 bus_ops = &mmc_sd_ops_unsafe;
648 else 632 else
649 bus_ops = &mmc_sd_ops; 633 bus_ops = &mmc_sd_ops;
650 mmc_attach_bus(host, bus_ops); 634 mmc_attach_bus(host, bus_ops);
651} 635}
652 636
653#endif
654
655/* 637/*
656 * Starting point for SD card init. 638 * Starting point for SD card init.
657 */ 639 */
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index cdb845b68ab5..2dd4cfe7ca17 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -188,6 +188,40 @@ static int sdio_disable_cd(struct mmc_card *card)
188} 188}
189 189
190/* 190/*
191 * Devices that remain active during a system suspend are
192 * put back into 1-bit mode.
193 */
194static int sdio_disable_wide(struct mmc_card *card)
195{
196 int ret;
197 u8 ctrl;
198
199 if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
200 return 0;
201
202 if (card->cccr.low_speed && !card->cccr.wide_bus)
203 return 0;
204
205 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
206 if (ret)
207 return ret;
208
209 if (!(ctrl & SDIO_BUS_WIDTH_4BIT))
210 return 0;
211
212 ctrl &= ~SDIO_BUS_WIDTH_4BIT;
213 ctrl |= SDIO_BUS_ASYNC_INT;
214
215 ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
216 if (ret)
217 return ret;
218
219 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1);
220
221 return 0;
222}
223
224/*
191 * Test if the card supports high-speed mode and, if so, switch to it. 225 * Test if the card supports high-speed mode and, if so, switch to it.
192 */ 226 */
193static int sdio_enable_hs(struct mmc_card *card) 227static int sdio_enable_hs(struct mmc_card *card)
@@ -224,7 +258,7 @@ static int sdio_enable_hs(struct mmc_card *card)
224 * we're trying to reinitialise. 258 * we're trying to reinitialise.
225 */ 259 */
226static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, 260static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
227 struct mmc_card *oldcard) 261 struct mmc_card *oldcard, int powered_resume)
228{ 262{
229 struct mmc_card *card; 263 struct mmc_card *card;
230 int err; 264 int err;
@@ -235,9 +269,11 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
235 /* 269 /*
236 * Inform the card of the voltage 270 * Inform the card of the voltage
237 */ 271 */
238 err = mmc_send_io_op_cond(host, host->ocr, &ocr); 272 if (!powered_resume) {
239 if (err) 273 err = mmc_send_io_op_cond(host, host->ocr, &ocr);
240 goto err; 274 if (err)
275 goto err;
276 }
241 277
242 /* 278 /*
243 * For SPI, enable CRC as appropriate. 279 * For SPI, enable CRC as appropriate.
@@ -262,7 +298,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
262 /* 298 /*
263 * For native busses: set card RCA and quit open drain mode. 299 * For native busses: set card RCA and quit open drain mode.
264 */ 300 */
265 if (!mmc_host_is_spi(host)) { 301 if (!powered_resume && !mmc_host_is_spi(host)) {
266 err = mmc_send_relative_addr(host, &card->rca); 302 err = mmc_send_relative_addr(host, &card->rca);
267 if (err) 303 if (err)
268 goto remove; 304 goto remove;
@@ -273,7 +309,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
273 /* 309 /*
274 * Select card, as all following commands rely on that. 310 * Select card, as all following commands rely on that.
275 */ 311 */
276 if (!mmc_host_is_spi(host)) { 312 if (!powered_resume && !mmc_host_is_spi(host)) {
277 err = mmc_select_card(card); 313 err = mmc_select_card(card);
278 if (err) 314 if (err)
279 goto remove; 315 goto remove;
@@ -425,6 +461,12 @@ static int mmc_sdio_suspend(struct mmc_host *host)
425 } 461 }
426 } 462 }
427 463
464 if (!err && host->pm_flags & MMC_PM_KEEP_POWER) {
465 mmc_claim_host(host);
466 sdio_disable_wide(host->card);
467 mmc_release_host(host);
468 }
469
428 return err; 470 return err;
429} 471}
430 472
@@ -437,7 +479,13 @@ static int mmc_sdio_resume(struct mmc_host *host)
437 479
438 /* Basic card reinitialization. */ 480 /* Basic card reinitialization. */
439 mmc_claim_host(host); 481 mmc_claim_host(host);
440 err = mmc_sdio_init_card(host, host->ocr, host->card); 482 err = mmc_sdio_init_card(host, host->ocr, host->card,
483 (host->pm_flags & MMC_PM_KEEP_POWER));
484 if (!err)
485 /* We may have switched to 1-bit mode during suspend. */
486 err = sdio_enable_wide(host->card);
487 if (!err && host->sdio_irqs)
488 mmc_signal_sdio_irq(host);
441 mmc_release_host(host); 489 mmc_release_host(host);
442 490
443 /* 491 /*
@@ -507,7 +555,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
507 /* 555 /*
508 * Detect and init the card. 556 * Detect and init the card.
509 */ 557 */
510 err = mmc_sdio_init_card(host, host->ocr, NULL); 558 err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
511 if (err) 559 if (err)
512 goto err; 560 goto err;
513 card = host->card; 561 card = host->card;
@@ -516,7 +564,8 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
516 * The number of functions on the card is encoded inside 564 * The number of functions on the card is encoded inside
517 * the ocr. 565 * the ocr.
518 */ 566 */
519 card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28; 567 funcs = (ocr & 0x70000000) >> 28;
568 card->sdio_funcs = 0;
520 569
521 /* 570 /*
522 * If needed, disconnect card detection pull-up resistor. 571 * If needed, disconnect card detection pull-up resistor.
@@ -528,7 +577,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
528 /* 577 /*
529 * Initialize (but don't add) all present functions. 578 * Initialize (but don't add) all present functions.
530 */ 579 */
531 for (i = 0;i < funcs;i++) { 580 for (i = 0; i < funcs; i++, card->sdio_funcs++) {
532 err = sdio_init_func(host->card, i + 1); 581 err = sdio_init_func(host->card, i + 1);
533 if (err) 582 if (err)
534 goto remove; 583 goto remove;
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index d37464e296a5..4a890dcb95ab 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/slab.h>
16 17
17#include <linux/mmc/card.h> 18#include <linux/mmc/card.h>
18#include <linux/mmc/sdio_func.h> 19#include <linux/mmc/sdio_func.h>
@@ -248,12 +249,15 @@ int sdio_add_func(struct sdio_func *func)
248/* 249/*
249 * Unregister a SDIO function with the driver model, and 250 * Unregister a SDIO function with the driver model, and
250 * (eventually) free it. 251 * (eventually) free it.
252 * This function can be called through error paths where sdio_add_func() was
253 * never executed (because a failure occurred at an earlier point).
251 */ 254 */
252void sdio_remove_func(struct sdio_func *func) 255void sdio_remove_func(struct sdio_func *func)
253{ 256{
254 if (sdio_func_present(func)) 257 if (!sdio_func_present(func))
255 device_del(&func->dev); 258 return;
256 259
260 device_del(&func->dev);
257 put_device(&func->dev); 261 put_device(&func->dev);
258} 262}
259 263
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index f85dcd536508..541bdb89e0c5 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/slab.h>
17 18
18#include <linux/mmc/host.h> 19#include <linux/mmc/host.h>
19#include <linux/mmc/card.h> 20#include <linux/mmc/card.h>
@@ -97,26 +98,56 @@ static const unsigned char speed_val[16] =
97static const unsigned int speed_unit[8] = 98static const unsigned int speed_unit[8] =
98 { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 }; 99 { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
99 100
100/* FUNCE tuples with these types get passed to SDIO drivers */ 101
101static const unsigned char funce_type_whitelist[] = { 102typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
102 4 /* CISTPL_FUNCE_LAN_NODE_ID used in Broadcom cards */ 103 const unsigned char *, unsigned);
104
105struct cis_tpl {
106 unsigned char code;
107 unsigned char min_size;
108 tpl_parse_t *parse;
103}; 109};
104 110
105static int cistpl_funce_whitelisted(unsigned char type) 111static int cis_tpl_parse(struct mmc_card *card, struct sdio_func *func,
112 const char *tpl_descr,
113 const struct cis_tpl *tpl, int tpl_count,
114 unsigned char code,
115 const unsigned char *buf, unsigned size)
106{ 116{
107 int i; 117 int i, ret;
108 118
109 for (i = 0; i < ARRAY_SIZE(funce_type_whitelist); i++) { 119 /* look for a matching code in the table */
110 if (funce_type_whitelist[i] == type) 120 for (i = 0; i < tpl_count; i++, tpl++) {
111 return 1; 121 if (tpl->code == code)
122 break;
112 } 123 }
113 return 0; 124 if (i < tpl_count) {
125 if (size >= tpl->min_size) {
126 if (tpl->parse)
127 ret = tpl->parse(card, func, buf, size);
128 else
129 ret = -EILSEQ; /* known tuple, not parsed */
130 } else {
131 /* invalid tuple */
132 ret = -EINVAL;
133 }
134 if (ret && ret != -EILSEQ && ret != -ENOENT) {
135 printk(KERN_ERR "%s: bad %s tuple 0x%02x (%u bytes)\n",
136 mmc_hostname(card->host), tpl_descr, code, size);
137 }
138 } else {
139 /* unknown tuple */
140 ret = -ENOENT;
141 }
142
143 return ret;
114} 144}
115 145
116static int cistpl_funce_common(struct mmc_card *card, 146static int cistpl_funce_common(struct mmc_card *card, struct sdio_func *func,
117 const unsigned char *buf, unsigned size) 147 const unsigned char *buf, unsigned size)
118{ 148{
119 if (size < 0x04 || buf[0] != 0) 149 /* Only valid for the common CIS (function 0) */
150 if (func)
120 return -EINVAL; 151 return -EINVAL;
121 152
122 /* TPLFE_FN0_BLK_SIZE */ 153 /* TPLFE_FN0_BLK_SIZE */
@@ -129,20 +160,24 @@ static int cistpl_funce_common(struct mmc_card *card,
129 return 0; 160 return 0;
130} 161}
131 162
132static int cistpl_funce_func(struct sdio_func *func, 163static int cistpl_funce_func(struct mmc_card *card, struct sdio_func *func,
133 const unsigned char *buf, unsigned size) 164 const unsigned char *buf, unsigned size)
134{ 165{
135 unsigned vsn; 166 unsigned vsn;
136 unsigned min_size; 167 unsigned min_size;
137 168
138 /* let SDIO drivers take care of whitelisted FUNCE tuples */ 169 /* Only valid for the individual function's CIS (1-7) */
139 if (cistpl_funce_whitelisted(buf[0])) 170 if (!func)
140 return -EILSEQ; 171 return -EINVAL;
141 172
173 /*
174 * This tuple has a different length depending on the SDIO spec
175 * version.
176 */
142 vsn = func->card->cccr.sdio_vsn; 177 vsn = func->card->cccr.sdio_vsn;
143 min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42; 178 min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
144 179
145 if (size < min_size || buf[0] != 1) 180 if (size < min_size)
146 return -EINVAL; 181 return -EINVAL;
147 182
148 /* TPLFE_MAX_BLK_SIZE */ 183 /* TPLFE_MAX_BLK_SIZE */
@@ -157,39 +192,32 @@ static int cistpl_funce_func(struct sdio_func *func,
157 return 0; 192 return 0;
158} 193}
159 194
195/*
196 * Known TPLFE_TYPEs table for CISTPL_FUNCE tuples.
197 *
198 * Note that, unlike PCMCIA, CISTPL_FUNCE tuples are not parsed depending
199 * on the TPLFID_FUNCTION value of the previous CISTPL_FUNCID as on SDIO
200 * TPLFID_FUNCTION is always hardcoded to 0x0C.
201 */
202static const struct cis_tpl cis_tpl_funce_list[] = {
203 { 0x00, 4, cistpl_funce_common },
204 { 0x01, 0, cistpl_funce_func },
205 { 0x04, 1+1+6, /* CISTPL_FUNCE_LAN_NODE_ID */ },
206};
207
160static int cistpl_funce(struct mmc_card *card, struct sdio_func *func, 208static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
161 const unsigned char *buf, unsigned size) 209 const unsigned char *buf, unsigned size)
162{ 210{
163 int ret; 211 if (size < 1)
164 212 return -EINVAL;
165 /*
166 * There should be two versions of the CISTPL_FUNCE tuple,
167 * one for the common CIS (function 0) and a version used by
168 * the individual function's CIS (1-7). Yet, the later has a
169 * different length depending on the SDIO spec version.
170 */
171 if (func)
172 ret = cistpl_funce_func(func, buf, size);
173 else
174 ret = cistpl_funce_common(card, buf, size);
175
176 if (ret && ret != -EILSEQ) {
177 printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
178 "type %u\n", mmc_hostname(card->host), size, buf[0]);
179 }
180 213
181 return ret; 214 return cis_tpl_parse(card, func, "CISTPL_FUNCE",
215 cis_tpl_funce_list,
216 ARRAY_SIZE(cis_tpl_funce_list),
217 buf[0], buf, size);
182} 218}
183 219
184typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *, 220/* Known TPL_CODEs table for CIS tuples */
185 const unsigned char *, unsigned);
186
187struct cis_tpl {
188 unsigned char code;
189 unsigned char min_size;
190 tpl_parse_t *parse;
191};
192
193static const struct cis_tpl cis_tpl_list[] = { 221static const struct cis_tpl cis_tpl_list[] = {
194 { 0x15, 3, cistpl_vers_1 }, 222 { 0x15, 3, cistpl_vers_1 },
195 { 0x20, 4, cistpl_manfid }, 223 { 0x20, 4, cistpl_manfid },
@@ -268,46 +296,38 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
268 break; 296 break;
269 } 297 }
270 298
271 for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++) 299 /* Try to parse the CIS tuple */
272 if (cis_tpl_list[i].code == tpl_code) 300 ret = cis_tpl_parse(card, func, "CIS",
273 break; 301 cis_tpl_list, ARRAY_SIZE(cis_tpl_list),
274 if (i < ARRAY_SIZE(cis_tpl_list)) { 302 tpl_code, this->data, tpl_link);
275 const struct cis_tpl *tpl = cis_tpl_list + i; 303 if (ret == -EILSEQ || ret == -ENOENT) {
276 if (tpl_link < tpl->min_size) {
277 printk(KERN_ERR
278 "%s: bad CIS tuple 0x%02x"
279 " (length = %u, expected >= %u)\n",
280 mmc_hostname(card->host),
281 tpl_code, tpl_link, tpl->min_size);
282 ret = -EINVAL;
283 } else if (tpl->parse) {
284 ret = tpl->parse(card, func,
285 this->data, tpl_link);
286 }
287 /* 304 /*
288 * We don't need the tuple anymore if it was 305 * The tuple is unknown or known but not parsed.
289 * successfully parsed by the SDIO core or if it is 306 * Queue the tuple for the function driver.
290 * not going to be parsed by SDIO drivers.
291 */ 307 */
292 if (!ret || ret != -EILSEQ)
293 kfree(this);
294 } else {
295 /* unknown tuple */
296 ret = -EILSEQ;
297 }
298
299 if (ret == -EILSEQ) {
300 /* this tuple is unknown to the core or whitelisted */
301 this->next = NULL; 308 this->next = NULL;
302 this->code = tpl_code; 309 this->code = tpl_code;
303 this->size = tpl_link; 310 this->size = tpl_link;
304 *prev = this; 311 *prev = this;
305 prev = &this->next; 312 prev = &this->next;
306 printk(KERN_DEBUG 313
307 "%s: queuing CIS tuple 0x%02x length %u\n", 314 if (ret == -ENOENT) {
308 mmc_hostname(card->host), tpl_code, tpl_link); 315 /* warn about unknown tuples */
316 printk(KERN_WARNING "%s: queuing unknown"
317 " CIS tuple 0x%02x (%u bytes)\n",
318 mmc_hostname(card->host),
319 tpl_code, tpl_link);
320 }
321
309 /* keep on analyzing tuples */ 322 /* keep on analyzing tuples */
310 ret = 0; 323 ret = 0;
324 } else {
325 /*
326 * We don't need the tuple anymore if it was
327 * successfully parsed by the SDIO core or if it is
328 * not going to be queued for a driver.
329 */
330 kfree(this);
311 } 331 }
312 332
313 ptr += tpl_link; 333 ptr += tpl_link;
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index f9aa8a7deffa..ff27c8c71355 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -189,7 +189,12 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
189{ 189{
190 unsigned mval = min(func->card->host->max_seg_size, 190 unsigned mval = min(func->card->host->max_seg_size,
191 func->card->host->max_blk_size); 191 func->card->host->max_blk_size);
192 mval = min(mval, func->max_blksize); 192
193 if (mmc_blksz_for_byte_mode(func->card))
194 mval = min(mval, func->cur_blksize);
195 else
196 mval = min(mval, func->max_blksize);
197
193 return min(mval, 512u); /* maximum size for byte mode */ 198 return min(mval, 512u); /* maximum size for byte mode */
194} 199}
195 200
@@ -635,3 +640,52 @@ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
635 *err_ret = ret; 640 *err_ret = ret;
636} 641}
637EXPORT_SYMBOL_GPL(sdio_f0_writeb); 642EXPORT_SYMBOL_GPL(sdio_f0_writeb);
643
644/**
645 * sdio_get_host_pm_caps - get host power management capabilities
646 * @func: SDIO function attached to host
647 *
648 * Returns a capability bitmask corresponding to power management
649 * features supported by the host controller that the card function
650 * might rely upon during a system suspend. The host doesn't need
651 * to be claimed, nor the function active, for this information to be
652 * obtained.
653 */
654mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
655{
656 BUG_ON(!func);
657 BUG_ON(!func->card);
658
659 return func->card->host->pm_caps;
660}
661EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);
662
663/**
664 * sdio_set_host_pm_flags - set wanted host power management capabilities
665 * @func: SDIO function attached to host
666 *
667 * Set a capability bitmask corresponding to wanted host controller
668 * power management features for the upcoming suspend state.
669 * This must be called, if needed, each time the suspend method of
670 * the function driver is called, and must contain only bits that
671 * were returned by sdio_get_host_pm_caps().
672 * The host doesn't need to be claimed, nor the function active,
673 * for this information to be set.
674 */
675int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
676{
677 struct mmc_host *host;
678
679 BUG_ON(!func);
680 BUG_ON(!func->card);
681
682 host = func->card->host;
683
684 if (flags & ~host->pm_caps)
685 return -EINVAL;
686
687 /* function suspend methods are serialized, hence no lock needed */
688 host->pm_flags |= flags;
689 return 0;
690}
691EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index 4eb7825fd1a7..dea36d9c22e6 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -67,13 +67,13 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
67 return err; 67 return err;
68} 68}
69 69
70int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, 70static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn,
71 unsigned addr, u8 in, u8* out) 71 unsigned addr, u8 in, u8 *out)
72{ 72{
73 struct mmc_command cmd; 73 struct mmc_command cmd;
74 int err; 74 int err;
75 75
76 BUG_ON(!card); 76 BUG_ON(!host);
77 BUG_ON(fn > 7); 77 BUG_ON(fn > 7);
78 78
79 /* sanity check */ 79 /* sanity check */
@@ -90,11 +90,11 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
90 cmd.arg |= in; 90 cmd.arg |= in;
91 cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; 91 cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
92 92
93 err = mmc_wait_for_cmd(card->host, &cmd, 0); 93 err = mmc_wait_for_cmd(host, &cmd, 0);
94 if (err) 94 if (err)
95 return err; 95 return err;
96 96
97 if (mmc_host_is_spi(card->host)) { 97 if (mmc_host_is_spi(host)) {
98 /* host driver already reported errors */ 98 /* host driver already reported errors */
99 } else { 99 } else {
100 if (cmd.resp[0] & R5_ERROR) 100 if (cmd.resp[0] & R5_ERROR)
@@ -106,7 +106,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
106 } 106 }
107 107
108 if (out) { 108 if (out) {
109 if (mmc_host_is_spi(card->host)) 109 if (mmc_host_is_spi(host))
110 *out = (cmd.resp[0] >> 8) & 0xFF; 110 *out = (cmd.resp[0] >> 8) & 0xFF;
111 else 111 else
112 *out = cmd.resp[0] & 0xFF; 112 *out = cmd.resp[0] & 0xFF;
@@ -115,6 +115,13 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
115 return 0; 115 return 0;
116} 116}
117 117
118int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
119 unsigned addr, u8 in, u8 *out)
120{
121 BUG_ON(!card);
122 return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out);
123}
124
118int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, 125int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
119 unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) 126 unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)
120{ 127{
@@ -182,3 +189,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
182 return 0; 189 return 0;
183} 190}
184 191
192int sdio_reset(struct mmc_host *host)
193{
194 int ret;
195 u8 abort;
196
197 /* SDIO Simplified Specification V2.0, 4.4 Reset for SDIO */
198
199 ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort);
200 if (ret)
201 abort = 0x08;
202 else
203 abort |= 0x08;
204
205 ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL);
206 return ret;
207}
208
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h
index e2e74b0d17d8..12a4d3ab174c 100644
--- a/drivers/mmc/core/sdio_ops.h
+++ b/drivers/mmc/core/sdio_ops.h
@@ -17,6 +17,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
17 unsigned addr, u8 in, u8* out); 17 unsigned addr, u8 in, u8* out);
18int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, 18int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
19 unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); 19 unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz);
20int sdio_reset(struct mmc_host *host);
20 21
21#endif 22#endif
22 23