diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 23:41:15 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-13 23:41:15 -0500 |
| commit | 4b8be38cf782f8ebebc089083fa0572ade79d7ca (patch) | |
| tree | 2f88a0a5c1c0be9121c31b5a2775ae2f979cfa66 | |
| parent | 5df1b274cd2f0304339c7f5586fa16cce0fdfce2 (diff) | |
| parent | 0db13fc2abbb0b1a8d8efee20dfbd7f3c5d54022 (diff) | |
Merge tag 'mmc-merge-for-3.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
MMC highlights for 3.3:
Core:
* Support for the HS200 high-speed eMMC mode.
* Support SDIO 3.0 Ultra High Speed cards.
* Kill pending block requests immediately if card is removed.
* Enable the eMMC feature for locking boot partitions read-only
until next power on, exposed via sysfs.
Drivers:
* Runtime PM support for Intel Medfield SDIO.
* Suspend/resume support for sdhci-spear.
* sh-mmcif now processes requests asynchronously.
* tag 'mmc-merge-for-3.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (58 commits)
mmc: fix a deadlock between system suspend and MMC block IO
mmc: sdhci: restore the enabled dma when do reset all
mmc: dw_mmc: miscaculated the fifo-depth with wrong bit operation
mmc: host: Adds support for eMMC 4.5 HS200 mode
mmc: core: HS200 mode support for eMMC 4.5
mmc: dw_mmc: fixed wrong bit operation for SDMMC_GET_FCNT()
mmc: core: Separate the timeout value for cache-ctrl
mmc: sdhci-spear: Fix compilation error
mmc: sdhci: Deal with failure case in sdhci_suspend_host
mmc: dw_mmc: Clear the DDR mode for non-DDR
mmc: sd: Fix SDR12 timing regression
mmc: sdhci: Fix tuning timer incorrect setting when suspending host
mmc: core: Add option to prevent eMMC sleep command
mmc: omap_hsmmc: use threaded irq handler for card-detect.
mmc: sdhci-pci: enable runtime PM for Medfield SDIO
mmc: sdhci: Always pass clock request value zero to set_clock host op
mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION
mmc: sdhci-pci: get gpio numbers from platform data
mmc: sdhci-pci: add platform data
mmc: sdhci: prevent card detection activity for non-removable cards
...
67 files changed, 1995 insertions, 850 deletions
diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt index 8898a95b41e..22ae8441489 100644 --- a/Documentation/mmc/mmc-dev-attrs.txt +++ b/Documentation/mmc/mmc-dev-attrs.txt | |||
| @@ -64,3 +64,13 @@ Note on Erase Size and Preferred Erase Size: | |||
| 64 | size specified by the card. | 64 | size specified by the card. |
| 65 | 65 | ||
| 66 | "preferred_erase_size" is in bytes. | 66 | "preferred_erase_size" is in bytes. |
| 67 | |||
| 68 | SD/MMC/SDIO Clock Gating Attribute | ||
| 69 | ================================== | ||
| 70 | |||
| 71 | Read and write access is provided to following attribute. | ||
| 72 | This attribute appears only if CONFIG_MMC_CLKGATE is enabled. | ||
| 73 | |||
| 74 | clkgate_delay Tune the clock gating delay with desired value in milliseconds. | ||
| 75 | |||
| 76 | echo <desired delay> > /sys/class/mmc_host/mmcX/clkgate_delay | ||
diff --git a/Documentation/mmc/mmc-dev-parts.txt b/Documentation/mmc/mmc-dev-parts.txt index 2db28b8e662..f08d078d43c 100644 --- a/Documentation/mmc/mmc-dev-parts.txt +++ b/Documentation/mmc/mmc-dev-parts.txt | |||
| @@ -25,3 +25,16 @@ echo 0 > /sys/block/mmcblkXbootY/force_ro | |||
| 25 | To re-enable read-only access: | 25 | To re-enable read-only access: |
| 26 | 26 | ||
| 27 | echo 1 > /sys/block/mmcblkXbootY/force_ro | 27 | echo 1 > /sys/block/mmcblkXbootY/force_ro |
| 28 | |||
| 29 | The boot partitions can also be locked read only until the next power on, | ||
| 30 | with: | ||
| 31 | |||
| 32 | echo 1 > /sys/block/mmcblkXbootY/ro_lock_until_next_power_on | ||
| 33 | |||
| 34 | This is a feature of the card and not of the kernel. If the card does | ||
| 35 | not support boot partition locking, the file will not exist. If the | ||
| 36 | feature has been disabled on the card, the file will be read-only. | ||
| 37 | |||
| 38 | The boot partitions can also be locked permanently, but this feature is | ||
| 39 | not accessible through sysfs in order to avoid accidental or malicious | ||
| 40 | bricking. | ||
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index 656dc00d30e..f82f888b91a 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h | |||
| @@ -63,6 +63,7 @@ enum clk_types { | |||
| 63 | struct s3c_sdhci_platdata { | 63 | struct s3c_sdhci_platdata { |
| 64 | unsigned int max_width; | 64 | unsigned int max_width; |
| 65 | unsigned int host_caps; | 65 | unsigned int host_caps; |
| 66 | unsigned int pm_caps; | ||
| 66 | enum cd_types cd_type; | 67 | enum cd_types cd_type; |
| 67 | enum clk_types clk_type; | 68 | enum clk_types clk_type; |
| 68 | 69 | ||
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c index ceb9fa3a80c..0f707184eae 100644 --- a/arch/arm/plat-samsung/platformdata.c +++ b/arch/arm/plat-samsung/platformdata.c | |||
| @@ -53,6 +53,8 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd, | |||
| 53 | set->cfg_gpio = pd->cfg_gpio; | 53 | set->cfg_gpio = pd->cfg_gpio; |
| 54 | if (pd->host_caps) | 54 | if (pd->host_caps) |
| 55 | set->host_caps |= pd->host_caps; | 55 | set->host_caps |= pd->host_caps; |
| 56 | if (pd->pm_caps) | ||
| 57 | set->pm_caps |= pd->pm_caps; | ||
| 56 | if (pd->clk_type) | 58 | if (pd->clk_type) |
| 57 | set->clk_type = pd->clk_type; | 59 | set->clk_type = pd->clk_type; |
| 58 | } | 60 | } |
diff --git a/drivers/Makefile b/drivers/Makefile index 1b3142127bf..c07be024b96 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
| @@ -97,7 +97,7 @@ obj-$(CONFIG_EISA) += eisa/ | |||
| 97 | obj-y += lguest/ | 97 | obj-y += lguest/ |
| 98 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 98 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
| 99 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ | 99 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ |
| 100 | obj-$(CONFIG_MMC) += mmc/ | 100 | obj-y += mmc/ |
| 101 | obj-$(CONFIG_MEMSTICK) += memstick/ | 101 | obj-$(CONFIG_MEMSTICK) += memstick/ |
| 102 | obj-y += leds/ | 102 | obj-y += leds/ |
| 103 | obj-$(CONFIG_INFINIBAND) += infiniband/ | 103 | obj-$(CONFIG_INFINIBAND) += infiniband/ |
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 12eef393e21..400756ec7c4 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile | |||
| @@ -6,5 +6,4 @@ subdir-ccflags-$(CONFIG_MMC_DEBUG) := -DDEBUG | |||
| 6 | 6 | ||
| 7 | obj-$(CONFIG_MMC) += core/ | 7 | obj-$(CONFIG_MMC) += core/ |
| 8 | obj-$(CONFIG_MMC) += card/ | 8 | obj-$(CONFIG_MMC) += card/ |
| 9 | obj-$(CONFIG_MMC) += host/ | 9 | obj-$(subst m,y,$(CONFIG_MMC)) += host/ |
| 10 | |||
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1e0e27cbe98..0cad48a284a 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
| @@ -107,6 +107,8 @@ struct mmc_blk_data { | |||
| 107 | */ | 107 | */ |
| 108 | unsigned int part_curr; | 108 | unsigned int part_curr; |
| 109 | struct device_attribute force_ro; | 109 | struct device_attribute force_ro; |
| 110 | struct device_attribute power_ro_lock; | ||
| 111 | int area_type; | ||
| 110 | }; | 112 | }; |
| 111 | 113 | ||
| 112 | static DEFINE_MUTEX(open_lock); | 114 | static DEFINE_MUTEX(open_lock); |
| @@ -119,6 +121,7 @@ enum mmc_blk_status { | |||
| 119 | MMC_BLK_ABORT, | 121 | MMC_BLK_ABORT, |
| 120 | MMC_BLK_DATA_ERR, | 122 | MMC_BLK_DATA_ERR, |
| 121 | MMC_BLK_ECC_ERR, | 123 | MMC_BLK_ECC_ERR, |
| 124 | MMC_BLK_NOMEDIUM, | ||
| 122 | }; | 125 | }; |
| 123 | 126 | ||
| 124 | module_param(perdev_minors, int, 0444); | 127 | module_param(perdev_minors, int, 0444); |
| @@ -165,6 +168,70 @@ static void mmc_blk_put(struct mmc_blk_data *md) | |||
| 165 | mutex_unlock(&open_lock); | 168 | mutex_unlock(&open_lock); |
| 166 | } | 169 | } |
| 167 | 170 | ||
| 171 | static ssize_t power_ro_lock_show(struct device *dev, | ||
| 172 | struct device_attribute *attr, char *buf) | ||
| 173 | { | ||
| 174 | int ret; | ||
| 175 | struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); | ||
| 176 | struct mmc_card *card = md->queue.card; | ||
| 177 | int locked = 0; | ||
| 178 | |||
| 179 | if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PERM_WP_EN) | ||
| 180 | locked = 2; | ||
| 181 | else if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_EN) | ||
| 182 | locked = 1; | ||
| 183 | |||
| 184 | ret = snprintf(buf, PAGE_SIZE, "%d\n", locked); | ||
| 185 | |||
| 186 | return ret; | ||
| 187 | } | ||
| 188 | |||
| 189 | static ssize_t power_ro_lock_store(struct device *dev, | ||
| 190 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 191 | { | ||
| 192 | int ret; | ||
| 193 | struct mmc_blk_data *md, *part_md; | ||
| 194 | struct mmc_card *card; | ||
| 195 | unsigned long set; | ||
| 196 | |||
| 197 | if (kstrtoul(buf, 0, &set)) | ||
| 198 | return -EINVAL; | ||
| 199 | |||
| 200 | if (set != 1) | ||
| 201 | return count; | ||
| 202 | |||
| 203 | md = mmc_blk_get(dev_to_disk(dev)); | ||
| 204 | card = md->queue.card; | ||
| 205 | |||
| 206 | mmc_claim_host(card->host); | ||
| 207 | |||
| 208 | ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, | ||
| 209 | card->ext_csd.boot_ro_lock | | ||
| 210 | EXT_CSD_BOOT_WP_B_PWR_WP_EN, | ||
| 211 | card->ext_csd.part_time); | ||
| 212 | if (ret) | ||
| 213 | pr_err("%s: Locking boot partition ro until next power on failed: %d\n", md->disk->disk_name, ret); | ||
| 214 | else | ||
| 215 | card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN; | ||
| 216 | |||
| 217 | mmc_release_host(card->host); | ||
| 218 | |||
| 219 | if (!ret) { | ||
| 220 | pr_info("%s: Locking boot partition ro until next power on\n", | ||
| 221 | md->disk->disk_name); | ||
| 222 | set_disk_ro(md->disk, 1); | ||
| 223 | |||
| 224 | list_for_each_entry(part_md, &md->part, part) | ||
| 225 | if (part_md->area_type == MMC_BLK_DATA_AREA_BOOT) { | ||
| 226 | pr_info("%s: Locking boot partition ro until next power on\n", part_md->disk->disk_name); | ||
| 227 | set_disk_ro(part_md->disk, 1); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | mmc_blk_put(md); | ||
| 232 | return count; | ||
| 233 | } | ||
| 234 | |||
| 168 | static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, | 235 | static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, |
| 169 | char *buf) | 236 | char *buf) |
| 170 | { | 237 | { |
| @@ -266,6 +333,9 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( | |||
| 266 | goto idata_err; | 333 | goto idata_err; |
| 267 | } | 334 | } |
| 268 | 335 | ||
| 336 | if (!idata->buf_bytes) | ||
| 337 | return idata; | ||
| 338 | |||
| 269 | idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); | 339 | idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); |
| 270 | if (!idata->buf) { | 340 | if (!idata->buf) { |
| 271 | err = -ENOMEM; | 341 | err = -ENOMEM; |
| @@ -312,25 +382,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
| 312 | if (IS_ERR(idata)) | 382 | if (IS_ERR(idata)) |
| 313 | return PTR_ERR(idata); | 383 | return PTR_ERR(idata); |
| 314 | 384 | ||
| 315 | cmd.opcode = idata->ic.opcode; | ||
| 316 | cmd.arg = idata->ic.arg; | ||
| 317 | cmd.flags = idata->ic.flags; | ||
| 318 | |||
| 319 | data.sg = &sg; | ||
| 320 | data.sg_len = 1; | ||
| 321 | data.blksz = idata->ic.blksz; | ||
| 322 | data.blocks = idata->ic.blocks; | ||
| 323 | |||
| 324 | sg_init_one(data.sg, idata->buf, idata->buf_bytes); | ||
| 325 | |||
| 326 | if (idata->ic.write_flag) | ||
| 327 | data.flags = MMC_DATA_WRITE; | ||
| 328 | else | ||
| 329 | data.flags = MMC_DATA_READ; | ||
| 330 | |||
| 331 | mrq.cmd = &cmd; | ||
| 332 | mrq.data = &data; | ||
| 333 | |||
| 334 | md = mmc_blk_get(bdev->bd_disk); | 385 | md = mmc_blk_get(bdev->bd_disk); |
| 335 | if (!md) { | 386 | if (!md) { |
| 336 | err = -EINVAL; | 387 | err = -EINVAL; |
| @@ -343,6 +394,48 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
| 343 | goto cmd_done; | 394 | goto cmd_done; |
| 344 | } | 395 | } |
| 345 | 396 | ||
| 397 | cmd.opcode = idata->ic.opcode; | ||
| 398 | cmd.arg = idata->ic.arg; | ||
| 399 | cmd.flags = idata->ic.flags; | ||
| 400 | |||
| 401 | if (idata->buf_bytes) { | ||
| 402 | data.sg = &sg; | ||
| 403 | data.sg_len = 1; | ||
| 404 | data.blksz = idata->ic.blksz; | ||
| 405 | data.blocks = idata->ic.blocks; | ||
| 406 | |||
| 407 | sg_init_one(data.sg, idata->buf, idata->buf_bytes); | ||
| 408 | |||
| 409 | if (idata->ic.write_flag) | ||
| 410 | data.flags = MMC_DATA_WRITE; | ||
| 411 | else | ||
| 412 | data.flags = MMC_DATA_READ; | ||
| 413 | |||
| 414 | /* data.flags must already be set before doing this. */ | ||
| 415 | mmc_set_data_timeout(&data, card); | ||
| 416 | |||
| 417 | /* Allow overriding the timeout_ns for empirical tuning. */ | ||
| 418 | if (idata->ic.data_timeout_ns) | ||
| 419 | data.timeout_ns = idata->ic.data_timeout_ns; | ||
| 420 | |||
| 421 | if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { | ||
| 422 | /* | ||
| 423 | * Pretend this is a data transfer and rely on the | ||
| 424 | * host driver to compute timeout. When all host | ||
| 425 | * drivers support cmd.cmd_timeout for R1B, this | ||
| 426 | * can be changed to: | ||
| 427 | * | ||
| 428 | * mrq.data = NULL; | ||
| 429 | * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; | ||
| 430 | */ | ||
| 431 | data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; | ||
| 432 | } | ||
| 433 | |||
| 434 | mrq.data = &data; | ||
| 435 | } | ||
| 436 | |||
| 437 | mrq.cmd = &cmd; | ||
| 438 | |||
| 346 | mmc_claim_host(card->host); | 439 | mmc_claim_host(card->host); |
| 347 | 440 | ||
| 348 | if (idata->ic.is_acmd) { | 441 | if (idata->ic.is_acmd) { |
| @@ -351,24 +444,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
| 351 | goto cmd_rel_host; | 444 | goto cmd_rel_host; |
| 352 | } | 445 | } |
| 353 | 446 | ||
| 354 | /* data.flags must already be set before doing this. */ | ||
| 355 | mmc_set_data_timeout(&data, card); | ||
| 356 | /* Allow overriding the timeout_ns for empirical tuning. */ | ||
| 357 | if (idata->ic.data_timeout_ns) | ||
| 358 | data.timeout_ns = idata->ic.data_timeout_ns; | ||
| 359 | |||
| 360 | if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { | ||
| 361 | /* | ||
| 362 | * Pretend this is a data transfer and rely on the host driver | ||
| 363 | * to compute timeout. When all host drivers support | ||
| 364 | * cmd.cmd_timeout for R1B, this can be changed to: | ||
| 365 | * | ||
| 366 | * mrq.data = NULL; | ||
| 367 | * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; | ||
| 368 | */ | ||
| 369 | data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; | ||
| 370 | } | ||
| 371 | |||
| 372 | mmc_wait_for_req(card->host, &mrq); | 447 | mmc_wait_for_req(card->host, &mrq); |
| 373 | 448 | ||
| 374 | if (cmd.error) { | 449 | if (cmd.error) { |
| @@ -565,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries) | |||
| 565 | return err; | 640 | return err; |
| 566 | } | 641 | } |
| 567 | 642 | ||
| 643 | #define ERR_NOMEDIUM 3 | ||
| 568 | #define ERR_RETRY 2 | 644 | #define ERR_RETRY 2 |
| 569 | #define ERR_ABORT 1 | 645 | #define ERR_ABORT 1 |
| 570 | #define ERR_CONTINUE 0 | 646 | #define ERR_CONTINUE 0 |
| @@ -632,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, | |||
| 632 | u32 status, stop_status = 0; | 708 | u32 status, stop_status = 0; |
| 633 | int err, retry; | 709 | int err, retry; |
| 634 | 710 | ||
| 711 | if (mmc_card_removed(card)) | ||
| 712 | return ERR_NOMEDIUM; | ||
| 713 | |||
| 635 | /* | 714 | /* |
| 636 | * Try to get card status which indicates both the card state | 715 | * Try to get card status which indicates both the card state |
| 637 | * and why there was no response. If the first attempt fails, | 716 | * and why there was no response. If the first attempt fails, |
| @@ -648,8 +727,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, | |||
| 648 | } | 727 | } |
| 649 | 728 | ||
| 650 | /* We couldn't get a response from the card. Give up. */ | 729 | /* We couldn't get a response from the card. Give up. */ |
| 651 | if (err) | 730 | if (err) { |
| 731 | /* Check if the card is removed */ | ||
| 732 | if (mmc_detect_card_removed(card->host)) | ||
| 733 | return ERR_NOMEDIUM; | ||
| 652 | return ERR_ABORT; | 734 | return ERR_ABORT; |
| 735 | } | ||
| 653 | 736 | ||
| 654 | /* Flag ECC errors */ | 737 | /* Flag ECC errors */ |
| 655 | if ((status & R1_CARD_ECC_FAILED) || | 738 | if ((status & R1_CARD_ECC_FAILED) || |
| @@ -922,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card, | |||
| 922 | return MMC_BLK_RETRY; | 1005 | return MMC_BLK_RETRY; |
| 923 | case ERR_ABORT: | 1006 | case ERR_ABORT: |
| 924 | return MMC_BLK_ABORT; | 1007 | return MMC_BLK_ABORT; |
| 1008 | case ERR_NOMEDIUM: | ||
| 1009 | return MMC_BLK_NOMEDIUM; | ||
| 925 | case ERR_CONTINUE: | 1010 | case ERR_CONTINUE: |
| 926 | break; | 1011 | break; |
| 927 | } | 1012 | } |
| @@ -1255,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
| 1255 | if (!ret) | 1340 | if (!ret) |
| 1256 | goto start_new_req; | 1341 | goto start_new_req; |
| 1257 | break; | 1342 | break; |
| 1343 | case MMC_BLK_NOMEDIUM: | ||
| 1344 | goto cmd_abort; | ||
| 1258 | } | 1345 | } |
| 1259 | 1346 | ||
| 1260 | if (ret) { | 1347 | if (ret) { |
| @@ -1271,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
| 1271 | 1358 | ||
| 1272 | cmd_abort: | 1359 | cmd_abort: |
| 1273 | spin_lock_irq(&md->lock); | 1360 | spin_lock_irq(&md->lock); |
| 1361 | if (mmc_card_removed(card)) | ||
| 1362 | req->cmd_flags |= REQ_QUIET; | ||
| 1274 | while (ret) | 1363 | while (ret) |
| 1275 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); | 1364 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); |
| 1276 | spin_unlock_irq(&md->lock); | 1365 | spin_unlock_irq(&md->lock); |
| @@ -1339,7 +1428,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
| 1339 | struct device *parent, | 1428 | struct device *parent, |
| 1340 | sector_t size, | 1429 | sector_t size, |
| 1341 | bool default_ro, | 1430 | bool default_ro, |
| 1342 | const char *subname) | 1431 | const char *subname, |
| 1432 | int area_type) | ||
| 1343 | { | 1433 | { |
| 1344 | struct mmc_blk_data *md; | 1434 | struct mmc_blk_data *md; |
| 1345 | int devidx, ret; | 1435 | int devidx, ret; |
| @@ -1364,11 +1454,12 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
| 1364 | if (!subname) { | 1454 | if (!subname) { |
| 1365 | md->name_idx = find_first_zero_bit(name_use, max_devices); | 1455 | md->name_idx = find_first_zero_bit(name_use, max_devices); |
| 1366 | __set_bit(md->name_idx, name_use); | 1456 | __set_bit(md->name_idx, name_use); |
| 1367 | } | 1457 | } else |
| 1368 | else | ||
| 1369 | md->name_idx = ((struct mmc_blk_data *) | 1458 | md->name_idx = ((struct mmc_blk_data *) |
| 1370 | dev_to_disk(parent)->private_data)->name_idx; | 1459 | dev_to_disk(parent)->private_data)->name_idx; |
| 1371 | 1460 | ||
| 1461 | md->area_type = area_type; | ||
| 1462 | |||
| 1372 | /* | 1463 | /* |
| 1373 | * Set the read-only status based on the supported commands | 1464 | * Set the read-only status based on the supported commands |
| 1374 | * and the write protect switch. | 1465 | * and the write protect switch. |
| @@ -1462,7 +1553,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
| 1462 | size = card->csd.capacity << (card->csd.read_blkbits - 9); | 1553 | size = card->csd.capacity << (card->csd.read_blkbits - 9); |
| 1463 | } | 1554 | } |
| 1464 | 1555 | ||
| 1465 | md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL); | 1556 | md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL, |
| 1557 | MMC_BLK_DATA_AREA_MAIN); | ||
| 1466 | return md; | 1558 | return md; |
| 1467 | } | 1559 | } |
| 1468 | 1560 | ||
| @@ -1471,13 +1563,14 @@ static int mmc_blk_alloc_part(struct mmc_card *card, | |||
| 1471 | unsigned int part_type, | 1563 | unsigned int part_type, |
| 1472 | sector_t size, | 1564 | sector_t size, |
| 1473 | bool default_ro, | 1565 | bool default_ro, |
| 1474 | const char *subname) | 1566 | const char *subname, |
| 1567 | int area_type) | ||
| 1475 | { | 1568 | { |
| 1476 | char cap_str[10]; | 1569 | char cap_str[10]; |
| 1477 | struct mmc_blk_data *part_md; | 1570 | struct mmc_blk_data *part_md; |
| 1478 | 1571 | ||
| 1479 | part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, | 1572 | part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, |
| 1480 | subname); | 1573 | subname, area_type); |
| 1481 | if (IS_ERR(part_md)) | 1574 | if (IS_ERR(part_md)) |
| 1482 | return PTR_ERR(part_md); | 1575 | return PTR_ERR(part_md); |
| 1483 | part_md->part_type = part_type; | 1576 | part_md->part_type = part_type; |
| @@ -1510,7 +1603,8 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) | |||
| 1510 | card->part[idx].part_cfg, | 1603 | card->part[idx].part_cfg, |
| 1511 | card->part[idx].size >> 9, | 1604 | card->part[idx].size >> 9, |
| 1512 | card->part[idx].force_ro, | 1605 | card->part[idx].force_ro, |
| 1513 | card->part[idx].name); | 1606 | card->part[idx].name, |
| 1607 | card->part[idx].area_type); | ||
| 1514 | if (ret) | 1608 | if (ret) |
| 1515 | return ret; | 1609 | return ret; |
| 1516 | } | 1610 | } |
| @@ -1539,9 +1633,16 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
| 1539 | 1633 | ||
| 1540 | static void mmc_blk_remove_req(struct mmc_blk_data *md) | 1634 | static void mmc_blk_remove_req(struct mmc_blk_data *md) |
| 1541 | { | 1635 | { |
| 1636 | struct mmc_card *card; | ||
| 1637 | |||
| 1542 | if (md) { | 1638 | if (md) { |
| 1639 | card = md->queue.card; | ||
| 1543 | if (md->disk->flags & GENHD_FL_UP) { | 1640 | if (md->disk->flags & GENHD_FL_UP) { |
| 1544 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); | 1641 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); |
| 1642 | if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && | ||
| 1643 | card->ext_csd.boot_ro_lockable) | ||
| 1644 | device_remove_file(disk_to_dev(md->disk), | ||
| 1645 | &md->power_ro_lock); | ||
| 1545 | 1646 | ||
| 1546 | /* Stop new requests from getting into the queue */ | 1647 | /* Stop new requests from getting into the queue */ |
| 1547 | del_gendisk(md->disk); | 1648 | del_gendisk(md->disk); |
| @@ -1570,6 +1671,7 @@ static void mmc_blk_remove_parts(struct mmc_card *card, | |||
| 1570 | static int mmc_add_disk(struct mmc_blk_data *md) | 1671 | static int mmc_add_disk(struct mmc_blk_data *md) |
| 1571 | { | 1672 | { |
| 1572 | int ret; | 1673 | int ret; |
| 1674 | struct mmc_card *card = md->queue.card; | ||
| 1573 | 1675 | ||
| 1574 | add_disk(md->disk); | 1676 | add_disk(md->disk); |
| 1575 | md->force_ro.show = force_ro_show; | 1677 | md->force_ro.show = force_ro_show; |
| @@ -1579,18 +1681,53 @@ static int mmc_add_disk(struct mmc_blk_data *md) | |||
| 1579 | md->force_ro.attr.mode = S_IRUGO | S_IWUSR; | 1681 | md->force_ro.attr.mode = S_IRUGO | S_IWUSR; |
| 1580 | ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); | 1682 | ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); |
| 1581 | if (ret) | 1683 | if (ret) |
| 1582 | del_gendisk(md->disk); | 1684 | goto force_ro_fail; |
| 1685 | |||
| 1686 | if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && | ||
| 1687 | card->ext_csd.boot_ro_lockable) { | ||
| 1688 | mode_t mode; | ||
| 1689 | |||
| 1690 | if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_DIS) | ||
| 1691 | mode = S_IRUGO; | ||
| 1692 | else | ||
| 1693 | mode = S_IRUGO | S_IWUSR; | ||
| 1694 | |||
| 1695 | md->power_ro_lock.show = power_ro_lock_show; | ||
| 1696 | md->power_ro_lock.store = power_ro_lock_store; | ||
| 1697 | md->power_ro_lock.attr.mode = mode; | ||
| 1698 | md->power_ro_lock.attr.name = | ||
| 1699 | "ro_lock_until_next_power_on"; | ||
| 1700 | ret = device_create_file(disk_to_dev(md->disk), | ||
| 1701 | &md->power_ro_lock); | ||
| 1702 | if (ret) | ||
| 1703 | goto power_ro_lock_fail; | ||
| 1704 | } | ||
| 1705 | return ret; | ||
| 1706 | |||
| 1707 | power_ro_lock_fail: | ||
| 1708 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); | ||
| 1709 | force_ro_fail: | ||
| 1710 | del_gendisk(md->disk); | ||
| 1583 | 1711 | ||
| 1584 | return ret; | 1712 | return ret; |
| 1585 | } | 1713 | } |
| 1586 | 1714 | ||
| 1715 | #define CID_MANFID_SANDISK 0x2 | ||
| 1716 | #define CID_MANFID_TOSHIBA 0x11 | ||
| 1717 | #define CID_MANFID_MICRON 0x13 | ||
| 1718 | |||
| 1587 | static const struct mmc_fixup blk_fixups[] = | 1719 | static const struct mmc_fixup blk_fixups[] = |
| 1588 | { | 1720 | { |
| 1589 | MMC_FIXUP("SEM02G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1721 | MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk, |
| 1590 | MMC_FIXUP("SEM04G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1722 | MMC_QUIRK_INAND_CMD38), |
| 1591 | MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1723 | MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk, |
| 1592 | MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1724 | MMC_QUIRK_INAND_CMD38), |
| 1593 | MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1725 | MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk, |
| 1726 | MMC_QUIRK_INAND_CMD38), | ||
| 1727 | MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
| 1728 | MMC_QUIRK_INAND_CMD38), | ||
| 1729 | MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
| 1730 | MMC_QUIRK_INAND_CMD38), | ||
| 1594 | 1731 | ||
| 1595 | /* | 1732 | /* |
| 1596 | * Some MMC cards experience performance degradation with CMD23 | 1733 | * Some MMC cards experience performance degradation with CMD23 |
| @@ -1600,18 +1737,18 @@ static const struct mmc_fixup blk_fixups[] = | |||
| 1600 | * | 1737 | * |
| 1601 | * N.B. This doesn't affect SD cards. | 1738 | * N.B. This doesn't affect SD cards. |
| 1602 | */ | 1739 | */ |
| 1603 | MMC_FIXUP("MMC08G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1740 | MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
| 1604 | MMC_QUIRK_BLK_NO_CMD23), | 1741 | MMC_QUIRK_BLK_NO_CMD23), |
| 1605 | MMC_FIXUP("MMC16G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1742 | MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
| 1606 | MMC_QUIRK_BLK_NO_CMD23), | 1743 | MMC_QUIRK_BLK_NO_CMD23), |
| 1607 | MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1744 | MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
| 1608 | MMC_QUIRK_BLK_NO_CMD23), | 1745 | MMC_QUIRK_BLK_NO_CMD23), |
| 1609 | 1746 | ||
| 1610 | /* | 1747 | /* |
| 1611 | * Some Micron MMC cards needs longer data read timeout than | 1748 | * Some Micron MMC cards needs longer data read timeout than |
| 1612 | * indicated in CSD. | 1749 | * indicated in CSD. |
| 1613 | */ | 1750 | */ |
| 1614 | MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc, | 1751 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, |
| 1615 | MMC_QUIRK_LONG_READ_TIME), | 1752 | MMC_QUIRK_LONG_READ_TIME), |
| 1616 | 1753 | ||
| 1617 | END_FIXUP | 1754 | END_FIXUP |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index e99bdc18002..759714ed6be 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
| @@ -1581,6 +1581,7 @@ static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill) | |||
| 1581 | 1581 | ||
| 1582 | t->max_segs = test->card->host->max_segs; | 1582 | t->max_segs = test->card->host->max_segs; |
| 1583 | t->max_seg_sz = test->card->host->max_seg_size; | 1583 | t->max_seg_sz = test->card->host->max_seg_size; |
| 1584 | t->max_seg_sz -= t->max_seg_sz % 512; | ||
| 1584 | 1585 | ||
| 1585 | t->max_tfr = t->max_sz; | 1586 | t->max_tfr = t->max_sz; |
| 1586 | if (t->max_tfr >> 9 > test->card->host->max_blk_count) | 1587 | if (t->max_tfr >> 9 > test->card->host->max_blk_count) |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index dcad59cbfef..2517547b436 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | */ | 29 | */ |
| 30 | static int mmc_prep_request(struct request_queue *q, struct request *req) | 30 | static int mmc_prep_request(struct request_queue *q, struct request *req) |
| 31 | { | 31 | { |
| 32 | struct mmc_queue *mq = q->queuedata; | ||
| 33 | |||
| 32 | /* | 34 | /* |
| 33 | * We only like normal block requests and discards. | 35 | * We only like normal block requests and discards. |
| 34 | */ | 36 | */ |
| @@ -37,6 +39,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) | |||
| 37 | return BLKPREP_KILL; | 39 | return BLKPREP_KILL; |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 42 | if (mq && mmc_card_removed(mq->card)) | ||
| 43 | return BLKPREP_KILL; | ||
| 44 | |||
| 40 | req->cmd_flags |= REQ_DONTPREP; | 45 | req->cmd_flags |= REQ_DONTPREP; |
| 41 | 46 | ||
| 42 | return BLKPREP_OK; | 47 | return BLKPREP_OK; |
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 639501970b4..dca4428380f 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile | |||
| @@ -7,6 +7,6 @@ mmc_core-y := core.o bus.o host.o \ | |||
| 7 | mmc.o mmc_ops.o sd.o sd_ops.o \ | 7 | mmc.o mmc_ops.o sd.o sd_ops.o \ |
| 8 | sdio.o sdio_ops.o sdio_bus.o \ | 8 | sdio.o sdio_ops.o sdio_bus.o \ |
| 9 | sdio_cis.o sdio_io.o sdio_irq.o \ | 9 | sdio_cis.o sdio_io.o sdio_irq.o \ |
| 10 | quirks.o | 10 | quirks.o cd-gpio.o |
| 11 | 11 | ||
| 12 | mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o | 12 | mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 6be49249895..5d011a39dff 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
| @@ -303,10 +303,11 @@ int mmc_add_card(struct mmc_card *card) | |||
| 303 | mmc_card_ddr_mode(card) ? "DDR " : "", | 303 | mmc_card_ddr_mode(card) ? "DDR " : "", |
| 304 | type); | 304 | type); |
| 305 | } else { | 305 | } else { |
| 306 | printk(KERN_INFO "%s: new %s%s%s card at address %04x\n", | 306 | pr_info("%s: new %s%s%s%s card at address %04x\n", |
| 307 | mmc_hostname(card->host), | 307 | mmc_hostname(card->host), |
| 308 | mmc_sd_card_uhs(card) ? "ultra high speed " : | 308 | mmc_card_uhs(card) ? "ultra high speed " : |
| 309 | (mmc_card_highspeed(card) ? "high speed " : ""), | 309 | (mmc_card_highspeed(card) ? "high speed " : ""), |
| 310 | (mmc_card_hs200(card) ? "HS200 " : ""), | ||
| 310 | mmc_card_ddr_mode(card) ? "DDR " : "", | 311 | mmc_card_ddr_mode(card) ? "DDR " : "", |
| 311 | type, card->rca); | 312 | type, card->rca); |
| 312 | } | 313 | } |
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c new file mode 100644 index 00000000000..082202ae4a0 --- /dev/null +++ b/drivers/mmc/core/cd-gpio.c | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* | ||
| 2 | * Generic GPIO card-detect helper | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
| 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 version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/err.h> | ||
| 12 | #include <linux/gpio.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/jiffies.h> | ||
| 15 | #include <linux/mmc/host.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | |||
| 19 | struct mmc_cd_gpio { | ||
| 20 | unsigned int gpio; | ||
| 21 | char label[0]; | ||
| 22 | }; | ||
| 23 | |||
| 24 | static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id) | ||
| 25 | { | ||
| 26 | /* Schedule a card detection after a debounce timeout */ | ||
| 27 | mmc_detect_change(dev_id, msecs_to_jiffies(100)); | ||
| 28 | return IRQ_HANDLED; | ||
| 29 | } | ||
| 30 | |||
| 31 | int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio, | ||
| 32 | unsigned int irq, unsigned long flags) | ||
| 33 | { | ||
| 34 | size_t len = strlen(dev_name(host->parent)) + 4; | ||
| 35 | struct mmc_cd_gpio *cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL); | ||
| 36 | int ret; | ||
| 37 | |||
| 38 | if (!cd) | ||
| 39 | return -ENOMEM; | ||
| 40 | |||
| 41 | snprintf(cd->label, len, "%s cd", dev_name(host->parent)); | ||
| 42 | |||
| 43 | ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label); | ||
| 44 | if (ret < 0) | ||
| 45 | goto egpioreq; | ||
| 46 | |||
| 47 | ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt, | ||
| 48 | flags, cd->label, host); | ||
| 49 | if (ret < 0) | ||
| 50 | goto eirqreq; | ||
| 51 | |||
| 52 | cd->gpio = gpio; | ||
| 53 | host->hotplug.irq = irq; | ||
| 54 | host->hotplug.handler_priv = cd; | ||
| 55 | |||
| 56 | return 0; | ||
| 57 | |||
| 58 | eirqreq: | ||
| 59 | gpio_free(gpio); | ||
| 60 | egpioreq: | ||
| 61 | kfree(cd); | ||
| 62 | return ret; | ||
| 63 | } | ||
| 64 | EXPORT_SYMBOL(mmc_cd_gpio_request); | ||
| 65 | |||
| 66 | void mmc_cd_gpio_free(struct mmc_host *host) | ||
| 67 | { | ||
| 68 | struct mmc_cd_gpio *cd = host->hotplug.handler_priv; | ||
| 69 | |||
| 70 | free_irq(host->hotplug.irq, host); | ||
| 71 | gpio_free(cd->gpio); | ||
| 72 | kfree(cd); | ||
| 73 | } | ||
| 74 | EXPORT_SYMBOL(mmc_cd_gpio_free); | ||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 950b97d7412..bec0bf21c87 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -140,7 +140,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | |||
| 140 | cmd->retries = 0; | 140 | cmd->retries = 0; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | if (err && cmd->retries) { | 143 | if (err && cmd->retries && !mmc_card_removed(host->card)) { |
| 144 | /* | 144 | /* |
| 145 | * Request starter must handle retries - see | 145 | * Request starter must handle retries - see |
| 146 | * mmc_wait_for_req_done(). | 146 | * mmc_wait_for_req_done(). |
| @@ -247,6 +247,11 @@ static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) | |||
| 247 | { | 247 | { |
| 248 | init_completion(&mrq->completion); | 248 | init_completion(&mrq->completion); |
| 249 | mrq->done = mmc_wait_done; | 249 | mrq->done = mmc_wait_done; |
| 250 | if (mmc_card_removed(host->card)) { | ||
| 251 | mrq->cmd->error = -ENOMEDIUM; | ||
| 252 | complete(&mrq->completion); | ||
| 253 | return; | ||
| 254 | } | ||
| 250 | mmc_start_request(host, mrq); | 255 | mmc_start_request(host, mrq); |
| 251 | } | 256 | } |
| 252 | 257 | ||
| @@ -259,7 +264,8 @@ static void mmc_wait_for_req_done(struct mmc_host *host, | |||
| 259 | wait_for_completion(&mrq->completion); | 264 | wait_for_completion(&mrq->completion); |
| 260 | 265 | ||
| 261 | cmd = mrq->cmd; | 266 | cmd = mrq->cmd; |
| 262 | if (!cmd->error || !cmd->retries) | 267 | if (!cmd->error || !cmd->retries || |
| 268 | mmc_card_removed(host->card)) | ||
| 263 | break; | 269 | break; |
| 264 | 270 | ||
| 265 | pr_debug("%s: req failed (CMD%u): %d, retrying...\n", | 271 | pr_debug("%s: req failed (CMD%u): %d, retrying...\n", |
| @@ -1456,7 +1462,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay) | |||
| 1456 | WARN_ON(host->removed); | 1462 | WARN_ON(host->removed); |
| 1457 | spin_unlock_irqrestore(&host->lock, flags); | 1463 | spin_unlock_irqrestore(&host->lock, flags); |
| 1458 | #endif | 1464 | #endif |
| 1459 | 1465 | host->detect_change = 1; | |
| 1460 | mmc_schedule_delayed_work(&host->detect, delay); | 1466 | mmc_schedule_delayed_work(&host->detect, delay); |
| 1461 | } | 1467 | } |
| 1462 | 1468 | ||
| @@ -2049,6 +2055,43 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) | |||
| 2049 | return -EIO; | 2055 | return -EIO; |
| 2050 | } | 2056 | } |
| 2051 | 2057 | ||
| 2058 | int _mmc_detect_card_removed(struct mmc_host *host) | ||
| 2059 | { | ||
| 2060 | int ret; | ||
| 2061 | |||
| 2062 | if ((host->caps & MMC_CAP_NONREMOVABLE) || !host->bus_ops->alive) | ||
| 2063 | return 0; | ||
| 2064 | |||
| 2065 | if (!host->card || mmc_card_removed(host->card)) | ||
| 2066 | return 1; | ||
| 2067 | |||
| 2068 | ret = host->bus_ops->alive(host); | ||
| 2069 | if (ret) { | ||
| 2070 | mmc_card_set_removed(host->card); | ||
| 2071 | pr_debug("%s: card remove detected\n", mmc_hostname(host)); | ||
| 2072 | } | ||
| 2073 | |||
| 2074 | return ret; | ||
| 2075 | } | ||
| 2076 | |||
| 2077 | int mmc_detect_card_removed(struct mmc_host *host) | ||
| 2078 | { | ||
| 2079 | struct mmc_card *card = host->card; | ||
| 2080 | |||
| 2081 | WARN_ON(!host->claimed); | ||
| 2082 | /* | ||
| 2083 | * The card will be considered unchanged unless we have been asked to | ||
| 2084 | * detect a change or host requires polling to provide card detection. | ||
| 2085 | */ | ||
| 2086 | if (card && !host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL)) | ||
| 2087 | return mmc_card_removed(card); | ||
| 2088 | |||
| 2089 | host->detect_change = 0; | ||
| 2090 | |||
| 2091 | return _mmc_detect_card_removed(host); | ||
| 2092 | } | ||
| 2093 | EXPORT_SYMBOL(mmc_detect_card_removed); | ||
| 2094 | |||
| 2052 | void mmc_rescan(struct work_struct *work) | 2095 | void mmc_rescan(struct work_struct *work) |
| 2053 | { | 2096 | { |
| 2054 | static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; | 2097 | static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; |
| @@ -2069,6 +2112,8 @@ void mmc_rescan(struct work_struct *work) | |||
| 2069 | && !(host->caps & MMC_CAP_NONREMOVABLE)) | 2112 | && !(host->caps & MMC_CAP_NONREMOVABLE)) |
| 2070 | host->bus_ops->detect(host); | 2113 | host->bus_ops->detect(host); |
| 2071 | 2114 | ||
| 2115 | host->detect_change = 0; | ||
| 2116 | |||
| 2072 | /* | 2117 | /* |
| 2073 | * Let mmc_bus_put() free the bus/bus_ops if we've found that | 2118 | * Let mmc_bus_put() free the bus/bus_ops if we've found that |
| 2074 | * the card is no longer present. | 2119 | * the card is no longer present. |
| @@ -2130,6 +2175,7 @@ void mmc_stop_host(struct mmc_host *host) | |||
| 2130 | 2175 | ||
| 2131 | mmc_bus_get(host); | 2176 | mmc_bus_get(host); |
| 2132 | if (host->bus_ops && !host->bus_dead) { | 2177 | if (host->bus_ops && !host->bus_dead) { |
| 2178 | /* Calling bus_ops->remove() with a claimed host can deadlock */ | ||
| 2133 | if (host->bus_ops->remove) | 2179 | if (host->bus_ops->remove) |
| 2134 | host->bus_ops->remove(host); | 2180 | host->bus_ops->remove(host); |
| 2135 | 2181 | ||
| @@ -2201,6 +2247,9 @@ int mmc_card_awake(struct mmc_host *host) | |||
| 2201 | { | 2247 | { |
| 2202 | int err = -ENOSYS; | 2248 | int err = -ENOSYS; |
| 2203 | 2249 | ||
| 2250 | if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) | ||
| 2251 | return 0; | ||
| 2252 | |||
| 2204 | mmc_bus_get(host); | 2253 | mmc_bus_get(host); |
| 2205 | 2254 | ||
| 2206 | if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) | 2255 | if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) |
| @@ -2216,6 +2265,9 @@ int mmc_card_sleep(struct mmc_host *host) | |||
| 2216 | { | 2265 | { |
| 2217 | int err = -ENOSYS; | 2266 | int err = -ENOSYS; |
| 2218 | 2267 | ||
| 2268 | if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) | ||
| 2269 | return 0; | ||
| 2270 | |||
| 2219 | mmc_bus_get(host); | 2271 | mmc_bus_get(host); |
| 2220 | 2272 | ||
| 2221 | if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) | 2273 | if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) |
| @@ -2270,6 +2322,7 @@ EXPORT_SYMBOL(mmc_flush_cache); | |||
| 2270 | int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | 2322 | int mmc_cache_ctrl(struct mmc_host *host, u8 enable) |
| 2271 | { | 2323 | { |
| 2272 | struct mmc_card *card = host->card; | 2324 | struct mmc_card *card = host->card; |
| 2325 | unsigned int timeout; | ||
| 2273 | int err = 0; | 2326 | int err = 0; |
| 2274 | 2327 | ||
| 2275 | if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) || | 2328 | if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) || |
| @@ -2280,16 +2333,18 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | |||
| 2280 | (card->ext_csd.cache_size > 0)) { | 2333 | (card->ext_csd.cache_size > 0)) { |
| 2281 | enable = !!enable; | 2334 | enable = !!enable; |
| 2282 | 2335 | ||
| 2283 | if (card->ext_csd.cache_ctrl ^ enable) | 2336 | if (card->ext_csd.cache_ctrl ^ enable) { |
| 2337 | timeout = enable ? card->ext_csd.generic_cmd6_time : 0; | ||
| 2284 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 2338 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
| 2285 | EXT_CSD_CACHE_CTRL, enable, 0); | 2339 | EXT_CSD_CACHE_CTRL, enable, timeout); |
| 2286 | if (err) | 2340 | if (err) |
| 2287 | pr_err("%s: cache %s error %d\n", | 2341 | pr_err("%s: cache %s error %d\n", |
| 2288 | mmc_hostname(card->host), | 2342 | mmc_hostname(card->host), |
| 2289 | enable ? "on" : "off", | 2343 | enable ? "on" : "off", |
| 2290 | err); | 2344 | err); |
| 2291 | else | 2345 | else |
| 2292 | card->ext_csd.cache_ctrl = enable; | 2346 | card->ext_csd.cache_ctrl = enable; |
| 2347 | } | ||
| 2293 | } | 2348 | } |
| 2294 | 2349 | ||
| 2295 | return err; | 2350 | return err; |
| @@ -2310,7 +2365,13 @@ int mmc_suspend_host(struct mmc_host *host) | |||
| 2310 | cancel_delayed_work(&host->disable); | 2365 | cancel_delayed_work(&host->disable); |
| 2311 | cancel_delayed_work(&host->detect); | 2366 | cancel_delayed_work(&host->detect); |
| 2312 | mmc_flush_scheduled_work(); | 2367 | mmc_flush_scheduled_work(); |
| 2313 | err = mmc_cache_ctrl(host, 0); | 2368 | if (mmc_try_claim_host(host)) { |
| 2369 | err = mmc_cache_ctrl(host, 0); | ||
| 2370 | mmc_do_release_host(host); | ||
| 2371 | } else { | ||
| 2372 | err = -EBUSY; | ||
| 2373 | } | ||
| 2374 | |||
| 2314 | if (err) | 2375 | if (err) |
| 2315 | goto out; | 2376 | goto out; |
| 2316 | 2377 | ||
| @@ -2338,7 +2399,9 @@ int mmc_suspend_host(struct mmc_host *host) | |||
| 2338 | if (err == -ENOSYS || !host->bus_ops->resume) { | 2399 | if (err == -ENOSYS || !host->bus_ops->resume) { |
| 2339 | /* | 2400 | /* |
| 2340 | * We simply "remove" the card in this case. | 2401 | * We simply "remove" the card in this case. |
| 2341 | * It will be redetected on resume. | 2402 | * It will be redetected on resume. (Calling |
| 2403 | * bus_ops->remove() with a claimed host can | ||
| 2404 | * deadlock.) | ||
| 2342 | */ | 2405 | */ |
| 2343 | if (host->bus_ops->remove) | 2406 | if (host->bus_ops->remove) |
| 2344 | host->bus_ops->remove(host); | 2407 | host->bus_ops->remove(host); |
| @@ -2431,11 +2494,11 @@ int mmc_pm_notify(struct notifier_block *notify_block, | |||
| 2431 | if (!host->bus_ops || host->bus_ops->suspend) | 2494 | if (!host->bus_ops || host->bus_ops->suspend) |
| 2432 | break; | 2495 | break; |
| 2433 | 2496 | ||
| 2434 | mmc_claim_host(host); | 2497 | /* Calling bus_ops->remove() with a claimed host can deadlock */ |
| 2435 | |||
| 2436 | if (host->bus_ops->remove) | 2498 | if (host->bus_ops->remove) |
| 2437 | host->bus_ops->remove(host); | 2499 | host->bus_ops->remove(host); |
| 2438 | 2500 | ||
| 2501 | mmc_claim_host(host); | ||
| 2439 | mmc_detach_bus(host); | 2502 | mmc_detach_bus(host); |
| 2440 | mmc_power_off(host); | 2503 | mmc_power_off(host); |
| 2441 | mmc_release_host(host); | 2504 | mmc_release_host(host); |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 14664f1fb16..34009241213 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
| @@ -24,6 +24,7 @@ struct mmc_bus_ops { | |||
| 24 | int (*resume)(struct mmc_host *); | 24 | int (*resume)(struct mmc_host *); |
| 25 | int (*power_save)(struct mmc_host *); | 25 | int (*power_save)(struct mmc_host *); |
| 26 | int (*power_restore)(struct mmc_host *); | 26 | int (*power_restore)(struct mmc_host *); |
| 27 | int (*alive)(struct mmc_host *); | ||
| 27 | }; | 28 | }; |
| 28 | 29 | ||
| 29 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 30 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
| @@ -59,6 +60,8 @@ void mmc_rescan(struct work_struct *work); | |||
| 59 | void mmc_start_host(struct mmc_host *host); | 60 | void mmc_start_host(struct mmc_host *host); |
| 60 | void mmc_stop_host(struct mmc_host *host); | 61 | void mmc_stop_host(struct mmc_host *host); |
| 61 | 62 | ||
| 63 | int _mmc_detect_card_removed(struct mmc_host *host); | ||
| 64 | |||
| 62 | int mmc_attach_mmc(struct mmc_host *host); | 65 | int mmc_attach_mmc(struct mmc_host *host); |
| 63 | int mmc_attach_sd(struct mmc_host *host); | 66 | int mmc_attach_sd(struct mmc_host *host); |
| 64 | int mmc_attach_sdio(struct mmc_host *host); | 67 | int mmc_attach_sdio(struct mmc_host *host); |
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 3923880118b..9ab5b17d488 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
| @@ -57,6 +57,8 @@ static int mmc_ios_show(struct seq_file *s, void *data) | |||
| 57 | const char *str; | 57 | const char *str; |
| 58 | 58 | ||
| 59 | seq_printf(s, "clock:\t\t%u Hz\n", ios->clock); | 59 | seq_printf(s, "clock:\t\t%u Hz\n", ios->clock); |
| 60 | if (host->actual_clock) | ||
| 61 | seq_printf(s, "actual clock:\t%u Hz\n", host->actual_clock); | ||
| 60 | seq_printf(s, "vdd:\t\t%u ", ios->vdd); | 62 | seq_printf(s, "vdd:\t\t%u ", ios->vdd); |
| 61 | if ((1 << ios->vdd) & MMC_VDD_165_195) | 63 | if ((1 << ios->vdd) & MMC_VDD_165_195) |
| 62 | seq_printf(s, "(1.65 - 1.95 V)\n"); | 64 | seq_printf(s, "(1.65 - 1.95 V)\n"); |
| @@ -133,6 +135,9 @@ static int mmc_ios_show(struct seq_file *s, void *data) | |||
| 133 | case MMC_TIMING_UHS_DDR50: | 135 | case MMC_TIMING_UHS_DDR50: |
| 134 | str = "sd uhs DDR50"; | 136 | str = "sd uhs DDR50"; |
| 135 | break; | 137 | break; |
| 138 | case MMC_TIMING_MMC_HS200: | ||
| 139 | str = "mmc high-speed SDR200"; | ||
| 140 | break; | ||
| 136 | default: | 141 | default: |
| 137 | str = "invalid"; | 142 | str = "invalid"; |
| 138 | break; | 143 | break; |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index d31c78b72b0..30055f2b0d4 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
| @@ -54,6 +54,27 @@ static DEFINE_IDR(mmc_host_idr); | |||
| 54 | static DEFINE_SPINLOCK(mmc_host_lock); | 54 | static DEFINE_SPINLOCK(mmc_host_lock); |
| 55 | 55 | ||
| 56 | #ifdef CONFIG_MMC_CLKGATE | 56 | #ifdef CONFIG_MMC_CLKGATE |
| 57 | static ssize_t clkgate_delay_show(struct device *dev, | ||
| 58 | struct device_attribute *attr, char *buf) | ||
| 59 | { | ||
| 60 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | ||
| 61 | return snprintf(buf, PAGE_SIZE, "%lu\n", host->clkgate_delay); | ||
| 62 | } | ||
| 63 | |||
| 64 | static ssize_t clkgate_delay_store(struct device *dev, | ||
| 65 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 66 | { | ||
| 67 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | ||
| 68 | unsigned long flags, value; | ||
| 69 | |||
| 70 | if (kstrtoul(buf, 0, &value)) | ||
| 71 | return -EINVAL; | ||
| 72 | |||
| 73 | spin_lock_irqsave(&host->clk_lock, flags); | ||
| 74 | host->clkgate_delay = value; | ||
| 75 | spin_unlock_irqrestore(&host->clk_lock, flags); | ||
| 76 | return count; | ||
| 77 | } | ||
| 57 | 78 | ||
| 58 | /* | 79 | /* |
| 59 | * Enabling clock gating will make the core call out to the host | 80 | * Enabling clock gating will make the core call out to the host |
| @@ -114,7 +135,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) | |||
| 114 | static void mmc_host_clk_gate_work(struct work_struct *work) | 135 | static void mmc_host_clk_gate_work(struct work_struct *work) |
| 115 | { | 136 | { |
| 116 | struct mmc_host *host = container_of(work, struct mmc_host, | 137 | struct mmc_host *host = container_of(work, struct mmc_host, |
| 117 | clk_gate_work); | 138 | clk_gate_work.work); |
| 118 | 139 | ||
| 119 | mmc_host_clk_gate_delayed(host); | 140 | mmc_host_clk_gate_delayed(host); |
| 120 | } | 141 | } |
| @@ -131,6 +152,8 @@ void mmc_host_clk_hold(struct mmc_host *host) | |||
| 131 | { | 152 | { |
| 132 | unsigned long flags; | 153 | unsigned long flags; |
| 133 | 154 | ||
| 155 | /* cancel any clock gating work scheduled by mmc_host_clk_release() */ | ||
| 156 | cancel_delayed_work_sync(&host->clk_gate_work); | ||
| 134 | mutex_lock(&host->clk_gate_mutex); | 157 | mutex_lock(&host->clk_gate_mutex); |
| 135 | spin_lock_irqsave(&host->clk_lock, flags); | 158 | spin_lock_irqsave(&host->clk_lock, flags); |
| 136 | if (host->clk_gated) { | 159 | if (host->clk_gated) { |
| @@ -180,7 +203,8 @@ void mmc_host_clk_release(struct mmc_host *host) | |||
| 180 | host->clk_requests--; | 203 | host->clk_requests--; |
| 181 | if (mmc_host_may_gate_card(host->card) && | 204 | if (mmc_host_may_gate_card(host->card) && |
| 182 | !host->clk_requests) | 205 | !host->clk_requests) |
| 183 | queue_work(system_nrt_wq, &host->clk_gate_work); | 206 | queue_delayed_work(system_nrt_wq, &host->clk_gate_work, |
| 207 | msecs_to_jiffies(host->clkgate_delay)); | ||
| 184 | spin_unlock_irqrestore(&host->clk_lock, flags); | 208 | spin_unlock_irqrestore(&host->clk_lock, flags); |
| 185 | } | 209 | } |
| 186 | 210 | ||
| @@ -213,8 +237,13 @@ static inline void mmc_host_clk_init(struct mmc_host *host) | |||
| 213 | host->clk_requests = 0; | 237 | host->clk_requests = 0; |
| 214 | /* Hold MCI clock for 8 cycles by default */ | 238 | /* Hold MCI clock for 8 cycles by default */ |
| 215 | host->clk_delay = 8; | 239 | host->clk_delay = 8; |
| 240 | /* | ||
| 241 | * Default clock gating delay is 200ms. | ||
| 242 | * This value can be tuned by writing into sysfs entry. | ||
| 243 | */ | ||
| 244 | host->clkgate_delay = 200; | ||
| 216 | host->clk_gated = false; | 245 | host->clk_gated = false; |
| 217 | INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); | 246 | INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); |
| 218 | spin_lock_init(&host->clk_lock); | 247 | spin_lock_init(&host->clk_lock); |
| 219 | mutex_init(&host->clk_gate_mutex); | 248 | mutex_init(&host->clk_gate_mutex); |
| 220 | } | 249 | } |
| @@ -229,7 +258,7 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) | |||
| 229 | * Wait for any outstanding gate and then make sure we're | 258 | * Wait for any outstanding gate and then make sure we're |
| 230 | * ungated before exiting. | 259 | * ungated before exiting. |
| 231 | */ | 260 | */ |
| 232 | if (cancel_work_sync(&host->clk_gate_work)) | 261 | if (cancel_delayed_work_sync(&host->clk_gate_work)) |
| 233 | mmc_host_clk_gate_delayed(host); | 262 | mmc_host_clk_gate_delayed(host); |
| 234 | if (host->clk_gated) | 263 | if (host->clk_gated) |
| 235 | mmc_host_clk_hold(host); | 264 | mmc_host_clk_hold(host); |
| @@ -237,6 +266,17 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) | |||
| 237 | WARN_ON(host->clk_requests > 1); | 266 | WARN_ON(host->clk_requests > 1); |
| 238 | } | 267 | } |
| 239 | 268 | ||
| 269 | static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) | ||
| 270 | { | ||
| 271 | host->clkgate_delay_attr.show = clkgate_delay_show; | ||
| 272 | host->clkgate_delay_attr.store = clkgate_delay_store; | ||
| 273 | sysfs_attr_init(&host->clkgate_delay_attr.attr); | ||
| 274 | host->clkgate_delay_attr.attr.name = "clkgate_delay"; | ||
| 275 | host->clkgate_delay_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
| 276 | if (device_create_file(&host->class_dev, &host->clkgate_delay_attr)) | ||
| 277 | pr_err("%s: Failed to create clkgate_delay sysfs entry\n", | ||
| 278 | mmc_hostname(host)); | ||
| 279 | } | ||
| 240 | #else | 280 | #else |
| 241 | 281 | ||
| 242 | static inline void mmc_host_clk_init(struct mmc_host *host) | 282 | static inline void mmc_host_clk_init(struct mmc_host *host) |
| @@ -247,6 +287,10 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) | |||
| 247 | { | 287 | { |
| 248 | } | 288 | } |
| 249 | 289 | ||
| 290 | static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) | ||
| 291 | { | ||
| 292 | } | ||
| 293 | |||
| 250 | #endif | 294 | #endif |
| 251 | 295 | ||
| 252 | /** | 296 | /** |
| @@ -335,6 +379,7 @@ int mmc_add_host(struct mmc_host *host) | |||
| 335 | #ifdef CONFIG_DEBUG_FS | 379 | #ifdef CONFIG_DEBUG_FS |
| 336 | mmc_add_host_debugfs(host); | 380 | mmc_add_host_debugfs(host); |
| 337 | #endif | 381 | #endif |
| 382 | mmc_host_clk_sysfs_init(host); | ||
| 338 | 383 | ||
| 339 | mmc_start_host(host); | 384 | mmc_start_host(host); |
| 340 | register_pm_notifier(&host->pm_notify); | 385 | register_pm_notifier(&host->pm_notify); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index d240427c124..59b9ba52e66 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
| @@ -286,6 +286,27 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
| 286 | } | 286 | } |
| 287 | card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; | 287 | card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; |
| 288 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { | 288 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { |
| 289 | case EXT_CSD_CARD_TYPE_SDR_ALL: | ||
| 290 | case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V: | ||
| 291 | case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V: | ||
| 292 | case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52: | ||
| 293 | card->ext_csd.hs_max_dtr = 200000000; | ||
| 294 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200; | ||
| 295 | break; | ||
| 296 | case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL: | ||
| 297 | case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V: | ||
| 298 | case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V: | ||
| 299 | case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52: | ||
| 300 | card->ext_csd.hs_max_dtr = 200000000; | ||
| 301 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V; | ||
| 302 | break; | ||
| 303 | case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL: | ||
| 304 | case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V: | ||
| 305 | case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V: | ||
| 306 | case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52: | ||
| 307 | card->ext_csd.hs_max_dtr = 200000000; | ||
| 308 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V; | ||
| 309 | break; | ||
| 289 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | | 310 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | |
| 290 | EXT_CSD_CARD_TYPE_26: | 311 | EXT_CSD_CARD_TYPE_26: |
| 291 | card->ext_csd.hs_max_dtr = 52000000; | 312 | card->ext_csd.hs_max_dtr = 52000000; |
| @@ -348,7 +369,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
| 348 | part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; | 369 | part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; |
| 349 | mmc_part_add(card, part_size, | 370 | mmc_part_add(card, part_size, |
| 350 | EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, | 371 | EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, |
| 351 | "boot%d", idx, true); | 372 | "boot%d", idx, true, |
| 373 | MMC_BLK_DATA_AREA_BOOT); | ||
| 352 | } | 374 | } |
| 353 | } | 375 | } |
| 354 | } | 376 | } |
| @@ -435,7 +457,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
| 435 | hc_wp_grp_sz); | 457 | hc_wp_grp_sz); |
| 436 | mmc_part_add(card, part_size << 19, | 458 | mmc_part_add(card, part_size << 19, |
| 437 | EXT_CSD_PART_CONFIG_ACC_GP0 + idx, | 459 | EXT_CSD_PART_CONFIG_ACC_GP0 + idx, |
| 438 | "gp%d", idx, false); | 460 | "gp%d", idx, false, |
| 461 | MMC_BLK_DATA_AREA_GP); | ||
| 439 | } | 462 | } |
| 440 | } | 463 | } |
| 441 | card->ext_csd.sec_trim_mult = | 464 | card->ext_csd.sec_trim_mult = |
| @@ -446,6 +469,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
| 446 | ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; | 469 | ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; |
| 447 | card->ext_csd.trim_timeout = 300 * | 470 | card->ext_csd.trim_timeout = 300 * |
| 448 | ext_csd[EXT_CSD_TRIM_MULT]; | 471 | ext_csd[EXT_CSD_TRIM_MULT]; |
| 472 | |||
| 473 | /* | ||
| 474 | * Note that the call to mmc_part_add above defaults to read | ||
| 475 | * only. If this default assumption is changed, the call must | ||
| 476 | * take into account the value of boot_locked below. | ||
| 477 | */ | ||
| 478 | card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP]; | ||
| 479 | card->ext_csd.boot_ro_lockable = true; | ||
| 449 | } | 480 | } |
| 450 | 481 | ||
| 451 | if (card->ext_csd.rev >= 5) { | 482 | if (card->ext_csd.rev >= 5) { |
| @@ -690,6 +721,79 @@ static int mmc_select_powerclass(struct mmc_card *card, | |||
| 690 | } | 721 | } |
| 691 | 722 | ||
| 692 | /* | 723 | /* |
| 724 | * Selects the desired buswidth and switch to the HS200 mode | ||
| 725 | * if bus width set without error | ||
| 726 | */ | ||
| 727 | static int mmc_select_hs200(struct mmc_card *card) | ||
| 728 | { | ||
| 729 | int idx, err = 0; | ||
| 730 | struct mmc_host *host; | ||
| 731 | static unsigned ext_csd_bits[] = { | ||
| 732 | EXT_CSD_BUS_WIDTH_4, | ||
| 733 | EXT_CSD_BUS_WIDTH_8, | ||
| 734 | }; | ||
| 735 | static unsigned bus_widths[] = { | ||
| 736 | MMC_BUS_WIDTH_4, | ||
| 737 | MMC_BUS_WIDTH_8, | ||
| 738 | }; | ||
| 739 | |||
| 740 | BUG_ON(!card); | ||
| 741 | |||
| 742 | host = card->host; | ||
| 743 | |||
| 744 | if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V && | ||
| 745 | host->caps2 & MMC_CAP2_HS200_1_2V_SDR) | ||
| 746 | if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0)) | ||
| 747 | err = mmc_set_signal_voltage(host, | ||
| 748 | MMC_SIGNAL_VOLTAGE_180, 0); | ||
| 749 | |||
| 750 | /* If fails try again during next card power cycle */ | ||
| 751 | if (err) | ||
| 752 | goto err; | ||
| 753 | |||
| 754 | idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 1 : 0; | ||
| 755 | |||
| 756 | /* | ||
| 757 | * Unlike SD, MMC cards dont have a configuration register to notify | ||
| 758 | * supported bus width. So bus test command should be run to identify | ||
| 759 | * the supported bus width or compare the ext csd values of current | ||
| 760 | * bus width and ext csd values of 1 bit mode read earlier. | ||
| 761 | */ | ||
| 762 | for (; idx >= 0; idx--) { | ||
| 763 | |||
| 764 | /* | ||
| 765 | * Host is capable of 8bit transfer, then switch | ||
| 766 | * the device to work in 8bit transfer mode. If the | ||
| 767 | * mmc switch command returns error then switch to | ||
| 768 | * 4bit transfer mode. On success set the corresponding | ||
| 769 | * bus width on the host. | ||
| 770 | */ | ||
| 771 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
| 772 | EXT_CSD_BUS_WIDTH, | ||
| 773 | ext_csd_bits[idx], | ||
| 774 | card->ext_csd.generic_cmd6_time); | ||
| 775 | if (err) | ||
| 776 | continue; | ||
| 777 | |||
| 778 | mmc_set_bus_width(card->host, bus_widths[idx]); | ||
| 779 | |||
| 780 | if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) | ||
| 781 | err = mmc_compare_ext_csds(card, bus_widths[idx]); | ||
| 782 | else | ||
| 783 | err = mmc_bus_test(card, bus_widths[idx]); | ||
| 784 | if (!err) | ||
| 785 | break; | ||
| 786 | } | ||
| 787 | |||
| 788 | /* switch to HS200 mode if bus width set successfully */ | ||
| 789 | if (!err) | ||
| 790 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
| 791 | EXT_CSD_HS_TIMING, 2, 0); | ||
| 792 | err: | ||
| 793 | return err; | ||
| 794 | } | ||
| 795 | |||
| 796 | /* | ||
| 693 | * Handle the detection and initialisation of a card. | 797 | * Handle the detection and initialisation of a card. |
| 694 | * | 798 | * |
| 695 | * In the case of a resume, "oldcard" will contain the card | 799 | * In the case of a resume, "oldcard" will contain the card |
| @@ -895,11 +999,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 895 | /* | 999 | /* |
| 896 | * Activate high speed (if supported) | 1000 | * Activate high speed (if supported) |
| 897 | */ | 1001 | */ |
| 898 | if ((card->ext_csd.hs_max_dtr != 0) && | 1002 | if (card->ext_csd.hs_max_dtr != 0) { |
| 899 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { | 1003 | err = 0; |
| 900 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1004 | if (card->ext_csd.hs_max_dtr > 52000000 && |
| 901 | EXT_CSD_HS_TIMING, 1, | 1005 | host->caps2 & MMC_CAP2_HS200) |
| 902 | card->ext_csd.generic_cmd6_time); | 1006 | err = mmc_select_hs200(card); |
| 1007 | else if (host->caps & MMC_CAP_MMC_HIGHSPEED) | ||
| 1008 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
| 1009 | EXT_CSD_HS_TIMING, 1, 0); | ||
| 1010 | |||
| 903 | if (err && err != -EBADMSG) | 1011 | if (err && err != -EBADMSG) |
| 904 | goto free_card; | 1012 | goto free_card; |
| 905 | 1013 | ||
| @@ -908,8 +1016,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 908 | mmc_hostname(card->host)); | 1016 | mmc_hostname(card->host)); |
| 909 | err = 0; | 1017 | err = 0; |
| 910 | } else { | 1018 | } else { |
| 911 | mmc_card_set_highspeed(card); | 1019 | if (card->ext_csd.hs_max_dtr > 52000000 && |
| 912 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | 1020 | host->caps2 & MMC_CAP2_HS200) { |
| 1021 | mmc_card_set_hs200(card); | ||
| 1022 | mmc_set_timing(card->host, | ||
| 1023 | MMC_TIMING_MMC_HS200); | ||
| 1024 | } else { | ||
| 1025 | mmc_card_set_highspeed(card); | ||
| 1026 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | ||
| 1027 | } | ||
| 913 | } | 1028 | } |
| 914 | } | 1029 | } |
| 915 | 1030 | ||
| @@ -934,7 +1049,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 934 | */ | 1049 | */ |
| 935 | max_dtr = (unsigned int)-1; | 1050 | max_dtr = (unsigned int)-1; |
| 936 | 1051 | ||
| 937 | if (mmc_card_highspeed(card)) { | 1052 | if (mmc_card_highspeed(card) || mmc_card_hs200(card)) { |
| 938 | if (max_dtr > card->ext_csd.hs_max_dtr) | 1053 | if (max_dtr > card->ext_csd.hs_max_dtr) |
| 939 | max_dtr = card->ext_csd.hs_max_dtr; | 1054 | max_dtr = card->ext_csd.hs_max_dtr; |
| 940 | } else if (max_dtr > card->csd.max_dtr) { | 1055 | } else if (max_dtr > card->csd.max_dtr) { |
| @@ -960,9 +1075,48 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 960 | } | 1075 | } |
| 961 | 1076 | ||
| 962 | /* | 1077 | /* |
| 1078 | * Indicate HS200 SDR mode (if supported). | ||
| 1079 | */ | ||
| 1080 | if (mmc_card_hs200(card)) { | ||
| 1081 | u32 ext_csd_bits; | ||
| 1082 | u32 bus_width = card->host->ios.bus_width; | ||
| 1083 | |||
| 1084 | /* | ||
| 1085 | * For devices supporting HS200 mode, the bus width has | ||
| 1086 | * to be set before executing the tuning function. If | ||
| 1087 | * set before tuning, then device will respond with CRC | ||
| 1088 | * errors for responses on CMD line. So for HS200 the | ||
| 1089 | * sequence will be | ||
| 1090 | * 1. set bus width 4bit / 8 bit (1 bit not supported) | ||
| 1091 | * 2. switch to HS200 mode | ||
| 1092 | * 3. set the clock to > 52Mhz <=200MHz and | ||
| 1093 | * 4. execute tuning for HS200 | ||
| 1094 | */ | ||
| 1095 | if ((host->caps2 & MMC_CAP2_HS200) && | ||
| 1096 | card->host->ops->execute_tuning) | ||
| 1097 | err = card->host->ops->execute_tuning(card->host, | ||
| 1098 | MMC_SEND_TUNING_BLOCK_HS200); | ||
| 1099 | if (err) { | ||
| 1100 | pr_warning("%s: tuning execution failed\n", | ||
| 1101 | mmc_hostname(card->host)); | ||
| 1102 | goto err; | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? | ||
| 1106 | EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; | ||
| 1107 | err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); | ||
| 1108 | if (err) { | ||
| 1109 | pr_err("%s: power class selection to bus width %d failed\n", | ||
| 1110 | mmc_hostname(card->host), 1 << bus_width); | ||
| 1111 | goto err; | ||
| 1112 | } | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | /* | ||
| 963 | * Activate wide bus and DDR (if supported). | 1116 | * Activate wide bus and DDR (if supported). |
| 964 | */ | 1117 | */ |
| 965 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && | 1118 | if (!mmc_card_hs200(card) && |
| 1119 | (card->csd.mmca_vsn >= CSD_SPEC_VER_3) && | ||
| 966 | (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { | 1120 | (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { |
| 967 | static unsigned ext_csd_bits[][2] = { | 1121 | static unsigned ext_csd_bits[][2] = { |
| 968 | { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, | 1122 | { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, |
| @@ -1048,7 +1202,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 1048 | * | 1202 | * |
| 1049 | * WARNING: eMMC rules are NOT the same as SD DDR | 1203 | * WARNING: eMMC rules are NOT the same as SD DDR |
| 1050 | */ | 1204 | */ |
| 1051 | if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) { | 1205 | if (ddr == MMC_1_2V_DDR_MODE) { |
| 1052 | err = mmc_set_signal_voltage(host, | 1206 | err = mmc_set_signal_voltage(host, |
| 1053 | MMC_SIGNAL_VOLTAGE_120, 0); | 1207 | MMC_SIGNAL_VOLTAGE_120, 0); |
| 1054 | if (err) | 1208 | if (err) |
| @@ -1067,14 +1221,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 1067 | if ((host->caps2 & MMC_CAP2_CACHE_CTRL) && | 1221 | if ((host->caps2 & MMC_CAP2_CACHE_CTRL) && |
| 1068 | card->ext_csd.cache_size > 0) { | 1222 | card->ext_csd.cache_size > 0) { |
| 1069 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1223 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
| 1070 | EXT_CSD_CACHE_CTRL, 1, 0); | 1224 | EXT_CSD_CACHE_CTRL, 1, |
| 1225 | card->ext_csd.generic_cmd6_time); | ||
| 1071 | if (err && err != -EBADMSG) | 1226 | if (err && err != -EBADMSG) |
| 1072 | goto free_card; | 1227 | goto free_card; |
| 1073 | 1228 | ||
| 1074 | /* | 1229 | /* |
| 1075 | * Only if no error, cache is turned on successfully. | 1230 | * Only if no error, cache is turned on successfully. |
| 1076 | */ | 1231 | */ |
| 1077 | card->ext_csd.cache_ctrl = err ? 0 : 1; | 1232 | if (err) { |
| 1233 | pr_warning("%s: Cache is supported, " | ||
| 1234 | "but failed to turn on (%d)\n", | ||
| 1235 | mmc_hostname(card->host), err); | ||
| 1236 | card->ext_csd.cache_ctrl = 0; | ||
| 1237 | err = 0; | ||
| 1238 | } else { | ||
| 1239 | card->ext_csd.cache_ctrl = 1; | ||
| 1240 | } | ||
| 1078 | } | 1241 | } |
| 1079 | 1242 | ||
| 1080 | if (!oldcard) | 1243 | if (!oldcard) |
| @@ -1105,6 +1268,14 @@ static void mmc_remove(struct mmc_host *host) | |||
| 1105 | } | 1268 | } |
| 1106 | 1269 | ||
| 1107 | /* | 1270 | /* |
| 1271 | * Card detection - card is alive. | ||
| 1272 | */ | ||
| 1273 | static int mmc_alive(struct mmc_host *host) | ||
| 1274 | { | ||
| 1275 | return mmc_send_status(host->card, NULL); | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | /* | ||
| 1108 | * Card detection callback from host. | 1279 | * Card detection callback from host. |
| 1109 | */ | 1280 | */ |
| 1110 | static void mmc_detect(struct mmc_host *host) | 1281 | static void mmc_detect(struct mmc_host *host) |
| @@ -1119,7 +1290,7 @@ static void mmc_detect(struct mmc_host *host) | |||
| 1119 | /* | 1290 | /* |
| 1120 | * Just check if our card has been removed. | 1291 | * Just check if our card has been removed. |
| 1121 | */ | 1292 | */ |
| 1122 | err = mmc_send_status(host->card, NULL); | 1293 | err = _mmc_detect_card_removed(host); |
| 1123 | 1294 | ||
| 1124 | mmc_release_host(host); | 1295 | mmc_release_host(host); |
| 1125 | 1296 | ||
| @@ -1224,6 +1395,7 @@ static const struct mmc_bus_ops mmc_ops = { | |||
| 1224 | .suspend = NULL, | 1395 | .suspend = NULL, |
| 1225 | .resume = NULL, | 1396 | .resume = NULL, |
| 1226 | .power_restore = mmc_power_restore, | 1397 | .power_restore = mmc_power_restore, |
| 1398 | .alive = mmc_alive, | ||
| 1227 | }; | 1399 | }; |
| 1228 | 1400 | ||
| 1229 | static const struct mmc_bus_ops mmc_ops_unsafe = { | 1401 | static const struct mmc_bus_ops mmc_ops_unsafe = { |
| @@ -1234,6 +1406,7 @@ static const struct mmc_bus_ops mmc_ops_unsafe = { | |||
| 1234 | .suspend = mmc_suspend, | 1406 | .suspend = mmc_suspend, |
| 1235 | .resume = mmc_resume, | 1407 | .resume = mmc_resume, |
| 1236 | .power_restore = mmc_power_restore, | 1408 | .power_restore = mmc_power_restore, |
| 1409 | .alive = mmc_alive, | ||
| 1237 | }; | 1410 | }; |
| 1238 | 1411 | ||
| 1239 | static void mmc_attach_bus_ops(struct mmc_host *host) | 1412 | static void mmc_attach_bus_ops(struct mmc_host *host) |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index f2a05ea40f2..c63ad03c29c 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
| @@ -307,8 +307,8 @@ static int mmc_read_switch(struct mmc_card *card) | |||
| 307 | goto out; | 307 | goto out; |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | if (status[13] & UHS_SDR50_BUS_SPEED) | 310 | if (status[13] & SD_MODE_HIGH_SPEED) |
| 311 | card->sw_caps.hs_max_dtr = 50000000; | 311 | card->sw_caps.hs_max_dtr = HIGH_SPEED_MAX_DTR; |
| 312 | 312 | ||
| 313 | if (card->scr.sda_spec3) { | 313 | if (card->scr.sda_spec3) { |
| 314 | card->sw_caps.sd3_bus_mode = status[13]; | 314 | card->sw_caps.sd3_bus_mode = status[13]; |
| @@ -661,7 +661,8 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) | |||
| 661 | 661 | ||
| 662 | /* SPI mode doesn't define CMD19 */ | 662 | /* SPI mode doesn't define CMD19 */ |
| 663 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) | 663 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) |
| 664 | err = card->host->ops->execute_tuning(card->host); | 664 | err = card->host->ops->execute_tuning(card->host, |
| 665 | MMC_SEND_TUNING_BLOCK); | ||
| 665 | 666 | ||
| 666 | out: | 667 | out: |
| 667 | kfree(status); | 668 | kfree(status); |
| @@ -960,7 +961,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
| 960 | goto free_card; | 961 | goto free_card; |
| 961 | 962 | ||
| 962 | /* Card is an ultra-high-speed card */ | 963 | /* Card is an ultra-high-speed card */ |
| 963 | mmc_sd_card_set_uhs(card); | 964 | mmc_card_set_uhs(card); |
| 964 | 965 | ||
| 965 | /* | 966 | /* |
| 966 | * Since initialization is now complete, enable preset | 967 | * Since initialization is now complete, enable preset |
| @@ -1019,6 +1020,14 @@ static void mmc_sd_remove(struct mmc_host *host) | |||
| 1019 | } | 1020 | } |
| 1020 | 1021 | ||
| 1021 | /* | 1022 | /* |
| 1023 | * Card detection - card is alive. | ||
| 1024 | */ | ||
| 1025 | static int mmc_sd_alive(struct mmc_host *host) | ||
| 1026 | { | ||
| 1027 | return mmc_send_status(host->card, NULL); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | /* | ||
| 1022 | * Card detection callback from host. | 1031 | * Card detection callback from host. |
| 1023 | */ | 1032 | */ |
| 1024 | static void mmc_sd_detect(struct mmc_host *host) | 1033 | static void mmc_sd_detect(struct mmc_host *host) |
| @@ -1033,7 +1042,7 @@ static void mmc_sd_detect(struct mmc_host *host) | |||
| 1033 | /* | 1042 | /* |
| 1034 | * Just check if our card has been removed. | 1043 | * Just check if our card has been removed. |
| 1035 | */ | 1044 | */ |
| 1036 | err = mmc_send_status(host->card, NULL); | 1045 | err = _mmc_detect_card_removed(host); |
| 1037 | 1046 | ||
| 1038 | mmc_release_host(host); | 1047 | mmc_release_host(host); |
| 1039 | 1048 | ||
| @@ -1102,6 +1111,7 @@ static const struct mmc_bus_ops mmc_sd_ops = { | |||
| 1102 | .suspend = NULL, | 1111 | .suspend = NULL, |
| 1103 | .resume = NULL, | 1112 | .resume = NULL, |
| 1104 | .power_restore = mmc_sd_power_restore, | 1113 | .power_restore = mmc_sd_power_restore, |
| 1114 | .alive = mmc_sd_alive, | ||
| 1105 | }; | 1115 | }; |
| 1106 | 1116 | ||
| 1107 | static const struct mmc_bus_ops mmc_sd_ops_unsafe = { | 1117 | static const struct mmc_bus_ops mmc_sd_ops_unsafe = { |
| @@ -1110,6 +1120,7 @@ static const struct mmc_bus_ops mmc_sd_ops_unsafe = { | |||
| 1110 | .suspend = mmc_sd_suspend, | 1120 | .suspend = mmc_sd_suspend, |
| 1111 | .resume = mmc_sd_resume, | 1121 | .resume = mmc_sd_resume, |
| 1112 | .power_restore = mmc_sd_power_restore, | 1122 | .power_restore = mmc_sd_power_restore, |
| 1123 | .alive = mmc_sd_alive, | ||
| 1113 | }; | 1124 | }; |
| 1114 | 1125 | ||
| 1115 | static void mmc_sd_attach_bus_ops(struct mmc_host *host) | 1126 | static void mmc_sd_attach_bus_ops(struct mmc_host *host) |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 3ab565e32a6..bd7bacc950d 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | #include <linux/mmc/host.h> | 15 | #include <linux/mmc/host.h> |
| 16 | #include <linux/mmc/card.h> | 16 | #include <linux/mmc/card.h> |
| 17 | #include <linux/mmc/mmc.h> | ||
| 17 | #include <linux/mmc/sdio.h> | 18 | #include <linux/mmc/sdio.h> |
| 18 | #include <linux/mmc/sdio_func.h> | 19 | #include <linux/mmc/sdio_func.h> |
| 19 | #include <linux/mmc/sdio_ids.h> | 20 | #include <linux/mmc/sdio_ids.h> |
| @@ -102,6 +103,7 @@ static int sdio_read_cccr(struct mmc_card *card) | |||
| 102 | int ret; | 103 | int ret; |
| 103 | int cccr_vsn; | 104 | int cccr_vsn; |
| 104 | unsigned char data; | 105 | unsigned char data; |
| 106 | unsigned char speed; | ||
| 105 | 107 | ||
| 106 | memset(&card->cccr, 0, sizeof(struct sdio_cccr)); | 108 | memset(&card->cccr, 0, sizeof(struct sdio_cccr)); |
| 107 | 109 | ||
| @@ -140,12 +142,60 @@ static int sdio_read_cccr(struct mmc_card *card) | |||
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | if (cccr_vsn >= SDIO_CCCR_REV_1_20) { | 144 | if (cccr_vsn >= SDIO_CCCR_REV_1_20) { |
| 143 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); | 145 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); |
| 144 | if (ret) | 146 | if (ret) |
| 145 | goto out; | 147 | goto out; |
| 146 | 148 | ||
| 147 | if (data & SDIO_SPEED_SHS) | 149 | card->scr.sda_spec3 = 0; |
| 148 | card->cccr.high_speed = 1; | 150 | card->sw_caps.sd3_bus_mode = 0; |
| 151 | card->sw_caps.sd3_drv_type = 0; | ||
| 152 | if (cccr_vsn >= SDIO_CCCR_REV_3_00) { | ||
| 153 | card->scr.sda_spec3 = 1; | ||
| 154 | ret = mmc_io_rw_direct(card, 0, 0, | ||
| 155 | SDIO_CCCR_UHS, 0, &data); | ||
| 156 | if (ret) | ||
| 157 | goto out; | ||
| 158 | |||
| 159 | if (card->host->caps & | ||
| 160 | (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | ||
| 161 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | | ||
| 162 | MMC_CAP_UHS_DDR50)) { | ||
| 163 | if (data & SDIO_UHS_DDR50) | ||
| 164 | card->sw_caps.sd3_bus_mode | ||
| 165 | |= SD_MODE_UHS_DDR50; | ||
| 166 | |||
| 167 | if (data & SDIO_UHS_SDR50) | ||
| 168 | card->sw_caps.sd3_bus_mode | ||
| 169 | |= SD_MODE_UHS_SDR50; | ||
| 170 | |||
| 171 | if (data & SDIO_UHS_SDR104) | ||
| 172 | card->sw_caps.sd3_bus_mode | ||
| 173 | |= SD_MODE_UHS_SDR104; | ||
| 174 | } | ||
| 175 | |||
| 176 | ret = mmc_io_rw_direct(card, 0, 0, | ||
| 177 | SDIO_CCCR_DRIVE_STRENGTH, 0, &data); | ||
| 178 | if (ret) | ||
| 179 | goto out; | ||
| 180 | |||
| 181 | if (data & SDIO_DRIVE_SDTA) | ||
| 182 | card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_A; | ||
| 183 | if (data & SDIO_DRIVE_SDTC) | ||
| 184 | card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C; | ||
| 185 | if (data & SDIO_DRIVE_SDTD) | ||
| 186 | card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D; | ||
| 187 | } | ||
| 188 | |||
| 189 | /* if no uhs mode ensure we check for high speed */ | ||
| 190 | if (!card->sw_caps.sd3_bus_mode) { | ||
| 191 | if (speed & SDIO_SPEED_SHS) { | ||
| 192 | card->cccr.high_speed = 1; | ||
| 193 | card->sw_caps.hs_max_dtr = 50000000; | ||
| 194 | } else { | ||
| 195 | card->cccr.high_speed = 0; | ||
| 196 | card->sw_caps.hs_max_dtr = 25000000; | ||
| 197 | } | ||
| 198 | } | ||
| 149 | } | 199 | } |
| 150 | 200 | ||
| 151 | out: | 201 | out: |
| @@ -327,6 +377,194 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) | |||
| 327 | return max_dtr; | 377 | return max_dtr; |
| 328 | } | 378 | } |
| 329 | 379 | ||
| 380 | static unsigned char host_drive_to_sdio_drive(int host_strength) | ||
| 381 | { | ||
| 382 | switch (host_strength) { | ||
| 383 | case MMC_SET_DRIVER_TYPE_A: | ||
| 384 | return SDIO_DTSx_SET_TYPE_A; | ||
| 385 | case MMC_SET_DRIVER_TYPE_B: | ||
| 386 | return SDIO_DTSx_SET_TYPE_B; | ||
| 387 | case MMC_SET_DRIVER_TYPE_C: | ||
| 388 | return SDIO_DTSx_SET_TYPE_C; | ||
| 389 | case MMC_SET_DRIVER_TYPE_D: | ||
| 390 | return SDIO_DTSx_SET_TYPE_D; | ||
| 391 | default: | ||
| 392 | return SDIO_DTSx_SET_TYPE_B; | ||
| 393 | } | ||
| 394 | } | ||
| 395 | |||
| 396 | static void sdio_select_driver_type(struct mmc_card *card) | ||
| 397 | { | ||
| 398 | int host_drv_type = SD_DRIVER_TYPE_B; | ||
| 399 | int card_drv_type = SD_DRIVER_TYPE_B; | ||
| 400 | int drive_strength; | ||
| 401 | unsigned char card_strength; | ||
| 402 | int err; | ||
| 403 | |||
| 404 | /* | ||
| 405 | * If the host doesn't support any of the Driver Types A,C or D, | ||
| 406 | * or there is no board specific handler then default Driver | ||
| 407 | * Type B is used. | ||
| 408 | */ | ||
| 409 | if (!(card->host->caps & | ||
| 410 | (MMC_CAP_DRIVER_TYPE_A | | ||
| 411 | MMC_CAP_DRIVER_TYPE_C | | ||
| 412 | MMC_CAP_DRIVER_TYPE_D))) | ||
| 413 | return; | ||
| 414 | |||
| 415 | if (!card->host->ops->select_drive_strength) | ||
| 416 | return; | ||
| 417 | |||
| 418 | if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) | ||
| 419 | host_drv_type |= SD_DRIVER_TYPE_A; | ||
| 420 | |||
| 421 | if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) | ||
| 422 | host_drv_type |= SD_DRIVER_TYPE_C; | ||
| 423 | |||
| 424 | if (card->host->caps & MMC_CAP_DRIVER_TYPE_D) | ||
| 425 | host_drv_type |= SD_DRIVER_TYPE_D; | ||
| 426 | |||
| 427 | if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A) | ||
| 428 | card_drv_type |= SD_DRIVER_TYPE_A; | ||
| 429 | |||
| 430 | if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) | ||
| 431 | card_drv_type |= SD_DRIVER_TYPE_C; | ||
| 432 | |||
| 433 | if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_D) | ||
| 434 | card_drv_type |= SD_DRIVER_TYPE_D; | ||
| 435 | |||
| 436 | /* | ||
| 437 | * The drive strength that the hardware can support | ||
| 438 | * depends on the board design. Pass the appropriate | ||
| 439 | * information and let the hardware specific code | ||
| 440 | * return what is possible given the options | ||
| 441 | */ | ||
| 442 | drive_strength = card->host->ops->select_drive_strength( | ||
| 443 | card->sw_caps.uhs_max_dtr, | ||
| 444 | host_drv_type, card_drv_type); | ||
| 445 | |||
| 446 | /* if error just use default for drive strength B */ | ||
| 447 | err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0, | ||
| 448 | &card_strength); | ||
| 449 | if (err) | ||
| 450 | return; | ||
| 451 | |||
| 452 | card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT); | ||
| 453 | card_strength |= host_drive_to_sdio_drive(drive_strength); | ||
| 454 | |||
| 455 | err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH, | ||
| 456 | card_strength, NULL); | ||
| 457 | |||
| 458 | /* if error default to drive strength B */ | ||
| 459 | if (!err) | ||
| 460 | mmc_set_driver_type(card->host, drive_strength); | ||
| 461 | } | ||
| 462 | |||
| 463 | |||
| 464 | static int sdio_set_bus_speed_mode(struct mmc_card *card) | ||
| 465 | { | ||
| 466 | unsigned int bus_speed, timing; | ||
| 467 | int err; | ||
| 468 | unsigned char speed; | ||
| 469 | |||
| 470 | /* | ||
| 471 | * If the host doesn't support any of the UHS-I modes, fallback on | ||
| 472 | * default speed. | ||
| 473 | */ | ||
| 474 | if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | ||
| 475 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) | ||
| 476 | return 0; | ||
| 477 | |||
| 478 | bus_speed = SDIO_SPEED_SDR12; | ||
| 479 | timing = MMC_TIMING_UHS_SDR12; | ||
| 480 | if ((card->host->caps & MMC_CAP_UHS_SDR104) && | ||
| 481 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { | ||
| 482 | bus_speed = SDIO_SPEED_SDR104; | ||
| 483 | timing = MMC_TIMING_UHS_SDR104; | ||
| 484 | card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; | ||
| 485 | } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && | ||
| 486 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { | ||
| 487 | bus_speed = SDIO_SPEED_DDR50; | ||
| 488 | timing = MMC_TIMING_UHS_DDR50; | ||
| 489 | card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; | ||
| 490 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | ||
| 491 | MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & | ||
| 492 | SD_MODE_UHS_SDR50)) { | ||
| 493 | bus_speed = SDIO_SPEED_SDR50; | ||
| 494 | timing = MMC_TIMING_UHS_SDR50; | ||
| 495 | card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; | ||
| 496 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | ||
| 497 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && | ||
| 498 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { | ||
| 499 | bus_speed = SDIO_SPEED_SDR25; | ||
| 500 | timing = MMC_TIMING_UHS_SDR25; | ||
| 501 | card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; | ||
| 502 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | ||
| 503 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | | ||
| 504 | MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & | ||
| 505 | SD_MODE_UHS_SDR12)) { | ||
| 506 | bus_speed = SDIO_SPEED_SDR12; | ||
| 507 | timing = MMC_TIMING_UHS_SDR12; | ||
| 508 | card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; | ||
| 509 | } | ||
| 510 | |||
| 511 | err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); | ||
| 512 | if (err) | ||
| 513 | return err; | ||
| 514 | |||
| 515 | speed &= ~SDIO_SPEED_BSS_MASK; | ||
| 516 | speed |= bus_speed; | ||
| 517 | err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); | ||
| 518 | if (err) | ||
| 519 | return err; | ||
| 520 | |||
| 521 | if (bus_speed) { | ||
| 522 | mmc_set_timing(card->host, timing); | ||
| 523 | mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); | ||
| 524 | } | ||
| 525 | |||
| 526 | return 0; | ||
| 527 | } | ||
| 528 | |||
| 529 | /* | ||
| 530 | * UHS-I specific initialization procedure | ||
| 531 | */ | ||
| 532 | static int mmc_sdio_init_uhs_card(struct mmc_card *card) | ||
| 533 | { | ||
| 534 | int err; | ||
| 535 | |||
| 536 | if (!card->scr.sda_spec3) | ||
| 537 | return 0; | ||
| 538 | |||
| 539 | /* | ||
| 540 | * Switch to wider bus (if supported). | ||
| 541 | */ | ||
| 542 | if (card->host->caps & MMC_CAP_4_BIT_DATA) { | ||
| 543 | err = sdio_enable_4bit_bus(card); | ||
| 544 | if (err > 0) { | ||
| 545 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
| 546 | err = 0; | ||
| 547 | } | ||
| 548 | } | ||
| 549 | |||
| 550 | /* Set the driver strength for the card */ | ||
| 551 | sdio_select_driver_type(card); | ||
| 552 | |||
| 553 | /* Set bus speed mode of the card */ | ||
| 554 | err = sdio_set_bus_speed_mode(card); | ||
| 555 | if (err) | ||
| 556 | goto out; | ||
| 557 | |||
| 558 | /* Initialize and start re-tuning timer */ | ||
| 559 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) | ||
| 560 | err = card->host->ops->execute_tuning(card->host, | ||
| 561 | MMC_SEND_TUNING_BLOCK); | ||
| 562 | |||
| 563 | out: | ||
| 564 | |||
| 565 | return err; | ||
| 566 | } | ||
| 567 | |||
| 330 | /* | 568 | /* |
| 331 | * Handle the detection and initialisation of a card. | 569 | * Handle the detection and initialisation of a card. |
| 332 | * | 570 | * |
| @@ -394,6 +632,30 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
| 394 | host->ops->init_card(host, card); | 632 | host->ops->init_card(host, card); |
| 395 | 633 | ||
| 396 | /* | 634 | /* |
| 635 | * If the host and card support UHS-I mode request the card | ||
| 636 | * to switch to 1.8V signaling level. No 1.8v signalling if | ||
| 637 | * UHS mode is not enabled to maintain compatibilty and some | ||
| 638 | * systems that claim 1.8v signalling in fact do not support | ||
| 639 | * it. | ||
| 640 | */ | ||
| 641 | if ((ocr & R4_18V_PRESENT) && | ||
| 642 | (host->caps & | ||
| 643 | (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | ||
| 644 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | | ||
| 645 | MMC_CAP_UHS_DDR50))) { | ||
| 646 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, | ||
| 647 | true); | ||
| 648 | if (err) { | ||
| 649 | ocr &= ~R4_18V_PRESENT; | ||
| 650 | host->ocr &= ~R4_18V_PRESENT; | ||
| 651 | } | ||
| 652 | err = 0; | ||
| 653 | } else { | ||
| 654 | ocr &= ~R4_18V_PRESENT; | ||
| 655 | host->ocr &= ~R4_18V_PRESENT; | ||
| 656 | } | ||
| 657 | |||
| 658 | /* | ||
| 397 | * For native busses: set card RCA and quit open drain mode. | 659 | * For native busses: set card RCA and quit open drain mode. |
| 398 | */ | 660 | */ |
| 399 | if (!powered_resume && !mmc_host_is_spi(host)) { | 661 | if (!powered_resume && !mmc_host_is_spi(host)) { |
| @@ -492,29 +754,39 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
| 492 | if (err) | 754 | if (err) |
| 493 | goto remove; | 755 | goto remove; |
| 494 | 756 | ||
| 495 | /* | 757 | /* Initialization sequence for UHS-I cards */ |
| 496 | * Switch to high-speed (if supported). | 758 | /* Only if card supports 1.8v and UHS signaling */ |
| 497 | */ | 759 | if ((ocr & R4_18V_PRESENT) && card->sw_caps.sd3_bus_mode) { |
| 498 | err = sdio_enable_hs(card); | 760 | err = mmc_sdio_init_uhs_card(card); |
| 499 | if (err > 0) | 761 | if (err) |
| 500 | mmc_sd_go_highspeed(card); | 762 | goto remove; |
| 501 | else if (err) | ||
| 502 | goto remove; | ||
| 503 | 763 | ||
| 504 | /* | 764 | /* Card is an ultra-high-speed card */ |
| 505 | * Change to the card's maximum speed. | 765 | mmc_card_set_uhs(card); |
| 506 | */ | 766 | } else { |
| 507 | mmc_set_clock(host, mmc_sdio_get_max_clock(card)); | 767 | /* |
| 768 | * Switch to high-speed (if supported). | ||
| 769 | */ | ||
| 770 | err = sdio_enable_hs(card); | ||
| 771 | if (err > 0) | ||
| 772 | mmc_sd_go_highspeed(card); | ||
| 773 | else if (err) | ||
| 774 | goto remove; | ||
| 508 | 775 | ||
| 509 | /* | 776 | /* |
| 510 | * Switch to wider bus (if supported). | 777 | * Change to the card's maximum speed. |
| 511 | */ | 778 | */ |
| 512 | err = sdio_enable_4bit_bus(card); | 779 | mmc_set_clock(host, mmc_sdio_get_max_clock(card)); |
| 513 | if (err > 0) | ||
| 514 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
| 515 | else if (err) | ||
| 516 | goto remove; | ||
| 517 | 780 | ||
| 781 | /* | ||
| 782 | * Switch to wider bus (if supported). | ||
| 783 | */ | ||
| 784 | err = sdio_enable_4bit_bus(card); | ||
| 785 | if (err > 0) | ||
| 786 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
| 787 | else if (err) | ||
| 788 | goto remove; | ||
| 789 | } | ||
| 518 | finish: | 790 | finish: |
| 519 | if (!oldcard) | 791 | if (!oldcard) |
| 520 | host->card = card; | 792 | host->card = card; |
| @@ -550,6 +822,14 @@ static void mmc_sdio_remove(struct mmc_host *host) | |||
| 550 | } | 822 | } |
| 551 | 823 | ||
| 552 | /* | 824 | /* |
| 825 | * Card detection - card is alive. | ||
| 826 | */ | ||
| 827 | static int mmc_sdio_alive(struct mmc_host *host) | ||
| 828 | { | ||
| 829 | return mmc_select_card(host->card); | ||
| 830 | } | ||
| 831 | |||
| 832 | /* | ||
| 553 | * Card detection callback from host. | 833 | * Card detection callback from host. |
| 554 | */ | 834 | */ |
| 555 | static void mmc_sdio_detect(struct mmc_host *host) | 835 | static void mmc_sdio_detect(struct mmc_host *host) |
| @@ -571,7 +851,7 @@ static void mmc_sdio_detect(struct mmc_host *host) | |||
| 571 | /* | 851 | /* |
| 572 | * Just check if our card has been removed. | 852 | * Just check if our card has been removed. |
| 573 | */ | 853 | */ |
| 574 | err = mmc_select_card(host->card); | 854 | err = _mmc_detect_card_removed(host); |
| 575 | 855 | ||
| 576 | mmc_release_host(host); | 856 | mmc_release_host(host); |
| 577 | 857 | ||
| @@ -749,6 +1029,7 @@ static const struct mmc_bus_ops mmc_sdio_ops = { | |||
| 749 | .suspend = mmc_sdio_suspend, | 1029 | .suspend = mmc_sdio_suspend, |
| 750 | .resume = mmc_sdio_resume, | 1030 | .resume = mmc_sdio_resume, |
| 751 | .power_restore = mmc_sdio_power_restore, | 1031 | .power_restore = mmc_sdio_power_restore, |
| 1032 | .alive = mmc_sdio_alive, | ||
| 752 | }; | 1033 | }; |
| 753 | 1034 | ||
| 754 | 1035 | ||
| @@ -797,8 +1078,17 @@ int mmc_attach_sdio(struct mmc_host *host) | |||
| 797 | * Detect and init the card. | 1078 | * Detect and init the card. |
| 798 | */ | 1079 | */ |
| 799 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); | 1080 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); |
| 800 | if (err) | 1081 | if (err) { |
| 801 | goto err; | 1082 | if (err == -EAGAIN) { |
| 1083 | /* | ||
| 1084 | * Retry initialization with S18R set to 0. | ||
| 1085 | */ | ||
| 1086 | host->ocr &= ~R4_18V_PRESENT; | ||
| 1087 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); | ||
| 1088 | } | ||
| 1089 | if (err) | ||
| 1090 | goto err; | ||
| 1091 | } | ||
| 802 | card = host->card; | 1092 | card = host->card; |
| 803 | 1093 | ||
| 804 | /* | 1094 | /* |
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index b1f3168f791..8f6f5ac131f 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c | |||
| @@ -196,6 +196,9 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func) | |||
| 196 | else | 196 | else |
| 197 | mval = min(mval, func->max_blksize); | 197 | mval = min(mval, func->max_blksize); |
| 198 | 198 | ||
| 199 | if (mmc_card_broken_byte_mode_512(func->card)) | ||
| 200 | return min(mval, 511u); | ||
| 201 | |||
| 199 | return min(mval, 512u); /* maximum size for byte mode */ | 202 | return min(mval, 512u); /* maximum size for byte mode */ |
| 200 | } | 203 | } |
| 201 | 204 | ||
| @@ -314,7 +317,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, | |||
| 314 | func->card->host->max_seg_size / func->cur_blksize); | 317 | func->card->host->max_seg_size / func->cur_blksize); |
| 315 | max_blocks = min(max_blocks, 511u); | 318 | max_blocks = min(max_blocks, 511u); |
| 316 | 319 | ||
| 317 | while (remainder > func->cur_blksize) { | 320 | while (remainder >= func->cur_blksize) { |
| 318 | unsigned blocks; | 321 | unsigned blocks; |
| 319 | 322 | ||
| 320 | blocks = remainder / func->cur_blksize; | 323 | blocks = remainder / func->cur_blksize; |
| @@ -339,8 +342,9 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, | |||
| 339 | while (remainder > 0) { | 342 | while (remainder > 0) { |
| 340 | size = min(remainder, sdio_max_byte_size(func)); | 343 | size = min(remainder, sdio_max_byte_size(func)); |
| 341 | 344 | ||
| 345 | /* Indicate byte mode by setting "blocks" = 0 */ | ||
| 342 | ret = mmc_io_rw_extended(func->card, write, func->num, addr, | 346 | ret = mmc_io_rw_extended(func->card, write, func->num, addr, |
| 343 | incr_addr, buf, 1, size); | 347 | incr_addr, buf, 0, size); |
| 344 | if (ret) | 348 | if (ret) |
| 345 | return ret; | 349 | return ret; |
| 346 | 350 | ||
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index b0517cc0620..d29e20630ee 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c | |||
| @@ -128,8 +128,6 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | |||
| 128 | 128 | ||
| 129 | BUG_ON(!card); | 129 | BUG_ON(!card); |
| 130 | BUG_ON(fn > 7); | 130 | BUG_ON(fn > 7); |
| 131 | BUG_ON(blocks == 1 && blksz > 512); | ||
| 132 | WARN_ON(blocks == 0); | ||
| 133 | WARN_ON(blksz == 0); | 131 | WARN_ON(blksz == 0); |
| 134 | 132 | ||
| 135 | /* sanity check */ | 133 | /* sanity check */ |
| @@ -144,22 +142,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | |||
| 144 | cmd.arg |= fn << 28; | 142 | cmd.arg |= fn << 28; |
| 145 | cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; | 143 | cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; |
| 146 | cmd.arg |= addr << 9; | 144 | cmd.arg |= addr << 9; |
| 147 | if (blocks == 1 && blksz < 512) | 145 | if (blocks == 0) |
| 148 | cmd.arg |= blksz; /* byte mode */ | 146 | cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */ |
| 149 | else if (blocks == 1 && blksz == 512 && | ||
| 150 | !(mmc_card_broken_byte_mode_512(card))) | ||
| 151 | cmd.arg |= 0; /* byte mode, 0==512 */ | ||
| 152 | else | 147 | else |
| 153 | cmd.arg |= 0x08000000 | blocks; /* block mode */ | 148 | cmd.arg |= 0x08000000 | blocks; /* block mode */ |
| 154 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; | 149 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; |
| 155 | 150 | ||
| 156 | data.blksz = blksz; | 151 | data.blksz = blksz; |
| 157 | data.blocks = blocks; | 152 | /* Code in host drivers/fwk assumes that "blocks" always is >=1 */ |
| 153 | data.blocks = blocks ? blocks : 1; | ||
| 158 | data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; | 154 | data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; |
| 159 | data.sg = &sg; | 155 | data.sg = &sg; |
| 160 | data.sg_len = 1; | 156 | data.sg_len = 1; |
| 161 | 157 | ||
| 162 | sg_init_one(&sg, buf, blksz * blocks); | 158 | sg_init_one(&sg, buf, data.blksz * data.blocks); |
| 163 | 159 | ||
| 164 | mmc_set_data_timeout(&data, card); | 160 | mmc_set_data_timeout(&data, card); |
| 165 | 161 | ||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index b4b83f302e3..745f8fce251 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
| @@ -9,6 +9,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o | |||
| 9 | obj-$(CONFIG_MMC_MXS) += mxs-mmc.o | 9 | obj-$(CONFIG_MMC_MXS) += mxs-mmc.o |
| 10 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | 10 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o |
| 11 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o | 11 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o |
| 12 | obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o | ||
| 12 | obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o | 13 | obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o |
| 13 | obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o | 14 | obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o |
| 14 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o | 15 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index f437c3e6f3a..947faa5d2ce 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
| @@ -236,7 +236,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
| 236 | 236 | ||
| 237 | sg = &data->sg[i]; | 237 | sg = &data->sg[i]; |
| 238 | 238 | ||
| 239 | sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 239 | sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset; |
| 240 | amount = min(size, sg->length); | 240 | amount = min(size, sg->length); |
| 241 | size -= amount; | 241 | size -= amount; |
| 242 | 242 | ||
| @@ -252,7 +252,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
| 252 | dmabuf = (unsigned *)tmpv; | 252 | dmabuf = (unsigned *)tmpv; |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 255 | kunmap_atomic(sgbuffer); |
| 256 | 256 | ||
| 257 | if (size == 0) | 257 | if (size == 0) |
| 258 | break; | 258 | break; |
| @@ -302,7 +302,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) | |||
| 302 | 302 | ||
| 303 | sg = &data->sg[i]; | 303 | sg = &data->sg[i]; |
| 304 | 304 | ||
| 305 | sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 305 | sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset; |
| 306 | amount = min(size, sg->length); | 306 | amount = min(size, sg->length); |
| 307 | size -= amount; | 307 | size -= amount; |
| 308 | 308 | ||
| @@ -318,7 +318,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) | |||
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | flush_kernel_dcache_page(sg_page(sg)); | 320 | flush_kernel_dcache_page(sg_page(sg)); |
| 321 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 321 | kunmap_atomic(sgbuffer); |
| 322 | data->bytes_xfered += amount; | 322 | data->bytes_xfered += amount; |
| 323 | if (size == 0) | 323 | if (size == 0) |
| 324 | break; | 324 | break; |
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 0371bf50224..03666174ca4 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c | |||
| @@ -627,17 +627,7 @@ static struct platform_driver sdh_driver = { | |||
| 627 | }, | 627 | }, |
| 628 | }; | 628 | }; |
| 629 | 629 | ||
| 630 | static int __init sdh_init(void) | 630 | module_platform_driver(sdh_driver); |
| 631 | { | ||
| 632 | return platform_driver_register(&sdh_driver); | ||
| 633 | } | ||
| 634 | module_init(sdh_init); | ||
| 635 | |||
| 636 | static void __exit sdh_exit(void) | ||
| 637 | { | ||
| 638 | platform_driver_unregister(&sdh_driver); | ||
| 639 | } | ||
| 640 | module_exit(sdh_exit); | ||
| 641 | 631 | ||
| 642 | MODULE_DESCRIPTION("Blackfin Secure Digital Host Driver"); | 632 | MODULE_DESCRIPTION("Blackfin Secure Digital Host Driver"); |
| 643 | MODULE_AUTHOR("Cliff Cai, Roy Huang"); | 633 | MODULE_AUTHOR("Cliff Cai, Roy Huang"); |
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c index ce2a47b71dd..83693fd7c6b 100644 --- a/drivers/mmc/host/cb710-mmc.c +++ b/drivers/mmc/host/cb710-mmc.c | |||
| @@ -780,18 +780,7 @@ static struct platform_driver cb710_mmc_driver = { | |||
| 780 | #endif | 780 | #endif |
| 781 | }; | 781 | }; |
| 782 | 782 | ||
| 783 | static int __init cb710_mmc_init_module(void) | 783 | module_platform_driver(cb710_mmc_driver); |
| 784 | { | ||
| 785 | return platform_driver_register(&cb710_mmc_driver); | ||
| 786 | } | ||
| 787 | |||
| 788 | static void __exit cb710_mmc_cleanup_module(void) | ||
| 789 | { | ||
| 790 | platform_driver_unregister(&cb710_mmc_driver); | ||
| 791 | } | ||
| 792 | |||
| 793 | module_init(cb710_mmc_init_module); | ||
| 794 | module_exit(cb710_mmc_cleanup_module); | ||
| 795 | 784 | ||
| 796 | MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>"); | 785 | MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>"); |
| 797 | MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part"); | 786 | MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part"); |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 3aaeb084191..0e342793ff1 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
| @@ -588,11 +588,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) | |||
| 588 | mci_writel(host, CTYPE, (slot->ctype << slot->id)); | 588 | mci_writel(host, CTYPE, (slot->ctype << slot->id)); |
| 589 | } | 589 | } |
| 590 | 590 | ||
| 591 | static void dw_mci_start_request(struct dw_mci *host, | 591 | static void __dw_mci_start_request(struct dw_mci *host, |
| 592 | struct dw_mci_slot *slot) | 592 | struct dw_mci_slot *slot, |
| 593 | struct mmc_command *cmd) | ||
| 593 | { | 594 | { |
| 594 | struct mmc_request *mrq; | 595 | struct mmc_request *mrq; |
| 595 | struct mmc_command *cmd; | ||
| 596 | struct mmc_data *data; | 596 | struct mmc_data *data; |
| 597 | u32 cmdflags; | 597 | u32 cmdflags; |
| 598 | 598 | ||
| @@ -610,14 +610,13 @@ static void dw_mci_start_request(struct dw_mci *host, | |||
| 610 | host->completed_events = 0; | 610 | host->completed_events = 0; |
| 611 | host->data_status = 0; | 611 | host->data_status = 0; |
| 612 | 612 | ||
| 613 | data = mrq->data; | 613 | data = cmd->data; |
| 614 | if (data) { | 614 | if (data) { |
| 615 | dw_mci_set_timeout(host); | 615 | dw_mci_set_timeout(host); |
| 616 | mci_writel(host, BYTCNT, data->blksz*data->blocks); | 616 | mci_writel(host, BYTCNT, data->blksz*data->blocks); |
| 617 | mci_writel(host, BLKSIZ, data->blksz); | 617 | mci_writel(host, BLKSIZ, data->blksz); |
| 618 | } | 618 | } |
| 619 | 619 | ||
| 620 | cmd = mrq->cmd; | ||
| 621 | cmdflags = dw_mci_prepare_command(slot->mmc, cmd); | 620 | cmdflags = dw_mci_prepare_command(slot->mmc, cmd); |
| 622 | 621 | ||
| 623 | /* this is the first command, send the initialization clock */ | 622 | /* this is the first command, send the initialization clock */ |
| @@ -635,6 +634,16 @@ static void dw_mci_start_request(struct dw_mci *host, | |||
| 635 | host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); | 634 | host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); |
| 636 | } | 635 | } |
| 637 | 636 | ||
| 637 | static void dw_mci_start_request(struct dw_mci *host, | ||
| 638 | struct dw_mci_slot *slot) | ||
| 639 | { | ||
| 640 | struct mmc_request *mrq = slot->mrq; | ||
| 641 | struct mmc_command *cmd; | ||
| 642 | |||
| 643 | cmd = mrq->sbc ? mrq->sbc : mrq->cmd; | ||
| 644 | __dw_mci_start_request(host, slot, cmd); | ||
| 645 | } | ||
| 646 | |||
| 638 | /* must be called with host->lock held */ | 647 | /* must be called with host->lock held */ |
| 639 | static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot, | 648 | static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot, |
| 640 | struct mmc_request *mrq) | 649 | struct mmc_request *mrq) |
| @@ -698,12 +707,15 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 698 | break; | 707 | break; |
| 699 | } | 708 | } |
| 700 | 709 | ||
| 710 | regs = mci_readl(slot->host, UHS_REG); | ||
| 711 | |||
| 701 | /* DDR mode set */ | 712 | /* DDR mode set */ |
| 702 | if (ios->timing == MMC_TIMING_UHS_DDR50) { | 713 | if (ios->timing == MMC_TIMING_UHS_DDR50) |
| 703 | regs = mci_readl(slot->host, UHS_REG); | ||
| 704 | regs |= (0x1 << slot->id) << 16; | 714 | regs |= (0x1 << slot->id) << 16; |
| 705 | mci_writel(slot->host, UHS_REG, regs); | 715 | else |
| 706 | } | 716 | regs &= ~(0x1 << slot->id) << 16; |
| 717 | |||
| 718 | mci_writel(slot->host, UHS_REG, regs); | ||
| 707 | 719 | ||
| 708 | if (ios->clock) { | 720 | if (ios->clock) { |
| 709 | /* | 721 | /* |
| @@ -889,7 +901,14 @@ static void dw_mci_tasklet_func(unsigned long priv) | |||
| 889 | cmd = host->cmd; | 901 | cmd = host->cmd; |
| 890 | host->cmd = NULL; | 902 | host->cmd = NULL; |
| 891 | set_bit(EVENT_CMD_COMPLETE, &host->completed_events); | 903 | set_bit(EVENT_CMD_COMPLETE, &host->completed_events); |
| 892 | dw_mci_command_complete(host, host->mrq->cmd); | 904 | dw_mci_command_complete(host, cmd); |
| 905 | if (cmd == host->mrq->sbc && !cmd->error) { | ||
| 906 | prev_state = state = STATE_SENDING_CMD; | ||
| 907 | __dw_mci_start_request(host, host->cur_slot, | ||
| 908 | host->mrq->cmd); | ||
| 909 | goto unlock; | ||
| 910 | } | ||
| 911 | |||
| 893 | if (!host->mrq->data || cmd->error) { | 912 | if (!host->mrq->data || cmd->error) { |
| 894 | dw_mci_request_end(host, host->mrq); | 913 | dw_mci_request_end(host, host->mrq); |
| 895 | goto unlock; | 914 | goto unlock; |
| @@ -967,6 +986,12 @@ static void dw_mci_tasklet_func(unsigned long priv) | |||
| 967 | goto unlock; | 986 | goto unlock; |
| 968 | } | 987 | } |
| 969 | 988 | ||
| 989 | if (host->mrq->sbc && !data->error) { | ||
| 990 | data->stop->error = 0; | ||
| 991 | dw_mci_request_end(host, host->mrq); | ||
| 992 | goto unlock; | ||
| 993 | } | ||
| 994 | |||
| 970 | prev_state = state = STATE_SENDING_STOP; | 995 | prev_state = state = STATE_SENDING_STOP; |
| 971 | if (!data->error) | 996 | if (!data->error) |
| 972 | send_stop_cmd(host, data); | 997 | send_stop_cmd(host, data); |
| @@ -1678,8 +1703,9 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
| 1678 | 1703 | ||
| 1679 | if (host->pdata->caps) | 1704 | if (host->pdata->caps) |
| 1680 | mmc->caps = host->pdata->caps; | 1705 | mmc->caps = host->pdata->caps; |
| 1681 | else | 1706 | |
| 1682 | mmc->caps = 0; | 1707 | if (host->pdata->caps2) |
| 1708 | mmc->caps2 = host->pdata->caps2; | ||
| 1683 | 1709 | ||
| 1684 | if (host->pdata->get_bus_wd) | 1710 | if (host->pdata->get_bus_wd) |
| 1685 | if (host->pdata->get_bus_wd(slot->id) >= 4) | 1711 | if (host->pdata->get_bus_wd(slot->id) >= 4) |
| @@ -1923,7 +1949,7 @@ static int dw_mci_probe(struct platform_device *pdev) | |||
| 1923 | * should put it in the platform data. | 1949 | * should put it in the platform data. |
| 1924 | */ | 1950 | */ |
| 1925 | fifo_size = mci_readl(host, FIFOTH); | 1951 | fifo_size = mci_readl(host, FIFOTH); |
| 1926 | fifo_size = 1 + ((fifo_size >> 16) & 0x7ff); | 1952 | fifo_size = 1 + ((fifo_size >> 16) & 0xfff); |
| 1927 | } else { | 1953 | } else { |
| 1928 | fifo_size = host->pdata->fifo_depth; | 1954 | fifo_size = host->pdata->fifo_depth; |
| 1929 | } | 1955 | } |
| @@ -2062,14 +2088,14 @@ static int __exit dw_mci_remove(struct platform_device *pdev) | |||
| 2062 | return 0; | 2088 | return 0; |
| 2063 | } | 2089 | } |
| 2064 | 2090 | ||
| 2065 | #ifdef CONFIG_PM | 2091 | #ifdef CONFIG_PM_SLEEP |
| 2066 | /* | 2092 | /* |
| 2067 | * TODO: we should probably disable the clock to the card in the suspend path. | 2093 | * TODO: we should probably disable the clock to the card in the suspend path. |
| 2068 | */ | 2094 | */ |
| 2069 | static int dw_mci_suspend(struct platform_device *pdev, pm_message_t mesg) | 2095 | static int dw_mci_suspend(struct device *dev) |
| 2070 | { | 2096 | { |
| 2071 | int i, ret; | 2097 | int i, ret; |
| 2072 | struct dw_mci *host = platform_get_drvdata(pdev); | 2098 | struct dw_mci *host = dev_get_drvdata(dev); |
| 2073 | 2099 | ||
| 2074 | for (i = 0; i < host->num_slots; i++) { | 2100 | for (i = 0; i < host->num_slots; i++) { |
| 2075 | struct dw_mci_slot *slot = host->slot[i]; | 2101 | struct dw_mci_slot *slot = host->slot[i]; |
| @@ -2092,10 +2118,10 @@ static int dw_mci_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
| 2092 | return 0; | 2118 | return 0; |
| 2093 | } | 2119 | } |
| 2094 | 2120 | ||
| 2095 | static int dw_mci_resume(struct platform_device *pdev) | 2121 | static int dw_mci_resume(struct device *dev) |
| 2096 | { | 2122 | { |
| 2097 | int i, ret; | 2123 | int i, ret; |
| 2098 | struct dw_mci *host = platform_get_drvdata(pdev); | 2124 | struct dw_mci *host = dev_get_drvdata(dev); |
| 2099 | 2125 | ||
| 2100 | if (host->vmmc) | 2126 | if (host->vmmc) |
| 2101 | regulator_enable(host->vmmc); | 2127 | regulator_enable(host->vmmc); |
| @@ -2103,7 +2129,7 @@ static int dw_mci_resume(struct platform_device *pdev) | |||
| 2103 | if (host->dma_ops->init) | 2129 | if (host->dma_ops->init) |
| 2104 | host->dma_ops->init(host); | 2130 | host->dma_ops->init(host); |
| 2105 | 2131 | ||
| 2106 | if (!mci_wait_reset(&pdev->dev, host)) { | 2132 | if (!mci_wait_reset(dev, host)) { |
| 2107 | ret = -ENODEV; | 2133 | ret = -ENODEV; |
| 2108 | return ret; | 2134 | return ret; |
| 2109 | } | 2135 | } |
| @@ -2131,14 +2157,15 @@ static int dw_mci_resume(struct platform_device *pdev) | |||
| 2131 | #else | 2157 | #else |
| 2132 | #define dw_mci_suspend NULL | 2158 | #define dw_mci_suspend NULL |
| 2133 | #define dw_mci_resume NULL | 2159 | #define dw_mci_resume NULL |
| 2134 | #endif /* CONFIG_PM */ | 2160 | #endif /* CONFIG_PM_SLEEP */ |
| 2161 | |||
| 2162 | static SIMPLE_DEV_PM_OPS(dw_mci_pmops, dw_mci_suspend, dw_mci_resume); | ||
| 2135 | 2163 | ||
| 2136 | static struct platform_driver dw_mci_driver = { | 2164 | static struct platform_driver dw_mci_driver = { |
| 2137 | .remove = __exit_p(dw_mci_remove), | 2165 | .remove = __exit_p(dw_mci_remove), |
| 2138 | .suspend = dw_mci_suspend, | ||
| 2139 | .resume = dw_mci_resume, | ||
| 2140 | .driver = { | 2166 | .driver = { |
| 2141 | .name = "dw_mmc", | 2167 | .name = "dw_mmc", |
| 2168 | .pm = &dw_mci_pmops, | ||
| 2142 | }, | 2169 | }, |
| 2143 | }; | 2170 | }; |
| 2144 | 2171 | ||
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 72c071f6e00..df392a1143f 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h | |||
| @@ -126,7 +126,7 @@ | |||
| 126 | #define SDMMC_CMD_RESP_EXP BIT(6) | 126 | #define SDMMC_CMD_RESP_EXP BIT(6) |
| 127 | #define SDMMC_CMD_INDX(n) ((n) & 0x1F) | 127 | #define SDMMC_CMD_INDX(n) ((n) & 0x1F) |
| 128 | /* Status register defines */ | 128 | /* Status register defines */ |
| 129 | #define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FF) | 129 | #define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FFF) |
| 130 | /* Internal DMAC interrupt defines */ | 130 | /* Internal DMAC interrupt defines */ |
| 131 | #define SDMMC_IDMAC_INT_AI BIT(9) | 131 | #define SDMMC_IDMAC_INT_AI BIT(9) |
| 132 | #define SDMMC_IDMAC_INT_NI BIT(8) | 132 | #define SDMMC_IDMAC_INT_NI BIT(8) |
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 74218ad677e..c8852a8128a 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c | |||
| @@ -1012,17 +1012,7 @@ static struct platform_driver jz4740_mmc_driver = { | |||
| 1012 | }, | 1012 | }, |
| 1013 | }; | 1013 | }; |
| 1014 | 1014 | ||
| 1015 | static int __init jz4740_mmc_init(void) | 1015 | module_platform_driver(jz4740_mmc_driver); |
| 1016 | { | ||
| 1017 | return platform_driver_register(&jz4740_mmc_driver); | ||
| 1018 | } | ||
| 1019 | module_init(jz4740_mmc_init); | ||
| 1020 | |||
| 1021 | static void __exit jz4740_mmc_exit(void) | ||
| 1022 | { | ||
| 1023 | platform_driver_unregister(&jz4740_mmc_driver); | ||
| 1024 | } | ||
| 1025 | module_exit(jz4740_mmc_exit); | ||
| 1026 | 1016 | ||
| 1027 | MODULE_DESCRIPTION("JZ4740 SD/MMC controller driver"); | 1017 | MODULE_DESCRIPTION("JZ4740 SD/MMC controller driver"); |
| 1028 | MODULE_LICENSE("GPL"); | 1018 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 92946b84e9f..273306c68d5 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
| @@ -1525,7 +1525,6 @@ static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { | |||
| 1525 | static struct spi_driver mmc_spi_driver = { | 1525 | static struct spi_driver mmc_spi_driver = { |
| 1526 | .driver = { | 1526 | .driver = { |
| 1527 | .name = "mmc_spi", | 1527 | .name = "mmc_spi", |
| 1528 | .bus = &spi_bus_type, | ||
| 1529 | .owner = THIS_MODULE, | 1528 | .owner = THIS_MODULE, |
| 1530 | .of_match_table = mmc_spi_of_match_table, | 1529 | .of_match_table = mmc_spi_of_match_table, |
| 1531 | }, | 1530 | }, |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index fa8dd2fda4b..ece03b491c7 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
| @@ -1245,6 +1245,7 @@ static int __devinit mmci_probe(struct amba_device *dev, | |||
| 1245 | if (host->vcc == NULL) | 1245 | if (host->vcc == NULL) |
| 1246 | mmc->ocr_avail = plat->ocr_mask; | 1246 | mmc->ocr_avail = plat->ocr_mask; |
| 1247 | mmc->caps = plat->capabilities; | 1247 | mmc->caps = plat->capabilities; |
| 1248 | mmc->caps2 = plat->capabilities2; | ||
| 1248 | 1249 | ||
| 1249 | /* | 1250 | /* |
| 1250 | * We can do SGIO | 1251 | * We can do SGIO |
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 80d8eb143b4..1d14cda95e5 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
| @@ -689,8 +689,8 @@ msmsdcc_pio_irq(int irq, void *dev_id) | |||
| 689 | 689 | ||
| 690 | /* Map the current scatter buffer */ | 690 | /* Map the current scatter buffer */ |
| 691 | local_irq_save(flags); | 691 | local_irq_save(flags); |
| 692 | buffer = kmap_atomic(sg_page(host->pio.sg), | 692 | buffer = kmap_atomic(sg_page(host->pio.sg)) |
| 693 | KM_BIO_SRC_IRQ) + host->pio.sg->offset; | 693 | + host->pio.sg->offset; |
| 694 | buffer += host->pio.sg_off; | 694 | buffer += host->pio.sg_off; |
| 695 | remain = host->pio.sg->length - host->pio.sg_off; | 695 | remain = host->pio.sg->length - host->pio.sg_off; |
| 696 | len = 0; | 696 | len = 0; |
| @@ -700,7 +700,7 @@ msmsdcc_pio_irq(int irq, void *dev_id) | |||
| 700 | len = msmsdcc_pio_write(host, buffer, remain, status); | 700 | len = msmsdcc_pio_write(host, buffer, remain, status); |
| 701 | 701 | ||
| 702 | /* Unmap the buffer */ | 702 | /* Unmap the buffer */ |
| 703 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); | 703 | kunmap_atomic(buffer); |
| 704 | local_irq_restore(flags); | 704 | local_irq_restore(flags); |
| 705 | 705 | ||
| 706 | host->pio.sg_off += len; | 706 | host->pio.sg_off += len; |
| @@ -1480,18 +1480,7 @@ static struct platform_driver msmsdcc_driver = { | |||
| 1480 | }, | 1480 | }, |
| 1481 | }; | 1481 | }; |
| 1482 | 1482 | ||
| 1483 | static int __init msmsdcc_init(void) | 1483 | module_platform_driver(msmsdcc_driver); |
| 1484 | { | ||
| 1485 | return platform_driver_register(&msmsdcc_driver); | ||
| 1486 | } | ||
| 1487 | |||
| 1488 | static void __exit msmsdcc_exit(void) | ||
| 1489 | { | ||
| 1490 | platform_driver_unregister(&msmsdcc_driver); | ||
| 1491 | } | ||
| 1492 | |||
| 1493 | module_init(msmsdcc_init); | ||
| 1494 | module_exit(msmsdcc_exit); | ||
| 1495 | 1484 | ||
| 1496 | MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver"); | 1485 | MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver"); |
| 1497 | MODULE_LICENSE("GPL"); | 1486 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 8e0fbe99404..7088b40f957 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
| @@ -1047,18 +1047,7 @@ static struct platform_driver mxcmci_driver = { | |||
| 1047 | } | 1047 | } |
| 1048 | }; | 1048 | }; |
| 1049 | 1049 | ||
| 1050 | static int __init mxcmci_init(void) | 1050 | module_platform_driver(mxcmci_driver); |
| 1051 | { | ||
| 1052 | return platform_driver_register(&mxcmci_driver); | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | static void __exit mxcmci_exit(void) | ||
| 1056 | { | ||
| 1057 | platform_driver_unregister(&mxcmci_driver); | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | module_init(mxcmci_init); | ||
| 1061 | module_exit(mxcmci_exit); | ||
| 1062 | 1051 | ||
| 1063 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); | 1052 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); |
| 1064 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | 1053 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 973011f9a29..4e2e019dd5c 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
| @@ -855,18 +855,7 @@ static struct platform_driver mxs_mmc_driver = { | |||
| 855 | }, | 855 | }, |
| 856 | }; | 856 | }; |
| 857 | 857 | ||
| 858 | static int __init mxs_mmc_init(void) | 858 | module_platform_driver(mxs_mmc_driver); |
| 859 | { | ||
| 860 | return platform_driver_register(&mxs_mmc_driver); | ||
| 861 | } | ||
| 862 | |||
| 863 | static void __exit mxs_mmc_exit(void) | ||
| 864 | { | ||
| 865 | platform_driver_unregister(&mxs_mmc_driver); | ||
| 866 | } | ||
| 867 | |||
| 868 | module_init(mxs_mmc_init); | ||
| 869 | module_exit(mxs_mmc_exit); | ||
| 870 | 859 | ||
| 871 | MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral"); | 860 | MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral"); |
| 872 | MODULE_AUTHOR("Freescale Semiconductor"); | 861 | MODULE_AUTHOR("Freescale Semiconductor"); |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d1fb561e089..fd0c661bbad 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
| 26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 27 | #include <linux/workqueue.h> | ||
| 28 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
| 29 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
| 30 | #include <linux/mmc/host.h> | 29 | #include <linux/mmc/host.h> |
| @@ -120,7 +119,6 @@ | |||
| 120 | 119 | ||
| 121 | #define MMC_AUTOSUSPEND_DELAY 100 | 120 | #define MMC_AUTOSUSPEND_DELAY 100 |
| 122 | #define MMC_TIMEOUT_MS 20 | 121 | #define MMC_TIMEOUT_MS 20 |
| 123 | #define OMAP_MMC_MASTER_CLOCK 96000000 | ||
| 124 | #define OMAP_MMC_MIN_CLOCK 400000 | 122 | #define OMAP_MMC_MIN_CLOCK 400000 |
| 125 | #define OMAP_MMC_MAX_CLOCK 52000000 | 123 | #define OMAP_MMC_MAX_CLOCK 52000000 |
| 126 | #define DRIVER_NAME "omap_hsmmc" | 124 | #define DRIVER_NAME "omap_hsmmc" |
| @@ -163,7 +161,6 @@ struct omap_hsmmc_host { | |||
| 163 | */ | 161 | */ |
| 164 | struct regulator *vcc; | 162 | struct regulator *vcc; |
| 165 | struct regulator *vcc_aux; | 163 | struct regulator *vcc_aux; |
| 166 | struct work_struct mmc_carddetect_work; | ||
| 167 | void __iomem *base; | 164 | void __iomem *base; |
| 168 | resource_size_t mapbase; | 165 | resource_size_t mapbase; |
| 169 | spinlock_t irq_lock; /* Prevent races with irq handler */ | 166 | spinlock_t irq_lock; /* Prevent races with irq handler */ |
| @@ -598,12 +595,12 @@ static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host) | |||
| 598 | } | 595 | } |
| 599 | 596 | ||
| 600 | /* Calculate divisor for the given clock frequency */ | 597 | /* Calculate divisor for the given clock frequency */ |
| 601 | static u16 calc_divisor(struct mmc_ios *ios) | 598 | static u16 calc_divisor(struct omap_hsmmc_host *host, struct mmc_ios *ios) |
| 602 | { | 599 | { |
| 603 | u16 dsor = 0; | 600 | u16 dsor = 0; |
| 604 | 601 | ||
| 605 | if (ios->clock) { | 602 | if (ios->clock) { |
| 606 | dsor = DIV_ROUND_UP(OMAP_MMC_MASTER_CLOCK, ios->clock); | 603 | dsor = DIV_ROUND_UP(clk_get_rate(host->fclk), ios->clock); |
| 607 | if (dsor > 250) | 604 | if (dsor > 250) |
| 608 | dsor = 250; | 605 | dsor = 250; |
| 609 | } | 606 | } |
| @@ -623,7 +620,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) | |||
| 623 | 620 | ||
| 624 | regval = OMAP_HSMMC_READ(host->base, SYSCTL); | 621 | regval = OMAP_HSMMC_READ(host->base, SYSCTL); |
| 625 | regval = regval & ~(CLKD_MASK | DTO_MASK); | 622 | regval = regval & ~(CLKD_MASK | DTO_MASK); |
| 626 | regval = regval | (calc_divisor(ios) << 6) | (DTO << 16); | 623 | regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16); |
| 627 | OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); | 624 | OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); |
| 628 | OMAP_HSMMC_WRITE(host->base, SYSCTL, | 625 | OMAP_HSMMC_WRITE(host->base, SYSCTL, |
| 629 | OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); | 626 | OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); |
| @@ -1280,17 +1277,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) | |||
| 1280 | } | 1277 | } |
| 1281 | 1278 | ||
| 1282 | /* | 1279 | /* |
| 1283 | * Work Item to notify the core about card insertion/removal | 1280 | * irq handler to notify the core about card insertion/removal |
| 1284 | */ | 1281 | */ |
| 1285 | static void omap_hsmmc_detect(struct work_struct *work) | 1282 | static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id) |
| 1286 | { | 1283 | { |
| 1287 | struct omap_hsmmc_host *host = | 1284 | struct omap_hsmmc_host *host = dev_id; |
| 1288 | container_of(work, struct omap_hsmmc_host, mmc_carddetect_work); | ||
| 1289 | struct omap_mmc_slot_data *slot = &mmc_slot(host); | 1285 | struct omap_mmc_slot_data *slot = &mmc_slot(host); |
| 1290 | int carddetect; | 1286 | int carddetect; |
| 1291 | 1287 | ||
| 1292 | if (host->suspended) | 1288 | if (host->suspended) |
| 1293 | return; | 1289 | return IRQ_HANDLED; |
| 1294 | 1290 | ||
| 1295 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); | 1291 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); |
| 1296 | 1292 | ||
| @@ -1305,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work) | |||
| 1305 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); | 1301 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); |
| 1306 | else | 1302 | else |
| 1307 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); | 1303 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); |
| 1308 | } | ||
| 1309 | |||
| 1310 | /* | ||
| 1311 | * ISR for handling card insertion and removal | ||
| 1312 | */ | ||
| 1313 | static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id) | ||
| 1314 | { | ||
| 1315 | struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id; | ||
| 1316 | |||
| 1317 | if (host->suspended) | ||
| 1318 | return IRQ_HANDLED; | ||
| 1319 | schedule_work(&host->mmc_carddetect_work); | ||
| 1320 | |||
| 1321 | return IRQ_HANDLED; | 1304 | return IRQ_HANDLED; |
| 1322 | } | 1305 | } |
| 1323 | 1306 | ||
| @@ -1919,7 +1902,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
| 1919 | host->next_data.cookie = 1; | 1902 | host->next_data.cookie = 1; |
| 1920 | 1903 | ||
| 1921 | platform_set_drvdata(pdev, host); | 1904 | platform_set_drvdata(pdev, host); |
| 1922 | INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); | ||
| 1923 | 1905 | ||
| 1924 | mmc->ops = &omap_hsmmc_ops; | 1906 | mmc->ops = &omap_hsmmc_ops; |
| 1925 | 1907 | ||
| @@ -2049,10 +2031,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
| 2049 | 2031 | ||
| 2050 | /* Request IRQ for card detect */ | 2032 | /* Request IRQ for card detect */ |
| 2051 | if ((mmc_slot(host).card_detect_irq)) { | 2033 | if ((mmc_slot(host).card_detect_irq)) { |
| 2052 | ret = request_irq(mmc_slot(host).card_detect_irq, | 2034 | ret = request_threaded_irq(mmc_slot(host).card_detect_irq, |
| 2053 | omap_hsmmc_cd_handler, | 2035 | NULL, |
| 2054 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 2036 | omap_hsmmc_detect, |
| 2055 | mmc_hostname(mmc), host); | 2037 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| 2038 | mmc_hostname(mmc), host); | ||
| 2056 | if (ret) { | 2039 | if (ret) { |
| 2057 | dev_dbg(mmc_dev(host->mmc), | 2040 | dev_dbg(mmc_dev(host->mmc), |
| 2058 | "Unable to grab MMC CD IRQ\n"); | 2041 | "Unable to grab MMC CD IRQ\n"); |
| @@ -2131,7 +2114,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
| 2131 | free_irq(host->irq, host); | 2114 | free_irq(host->irq, host); |
| 2132 | if (mmc_slot(host).card_detect_irq) | 2115 | if (mmc_slot(host).card_detect_irq) |
| 2133 | free_irq(mmc_slot(host).card_detect_irq, host); | 2116 | free_irq(mmc_slot(host).card_detect_irq, host); |
| 2134 | flush_work_sync(&host->mmc_carddetect_work); | ||
| 2135 | 2117 | ||
| 2136 | pm_runtime_put_sync(host->dev); | 2118 | pm_runtime_put_sync(host->dev); |
| 2137 | pm_runtime_disable(host->dev); | 2119 | pm_runtime_disable(host->dev); |
| @@ -2178,7 +2160,6 @@ static int omap_hsmmc_suspend(struct device *dev) | |||
| 2178 | return ret; | 2160 | return ret; |
| 2179 | } | 2161 | } |
| 2180 | } | 2162 | } |
| 2181 | cancel_work_sync(&host->mmc_carddetect_work); | ||
| 2182 | ret = mmc_suspend_host(host->mmc); | 2163 | ret = mmc_suspend_host(host->mmc); |
| 2183 | 2164 | ||
| 2184 | if (ret) { | 2165 | if (ret) { |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index fc4356e00d4..cb2dc0e75ba 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
| @@ -872,18 +872,7 @@ static struct platform_driver pxamci_driver = { | |||
| 872 | }, | 872 | }, |
| 873 | }; | 873 | }; |
| 874 | 874 | ||
| 875 | static int __init pxamci_init(void) | 875 | module_platform_driver(pxamci_driver); |
| 876 | { | ||
| 877 | return platform_driver_register(&pxamci_driver); | ||
| 878 | } | ||
| 879 | |||
| 880 | static void __exit pxamci_exit(void) | ||
| 881 | { | ||
| 882 | platform_driver_unregister(&pxamci_driver); | ||
| 883 | } | ||
| 884 | |||
| 885 | module_init(pxamci_init); | ||
| 886 | module_exit(pxamci_exit); | ||
| 887 | 876 | ||
| 888 | MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver"); | 877 | MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver"); |
| 889 | MODULE_LICENSE("GPL"); | 878 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 720f99334a7..1bcfd6dbb5c 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
| @@ -1914,18 +1914,7 @@ static struct platform_driver s3cmci_driver = { | |||
| 1914 | .shutdown = s3cmci_shutdown, | 1914 | .shutdown = s3cmci_shutdown, |
| 1915 | }; | 1915 | }; |
| 1916 | 1916 | ||
| 1917 | static int __init s3cmci_init(void) | 1917 | module_platform_driver(s3cmci_driver); |
| 1918 | { | ||
| 1919 | return platform_driver_register(&s3cmci_driver); | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | static void __exit s3cmci_exit(void) | ||
| 1923 | { | ||
| 1924 | platform_driver_unregister(&s3cmci_driver); | ||
| 1925 | } | ||
| 1926 | |||
| 1927 | module_init(s3cmci_init); | ||
| 1928 | module_exit(s3cmci_exit); | ||
| 1929 | 1918 | ||
| 1930 | MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); | 1919 | MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); |
| 1931 | MODULE_LICENSE("GPL v2"); | 1920 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c index b4257e70061..28a870804f6 100644 --- a/drivers/mmc/host/sdhci-cns3xxx.c +++ b/drivers/mmc/host/sdhci-cns3xxx.c | |||
| @@ -115,17 +115,7 @@ static struct platform_driver sdhci_cns3xxx_driver = { | |||
| 115 | .remove = __devexit_p(sdhci_cns3xxx_remove), | 115 | .remove = __devexit_p(sdhci_cns3xxx_remove), |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | static int __init sdhci_cns3xxx_init(void) | 118 | module_platform_driver(sdhci_cns3xxx_driver); |
| 119 | { | ||
| 120 | return platform_driver_register(&sdhci_cns3xxx_driver); | ||
| 121 | } | ||
| 122 | module_init(sdhci_cns3xxx_init); | ||
| 123 | |||
| 124 | static void __exit sdhci_cns3xxx_exit(void) | ||
| 125 | { | ||
| 126 | platform_driver_unregister(&sdhci_cns3xxx_driver); | ||
| 127 | } | ||
| 128 | module_exit(sdhci_cns3xxx_exit); | ||
| 129 | 119 | ||
| 130 | MODULE_DESCRIPTION("SDHCI driver for CNS3xxx"); | 120 | MODULE_DESCRIPTION("SDHCI driver for CNS3xxx"); |
| 131 | MODULE_AUTHOR("Scott Shu, " | 121 | MODULE_AUTHOR("Scott Shu, " |
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index a81312c91f7..46fd1fd1b60 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c | |||
| @@ -88,17 +88,7 @@ static struct platform_driver sdhci_dove_driver = { | |||
| 88 | .remove = __devexit_p(sdhci_dove_remove), | 88 | .remove = __devexit_p(sdhci_dove_remove), |
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | static int __init sdhci_dove_init(void) | 91 | module_platform_driver(sdhci_dove_driver); |
| 92 | { | ||
| 93 | return platform_driver_register(&sdhci_dove_driver); | ||
| 94 | } | ||
| 95 | module_init(sdhci_dove_init); | ||
| 96 | |||
| 97 | static void __exit sdhci_dove_exit(void) | ||
| 98 | { | ||
| 99 | platform_driver_unregister(&sdhci_dove_driver); | ||
| 100 | } | ||
| 101 | module_exit(sdhci_dove_exit); | ||
| 102 | 92 | ||
| 103 | MODULE_DESCRIPTION("SDHCI driver for Dove"); | 93 | MODULE_DESCRIPTION("SDHCI driver for Dove"); |
| 104 | MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>, " | 94 | MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>, " |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 38ebc4ea259..d601e41af28 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
| @@ -606,17 +606,7 @@ static struct platform_driver sdhci_esdhc_imx_driver = { | |||
| 606 | .remove = __devexit_p(sdhci_esdhc_imx_remove), | 606 | .remove = __devexit_p(sdhci_esdhc_imx_remove), |
| 607 | }; | 607 | }; |
| 608 | 608 | ||
| 609 | static int __init sdhci_esdhc_imx_init(void) | 609 | module_platform_driver(sdhci_esdhc_imx_driver); |
| 610 | { | ||
| 611 | return platform_driver_register(&sdhci_esdhc_imx_driver); | ||
| 612 | } | ||
| 613 | module_init(sdhci_esdhc_imx_init); | ||
| 614 | |||
| 615 | static void __exit sdhci_esdhc_imx_exit(void) | ||
| 616 | { | ||
| 617 | platform_driver_unregister(&sdhci_esdhc_imx_driver); | ||
| 618 | } | ||
| 619 | module_exit(sdhci_esdhc_imx_exit); | ||
| 620 | 610 | ||
| 621 | MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC"); | 611 | MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC"); |
| 622 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); | 612 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); |
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index c3b08f11194..b97b2f5dafd 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h | |||
| @@ -73,7 +73,7 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) | |||
| 73 | | (div << ESDHC_DIVIDER_SHIFT) | 73 | | (div << ESDHC_DIVIDER_SHIFT) |
| 74 | | (pre_div << ESDHC_PREDIV_SHIFT)); | 74 | | (pre_div << ESDHC_PREDIV_SHIFT)); |
| 75 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); | 75 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); |
| 76 | mdelay(100); | 76 | mdelay(1); |
| 77 | out: | 77 | out: |
| 78 | host->clock = clock; | 78 | host->clock = clock; |
| 79 | } | 79 | } |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 01e5f627e0f..ff4adc01804 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
| @@ -131,17 +131,7 @@ static struct platform_driver sdhci_esdhc_driver = { | |||
| 131 | .remove = __devexit_p(sdhci_esdhc_remove), | 131 | .remove = __devexit_p(sdhci_esdhc_remove), |
| 132 | }; | 132 | }; |
| 133 | 133 | ||
| 134 | static int __init sdhci_esdhc_init(void) | 134 | module_platform_driver(sdhci_esdhc_driver); |
| 135 | { | ||
| 136 | return platform_driver_register(&sdhci_esdhc_driver); | ||
| 137 | } | ||
| 138 | module_init(sdhci_esdhc_init); | ||
| 139 | |||
| 140 | static void __exit sdhci_esdhc_exit(void) | ||
| 141 | { | ||
| 142 | platform_driver_unregister(&sdhci_esdhc_driver); | ||
| 143 | } | ||
| 144 | module_exit(sdhci_esdhc_exit); | ||
| 145 | 135 | ||
| 146 | MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC"); | 136 | MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC"); |
| 147 | MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, " | 137 | MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, " |
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c index 3619adc7d9f..0ce088ae022 100644 --- a/drivers/mmc/host/sdhci-of-hlwd.c +++ b/drivers/mmc/host/sdhci-of-hlwd.c | |||
| @@ -93,17 +93,7 @@ static struct platform_driver sdhci_hlwd_driver = { | |||
| 93 | .remove = __devexit_p(sdhci_hlwd_remove), | 93 | .remove = __devexit_p(sdhci_hlwd_remove), |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | static int __init sdhci_hlwd_init(void) | 96 | module_platform_driver(sdhci_hlwd_driver); |
| 97 | { | ||
| 98 | return platform_driver_register(&sdhci_hlwd_driver); | ||
| 99 | } | ||
| 100 | module_init(sdhci_hlwd_init); | ||
| 101 | |||
| 102 | static void __exit sdhci_hlwd_exit(void) | ||
| 103 | { | ||
| 104 | platform_driver_unregister(&sdhci_hlwd_driver); | ||
| 105 | } | ||
| 106 | module_exit(sdhci_hlwd_exit); | ||
| 107 | 97 | ||
| 108 | MODULE_DESCRIPTION("Nintendo Wii SDHCI OF driver"); | 98 | MODULE_DESCRIPTION("Nintendo Wii SDHCI OF driver"); |
| 109 | MODULE_AUTHOR("The GameCube Linux Team, Albert Herranz"); | 99 | MODULE_AUTHOR("The GameCube Linux Team, Albert Herranz"); |
diff --git a/drivers/mmc/host/sdhci-pci-data.c b/drivers/mmc/host/sdhci-pci-data.c new file mode 100644 index 00000000000..a611217769f --- /dev/null +++ b/drivers/mmc/host/sdhci-pci-data.c | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #include <linux/module.h> | ||
| 2 | #include <linux/mmc/sdhci-pci-data.h> | ||
| 3 | |||
| 4 | struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, int slotno); | ||
| 5 | EXPORT_SYMBOL_GPL(sdhci_pci_get_data); | ||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 6878a94626b..7165e6a0927 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
| @@ -23,8 +23,8 @@ | |||
| 23 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
| 24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
| 25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
| 26 | #include <linux/sfi.h> | ||
| 27 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
| 27 | #include <linux/mmc/sdhci-pci-data.h> | ||
| 28 | 28 | ||
| 29 | #include "sdhci.h" | 29 | #include "sdhci.h" |
| 30 | 30 | ||
| @@ -61,6 +61,7 @@ struct sdhci_pci_fixes { | |||
| 61 | struct sdhci_pci_slot { | 61 | struct sdhci_pci_slot { |
| 62 | struct sdhci_pci_chip *chip; | 62 | struct sdhci_pci_chip *chip; |
| 63 | struct sdhci_host *host; | 63 | struct sdhci_host *host; |
| 64 | struct sdhci_pci_data *data; | ||
| 64 | 65 | ||
| 65 | int pci_bar; | 66 | int pci_bar; |
| 66 | int rst_n_gpio; | 67 | int rst_n_gpio; |
| @@ -171,32 +172,9 @@ static int mrst_hc_probe(struct sdhci_pci_chip *chip) | |||
| 171 | return 0; | 172 | return 0; |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | /* Medfield eMMC hardware reset GPIOs */ | ||
| 175 | static int mfd_emmc0_rst_gpio = -EINVAL; | ||
| 176 | static int mfd_emmc1_rst_gpio = -EINVAL; | ||
| 177 | |||
| 178 | static int mfd_emmc_gpio_parse(struct sfi_table_header *table) | ||
| 179 | { | ||
| 180 | struct sfi_table_simple *sb = (struct sfi_table_simple *)table; | ||
| 181 | struct sfi_gpio_table_entry *entry; | ||
| 182 | int i, num; | ||
| 183 | |||
| 184 | num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry); | ||
| 185 | entry = (struct sfi_gpio_table_entry *)sb->pentry; | ||
| 186 | |||
| 187 | for (i = 0; i < num; i++, entry++) { | ||
| 188 | if (!strncmp(entry->pin_name, "emmc0_rst", SFI_NAME_LEN)) | ||
| 189 | mfd_emmc0_rst_gpio = entry->pin_no; | ||
| 190 | else if (!strncmp(entry->pin_name, "emmc1_rst", SFI_NAME_LEN)) | ||
| 191 | mfd_emmc1_rst_gpio = entry->pin_no; | ||
| 192 | } | ||
| 193 | |||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | #ifdef CONFIG_PM_RUNTIME | 175 | #ifdef CONFIG_PM_RUNTIME |
| 198 | 176 | ||
| 199 | static irqreturn_t mfd_sd_cd(int irq, void *dev_id) | 177 | static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id) |
| 200 | { | 178 | { |
| 201 | struct sdhci_pci_slot *slot = dev_id; | 179 | struct sdhci_pci_slot *slot = dev_id; |
| 202 | struct sdhci_host *host = slot->host; | 180 | struct sdhci_host *host = slot->host; |
| @@ -205,15 +183,16 @@ static irqreturn_t mfd_sd_cd(int irq, void *dev_id) | |||
| 205 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
| 206 | } | 184 | } |
| 207 | 185 | ||
| 208 | #define MFLD_SD_CD_PIN 69 | 186 | static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot) |
| 209 | |||
| 210 | static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot) | ||
| 211 | { | 187 | { |
| 212 | int err, irq, gpio = MFLD_SD_CD_PIN; | 188 | int err, irq, gpio = slot->cd_gpio; |
| 213 | 189 | ||
| 214 | slot->cd_gpio = -EINVAL; | 190 | slot->cd_gpio = -EINVAL; |
| 215 | slot->cd_irq = -EINVAL; | 191 | slot->cd_irq = -EINVAL; |
| 216 | 192 | ||
| 193 | if (!gpio_is_valid(gpio)) | ||
| 194 | return; | ||
| 195 | |||
| 217 | err = gpio_request(gpio, "sd_cd"); | 196 | err = gpio_request(gpio, "sd_cd"); |
| 218 | if (err < 0) | 197 | if (err < 0) |
| 219 | goto out; | 198 | goto out; |
| @@ -226,72 +205,53 @@ static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot) | |||
| 226 | if (irq < 0) | 205 | if (irq < 0) |
| 227 | goto out_free; | 206 | goto out_free; |
| 228 | 207 | ||
| 229 | err = request_irq(irq, mfd_sd_cd, IRQF_TRIGGER_RISING | | 208 | err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING | |
| 230 | IRQF_TRIGGER_FALLING, "sd_cd", slot); | 209 | IRQF_TRIGGER_FALLING, "sd_cd", slot); |
| 231 | if (err) | 210 | if (err) |
| 232 | goto out_free; | 211 | goto out_free; |
| 233 | 212 | ||
| 234 | slot->cd_gpio = gpio; | 213 | slot->cd_gpio = gpio; |
| 235 | slot->cd_irq = irq; | 214 | slot->cd_irq = irq; |
| 236 | slot->host->quirks2 |= SDHCI_QUIRK2_OWN_CARD_DETECTION; | ||
| 237 | 215 | ||
| 238 | return 0; | 216 | return; |
| 239 | 217 | ||
| 240 | out_free: | 218 | out_free: |
| 241 | gpio_free(gpio); | 219 | gpio_free(gpio); |
| 242 | out: | 220 | out: |
| 243 | dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n"); | 221 | dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n"); |
| 244 | return 0; | ||
| 245 | } | 222 | } |
| 246 | 223 | ||
| 247 | static void mfd_sd_remove_slot(struct sdhci_pci_slot *slot, int dead) | 224 | static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot) |
| 248 | { | 225 | { |
| 249 | if (slot->cd_irq >= 0) | 226 | if (slot->cd_irq >= 0) |
| 250 | free_irq(slot->cd_irq, slot); | 227 | free_irq(slot->cd_irq, slot); |
| 251 | gpio_free(slot->cd_gpio); | 228 | if (gpio_is_valid(slot->cd_gpio)) |
| 229 | gpio_free(slot->cd_gpio); | ||
| 252 | } | 230 | } |
| 253 | 231 | ||
| 254 | #else | 232 | #else |
| 255 | 233 | ||
| 256 | #define mfd_sd_probe_slot NULL | 234 | static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot) |
| 257 | #define mfd_sd_remove_slot NULL | 235 | { |
| 236 | } | ||
| 237 | |||
| 238 | static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot) | ||
| 239 | { | ||
| 240 | } | ||
| 258 | 241 | ||
| 259 | #endif | 242 | #endif |
| 260 | 243 | ||
| 261 | static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot) | 244 | static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot) |
| 262 | { | 245 | { |
| 263 | const char *name = NULL; | ||
| 264 | int gpio = -EINVAL; | ||
| 265 | |||
| 266 | sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, mfd_emmc_gpio_parse); | ||
| 267 | |||
| 268 | switch (slot->chip->pdev->device) { | ||
| 269 | case PCI_DEVICE_ID_INTEL_MFD_EMMC0: | ||
| 270 | gpio = mfd_emmc0_rst_gpio; | ||
| 271 | name = "eMMC0_reset"; | ||
| 272 | break; | ||
| 273 | case PCI_DEVICE_ID_INTEL_MFD_EMMC1: | ||
| 274 | gpio = mfd_emmc1_rst_gpio; | ||
| 275 | name = "eMMC1_reset"; | ||
| 276 | break; | ||
| 277 | } | ||
| 278 | |||
| 279 | if (!gpio_request(gpio, name)) { | ||
| 280 | gpio_direction_output(gpio, 1); | ||
| 281 | slot->rst_n_gpio = gpio; | ||
| 282 | slot->host->mmc->caps |= MMC_CAP_HW_RESET; | ||
| 283 | } | ||
| 284 | |||
| 285 | slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE; | 246 | slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE; |
| 286 | |||
| 287 | slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC; | 247 | slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC; |
| 288 | |||
| 289 | return 0; | 248 | return 0; |
| 290 | } | 249 | } |
| 291 | 250 | ||
| 292 | static void mfd_emmc_remove_slot(struct sdhci_pci_slot *slot, int dead) | 251 | static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot) |
| 293 | { | 252 | { |
| 294 | gpio_free(slot->rst_n_gpio); | 253 | slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD; |
| 254 | return 0; | ||
| 295 | } | 255 | } |
| 296 | 256 | ||
| 297 | static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = { | 257 | static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = { |
| @@ -307,20 +267,18 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = { | |||
| 307 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { | 267 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { |
| 308 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 268 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
| 309 | .allow_runtime_pm = true, | 269 | .allow_runtime_pm = true, |
| 310 | .probe_slot = mfd_sd_probe_slot, | ||
| 311 | .remove_slot = mfd_sd_remove_slot, | ||
| 312 | }; | 270 | }; |
| 313 | 271 | ||
| 314 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = { | 272 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = { |
| 315 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 273 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
| 316 | .allow_runtime_pm = true, | 274 | .allow_runtime_pm = true, |
| 275 | .probe_slot = mfd_sdio_probe_slot, | ||
| 317 | }; | 276 | }; |
| 318 | 277 | ||
| 319 | static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = { | 278 | static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = { |
| 320 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 279 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
| 321 | .allow_runtime_pm = true, | 280 | .allow_runtime_pm = true, |
| 322 | .probe_slot = mfd_emmc_probe_slot, | 281 | .probe_slot = mfd_emmc_probe_slot, |
| 323 | .remove_slot = mfd_emmc_remove_slot, | ||
| 324 | }; | 282 | }; |
| 325 | 283 | ||
| 326 | /* O2Micro extra registers */ | 284 | /* O2Micro extra registers */ |
| @@ -1012,11 +970,8 @@ static int sdhci_pci_suspend(struct device *dev) | |||
| 1012 | 970 | ||
| 1013 | ret = sdhci_suspend_host(slot->host); | 971 | ret = sdhci_suspend_host(slot->host); |
| 1014 | 972 | ||
| 1015 | if (ret) { | 973 | if (ret) |
| 1016 | for (i--; i >= 0; i--) | 974 | goto err_pci_suspend; |
| 1017 | sdhci_resume_host(chip->slots[i]->host); | ||
| 1018 | return ret; | ||
| 1019 | } | ||
| 1020 | 975 | ||
| 1021 | slot_pm_flags = slot->host->mmc->pm_flags; | 976 | slot_pm_flags = slot->host->mmc->pm_flags; |
| 1022 | if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ) | 977 | if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ) |
| @@ -1027,11 +982,8 @@ static int sdhci_pci_suspend(struct device *dev) | |||
| 1027 | 982 | ||
| 1028 | if (chip->fixes && chip->fixes->suspend) { | 983 | if (chip->fixes && chip->fixes->suspend) { |
| 1029 | ret = chip->fixes->suspend(chip); | 984 | ret = chip->fixes->suspend(chip); |
| 1030 | if (ret) { | 985 | if (ret) |
| 1031 | for (i = chip->num_slots - 1; i >= 0; i--) | 986 | goto err_pci_suspend; |
| 1032 | sdhci_resume_host(chip->slots[i]->host); | ||
| 1033 | return ret; | ||
| 1034 | } | ||
| 1035 | } | 987 | } |
| 1036 | 988 | ||
| 1037 | pci_save_state(pdev); | 989 | pci_save_state(pdev); |
| @@ -1048,6 +1000,11 @@ static int sdhci_pci_suspend(struct device *dev) | |||
| 1048 | } | 1000 | } |
| 1049 | 1001 | ||
| 1050 | return 0; | 1002 | return 0; |
| 1003 | |||
| 1004 | err_pci_suspend: | ||
| 1005 | while (--i >= 0) | ||
| 1006 | sdhci_resume_host(chip->slots[i]->host); | ||
| 1007 | return ret; | ||
| 1051 | } | 1008 | } |
| 1052 | 1009 | ||
| 1053 | static int sdhci_pci_resume(struct device *dev) | 1010 | static int sdhci_pci_resume(struct device *dev) |
| @@ -1113,23 +1070,22 @@ static int sdhci_pci_runtime_suspend(struct device *dev) | |||
| 1113 | 1070 | ||
| 1114 | ret = sdhci_runtime_suspend_host(slot->host); | 1071 | ret = sdhci_runtime_suspend_host(slot->host); |
| 1115 | 1072 | ||
| 1116 | if (ret) { | 1073 | if (ret) |
| 1117 | for (i--; i >= 0; i--) | 1074 | goto err_pci_runtime_suspend; |
| 1118 | sdhci_runtime_resume_host(chip->slots[i]->host); | ||
| 1119 | return ret; | ||
| 1120 | } | ||
| 1121 | } | 1075 | } |
| 1122 | 1076 | ||
| 1123 | if (chip->fixes && chip->fixes->suspend) { | 1077 | if (chip->fixes && chip->fixes->suspend) { |
| 1124 | ret = chip->fixes->suspend(chip); | 1078 | ret = chip->fixes->suspend(chip); |
| 1125 | if (ret) { | 1079 | if (ret) |
| 1126 | for (i = chip->num_slots - 1; i >= 0; i--) | 1080 | goto err_pci_runtime_suspend; |
| 1127 | sdhci_runtime_resume_host(chip->slots[i]->host); | ||
| 1128 | return ret; | ||
| 1129 | } | ||
| 1130 | } | 1081 | } |
| 1131 | 1082 | ||
| 1132 | return 0; | 1083 | return 0; |
| 1084 | |||
| 1085 | err_pci_runtime_suspend: | ||
| 1086 | while (--i >= 0) | ||
| 1087 | sdhci_runtime_resume_host(chip->slots[i]->host); | ||
| 1088 | return ret; | ||
| 1133 | } | 1089 | } |
| 1134 | 1090 | ||
| 1135 | static int sdhci_pci_runtime_resume(struct device *dev) | 1091 | static int sdhci_pci_runtime_resume(struct device *dev) |
| @@ -1190,11 +1146,12 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = { | |||
| 1190 | \*****************************************************************************/ | 1146 | \*****************************************************************************/ |
| 1191 | 1147 | ||
| 1192 | static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | 1148 | static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( |
| 1193 | struct pci_dev *pdev, struct sdhci_pci_chip *chip, int bar) | 1149 | struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar, |
| 1150 | int slotno) | ||
| 1194 | { | 1151 | { |
| 1195 | struct sdhci_pci_slot *slot; | 1152 | struct sdhci_pci_slot *slot; |
| 1196 | struct sdhci_host *host; | 1153 | struct sdhci_host *host; |
| 1197 | int ret; | 1154 | int ret, bar = first_bar + slotno; |
| 1198 | 1155 | ||
| 1199 | if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { | 1156 | if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { |
| 1200 | dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar); | 1157 | dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar); |
| @@ -1228,6 +1185,23 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
| 1228 | slot->host = host; | 1185 | slot->host = host; |
| 1229 | slot->pci_bar = bar; | 1186 | slot->pci_bar = bar; |
| 1230 | slot->rst_n_gpio = -EINVAL; | 1187 | slot->rst_n_gpio = -EINVAL; |
| 1188 | slot->cd_gpio = -EINVAL; | ||
| 1189 | |||
| 1190 | /* Retrieve platform data if there is any */ | ||
| 1191 | if (*sdhci_pci_get_data) | ||
| 1192 | slot->data = sdhci_pci_get_data(pdev, slotno); | ||
| 1193 | |||
| 1194 | if (slot->data) { | ||
| 1195 | if (slot->data->setup) { | ||
| 1196 | ret = slot->data->setup(slot->data); | ||
| 1197 | if (ret) { | ||
| 1198 | dev_err(&pdev->dev, "platform setup failed\n"); | ||
| 1199 | goto free; | ||
| 1200 | } | ||
| 1201 | } | ||
| 1202 | slot->rst_n_gpio = slot->data->rst_n_gpio; | ||
| 1203 | slot->cd_gpio = slot->data->cd_gpio; | ||
| 1204 | } | ||
| 1231 | 1205 | ||
| 1232 | host->hw_name = "PCI"; | 1206 | host->hw_name = "PCI"; |
| 1233 | host->ops = &sdhci_pci_ops; | 1207 | host->ops = &sdhci_pci_ops; |
| @@ -1238,7 +1212,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
| 1238 | ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc)); | 1212 | ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc)); |
| 1239 | if (ret) { | 1213 | if (ret) { |
| 1240 | dev_err(&pdev->dev, "cannot request region\n"); | 1214 | dev_err(&pdev->dev, "cannot request region\n"); |
| 1241 | goto free; | 1215 | goto cleanup; |
| 1242 | } | 1216 | } |
| 1243 | 1217 | ||
| 1244 | host->ioaddr = pci_ioremap_bar(pdev, bar); | 1218 | host->ioaddr = pci_ioremap_bar(pdev, bar); |
| @@ -1254,15 +1228,30 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
| 1254 | goto unmap; | 1228 | goto unmap; |
| 1255 | } | 1229 | } |
| 1256 | 1230 | ||
| 1231 | if (gpio_is_valid(slot->rst_n_gpio)) { | ||
| 1232 | if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) { | ||
| 1233 | gpio_direction_output(slot->rst_n_gpio, 1); | ||
| 1234 | slot->host->mmc->caps |= MMC_CAP_HW_RESET; | ||
| 1235 | } else { | ||
| 1236 | dev_warn(&pdev->dev, "failed to request rst_n_gpio\n"); | ||
| 1237 | slot->rst_n_gpio = -EINVAL; | ||
| 1238 | } | ||
| 1239 | } | ||
| 1240 | |||
| 1257 | host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; | 1241 | host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; |
| 1258 | 1242 | ||
| 1259 | ret = sdhci_add_host(host); | 1243 | ret = sdhci_add_host(host); |
| 1260 | if (ret) | 1244 | if (ret) |
| 1261 | goto remove; | 1245 | goto remove; |
| 1262 | 1246 | ||
| 1247 | sdhci_pci_add_own_cd(slot); | ||
| 1248 | |||
| 1263 | return slot; | 1249 | return slot; |
| 1264 | 1250 | ||
| 1265 | remove: | 1251 | remove: |
| 1252 | if (gpio_is_valid(slot->rst_n_gpio)) | ||
| 1253 | gpio_free(slot->rst_n_gpio); | ||
| 1254 | |||
| 1266 | if (chip->fixes && chip->fixes->remove_slot) | 1255 | if (chip->fixes && chip->fixes->remove_slot) |
| 1267 | chip->fixes->remove_slot(slot, 0); | 1256 | chip->fixes->remove_slot(slot, 0); |
| 1268 | 1257 | ||
| @@ -1272,6 +1261,10 @@ unmap: | |||
| 1272 | release: | 1261 | release: |
| 1273 | pci_release_region(pdev, bar); | 1262 | pci_release_region(pdev, bar); |
| 1274 | 1263 | ||
| 1264 | cleanup: | ||
| 1265 | if (slot->data && slot->data->cleanup) | ||
| 1266 | slot->data->cleanup(slot->data); | ||
| 1267 | |||
| 1275 | free: | 1268 | free: |
| 1276 | sdhci_free_host(host); | 1269 | sdhci_free_host(host); |
| 1277 | 1270 | ||
| @@ -1283,6 +1276,8 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) | |||
| 1283 | int dead; | 1276 | int dead; |
| 1284 | u32 scratch; | 1277 | u32 scratch; |
| 1285 | 1278 | ||
| 1279 | sdhci_pci_remove_own_cd(slot); | ||
| 1280 | |||
| 1286 | dead = 0; | 1281 | dead = 0; |
| 1287 | scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); | 1282 | scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); |
| 1288 | if (scratch == (u32)-1) | 1283 | if (scratch == (u32)-1) |
| @@ -1290,9 +1285,15 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) | |||
| 1290 | 1285 | ||
| 1291 | sdhci_remove_host(slot->host, dead); | 1286 | sdhci_remove_host(slot->host, dead); |
| 1292 | 1287 | ||
| 1288 | if (gpio_is_valid(slot->rst_n_gpio)) | ||
| 1289 | gpio_free(slot->rst_n_gpio); | ||
| 1290 | |||
| 1293 | if (slot->chip->fixes && slot->chip->fixes->remove_slot) | 1291 | if (slot->chip->fixes && slot->chip->fixes->remove_slot) |
| 1294 | slot->chip->fixes->remove_slot(slot, dead); | 1292 | slot->chip->fixes->remove_slot(slot, dead); |
| 1295 | 1293 | ||
| 1294 | if (slot->data && slot->data->cleanup) | ||
| 1295 | slot->data->cleanup(slot->data); | ||
| 1296 | |||
| 1296 | pci_release_region(slot->chip->pdev, slot->pci_bar); | 1297 | pci_release_region(slot->chip->pdev, slot->pci_bar); |
| 1297 | 1298 | ||
| 1298 | sdhci_free_host(slot->host); | 1299 | sdhci_free_host(slot->host); |
| @@ -1379,7 +1380,7 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, | |||
| 1379 | slots = chip->num_slots; /* Quirk may have changed this */ | 1380 | slots = chip->num_slots; /* Quirk may have changed this */ |
| 1380 | 1381 | ||
| 1381 | for (i = 0; i < slots; i++) { | 1382 | for (i = 0; i < slots; i++) { |
| 1382 | slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i); | 1383 | slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i); |
| 1383 | if (IS_ERR(slot)) { | 1384 | if (IS_ERR(slot)) { |
| 1384 | for (i--; i >= 0; i--) | 1385 | for (i--; i >= 0; i--) |
| 1385 | sdhci_pci_remove_slot(chip->slots[i]); | 1386 | sdhci_pci_remove_slot(chip->slots[i]); |
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index 7a039c3cb1f..dbb75bfbcff 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c | |||
| @@ -223,18 +223,8 @@ static struct platform_driver sdhci_pxav2_driver = { | |||
| 223 | .probe = sdhci_pxav2_probe, | 223 | .probe = sdhci_pxav2_probe, |
| 224 | .remove = __devexit_p(sdhci_pxav2_remove), | 224 | .remove = __devexit_p(sdhci_pxav2_remove), |
| 225 | }; | 225 | }; |
| 226 | static int __init sdhci_pxav2_init(void) | ||
| 227 | { | ||
| 228 | return platform_driver_register(&sdhci_pxav2_driver); | ||
| 229 | } | ||
| 230 | |||
| 231 | static void __exit sdhci_pxav2_exit(void) | ||
| 232 | { | ||
| 233 | platform_driver_unregister(&sdhci_pxav2_driver); | ||
| 234 | } | ||
| 235 | 226 | ||
| 236 | module_init(sdhci_pxav2_init); | 227 | module_platform_driver(sdhci_pxav2_driver); |
| 237 | module_exit(sdhci_pxav2_exit); | ||
| 238 | 228 | ||
| 239 | MODULE_DESCRIPTION("SDHCI driver for pxav2"); | 229 | MODULE_DESCRIPTION("SDHCI driver for pxav2"); |
| 240 | MODULE_AUTHOR("Marvell International Ltd."); | 230 | MODULE_AUTHOR("Marvell International Ltd."); |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 15673a7ee6a..f2969568355 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
| @@ -269,18 +269,8 @@ static struct platform_driver sdhci_pxav3_driver = { | |||
| 269 | .probe = sdhci_pxav3_probe, | 269 | .probe = sdhci_pxav3_probe, |
| 270 | .remove = __devexit_p(sdhci_pxav3_remove), | 270 | .remove = __devexit_p(sdhci_pxav3_remove), |
| 271 | }; | 271 | }; |
| 272 | static int __init sdhci_pxav3_init(void) | ||
| 273 | { | ||
| 274 | return platform_driver_register(&sdhci_pxav3_driver); | ||
| 275 | } | ||
| 276 | |||
| 277 | static void __exit sdhci_pxav3_exit(void) | ||
| 278 | { | ||
| 279 | platform_driver_unregister(&sdhci_pxav3_driver); | ||
| 280 | } | ||
| 281 | 272 | ||
| 282 | module_init(sdhci_pxav3_init); | 273 | module_platform_driver(sdhci_pxav3_driver); |
| 283 | module_exit(sdhci_pxav3_exit); | ||
| 284 | 274 | ||
| 285 | MODULE_DESCRIPTION("SDHCI driver for pxav3"); | 275 | MODULE_DESCRIPTION("SDHCI driver for pxav3"); |
| 286 | MODULE_AUTHOR("Marvell International Ltd."); | 276 | MODULE_AUTHOR("Marvell International Ltd."); |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 9a20d1f55bb..1af756ee0f9 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
| @@ -80,7 +80,7 @@ static void sdhci_s3c_check_sclk(struct sdhci_host *host) | |||
| 80 | 80 | ||
| 81 | tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; | 81 | tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; |
| 82 | tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; | 82 | tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; |
| 83 | writel(tmp, host->ioaddr + 0x80); | 83 | writel(tmp, host->ioaddr + S3C_SDHCI_CONTROL2); |
| 84 | } | 84 | } |
| 85 | } | 85 | } |
| 86 | 86 | ||
| @@ -521,6 +521,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 521 | if (pdata->host_caps) | 521 | if (pdata->host_caps) |
| 522 | host->mmc->caps |= pdata->host_caps; | 522 | host->mmc->caps |= pdata->host_caps; |
| 523 | 523 | ||
| 524 | if (pdata->pm_caps) | ||
| 525 | host->mmc->pm_caps |= pdata->pm_caps; | ||
| 526 | |||
| 524 | host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR | | 527 | host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR | |
| 525 | SDHCI_QUIRK_32BIT_DMA_SIZE); | 528 | SDHCI_QUIRK_32BIT_DMA_SIZE); |
| 526 | 529 | ||
| @@ -654,18 +657,7 @@ static struct platform_driver sdhci_s3c_driver = { | |||
| 654 | }, | 657 | }, |
| 655 | }; | 658 | }; |
| 656 | 659 | ||
| 657 | static int __init sdhci_s3c_init(void) | 660 | module_platform_driver(sdhci_s3c_driver); |
| 658 | { | ||
| 659 | return platform_driver_register(&sdhci_s3c_driver); | ||
| 660 | } | ||
| 661 | |||
| 662 | static void __exit sdhci_s3c_exit(void) | ||
| 663 | { | ||
| 664 | platform_driver_unregister(&sdhci_s3c_driver); | ||
| 665 | } | ||
| 666 | |||
| 667 | module_init(sdhci_s3c_init); | ||
| 668 | module_exit(sdhci_s3c_exit); | ||
| 669 | 661 | ||
| 670 | MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue"); | 662 | MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue"); |
| 671 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | 663 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); |
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 63cc8b6a1c9..b7f8b33c5f1 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
| 22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/pm.h> | ||
| 24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 25 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
| 26 | #include <linux/mmc/sdhci-spear.h> | 27 | #include <linux/mmc/sdhci-spear.h> |
| @@ -271,26 +272,54 @@ static int __devexit sdhci_remove(struct platform_device *pdev) | |||
| 271 | return 0; | 272 | return 0; |
| 272 | } | 273 | } |
| 273 | 274 | ||
| 275 | #ifdef CONFIG_PM | ||
| 276 | static int sdhci_suspend(struct device *dev) | ||
| 277 | { | ||
| 278 | struct sdhci_host *host = dev_get_drvdata(dev); | ||
| 279 | struct spear_sdhci *sdhci = dev_get_platdata(dev); | ||
| 280 | int ret; | ||
| 281 | |||
| 282 | ret = sdhci_suspend_host(host); | ||
| 283 | if (!ret) | ||
| 284 | clk_disable(sdhci->clk); | ||
| 285 | |||
| 286 | return ret; | ||
| 287 | } | ||
| 288 | |||
| 289 | static int sdhci_resume(struct device *dev) | ||
| 290 | { | ||
| 291 | struct sdhci_host *host = dev_get_drvdata(dev); | ||
| 292 | struct spear_sdhci *sdhci = dev_get_platdata(dev); | ||
| 293 | int ret; | ||
| 294 | |||
| 295 | ret = clk_enable(sdhci->clk); | ||
| 296 | if (ret) { | ||
| 297 | dev_dbg(dev, "Resume: Error enabling clock\n"); | ||
| 298 | return ret; | ||
| 299 | } | ||
| 300 | |||
| 301 | return sdhci_resume_host(host); | ||
| 302 | } | ||
| 303 | |||
| 304 | const struct dev_pm_ops sdhci_pm_ops = { | ||
| 305 | .suspend = sdhci_suspend, | ||
| 306 | .resume = sdhci_resume, | ||
| 307 | }; | ||
| 308 | #endif | ||
| 309 | |||
| 274 | static struct platform_driver sdhci_driver = { | 310 | static struct platform_driver sdhci_driver = { |
| 275 | .driver = { | 311 | .driver = { |
| 276 | .name = "sdhci", | 312 | .name = "sdhci", |
| 277 | .owner = THIS_MODULE, | 313 | .owner = THIS_MODULE, |
| 314 | #ifdef CONFIG_PM | ||
| 315 | .pm = &sdhci_pm_ops, | ||
| 316 | #endif | ||
| 278 | }, | 317 | }, |
| 279 | .probe = sdhci_probe, | 318 | .probe = sdhci_probe, |
| 280 | .remove = __devexit_p(sdhci_remove), | 319 | .remove = __devexit_p(sdhci_remove), |
| 281 | }; | 320 | }; |
| 282 | 321 | ||
| 283 | static int __init sdhci_init(void) | 322 | module_platform_driver(sdhci_driver); |
| 284 | { | ||
| 285 | return platform_driver_register(&sdhci_driver); | ||
| 286 | } | ||
| 287 | module_init(sdhci_init); | ||
| 288 | |||
| 289 | static void __exit sdhci_exit(void) | ||
| 290 | { | ||
| 291 | platform_driver_unregister(&sdhci_driver); | ||
| 292 | } | ||
| 293 | module_exit(sdhci_exit); | ||
| 294 | 323 | ||
| 295 | MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); | 324 | MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); |
| 296 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); | 325 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); |
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index e2e18d3f949..78a36eba4df 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
| @@ -324,17 +324,7 @@ static struct platform_driver sdhci_tegra_driver = { | |||
| 324 | .remove = __devexit_p(sdhci_tegra_remove), | 324 | .remove = __devexit_p(sdhci_tegra_remove), |
| 325 | }; | 325 | }; |
| 326 | 326 | ||
| 327 | static int __init sdhci_tegra_init(void) | 327 | module_platform_driver(sdhci_tegra_driver); |
| 328 | { | ||
| 329 | return platform_driver_register(&sdhci_tegra_driver); | ||
| 330 | } | ||
| 331 | module_init(sdhci_tegra_init); | ||
| 332 | |||
| 333 | static void __exit sdhci_tegra_exit(void) | ||
| 334 | { | ||
| 335 | platform_driver_unregister(&sdhci_tegra_driver); | ||
| 336 | } | ||
| 337 | module_exit(sdhci_tegra_exit); | ||
| 338 | 328 | ||
| 339 | MODULE_DESCRIPTION("SDHCI driver for Tegra"); | 329 | MODULE_DESCRIPTION("SDHCI driver for Tegra"); |
| 340 | MODULE_AUTHOR(" Google, Inc."); | 330 | MODULE_AUTHOR(" Google, Inc."); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 19ed580f2ca..8d66706824a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -49,7 +49,7 @@ static void sdhci_finish_data(struct sdhci_host *); | |||
| 49 | 49 | ||
| 50 | static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); | 50 | static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); |
| 51 | static void sdhci_finish_command(struct sdhci_host *); | 51 | static void sdhci_finish_command(struct sdhci_host *); |
| 52 | static int sdhci_execute_tuning(struct mmc_host *mmc); | 52 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); |
| 53 | static void sdhci_tuning_timer(unsigned long data); | 53 | static void sdhci_tuning_timer(unsigned long data); |
| 54 | 54 | ||
| 55 | #ifdef CONFIG_PM_RUNTIME | 55 | #ifdef CONFIG_PM_RUNTIME |
| @@ -146,10 +146,8 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) | |||
| 146 | { | 146 | { |
| 147 | u32 present, irqs; | 147 | u32 present, irqs; |
| 148 | 148 | ||
| 149 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) | 149 | if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || |
| 150 | return; | 150 | !mmc_card_is_removable(host->mmc)) |
| 151 | |||
| 152 | if (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION) | ||
| 153 | return; | 151 | return; |
| 154 | 152 | ||
| 155 | present = sdhci_readl(host, SDHCI_PRESENT_STATE) & | 153 | present = sdhci_readl(host, SDHCI_PRESENT_STATE) & |
| @@ -214,6 +212,11 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) | |||
| 214 | 212 | ||
| 215 | if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) | 213 | if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) |
| 216 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); | 214 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); |
| 215 | |||
| 216 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { | ||
| 217 | if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL)) | ||
| 218 | host->ops->enable_dma(host); | ||
| 219 | } | ||
| 217 | } | 220 | } |
| 218 | 221 | ||
| 219 | static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); | 222 | static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); |
| @@ -423,12 +426,12 @@ static void sdhci_transfer_pio(struct sdhci_host *host) | |||
| 423 | static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) | 426 | static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) |
| 424 | { | 427 | { |
| 425 | local_irq_save(*flags); | 428 | local_irq_save(*flags); |
| 426 | return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 429 | return kmap_atomic(sg_page(sg)) + sg->offset; |
| 427 | } | 430 | } |
| 428 | 431 | ||
| 429 | static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) | 432 | static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) |
| 430 | { | 433 | { |
| 431 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); | 434 | kunmap_atomic(buffer); |
| 432 | local_irq_restore(*flags); | 435 | local_irq_restore(*flags); |
| 433 | } | 436 | } |
| 434 | 437 | ||
| @@ -1016,7 +1019,8 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
| 1016 | flags |= SDHCI_CMD_INDEX; | 1019 | flags |= SDHCI_CMD_INDEX; |
| 1017 | 1020 | ||
| 1018 | /* CMD19 is special in that the Data Present Select should be set */ | 1021 | /* CMD19 is special in that the Data Present Select should be set */ |
| 1019 | if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK)) | 1022 | if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK || |
| 1023 | cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) | ||
| 1020 | flags |= SDHCI_CMD_DATA; | 1024 | flags |= SDHCI_CMD_DATA; |
| 1021 | 1025 | ||
| 1022 | sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); | 1026 | sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); |
| @@ -1066,12 +1070,15 @@ static void sdhci_finish_command(struct sdhci_host *host) | |||
| 1066 | static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | 1070 | static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) |
| 1067 | { | 1071 | { |
| 1068 | int div = 0; /* Initialized for compiler warning */ | 1072 | int div = 0; /* Initialized for compiler warning */ |
| 1073 | int real_div = div, clk_mul = 1; | ||
| 1069 | u16 clk = 0; | 1074 | u16 clk = 0; |
| 1070 | unsigned long timeout; | 1075 | unsigned long timeout; |
| 1071 | 1076 | ||
| 1072 | if (clock == host->clock) | 1077 | if (clock && clock == host->clock) |
| 1073 | return; | 1078 | return; |
| 1074 | 1079 | ||
| 1080 | host->mmc->actual_clock = 0; | ||
| 1081 | |||
| 1075 | if (host->ops->set_clock) { | 1082 | if (host->ops->set_clock) { |
| 1076 | host->ops->set_clock(host, clock); | 1083 | host->ops->set_clock(host, clock); |
| 1077 | if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) | 1084 | if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) |
| @@ -1109,6 +1116,8 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
| 1109 | * Control register. | 1116 | * Control register. |
| 1110 | */ | 1117 | */ |
| 1111 | clk = SDHCI_PROG_CLOCK_MODE; | 1118 | clk = SDHCI_PROG_CLOCK_MODE; |
| 1119 | real_div = div; | ||
| 1120 | clk_mul = host->clk_mul; | ||
| 1112 | div--; | 1121 | div--; |
| 1113 | } | 1122 | } |
| 1114 | } else { | 1123 | } else { |
| @@ -1122,6 +1131,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
| 1122 | break; | 1131 | break; |
| 1123 | } | 1132 | } |
| 1124 | } | 1133 | } |
| 1134 | real_div = div; | ||
| 1125 | div >>= 1; | 1135 | div >>= 1; |
| 1126 | } | 1136 | } |
| 1127 | } else { | 1137 | } else { |
| @@ -1130,9 +1140,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
| 1130 | if ((host->max_clk / div) <= clock) | 1140 | if ((host->max_clk / div) <= clock) |
| 1131 | break; | 1141 | break; |
| 1132 | } | 1142 | } |
| 1143 | real_div = div; | ||
| 1133 | div >>= 1; | 1144 | div >>= 1; |
| 1134 | } | 1145 | } |
| 1135 | 1146 | ||
| 1147 | if (real_div) | ||
| 1148 | host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; | ||
| 1149 | |||
| 1136 | clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; | 1150 | clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; |
| 1137 | clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) | 1151 | clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) |
| 1138 | << SDHCI_DIVIDER_HI_SHIFT; | 1152 | << SDHCI_DIVIDER_HI_SHIFT; |
| @@ -1160,7 +1174,7 @@ out: | |||
| 1160 | host->clock = clock; | 1174 | host->clock = clock; |
| 1161 | } | 1175 | } |
| 1162 | 1176 | ||
| 1163 | static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | 1177 | static int sdhci_set_power(struct sdhci_host *host, unsigned short power) |
| 1164 | { | 1178 | { |
| 1165 | u8 pwr = 0; | 1179 | u8 pwr = 0; |
| 1166 | 1180 | ||
| @@ -1183,13 +1197,13 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
| 1183 | } | 1197 | } |
| 1184 | 1198 | ||
| 1185 | if (host->pwr == pwr) | 1199 | if (host->pwr == pwr) |
| 1186 | return; | 1200 | return -1; |
| 1187 | 1201 | ||
| 1188 | host->pwr = pwr; | 1202 | host->pwr = pwr; |
| 1189 | 1203 | ||
| 1190 | if (pwr == 0) { | 1204 | if (pwr == 0) { |
| 1191 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); | 1205 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); |
| 1192 | return; | 1206 | return 0; |
| 1193 | } | 1207 | } |
| 1194 | 1208 | ||
| 1195 | /* | 1209 | /* |
| @@ -1216,6 +1230,8 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
| 1216 | */ | 1230 | */ |
| 1217 | if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) | 1231 | if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) |
| 1218 | mdelay(10); | 1232 | mdelay(10); |
| 1233 | |||
| 1234 | return power; | ||
| 1219 | } | 1235 | } |
| 1220 | 1236 | ||
| 1221 | /*****************************************************************************\ | 1237 | /*****************************************************************************\ |
| @@ -1277,7 +1293,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 1277 | if ((host->flags & SDHCI_NEEDS_RETUNING) && | 1293 | if ((host->flags & SDHCI_NEEDS_RETUNING) && |
| 1278 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { | 1294 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { |
| 1279 | spin_unlock_irqrestore(&host->lock, flags); | 1295 | spin_unlock_irqrestore(&host->lock, flags); |
| 1280 | sdhci_execute_tuning(mmc); | 1296 | sdhci_execute_tuning(mmc, mrq->cmd->opcode); |
| 1281 | spin_lock_irqsave(&host->lock, flags); | 1297 | spin_lock_irqsave(&host->lock, flags); |
| 1282 | 1298 | ||
| 1283 | /* Restore original mmc_request structure */ | 1299 | /* Restore original mmc_request structure */ |
| @@ -1297,12 +1313,17 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 1297 | static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | 1313 | static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) |
| 1298 | { | 1314 | { |
| 1299 | unsigned long flags; | 1315 | unsigned long flags; |
| 1316 | int vdd_bit = -1; | ||
| 1300 | u8 ctrl; | 1317 | u8 ctrl; |
| 1301 | 1318 | ||
| 1302 | spin_lock_irqsave(&host->lock, flags); | 1319 | spin_lock_irqsave(&host->lock, flags); |
| 1303 | 1320 | ||
| 1304 | if (host->flags & SDHCI_DEVICE_DEAD) | 1321 | if (host->flags & SDHCI_DEVICE_DEAD) { |
| 1305 | goto out; | 1322 | spin_unlock_irqrestore(&host->lock, flags); |
| 1323 | if (host->vmmc && ios->power_mode == MMC_POWER_OFF) | ||
| 1324 | mmc_regulator_set_ocr(host->mmc, host->vmmc, 0); | ||
| 1325 | return; | ||
| 1326 | } | ||
| 1306 | 1327 | ||
| 1307 | /* | 1328 | /* |
| 1308 | * Reset the chip on each power off. | 1329 | * Reset the chip on each power off. |
| @@ -1316,9 +1337,15 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
| 1316 | sdhci_set_clock(host, ios->clock); | 1337 | sdhci_set_clock(host, ios->clock); |
| 1317 | 1338 | ||
| 1318 | if (ios->power_mode == MMC_POWER_OFF) | 1339 | if (ios->power_mode == MMC_POWER_OFF) |
| 1319 | sdhci_set_power(host, -1); | 1340 | vdd_bit = sdhci_set_power(host, -1); |
| 1320 | else | 1341 | else |
| 1321 | sdhci_set_power(host, ios->vdd); | 1342 | vdd_bit = sdhci_set_power(host, ios->vdd); |
| 1343 | |||
| 1344 | if (host->vmmc && vdd_bit != -1) { | ||
| 1345 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 1346 | mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit); | ||
| 1347 | spin_lock_irqsave(&host->lock, flags); | ||
| 1348 | } | ||
| 1322 | 1349 | ||
| 1323 | if (host->ops->platform_send_init_74_clocks) | 1350 | if (host->ops->platform_send_init_74_clocks) |
| 1324 | host->ops->platform_send_init_74_clocks(host, ios->power_mode); | 1351 | host->ops->platform_send_init_74_clocks(host, ios->power_mode); |
| @@ -1361,11 +1388,11 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
| 1361 | unsigned int clock; | 1388 | unsigned int clock; |
| 1362 | 1389 | ||
| 1363 | /* In case of UHS-I modes, set High Speed Enable */ | 1390 | /* In case of UHS-I modes, set High Speed Enable */ |
| 1364 | if ((ios->timing == MMC_TIMING_UHS_SDR50) || | 1391 | if ((ios->timing == MMC_TIMING_MMC_HS200) || |
| 1392 | (ios->timing == MMC_TIMING_UHS_SDR50) || | ||
| 1365 | (ios->timing == MMC_TIMING_UHS_SDR104) || | 1393 | (ios->timing == MMC_TIMING_UHS_SDR104) || |
| 1366 | (ios->timing == MMC_TIMING_UHS_DDR50) || | 1394 | (ios->timing == MMC_TIMING_UHS_DDR50) || |
| 1367 | (ios->timing == MMC_TIMING_UHS_SDR25) || | 1395 | (ios->timing == MMC_TIMING_UHS_SDR25)) |
| 1368 | (ios->timing == MMC_TIMING_UHS_SDR12)) | ||
| 1369 | ctrl |= SDHCI_CTRL_HISPD; | 1396 | ctrl |= SDHCI_CTRL_HISPD; |
| 1370 | 1397 | ||
| 1371 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1398 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| @@ -1415,7 +1442,9 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
| 1415 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1442 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| 1416 | /* Select Bus Speed Mode for host */ | 1443 | /* Select Bus Speed Mode for host */ |
| 1417 | ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; | 1444 | ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; |
| 1418 | if (ios->timing == MMC_TIMING_UHS_SDR12) | 1445 | if (ios->timing == MMC_TIMING_MMC_HS200) |
| 1446 | ctrl_2 |= SDHCI_CTRL_HS_SDR200; | ||
| 1447 | else if (ios->timing == MMC_TIMING_UHS_SDR12) | ||
| 1419 | ctrl_2 |= SDHCI_CTRL_UHS_SDR12; | 1448 | ctrl_2 |= SDHCI_CTRL_UHS_SDR12; |
| 1420 | else if (ios->timing == MMC_TIMING_UHS_SDR25) | 1449 | else if (ios->timing == MMC_TIMING_UHS_SDR25) |
| 1421 | ctrl_2 |= SDHCI_CTRL_UHS_SDR25; | 1450 | ctrl_2 |= SDHCI_CTRL_UHS_SDR25; |
| @@ -1443,7 +1472,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
| 1443 | if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) | 1472 | if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) |
| 1444 | sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); | 1473 | sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); |
| 1445 | 1474 | ||
| 1446 | out: | ||
| 1447 | mmiowb(); | 1475 | mmiowb(); |
| 1448 | spin_unlock_irqrestore(&host->lock, flags); | 1476 | spin_unlock_irqrestore(&host->lock, flags); |
| 1449 | } | 1477 | } |
| @@ -1663,7 +1691,7 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, | |||
| 1663 | return err; | 1691 | return err; |
| 1664 | } | 1692 | } |
| 1665 | 1693 | ||
| 1666 | static int sdhci_execute_tuning(struct mmc_host *mmc) | 1694 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) |
| 1667 | { | 1695 | { |
| 1668 | struct sdhci_host *host; | 1696 | struct sdhci_host *host; |
| 1669 | u16 ctrl; | 1697 | u16 ctrl; |
| @@ -1671,6 +1699,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) | |||
| 1671 | int tuning_loop_counter = MAX_TUNING_LOOP; | 1699 | int tuning_loop_counter = MAX_TUNING_LOOP; |
| 1672 | unsigned long timeout; | 1700 | unsigned long timeout; |
| 1673 | int err = 0; | 1701 | int err = 0; |
| 1702 | bool requires_tuning_nonuhs = false; | ||
| 1674 | 1703 | ||
| 1675 | host = mmc_priv(mmc); | 1704 | host = mmc_priv(mmc); |
| 1676 | 1705 | ||
| @@ -1681,13 +1710,19 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) | |||
| 1681 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1710 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| 1682 | 1711 | ||
| 1683 | /* | 1712 | /* |
| 1684 | * Host Controller needs tuning only in case of SDR104 mode | 1713 | * The Host Controller needs tuning only in case of SDR104 mode |
| 1685 | * and for SDR50 mode when Use Tuning for SDR50 is set in | 1714 | * and for SDR50 mode when Use Tuning for SDR50 is set in the |
| 1686 | * Capabilities register. | 1715 | * Capabilities register. |
| 1716 | * If the Host Controller supports the HS200 mode then the | ||
| 1717 | * tuning function has to be executed. | ||
| 1687 | */ | 1718 | */ |
| 1719 | if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) && | ||
| 1720 | (host->flags & SDHCI_SDR50_NEEDS_TUNING || | ||
| 1721 | host->flags & SDHCI_HS200_NEEDS_TUNING)) | ||
| 1722 | requires_tuning_nonuhs = true; | ||
| 1723 | |||
| 1688 | if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) || | 1724 | if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) || |
| 1689 | (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) && | 1725 | requires_tuning_nonuhs) |
| 1690 | (host->flags & SDHCI_SDR50_NEEDS_TUNING))) | ||
| 1691 | ctrl |= SDHCI_CTRL_EXEC_TUNING; | 1726 | ctrl |= SDHCI_CTRL_EXEC_TUNING; |
| 1692 | else { | 1727 | else { |
| 1693 | spin_unlock(&host->lock); | 1728 | spin_unlock(&host->lock); |
| @@ -1723,7 +1758,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) | |||
| 1723 | if (!tuning_loop_counter && !timeout) | 1758 | if (!tuning_loop_counter && !timeout) |
| 1724 | break; | 1759 | break; |
| 1725 | 1760 | ||
| 1726 | cmd.opcode = MMC_SEND_TUNING_BLOCK; | 1761 | cmd.opcode = opcode; |
| 1727 | cmd.arg = 0; | 1762 | cmd.arg = 0; |
| 1728 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 1763 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
| 1729 | cmd.retries = 0; | 1764 | cmd.retries = 0; |
| @@ -1738,7 +1773,17 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) | |||
| 1738 | * block to the Host Controller. So we set the block size | 1773 | * block to the Host Controller. So we set the block size |
| 1739 | * to 64 here. | 1774 | * to 64 here. |
| 1740 | */ | 1775 | */ |
| 1741 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE); | 1776 | if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200) { |
| 1777 | if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) | ||
| 1778 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128), | ||
| 1779 | SDHCI_BLOCK_SIZE); | ||
| 1780 | else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) | ||
| 1781 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), | ||
| 1782 | SDHCI_BLOCK_SIZE); | ||
| 1783 | } else { | ||
| 1784 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), | ||
| 1785 | SDHCI_BLOCK_SIZE); | ||
| 1786 | } | ||
| 1742 | 1787 | ||
| 1743 | /* | 1788 | /* |
| 1744 | * The tuning block is sent by the card to the host controller. | 1789 | * The tuning block is sent by the card to the host controller. |
| @@ -2121,12 +2166,14 @@ static void sdhci_show_adma_error(struct sdhci_host *host) { } | |||
| 2121 | 2166 | ||
| 2122 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | 2167 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) |
| 2123 | { | 2168 | { |
| 2169 | u32 command; | ||
| 2124 | BUG_ON(intmask == 0); | 2170 | BUG_ON(intmask == 0); |
| 2125 | 2171 | ||
| 2126 | /* CMD19 generates _only_ Buffer Read Ready interrupt */ | 2172 | /* CMD19 generates _only_ Buffer Read Ready interrupt */ |
| 2127 | if (intmask & SDHCI_INT_DATA_AVAIL) { | 2173 | if (intmask & SDHCI_INT_DATA_AVAIL) { |
| 2128 | if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) == | 2174 | command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)); |
| 2129 | MMC_SEND_TUNING_BLOCK) { | 2175 | if (command == MMC_SEND_TUNING_BLOCK || |
| 2176 | command == MMC_SEND_TUNING_BLOCK_HS200) { | ||
| 2130 | host->tuning_done = 1; | 2177 | host->tuning_done = 1; |
| 2131 | wake_up(&host->buf_ready_int); | 2178 | wake_up(&host->buf_ready_int); |
| 2132 | return; | 2179 | return; |
| @@ -2330,26 +2377,33 @@ out: | |||
| 2330 | int sdhci_suspend_host(struct sdhci_host *host) | 2377 | int sdhci_suspend_host(struct sdhci_host *host) |
| 2331 | { | 2378 | { |
| 2332 | int ret; | 2379 | int ret; |
| 2380 | bool has_tuning_timer; | ||
| 2333 | 2381 | ||
| 2334 | sdhci_disable_card_detection(host); | 2382 | sdhci_disable_card_detection(host); |
| 2335 | 2383 | ||
| 2336 | /* Disable tuning since we are suspending */ | 2384 | /* Disable tuning since we are suspending */ |
| 2337 | if (host->version >= SDHCI_SPEC_300 && host->tuning_count && | 2385 | has_tuning_timer = host->version >= SDHCI_SPEC_300 && |
| 2338 | host->tuning_mode == SDHCI_TUNING_MODE_1) { | 2386 | host->tuning_count && host->tuning_mode == SDHCI_TUNING_MODE_1; |
| 2387 | if (has_tuning_timer) { | ||
| 2388 | del_timer_sync(&host->tuning_timer); | ||
| 2339 | host->flags &= ~SDHCI_NEEDS_RETUNING; | 2389 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
| 2340 | mod_timer(&host->tuning_timer, jiffies + | ||
| 2341 | host->tuning_count * HZ); | ||
| 2342 | } | 2390 | } |
| 2343 | 2391 | ||
| 2344 | ret = mmc_suspend_host(host->mmc); | 2392 | ret = mmc_suspend_host(host->mmc); |
| 2345 | if (ret) | 2393 | if (ret) { |
| 2394 | if (has_tuning_timer) { | ||
| 2395 | host->flags |= SDHCI_NEEDS_RETUNING; | ||
| 2396 | mod_timer(&host->tuning_timer, jiffies + | ||
| 2397 | host->tuning_count * HZ); | ||
| 2398 | } | ||
| 2399 | |||
| 2400 | sdhci_enable_card_detection(host); | ||
| 2401 | |||
| 2346 | return ret; | 2402 | return ret; |
| 2403 | } | ||
| 2347 | 2404 | ||
| 2348 | free_irq(host->irq, host); | 2405 | free_irq(host->irq, host); |
| 2349 | 2406 | ||
| 2350 | if (host->vmmc) | ||
| 2351 | ret = regulator_disable(host->vmmc); | ||
| 2352 | |||
| 2353 | return ret; | 2407 | return ret; |
| 2354 | } | 2408 | } |
| 2355 | 2409 | ||
| @@ -2359,12 +2413,6 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
| 2359 | { | 2413 | { |
| 2360 | int ret; | 2414 | int ret; |
| 2361 | 2415 | ||
| 2362 | if (host->vmmc) { | ||
| 2363 | int ret = regulator_enable(host->vmmc); | ||
| 2364 | if (ret) | ||
| 2365 | return ret; | ||
| 2366 | } | ||
| 2367 | |||
| 2368 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { | 2416 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { |
| 2369 | if (host->ops->enable_dma) | 2417 | if (host->ops->enable_dma) |
| 2370 | host->ops->enable_dma(host); | 2418 | host->ops->enable_dma(host); |
| @@ -2727,10 +2775,14 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 2727 | if (caps[1] & SDHCI_SUPPORT_DDR50) | 2775 | if (caps[1] & SDHCI_SUPPORT_DDR50) |
| 2728 | mmc->caps |= MMC_CAP_UHS_DDR50; | 2776 | mmc->caps |= MMC_CAP_UHS_DDR50; |
| 2729 | 2777 | ||
| 2730 | /* Does the host needs tuning for SDR50? */ | 2778 | /* Does the host need tuning for SDR50? */ |
| 2731 | if (caps[1] & SDHCI_USE_SDR50_TUNING) | 2779 | if (caps[1] & SDHCI_USE_SDR50_TUNING) |
| 2732 | host->flags |= SDHCI_SDR50_NEEDS_TUNING; | 2780 | host->flags |= SDHCI_SDR50_NEEDS_TUNING; |
| 2733 | 2781 | ||
| 2782 | /* Does the host need tuning for HS200? */ | ||
| 2783 | if (mmc->caps2 & MMC_CAP2_HS200) | ||
| 2784 | host->flags |= SDHCI_HS200_NEEDS_TUNING; | ||
| 2785 | |||
| 2734 | /* Driver Type(s) (A, C, D) supported by the host */ | 2786 | /* Driver Type(s) (A, C, D) supported by the host */ |
| 2735 | if (caps[1] & SDHCI_DRIVER_TYPE_A) | 2787 | if (caps[1] & SDHCI_DRIVER_TYPE_A) |
| 2736 | mmc->caps |= MMC_CAP_DRIVER_TYPE_A; | 2788 | mmc->caps |= MMC_CAP_DRIVER_TYPE_A; |
| @@ -2926,8 +2978,6 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 2926 | if (IS_ERR(host->vmmc)) { | 2978 | if (IS_ERR(host->vmmc)) { |
| 2927 | pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); | 2979 | pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); |
| 2928 | host->vmmc = NULL; | 2980 | host->vmmc = NULL; |
| 2929 | } else { | ||
| 2930 | regulator_enable(host->vmmc); | ||
| 2931 | } | 2981 | } |
| 2932 | 2982 | ||
| 2933 | sdhci_init(host, 0); | 2983 | sdhci_init(host, 0); |
| @@ -3016,10 +3066,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) | |||
| 3016 | tasklet_kill(&host->card_tasklet); | 3066 | tasklet_kill(&host->card_tasklet); |
| 3017 | tasklet_kill(&host->finish_tasklet); | 3067 | tasklet_kill(&host->finish_tasklet); |
| 3018 | 3068 | ||
| 3019 | if (host->vmmc) { | 3069 | if (host->vmmc) |
| 3020 | regulator_disable(host->vmmc); | ||
| 3021 | regulator_put(host->vmmc); | 3070 | regulator_put(host->vmmc); |
| 3022 | } | ||
| 3023 | 3071 | ||
| 3024 | kfree(host->adma_desc); | 3072 | kfree(host->adma_desc); |
| 3025 | kfree(host->align_buffer); | 3073 | kfree(host->align_buffer); |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index a04d4d0c6fd..ad265b96b75 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
| @@ -158,6 +158,7 @@ | |||
| 158 | #define SDHCI_CTRL_UHS_SDR50 0x0002 | 158 | #define SDHCI_CTRL_UHS_SDR50 0x0002 |
| 159 | #define SDHCI_CTRL_UHS_SDR104 0x0003 | 159 | #define SDHCI_CTRL_UHS_SDR104 0x0003 |
| 160 | #define SDHCI_CTRL_UHS_DDR50 0x0004 | 160 | #define SDHCI_CTRL_UHS_DDR50 0x0004 |
| 161 | #define SDHCI_CTRL_HS_SDR200 0x0005 /* reserved value in SDIO spec */ | ||
| 161 | #define SDHCI_CTRL_VDD_180 0x0008 | 162 | #define SDHCI_CTRL_VDD_180 0x0008 |
| 162 | #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 | 163 | #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 |
| 163 | #define SDHCI_CTRL_DRV_TYPE_B 0x0000 | 164 | #define SDHCI_CTRL_DRV_TYPE_B 0x0000 |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index d5505f3fe2a..4a2c5b2355f 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
| @@ -16,6 +16,33 @@ | |||
| 16 | * | 16 | * |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | /* | ||
| 20 | * The MMCIF driver is now processing MMC requests asynchronously, according | ||
| 21 | * to the Linux MMC API requirement. | ||
| 22 | * | ||
| 23 | * The MMCIF driver processes MMC requests in up to 3 stages: command, optional | ||
| 24 | * data, and optional stop. To achieve asynchronous processing each of these | ||
| 25 | * stages is split into two halves: a top and a bottom half. The top half | ||
| 26 | * initialises the hardware, installs a timeout handler to handle completion | ||
| 27 | * timeouts, and returns. In case of the command stage this immediately returns | ||
| 28 | * control to the caller, leaving all further processing to run asynchronously. | ||
| 29 | * All further request processing is performed by the bottom halves. | ||
| 30 | * | ||
| 31 | * The bottom half further consists of a "hard" IRQ handler, an IRQ handler | ||
| 32 | * thread, a DMA completion callback, if DMA is used, a timeout work, and | ||
| 33 | * request- and stage-specific handler methods. | ||
| 34 | * | ||
| 35 | * Each bottom half run begins with either a hardware interrupt, a DMA callback | ||
| 36 | * invocation, or a timeout work run. In case of an error or a successful | ||
| 37 | * processing completion, the MMC core is informed and the request processing is | ||
| 38 | * finished. In case processing has to continue, i.e., if data has to be read | ||
| 39 | * from or written to the card, or if a stop command has to be sent, the next | ||
| 40 | * top half is called, which performs the necessary hardware handling and | ||
| 41 | * reschedules the timeout work. This returns the driver state machine into the | ||
| 42 | * bottom half waiting state. | ||
| 43 | */ | ||
| 44 | |||
| 45 | #include <linux/bitops.h> | ||
| 19 | #include <linux/clk.h> | 46 | #include <linux/clk.h> |
| 20 | #include <linux/completion.h> | 47 | #include <linux/completion.h> |
| 21 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
| @@ -123,6 +150,11 @@ | |||
| 123 | #define MASK_MRBSYTO (1 << 1) | 150 | #define MASK_MRBSYTO (1 << 1) |
| 124 | #define MASK_MRSPTO (1 << 0) | 151 | #define MASK_MRSPTO (1 << 0) |
| 125 | 152 | ||
| 153 | #define MASK_START_CMD (MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | \ | ||
| 154 | MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | \ | ||
| 155 | MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \ | ||
| 156 | MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO) | ||
| 157 | |||
| 126 | /* CE_HOST_STS1 */ | 158 | /* CE_HOST_STS1 */ |
| 127 | #define STS1_CMDSEQ (1 << 31) | 159 | #define STS1_CMDSEQ (1 << 31) |
| 128 | 160 | ||
| @@ -162,9 +194,21 @@ enum mmcif_state { | |||
| 162 | STATE_IOS, | 194 | STATE_IOS, |
| 163 | }; | 195 | }; |
| 164 | 196 | ||
| 197 | enum mmcif_wait_for { | ||
| 198 | MMCIF_WAIT_FOR_REQUEST, | ||
| 199 | MMCIF_WAIT_FOR_CMD, | ||
| 200 | MMCIF_WAIT_FOR_MREAD, | ||
| 201 | MMCIF_WAIT_FOR_MWRITE, | ||
| 202 | MMCIF_WAIT_FOR_READ, | ||
| 203 | MMCIF_WAIT_FOR_WRITE, | ||
| 204 | MMCIF_WAIT_FOR_READ_END, | ||
| 205 | MMCIF_WAIT_FOR_WRITE_END, | ||
| 206 | MMCIF_WAIT_FOR_STOP, | ||
| 207 | }; | ||
| 208 | |||
| 165 | struct sh_mmcif_host { | 209 | struct sh_mmcif_host { |
| 166 | struct mmc_host *mmc; | 210 | struct mmc_host *mmc; |
| 167 | struct mmc_data *data; | 211 | struct mmc_request *mrq; |
| 168 | struct platform_device *pd; | 212 | struct platform_device *pd; |
| 169 | struct sh_dmae_slave dma_slave_tx; | 213 | struct sh_dmae_slave dma_slave_tx; |
| 170 | struct sh_dmae_slave dma_slave_rx; | 214 | struct sh_dmae_slave dma_slave_rx; |
| @@ -172,11 +216,17 @@ struct sh_mmcif_host { | |||
| 172 | unsigned int clk; | 216 | unsigned int clk; |
| 173 | int bus_width; | 217 | int bus_width; |
| 174 | bool sd_error; | 218 | bool sd_error; |
| 219 | bool dying; | ||
| 175 | long timeout; | 220 | long timeout; |
| 176 | void __iomem *addr; | 221 | void __iomem *addr; |
| 177 | struct completion intr_wait; | 222 | u32 *pio_ptr; |
| 223 | spinlock_t lock; /* protect sh_mmcif_host::state */ | ||
| 178 | enum mmcif_state state; | 224 | enum mmcif_state state; |
| 179 | spinlock_t lock; | 225 | enum mmcif_wait_for wait_for; |
| 226 | struct delayed_work timeout_work; | ||
| 227 | size_t blocksize; | ||
| 228 | int sg_idx; | ||
| 229 | int sg_blkidx; | ||
| 180 | bool power; | 230 | bool power; |
| 181 | bool card_present; | 231 | bool card_present; |
| 182 | 232 | ||
| @@ -202,19 +252,21 @@ static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host, | |||
| 202 | static void mmcif_dma_complete(void *arg) | 252 | static void mmcif_dma_complete(void *arg) |
| 203 | { | 253 | { |
| 204 | struct sh_mmcif_host *host = arg; | 254 | struct sh_mmcif_host *host = arg; |
| 255 | struct mmc_data *data = host->mrq->data; | ||
| 256 | |||
| 205 | dev_dbg(&host->pd->dev, "Command completed\n"); | 257 | dev_dbg(&host->pd->dev, "Command completed\n"); |
| 206 | 258 | ||
| 207 | if (WARN(!host->data, "%s: NULL data in DMA completion!\n", | 259 | if (WARN(!data, "%s: NULL data in DMA completion!\n", |
| 208 | dev_name(&host->pd->dev))) | 260 | dev_name(&host->pd->dev))) |
| 209 | return; | 261 | return; |
| 210 | 262 | ||
| 211 | if (host->data->flags & MMC_DATA_READ) | 263 | if (data->flags & MMC_DATA_READ) |
| 212 | dma_unmap_sg(host->chan_rx->device->dev, | 264 | dma_unmap_sg(host->chan_rx->device->dev, |
| 213 | host->data->sg, host->data->sg_len, | 265 | data->sg, data->sg_len, |
| 214 | DMA_FROM_DEVICE); | 266 | DMA_FROM_DEVICE); |
| 215 | else | 267 | else |
| 216 | dma_unmap_sg(host->chan_tx->device->dev, | 268 | dma_unmap_sg(host->chan_tx->device->dev, |
| 217 | host->data->sg, host->data->sg_len, | 269 | data->sg, data->sg_len, |
| 218 | DMA_TO_DEVICE); | 270 | DMA_TO_DEVICE); |
| 219 | 271 | ||
| 220 | complete(&host->dma_complete); | 272 | complete(&host->dma_complete); |
| @@ -222,13 +274,14 @@ static void mmcif_dma_complete(void *arg) | |||
| 222 | 274 | ||
| 223 | static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) | 275 | static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) |
| 224 | { | 276 | { |
| 225 | struct scatterlist *sg = host->data->sg; | 277 | struct mmc_data *data = host->mrq->data; |
| 278 | struct scatterlist *sg = data->sg; | ||
| 226 | struct dma_async_tx_descriptor *desc = NULL; | 279 | struct dma_async_tx_descriptor *desc = NULL; |
| 227 | struct dma_chan *chan = host->chan_rx; | 280 | struct dma_chan *chan = host->chan_rx; |
| 228 | dma_cookie_t cookie = -EINVAL; | 281 | dma_cookie_t cookie = -EINVAL; |
| 229 | int ret; | 282 | int ret; |
| 230 | 283 | ||
| 231 | ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len, | 284 | ret = dma_map_sg(chan->device->dev, sg, data->sg_len, |
| 232 | DMA_FROM_DEVICE); | 285 | DMA_FROM_DEVICE); |
| 233 | if (ret > 0) { | 286 | if (ret > 0) { |
| 234 | host->dma_active = true; | 287 | host->dma_active = true; |
| @@ -244,7 +297,7 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) | |||
| 244 | dma_async_issue_pending(chan); | 297 | dma_async_issue_pending(chan); |
| 245 | } | 298 | } |
| 246 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", | 299 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", |
| 247 | __func__, host->data->sg_len, ret, cookie); | 300 | __func__, data->sg_len, ret, cookie); |
| 248 | 301 | ||
| 249 | if (!desc) { | 302 | if (!desc) { |
| 250 | /* DMA failed, fall back to PIO */ | 303 | /* DMA failed, fall back to PIO */ |
| @@ -265,18 +318,19 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) | |||
| 265 | } | 318 | } |
| 266 | 319 | ||
| 267 | dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, | 320 | dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, |
| 268 | desc, cookie, host->data->sg_len); | 321 | desc, cookie, data->sg_len); |
| 269 | } | 322 | } |
| 270 | 323 | ||
| 271 | static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host) | 324 | static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host) |
| 272 | { | 325 | { |
| 273 | struct scatterlist *sg = host->data->sg; | 326 | struct mmc_data *data = host->mrq->data; |
| 327 | struct scatterlist *sg = data->sg; | ||
| 274 | struct dma_async_tx_descriptor *desc = NULL; | 328 | struct dma_async_tx_descriptor *desc = NULL; |
| 275 | struct dma_chan *chan = host->chan_tx; | 329 | struct dma_chan *chan = host->chan_tx; |
| 276 | dma_cookie_t cookie = -EINVAL; | 330 | dma_cookie_t cookie = -EINVAL; |
| 277 | int ret; | 331 | int ret; |
| 278 | 332 | ||
| 279 | ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len, | 333 | ret = dma_map_sg(chan->device->dev, sg, data->sg_len, |
| 280 | DMA_TO_DEVICE); | 334 | DMA_TO_DEVICE); |
| 281 | if (ret > 0) { | 335 | if (ret > 0) { |
| 282 | host->dma_active = true; | 336 | host->dma_active = true; |
| @@ -292,7 +346,7 @@ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host) | |||
| 292 | dma_async_issue_pending(chan); | 346 | dma_async_issue_pending(chan); |
| 293 | } | 347 | } |
| 294 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", | 348 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", |
| 295 | __func__, host->data->sg_len, ret, cookie); | 349 | __func__, data->sg_len, ret, cookie); |
| 296 | 350 | ||
| 297 | if (!desc) { | 351 | if (!desc) { |
| 298 | /* DMA failed, fall back to PIO */ | 352 | /* DMA failed, fall back to PIO */ |
| @@ -399,7 +453,7 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) | |||
| 399 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); | 453 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); |
| 400 | else | 454 | else |
| 401 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & | 455 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & |
| 402 | (ilog2(__rounddown_pow_of_two(host->clk / clk)) << 16)); | 456 | ((fls(host->clk / clk) - 1) << 16)); |
| 403 | 457 | ||
| 404 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); | 458 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); |
| 405 | } | 459 | } |
| @@ -421,7 +475,7 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host) | |||
| 421 | static int sh_mmcif_error_manage(struct sh_mmcif_host *host) | 475 | static int sh_mmcif_error_manage(struct sh_mmcif_host *host) |
| 422 | { | 476 | { |
| 423 | u32 state1, state2; | 477 | u32 state1, state2; |
| 424 | int ret, timeout = 10000000; | 478 | int ret, timeout; |
| 425 | 479 | ||
| 426 | host->sd_error = false; | 480 | host->sd_error = false; |
| 427 | 481 | ||
| @@ -433,155 +487,212 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) | |||
| 433 | if (state1 & STS1_CMDSEQ) { | 487 | if (state1 & STS1_CMDSEQ) { |
| 434 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); | 488 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); |
| 435 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK); | 489 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK); |
| 436 | while (1) { | 490 | for (timeout = 10000000; timeout; timeout--) { |
| 437 | timeout--; | ||
| 438 | if (timeout < 0) { | ||
| 439 | dev_err(&host->pd->dev, | ||
| 440 | "Forceed end of command sequence timeout err\n"); | ||
| 441 | return -EIO; | ||
| 442 | } | ||
| 443 | if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) | 491 | if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) |
| 444 | & STS1_CMDSEQ)) | 492 | & STS1_CMDSEQ)) |
| 445 | break; | 493 | break; |
| 446 | mdelay(1); | 494 | mdelay(1); |
| 447 | } | 495 | } |
| 496 | if (!timeout) { | ||
| 497 | dev_err(&host->pd->dev, | ||
| 498 | "Forced end of command sequence timeout err\n"); | ||
| 499 | return -EIO; | ||
| 500 | } | ||
| 448 | sh_mmcif_sync_reset(host); | 501 | sh_mmcif_sync_reset(host); |
| 449 | dev_dbg(&host->pd->dev, "Forced end of command sequence\n"); | 502 | dev_dbg(&host->pd->dev, "Forced end of command sequence\n"); |
| 450 | return -EIO; | 503 | return -EIO; |
| 451 | } | 504 | } |
| 452 | 505 | ||
| 453 | if (state2 & STS2_CRC_ERR) { | 506 | if (state2 & STS2_CRC_ERR) { |
| 454 | dev_dbg(&host->pd->dev, ": Happened CRC error\n"); | 507 | dev_dbg(&host->pd->dev, ": CRC error\n"); |
| 455 | ret = -EIO; | 508 | ret = -EIO; |
| 456 | } else if (state2 & STS2_TIMEOUT_ERR) { | 509 | } else if (state2 & STS2_TIMEOUT_ERR) { |
| 457 | dev_dbg(&host->pd->dev, ": Happened Timeout error\n"); | 510 | dev_dbg(&host->pd->dev, ": Timeout\n"); |
| 458 | ret = -ETIMEDOUT; | 511 | ret = -ETIMEDOUT; |
| 459 | } else { | 512 | } else { |
| 460 | dev_dbg(&host->pd->dev, ": Happened End/Index error\n"); | 513 | dev_dbg(&host->pd->dev, ": End/Index error\n"); |
| 461 | ret = -EIO; | 514 | ret = -EIO; |
| 462 | } | 515 | } |
| 463 | return ret; | 516 | return ret; |
| 464 | } | 517 | } |
| 465 | 518 | ||
| 466 | static int sh_mmcif_single_read(struct sh_mmcif_host *host, | 519 | static bool sh_mmcif_next_block(struct sh_mmcif_host *host, u32 *p) |
| 467 | struct mmc_request *mrq) | ||
| 468 | { | 520 | { |
| 469 | struct mmc_data *data = mrq->data; | 521 | struct mmc_data *data = host->mrq->data; |
| 470 | long time; | 522 | |
| 471 | u32 blocksize, i, *p = sg_virt(data->sg); | 523 | host->sg_blkidx += host->blocksize; |
| 524 | |||
| 525 | /* data->sg->length must be a multiple of host->blocksize? */ | ||
| 526 | BUG_ON(host->sg_blkidx > data->sg->length); | ||
| 527 | |||
| 528 | if (host->sg_blkidx == data->sg->length) { | ||
| 529 | host->sg_blkidx = 0; | ||
| 530 | if (++host->sg_idx < data->sg_len) | ||
| 531 | host->pio_ptr = sg_virt(++data->sg); | ||
| 532 | } else { | ||
| 533 | host->pio_ptr = p; | ||
| 534 | } | ||
| 535 | |||
| 536 | if (host->sg_idx == data->sg_len) | ||
| 537 | return false; | ||
| 538 | |||
| 539 | return true; | ||
| 540 | } | ||
| 541 | |||
| 542 | static void sh_mmcif_single_read(struct sh_mmcif_host *host, | ||
| 543 | struct mmc_request *mrq) | ||
| 544 | { | ||
| 545 | host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) & | ||
| 546 | BLOCK_SIZE_MASK) + 3; | ||
| 547 | |||
| 548 | host->wait_for = MMCIF_WAIT_FOR_READ; | ||
| 549 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
| 472 | 550 | ||
| 473 | /* buf read enable */ | 551 | /* buf read enable */ |
| 474 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | 552 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); |
| 475 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 553 | } |
| 476 | host->timeout); | 554 | |
| 477 | if (time <= 0 || host->sd_error) | 555 | static bool sh_mmcif_read_block(struct sh_mmcif_host *host) |
| 478 | return sh_mmcif_error_manage(host); | 556 | { |
| 479 | 557 | struct mmc_data *data = host->mrq->data; | |
| 480 | blocksize = (BLOCK_SIZE_MASK & | 558 | u32 *p = sg_virt(data->sg); |
| 481 | sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; | 559 | int i; |
| 482 | for (i = 0; i < blocksize / 4; i++) | 560 | |
| 561 | if (host->sd_error) { | ||
| 562 | data->error = sh_mmcif_error_manage(host); | ||
| 563 | return false; | ||
| 564 | } | ||
| 565 | |||
| 566 | for (i = 0; i < host->blocksize / 4; i++) | ||
| 483 | *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA); | 567 | *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA); |
| 484 | 568 | ||
| 485 | /* buffer read end */ | 569 | /* buffer read end */ |
| 486 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); | 570 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); |
| 487 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 571 | host->wait_for = MMCIF_WAIT_FOR_READ_END; |
| 488 | host->timeout); | ||
| 489 | if (time <= 0 || host->sd_error) | ||
| 490 | return sh_mmcif_error_manage(host); | ||
| 491 | 572 | ||
| 492 | return 0; | 573 | return true; |
| 493 | } | 574 | } |
| 494 | 575 | ||
| 495 | static int sh_mmcif_multi_read(struct sh_mmcif_host *host, | 576 | static void sh_mmcif_multi_read(struct sh_mmcif_host *host, |
| 496 | struct mmc_request *mrq) | 577 | struct mmc_request *mrq) |
| 497 | { | 578 | { |
| 498 | struct mmc_data *data = mrq->data; | 579 | struct mmc_data *data = mrq->data; |
| 499 | long time; | 580 | |
| 500 | u32 blocksize, i, j, sec, *p; | 581 | if (!data->sg_len || !data->sg->length) |
| 501 | 582 | return; | |
| 502 | blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr, | 583 | |
| 503 | MMCIF_CE_BLOCK_SET); | 584 | host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) & |
| 504 | for (j = 0; j < data->sg_len; j++) { | 585 | BLOCK_SIZE_MASK; |
| 505 | p = sg_virt(data->sg); | 586 | |
| 506 | for (sec = 0; sec < data->sg->length / blocksize; sec++) { | 587 | host->wait_for = MMCIF_WAIT_FOR_MREAD; |
| 507 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | 588 | host->sg_idx = 0; |
| 508 | /* buf read enable */ | 589 | host->sg_blkidx = 0; |
| 509 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 590 | host->pio_ptr = sg_virt(data->sg); |
| 510 | host->timeout); | 591 | schedule_delayed_work(&host->timeout_work, host->timeout); |
| 511 | 592 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | |
| 512 | if (time <= 0 || host->sd_error) | 593 | } |
| 513 | return sh_mmcif_error_manage(host); | 594 | |
| 514 | 595 | static bool sh_mmcif_mread_block(struct sh_mmcif_host *host) | |
| 515 | for (i = 0; i < blocksize / 4; i++) | 596 | { |
| 516 | *p++ = sh_mmcif_readl(host->addr, | 597 | struct mmc_data *data = host->mrq->data; |
| 517 | MMCIF_CE_DATA); | 598 | u32 *p = host->pio_ptr; |
| 518 | } | 599 | int i; |
| 519 | if (j < data->sg_len - 1) | 600 | |
| 520 | data->sg++; | 601 | if (host->sd_error) { |
| 602 | data->error = sh_mmcif_error_manage(host); | ||
| 603 | return false; | ||
| 521 | } | 604 | } |
| 522 | return 0; | 605 | |
| 606 | BUG_ON(!data->sg->length); | ||
| 607 | |||
| 608 | for (i = 0; i < host->blocksize / 4; i++) | ||
| 609 | *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA); | ||
| 610 | |||
| 611 | if (!sh_mmcif_next_block(host, p)) | ||
| 612 | return false; | ||
| 613 | |||
| 614 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
| 615 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | ||
| 616 | |||
| 617 | return true; | ||
| 523 | } | 618 | } |
| 524 | 619 | ||
| 525 | static int sh_mmcif_single_write(struct sh_mmcif_host *host, | 620 | static void sh_mmcif_single_write(struct sh_mmcif_host *host, |
| 526 | struct mmc_request *mrq) | 621 | struct mmc_request *mrq) |
| 527 | { | 622 | { |
| 528 | struct mmc_data *data = mrq->data; | 623 | host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) & |
| 529 | long time; | 624 | BLOCK_SIZE_MASK) + 3; |
| 530 | u32 blocksize, i, *p = sg_virt(data->sg); | ||
| 531 | 625 | ||
| 532 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | 626 | host->wait_for = MMCIF_WAIT_FOR_WRITE; |
| 627 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
| 533 | 628 | ||
| 534 | /* buf write enable */ | 629 | /* buf write enable */ |
| 535 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 630 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); |
| 536 | host->timeout); | 631 | } |
| 537 | if (time <= 0 || host->sd_error) | 632 | |
| 538 | return sh_mmcif_error_manage(host); | 633 | static bool sh_mmcif_write_block(struct sh_mmcif_host *host) |
| 539 | 634 | { | |
| 540 | blocksize = (BLOCK_SIZE_MASK & | 635 | struct mmc_data *data = host->mrq->data; |
| 541 | sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; | 636 | u32 *p = sg_virt(data->sg); |
| 542 | for (i = 0; i < blocksize / 4; i++) | 637 | int i; |
| 638 | |||
| 639 | if (host->sd_error) { | ||
| 640 | data->error = sh_mmcif_error_manage(host); | ||
| 641 | return false; | ||
| 642 | } | ||
| 643 | |||
| 644 | for (i = 0; i < host->blocksize / 4; i++) | ||
| 543 | sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++); | 645 | sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++); |
| 544 | 646 | ||
| 545 | /* buffer write end */ | 647 | /* buffer write end */ |
| 546 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); | 648 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); |
| 649 | host->wait_for = MMCIF_WAIT_FOR_WRITE_END; | ||
| 547 | 650 | ||
| 548 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 651 | return true; |
| 549 | host->timeout); | ||
| 550 | if (time <= 0 || host->sd_error) | ||
| 551 | return sh_mmcif_error_manage(host); | ||
| 552 | |||
| 553 | return 0; | ||
| 554 | } | 652 | } |
| 555 | 653 | ||
| 556 | static int sh_mmcif_multi_write(struct sh_mmcif_host *host, | 654 | static void sh_mmcif_multi_write(struct sh_mmcif_host *host, |
| 557 | struct mmc_request *mrq) | 655 | struct mmc_request *mrq) |
| 558 | { | 656 | { |
| 559 | struct mmc_data *data = mrq->data; | 657 | struct mmc_data *data = mrq->data; |
| 560 | long time; | ||
| 561 | u32 i, sec, j, blocksize, *p; | ||
| 562 | 658 | ||
| 563 | blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr, | 659 | if (!data->sg_len || !data->sg->length) |
| 564 | MMCIF_CE_BLOCK_SET); | 660 | return; |
| 565 | 661 | ||
| 566 | for (j = 0; j < data->sg_len; j++) { | 662 | host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) & |
| 567 | p = sg_virt(data->sg); | 663 | BLOCK_SIZE_MASK; |
| 568 | for (sec = 0; sec < data->sg->length / blocksize; sec++) { | ||
| 569 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | ||
| 570 | /* buf write enable*/ | ||
| 571 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | ||
| 572 | host->timeout); | ||
| 573 | 664 | ||
| 574 | if (time <= 0 || host->sd_error) | 665 | host->wait_for = MMCIF_WAIT_FOR_MWRITE; |
| 575 | return sh_mmcif_error_manage(host); | 666 | host->sg_idx = 0; |
| 667 | host->sg_blkidx = 0; | ||
| 668 | host->pio_ptr = sg_virt(data->sg); | ||
| 669 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
| 670 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | ||
| 671 | } | ||
| 576 | 672 | ||
| 577 | for (i = 0; i < blocksize / 4; i++) | 673 | static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host) |
| 578 | sh_mmcif_writel(host->addr, | 674 | { |
| 579 | MMCIF_CE_DATA, *p++); | 675 | struct mmc_data *data = host->mrq->data; |
| 580 | } | 676 | u32 *p = host->pio_ptr; |
| 581 | if (j < data->sg_len - 1) | 677 | int i; |
| 582 | data->sg++; | 678 | |
| 679 | if (host->sd_error) { | ||
| 680 | data->error = sh_mmcif_error_manage(host); | ||
| 681 | return false; | ||
| 583 | } | 682 | } |
| 584 | return 0; | 683 | |
| 684 | BUG_ON(!data->sg->length); | ||
| 685 | |||
| 686 | for (i = 0; i < host->blocksize / 4; i++) | ||
| 687 | sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++); | ||
| 688 | |||
| 689 | if (!sh_mmcif_next_block(host, p)) | ||
| 690 | return false; | ||
| 691 | |||
| 692 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
| 693 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | ||
| 694 | |||
| 695 | return true; | ||
| 585 | } | 696 | } |
| 586 | 697 | ||
| 587 | static void sh_mmcif_get_response(struct sh_mmcif_host *host, | 698 | static void sh_mmcif_get_response(struct sh_mmcif_host *host, |
| @@ -603,8 +714,11 @@ static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host, | |||
| 603 | } | 714 | } |
| 604 | 715 | ||
| 605 | static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | 716 | static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, |
| 606 | struct mmc_request *mrq, struct mmc_command *cmd, u32 opc) | 717 | struct mmc_request *mrq) |
| 607 | { | 718 | { |
| 719 | struct mmc_data *data = mrq->data; | ||
| 720 | struct mmc_command *cmd = mrq->cmd; | ||
| 721 | u32 opc = cmd->opcode; | ||
| 608 | u32 tmp = 0; | 722 | u32 tmp = 0; |
| 609 | 723 | ||
| 610 | /* Response Type check */ | 724 | /* Response Type check */ |
| @@ -636,7 +750,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
| 636 | break; | 750 | break; |
| 637 | } | 751 | } |
| 638 | /* WDAT / DATW */ | 752 | /* WDAT / DATW */ |
| 639 | if (host->data) { | 753 | if (data) { |
| 640 | tmp |= CMD_SET_WDAT; | 754 | tmp |= CMD_SET_WDAT; |
| 641 | switch (host->bus_width) { | 755 | switch (host->bus_width) { |
| 642 | case MMC_BUS_WIDTH_1: | 756 | case MMC_BUS_WIDTH_1: |
| @@ -660,7 +774,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
| 660 | if (opc == MMC_READ_MULTIPLE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK) { | 774 | if (opc == MMC_READ_MULTIPLE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK) { |
| 661 | tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN; | 775 | tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN; |
| 662 | sh_mmcif_bitset(host, MMCIF_CE_BLOCK_SET, | 776 | sh_mmcif_bitset(host, MMCIF_CE_BLOCK_SET, |
| 663 | mrq->data->blocks << 16); | 777 | data->blocks << 16); |
| 664 | } | 778 | } |
| 665 | /* RIDXC[1:0] check bits */ | 779 | /* RIDXC[1:0] check bits */ |
| 666 | if (opc == MMC_SEND_OP_COND || opc == MMC_ALL_SEND_CID || | 780 | if (opc == MMC_SEND_OP_COND || opc == MMC_ALL_SEND_CID || |
| @@ -674,68 +788,60 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
| 674 | opc == MMC_SEND_CSD || opc == MMC_SEND_CID) | 788 | opc == MMC_SEND_CSD || opc == MMC_SEND_CID) |
| 675 | tmp |= CMD_SET_CRC7C_INTERNAL; | 789 | tmp |= CMD_SET_CRC7C_INTERNAL; |
| 676 | 790 | ||
| 677 | return opc = ((opc << 24) | tmp); | 791 | return (opc << 24) | tmp; |
| 678 | } | 792 | } |
| 679 | 793 | ||
| 680 | static int sh_mmcif_data_trans(struct sh_mmcif_host *host, | 794 | static int sh_mmcif_data_trans(struct sh_mmcif_host *host, |
| 681 | struct mmc_request *mrq, u32 opc) | 795 | struct mmc_request *mrq, u32 opc) |
| 682 | { | 796 | { |
| 683 | int ret; | ||
| 684 | |||
| 685 | switch (opc) { | 797 | switch (opc) { |
| 686 | case MMC_READ_MULTIPLE_BLOCK: | 798 | case MMC_READ_MULTIPLE_BLOCK: |
| 687 | ret = sh_mmcif_multi_read(host, mrq); | 799 | sh_mmcif_multi_read(host, mrq); |
| 688 | break; | 800 | return 0; |
| 689 | case MMC_WRITE_MULTIPLE_BLOCK: | 801 | case MMC_WRITE_MULTIPLE_BLOCK: |
| 690 | ret = sh_mmcif_multi_write(host, mrq); | 802 | sh_mmcif_multi_write(host, mrq); |
| 691 | break; | 803 | return 0; |
| 692 | case MMC_WRITE_BLOCK: | 804 | case MMC_WRITE_BLOCK: |
| 693 | ret = sh_mmcif_single_write(host, mrq); | 805 | sh_mmcif_single_write(host, mrq); |
| 694 | break; | 806 | return 0; |
| 695 | case MMC_READ_SINGLE_BLOCK: | 807 | case MMC_READ_SINGLE_BLOCK: |
| 696 | case MMC_SEND_EXT_CSD: | 808 | case MMC_SEND_EXT_CSD: |
| 697 | ret = sh_mmcif_single_read(host, mrq); | 809 | sh_mmcif_single_read(host, mrq); |
| 698 | break; | 810 | return 0; |
| 699 | default: | 811 | default: |
| 700 | dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc); | 812 | dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc); |
| 701 | ret = -EINVAL; | 813 | return -EINVAL; |
| 702 | break; | ||
| 703 | } | 814 | } |
| 704 | return ret; | ||
| 705 | } | 815 | } |
| 706 | 816 | ||
| 707 | static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, | 817 | static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, |
| 708 | struct mmc_request *mrq, struct mmc_command *cmd) | 818 | struct mmc_request *mrq) |
| 709 | { | 819 | { |
| 710 | long time; | 820 | struct mmc_command *cmd = mrq->cmd; |
| 711 | int ret = 0, mask = 0; | ||
| 712 | u32 opc = cmd->opcode; | 821 | u32 opc = cmd->opcode; |
| 822 | u32 mask; | ||
| 713 | 823 | ||
| 714 | switch (opc) { | 824 | switch (opc) { |
| 715 | /* respons busy check */ | 825 | /* response busy check */ |
| 716 | case MMC_SWITCH: | 826 | case MMC_SWITCH: |
| 717 | case MMC_STOP_TRANSMISSION: | 827 | case MMC_STOP_TRANSMISSION: |
| 718 | case MMC_SET_WRITE_PROT: | 828 | case MMC_SET_WRITE_PROT: |
| 719 | case MMC_CLR_WRITE_PROT: | 829 | case MMC_CLR_WRITE_PROT: |
| 720 | case MMC_ERASE: | 830 | case MMC_ERASE: |
| 721 | case MMC_GEN_CMD: | 831 | case MMC_GEN_CMD: |
| 722 | mask = MASK_MRBSYE; | 832 | mask = MASK_START_CMD | MASK_MRBSYE; |
| 723 | break; | 833 | break; |
| 724 | default: | 834 | default: |
| 725 | mask = MASK_MCRSPE; | 835 | mask = MASK_START_CMD | MASK_MCRSPE; |
| 726 | break; | 836 | break; |
| 727 | } | 837 | } |
| 728 | mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | | ||
| 729 | MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | | ||
| 730 | MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | | ||
| 731 | MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO; | ||
| 732 | 838 | ||
| 733 | if (host->data) { | 839 | if (mrq->data) { |
| 734 | sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0); | 840 | sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0); |
| 735 | sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, | 841 | sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, |
| 736 | mrq->data->blksz); | 842 | mrq->data->blksz); |
| 737 | } | 843 | } |
| 738 | opc = sh_mmcif_set_cmd(host, mrq, cmd, opc); | 844 | opc = sh_mmcif_set_cmd(host, mrq); |
| 739 | 845 | ||
| 740 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0); | 846 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0); |
| 741 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); | 847 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); |
| @@ -744,80 +850,28 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, | |||
| 744 | /* set cmd */ | 850 | /* set cmd */ |
| 745 | sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); | 851 | sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); |
| 746 | 852 | ||
| 747 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 853 | host->wait_for = MMCIF_WAIT_FOR_CMD; |
| 748 | host->timeout); | 854 | schedule_delayed_work(&host->timeout_work, host->timeout); |
| 749 | if (time <= 0) { | ||
| 750 | cmd->error = sh_mmcif_error_manage(host); | ||
| 751 | return; | ||
| 752 | } | ||
| 753 | if (host->sd_error) { | ||
| 754 | switch (cmd->opcode) { | ||
| 755 | case MMC_ALL_SEND_CID: | ||
| 756 | case MMC_SELECT_CARD: | ||
| 757 | case MMC_APP_CMD: | ||
| 758 | cmd->error = -ETIMEDOUT; | ||
| 759 | break; | ||
| 760 | default: | ||
| 761 | dev_dbg(&host->pd->dev, "Cmd(d'%d) err\n", | ||
| 762 | cmd->opcode); | ||
| 763 | cmd->error = sh_mmcif_error_manage(host); | ||
| 764 | break; | ||
| 765 | } | ||
| 766 | host->sd_error = false; | ||
| 767 | return; | ||
| 768 | } | ||
| 769 | if (!(cmd->flags & MMC_RSP_PRESENT)) { | ||
| 770 | cmd->error = 0; | ||
| 771 | return; | ||
| 772 | } | ||
| 773 | sh_mmcif_get_response(host, cmd); | ||
| 774 | if (host->data) { | ||
| 775 | if (!host->dma_active) { | ||
| 776 | ret = sh_mmcif_data_trans(host, mrq, cmd->opcode); | ||
| 777 | } else { | ||
| 778 | long time = | ||
| 779 | wait_for_completion_interruptible_timeout(&host->dma_complete, | ||
| 780 | host->timeout); | ||
| 781 | if (!time) | ||
| 782 | ret = -ETIMEDOUT; | ||
| 783 | else if (time < 0) | ||
| 784 | ret = time; | ||
| 785 | sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, | ||
| 786 | BUF_ACC_DMAREN | BUF_ACC_DMAWEN); | ||
| 787 | host->dma_active = false; | ||
| 788 | } | ||
| 789 | if (ret < 0) | ||
| 790 | mrq->data->bytes_xfered = 0; | ||
| 791 | else | ||
| 792 | mrq->data->bytes_xfered = | ||
| 793 | mrq->data->blocks * mrq->data->blksz; | ||
| 794 | } | ||
| 795 | cmd->error = ret; | ||
| 796 | } | 855 | } |
| 797 | 856 | ||
| 798 | static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, | 857 | static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, |
| 799 | struct mmc_request *mrq, struct mmc_command *cmd) | 858 | struct mmc_request *mrq) |
| 800 | { | 859 | { |
| 801 | long time; | 860 | switch (mrq->cmd->opcode) { |
| 802 | 861 | case MMC_READ_MULTIPLE_BLOCK: | |
| 803 | if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK) | ||
| 804 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE); | 862 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE); |
| 805 | else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) | 863 | break; |
| 864 | case MMC_WRITE_MULTIPLE_BLOCK: | ||
| 806 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); | 865 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); |
| 807 | else { | 866 | break; |
| 867 | default: | ||
| 808 | dev_err(&host->pd->dev, "unsupported stop cmd\n"); | 868 | dev_err(&host->pd->dev, "unsupported stop cmd\n"); |
| 809 | cmd->error = sh_mmcif_error_manage(host); | 869 | mrq->stop->error = sh_mmcif_error_manage(host); |
| 810 | return; | 870 | return; |
| 811 | } | 871 | } |
| 812 | 872 | ||
| 813 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 873 | host->wait_for = MMCIF_WAIT_FOR_STOP; |
| 814 | host->timeout); | 874 | schedule_delayed_work(&host->timeout_work, host->timeout); |
| 815 | if (time <= 0 || host->sd_error) { | ||
| 816 | cmd->error = sh_mmcif_error_manage(host); | ||
| 817 | return; | ||
| 818 | } | ||
| 819 | sh_mmcif_get_cmd12response(host, cmd); | ||
| 820 | cmd->error = 0; | ||
| 821 | } | 875 | } |
| 822 | 876 | ||
| 823 | static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) | 877 | static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) |
| @@ -856,23 +910,10 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 856 | default: | 910 | default: |
| 857 | break; | 911 | break; |
| 858 | } | 912 | } |
| 859 | host->data = mrq->data; | ||
| 860 | if (mrq->data) { | ||
| 861 | if (mrq->data->flags & MMC_DATA_READ) { | ||
| 862 | if (host->chan_rx) | ||
| 863 | sh_mmcif_start_dma_rx(host); | ||
| 864 | } else { | ||
| 865 | if (host->chan_tx) | ||
| 866 | sh_mmcif_start_dma_tx(host); | ||
| 867 | } | ||
| 868 | } | ||
| 869 | sh_mmcif_start_cmd(host, mrq, mrq->cmd); | ||
| 870 | host->data = NULL; | ||
| 871 | 913 | ||
| 872 | if (!mrq->cmd->error && mrq->stop) | 914 | host->mrq = mrq; |
| 873 | sh_mmcif_stop_cmd(host, mrq, mrq->stop); | 915 | |
| 874 | host->state = STATE_IDLE; | 916 | sh_mmcif_start_cmd(host, mrq); |
| 875 | mmc_request_done(mmc, mrq); | ||
| 876 | } | 917 | } |
| 877 | 918 | ||
| 878 | static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 919 | static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| @@ -947,9 +988,156 @@ static struct mmc_host_ops sh_mmcif_ops = { | |||
| 947 | .get_cd = sh_mmcif_get_cd, | 988 | .get_cd = sh_mmcif_get_cd, |
| 948 | }; | 989 | }; |
| 949 | 990 | ||
| 950 | static void sh_mmcif_detect(struct mmc_host *mmc) | 991 | static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host) |
| 951 | { | 992 | { |
| 952 | mmc_detect_change(mmc, 0); | 993 | struct mmc_command *cmd = host->mrq->cmd; |
| 994 | struct mmc_data *data = host->mrq->data; | ||
| 995 | long time; | ||
| 996 | |||
| 997 | if (host->sd_error) { | ||
| 998 | switch (cmd->opcode) { | ||
| 999 | case MMC_ALL_SEND_CID: | ||
| 1000 | case MMC_SELECT_CARD: | ||
| 1001 | case MMC_APP_CMD: | ||
| 1002 | cmd->error = -ETIMEDOUT; | ||
| 1003 | host->sd_error = false; | ||
| 1004 | break; | ||
| 1005 | default: | ||
| 1006 | cmd->error = sh_mmcif_error_manage(host); | ||
| 1007 | dev_dbg(&host->pd->dev, "Cmd(d'%d) error %d\n", | ||
| 1008 | cmd->opcode, cmd->error); | ||
| 1009 | break; | ||
| 1010 | } | ||
| 1011 | return false; | ||
| 1012 | } | ||
| 1013 | if (!(cmd->flags & MMC_RSP_PRESENT)) { | ||
| 1014 | cmd->error = 0; | ||
| 1015 | return false; | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | sh_mmcif_get_response(host, cmd); | ||
| 1019 | |||
| 1020 | if (!data) | ||
| 1021 | return false; | ||
| 1022 | |||
| 1023 | if (data->flags & MMC_DATA_READ) { | ||
| 1024 | if (host->chan_rx) | ||
| 1025 | sh_mmcif_start_dma_rx(host); | ||
| 1026 | } else { | ||
| 1027 | if (host->chan_tx) | ||
| 1028 | sh_mmcif_start_dma_tx(host); | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | if (!host->dma_active) { | ||
| 1032 | data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode); | ||
| 1033 | if (!data->error) | ||
| 1034 | return true; | ||
| 1035 | return false; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | /* Running in the IRQ thread, can sleep */ | ||
| 1039 | time = wait_for_completion_interruptible_timeout(&host->dma_complete, | ||
| 1040 | host->timeout); | ||
| 1041 | if (host->sd_error) { | ||
| 1042 | dev_err(host->mmc->parent, | ||
| 1043 | "Error IRQ while waiting for DMA completion!\n"); | ||
| 1044 | /* Woken up by an error IRQ: abort DMA */ | ||
| 1045 | if (data->flags & MMC_DATA_READ) | ||
| 1046 | dmaengine_terminate_all(host->chan_rx); | ||
| 1047 | else | ||
| 1048 | dmaengine_terminate_all(host->chan_tx); | ||
| 1049 | data->error = sh_mmcif_error_manage(host); | ||
| 1050 | } else if (!time) { | ||
| 1051 | data->error = -ETIMEDOUT; | ||
| 1052 | } else if (time < 0) { | ||
| 1053 | data->error = time; | ||
| 1054 | } | ||
| 1055 | sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, | ||
| 1056 | BUF_ACC_DMAREN | BUF_ACC_DMAWEN); | ||
| 1057 | host->dma_active = false; | ||
| 1058 | |||
| 1059 | if (data->error) | ||
| 1060 | data->bytes_xfered = 0; | ||
| 1061 | |||
| 1062 | return false; | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) | ||
| 1066 | { | ||
| 1067 | struct sh_mmcif_host *host = dev_id; | ||
| 1068 | struct mmc_request *mrq = host->mrq; | ||
| 1069 | struct mmc_data *data = mrq->data; | ||
| 1070 | |||
| 1071 | cancel_delayed_work_sync(&host->timeout_work); | ||
| 1072 | |||
| 1073 | /* | ||
| 1074 | * All handlers return true, if processing continues, and false, if the | ||
| 1075 | * request has to be completed - successfully or not | ||
| 1076 | */ | ||
| 1077 | switch (host->wait_for) { | ||
| 1078 | case MMCIF_WAIT_FOR_REQUEST: | ||
| 1079 | /* We're too late, the timeout has already kicked in */ | ||
| 1080 | return IRQ_HANDLED; | ||
| 1081 | case MMCIF_WAIT_FOR_CMD: | ||
| 1082 | if (sh_mmcif_end_cmd(host)) | ||
| 1083 | /* Wait for data */ | ||
| 1084 | return IRQ_HANDLED; | ||
| 1085 | break; | ||
| 1086 | case MMCIF_WAIT_FOR_MREAD: | ||
| 1087 | if (sh_mmcif_mread_block(host)) | ||
| 1088 | /* Wait for more data */ | ||
| 1089 | return IRQ_HANDLED; | ||
| 1090 | break; | ||
| 1091 | case MMCIF_WAIT_FOR_READ: | ||
| 1092 | if (sh_mmcif_read_block(host)) | ||
| 1093 | /* Wait for data end */ | ||
| 1094 | return IRQ_HANDLED; | ||
| 1095 | break; | ||
| 1096 | case MMCIF_WAIT_FOR_MWRITE: | ||
| 1097 | if (sh_mmcif_mwrite_block(host)) | ||
| 1098 | /* Wait data to write */ | ||
| 1099 | return IRQ_HANDLED; | ||
| 1100 | break; | ||
| 1101 | case MMCIF_WAIT_FOR_WRITE: | ||
| 1102 | if (sh_mmcif_write_block(host)) | ||
| 1103 | /* Wait for data end */ | ||
| 1104 | return IRQ_HANDLED; | ||
| 1105 | break; | ||
| 1106 | case MMCIF_WAIT_FOR_STOP: | ||
| 1107 | if (host->sd_error) { | ||
| 1108 | mrq->stop->error = sh_mmcif_error_manage(host); | ||
| 1109 | break; | ||
| 1110 | } | ||
| 1111 | sh_mmcif_get_cmd12response(host, mrq->stop); | ||
| 1112 | mrq->stop->error = 0; | ||
| 1113 | break; | ||
| 1114 | case MMCIF_WAIT_FOR_READ_END: | ||
| 1115 | case MMCIF_WAIT_FOR_WRITE_END: | ||
| 1116 | if (host->sd_error) | ||
| 1117 | data->error = sh_mmcif_error_manage(host); | ||
| 1118 | break; | ||
| 1119 | default: | ||
| 1120 | BUG(); | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | if (host->wait_for != MMCIF_WAIT_FOR_STOP) { | ||
| 1124 | if (!mrq->cmd->error && data && !data->error) | ||
| 1125 | data->bytes_xfered = | ||
| 1126 | data->blocks * data->blksz; | ||
| 1127 | |||
| 1128 | if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) { | ||
| 1129 | sh_mmcif_stop_cmd(host, mrq); | ||
| 1130 | if (!mrq->stop->error) | ||
| 1131 | return IRQ_HANDLED; | ||
| 1132 | } | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | host->wait_for = MMCIF_WAIT_FOR_REQUEST; | ||
| 1136 | host->state = STATE_IDLE; | ||
| 1137 | host->mrq = NULL; | ||
| 1138 | mmc_request_done(host->mmc, mrq); | ||
| 1139 | |||
| 1140 | return IRQ_HANDLED; | ||
| 953 | } | 1141 | } |
| 954 | 1142 | ||
| 955 | static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | 1143 | static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) |
| @@ -960,7 +1148,12 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | |||
| 960 | 1148 | ||
| 961 | state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); | 1149 | state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); |
| 962 | 1150 | ||
| 963 | if (state & INT_RBSYE) { | 1151 | if (state & INT_ERR_STS) { |
| 1152 | /* error interrupts - process first */ | ||
| 1153 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); | ||
| 1154 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); | ||
| 1155 | err = 1; | ||
| 1156 | } else if (state & INT_RBSYE) { | ||
| 964 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, | 1157 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, |
| 965 | ~(INT_RBSYE | INT_CRSPE)); | 1158 | ~(INT_RBSYE | INT_CRSPE)); |
| 966 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE); | 1159 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE); |
| @@ -988,11 +1181,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | |||
| 988 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, | 1181 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, |
| 989 | ~(INT_CMD12RBE | INT_CMD12CRE)); | 1182 | ~(INT_CMD12RBE | INT_CMD12CRE)); |
| 990 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); | 1183 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); |
| 991 | } else if (state & INT_ERR_STS) { | ||
| 992 | /* err interrupts */ | ||
| 993 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); | ||
| 994 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); | ||
| 995 | err = 1; | ||
| 996 | } else { | 1184 | } else { |
| 997 | dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state); | 1185 | dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state); |
| 998 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); | 1186 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); |
| @@ -1003,14 +1191,57 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | |||
| 1003 | host->sd_error = true; | 1191 | host->sd_error = true; |
| 1004 | dev_dbg(&host->pd->dev, "int err state = %08x\n", state); | 1192 | dev_dbg(&host->pd->dev, "int err state = %08x\n", state); |
| 1005 | } | 1193 | } |
| 1006 | if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) | 1194 | if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) { |
| 1007 | complete(&host->intr_wait); | 1195 | if (!host->dma_active) |
| 1008 | else | 1196 | return IRQ_WAKE_THREAD; |
| 1197 | else if (host->sd_error) | ||
| 1198 | mmcif_dma_complete(host); | ||
| 1199 | } else { | ||
| 1009 | dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state); | 1200 | dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state); |
| 1201 | } | ||
| 1010 | 1202 | ||
| 1011 | return IRQ_HANDLED; | 1203 | return IRQ_HANDLED; |
| 1012 | } | 1204 | } |
| 1013 | 1205 | ||
| 1206 | static void mmcif_timeout_work(struct work_struct *work) | ||
| 1207 | { | ||
| 1208 | struct delayed_work *d = container_of(work, struct delayed_work, work); | ||
| 1209 | struct sh_mmcif_host *host = container_of(d, struct sh_mmcif_host, timeout_work); | ||
| 1210 | struct mmc_request *mrq = host->mrq; | ||
| 1211 | |||
| 1212 | if (host->dying) | ||
| 1213 | /* Don't run after mmc_remove_host() */ | ||
| 1214 | return; | ||
| 1215 | |||
| 1216 | /* | ||
| 1217 | * Handle races with cancel_delayed_work(), unless | ||
| 1218 | * cancel_delayed_work_sync() is used | ||
| 1219 | */ | ||
| 1220 | switch (host->wait_for) { | ||
| 1221 | case MMCIF_WAIT_FOR_CMD: | ||
| 1222 | mrq->cmd->error = sh_mmcif_error_manage(host); | ||
| 1223 | break; | ||
| 1224 | case MMCIF_WAIT_FOR_STOP: | ||
| 1225 | mrq->stop->error = sh_mmcif_error_manage(host); | ||
| 1226 | break; | ||
| 1227 | case MMCIF_WAIT_FOR_MREAD: | ||
| 1228 | case MMCIF_WAIT_FOR_MWRITE: | ||
| 1229 | case MMCIF_WAIT_FOR_READ: | ||
| 1230 | case MMCIF_WAIT_FOR_WRITE: | ||
| 1231 | case MMCIF_WAIT_FOR_READ_END: | ||
| 1232 | case MMCIF_WAIT_FOR_WRITE_END: | ||
| 1233 | mrq->data->error = sh_mmcif_error_manage(host); | ||
| 1234 | break; | ||
| 1235 | default: | ||
| 1236 | BUG(); | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | host->state = STATE_IDLE; | ||
| 1240 | host->wait_for = MMCIF_WAIT_FOR_REQUEST; | ||
| 1241 | host->mrq = NULL; | ||
| 1242 | mmc_request_done(host->mmc, mrq); | ||
| 1243 | } | ||
| 1244 | |||
| 1014 | static int __devinit sh_mmcif_probe(struct platform_device *pdev) | 1245 | static int __devinit sh_mmcif_probe(struct platform_device *pdev) |
| 1015 | { | 1246 | { |
| 1016 | int ret = 0, irq[2]; | 1247 | int ret = 0, irq[2]; |
| @@ -1064,7 +1295,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
| 1064 | host->clk = clk_get_rate(host->hclk); | 1295 | host->clk = clk_get_rate(host->hclk); |
| 1065 | host->pd = pdev; | 1296 | host->pd = pdev; |
| 1066 | 1297 | ||
| 1067 | init_completion(&host->intr_wait); | ||
| 1068 | spin_lock_init(&host->lock); | 1298 | spin_lock_init(&host->lock); |
| 1069 | 1299 | ||
| 1070 | mmc->ops = &sh_mmcif_ops; | 1300 | mmc->ops = &sh_mmcif_ops; |
| @@ -1101,19 +1331,21 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
| 1101 | 1331 | ||
| 1102 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1332 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
| 1103 | 1333 | ||
| 1104 | ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host); | 1334 | ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host); |
| 1105 | if (ret) { | 1335 | if (ret) { |
| 1106 | dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n"); | 1336 | dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n"); |
| 1107 | goto clean_up3; | 1337 | goto clean_up3; |
| 1108 | } | 1338 | } |
| 1109 | ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host); | 1339 | ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host); |
| 1110 | if (ret) { | 1340 | if (ret) { |
| 1111 | free_irq(irq[0], host); | 1341 | free_irq(irq[0], host); |
| 1112 | dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); | 1342 | dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); |
| 1113 | goto clean_up3; | 1343 | goto clean_up3; |
| 1114 | } | 1344 | } |
| 1115 | 1345 | ||
| 1116 | sh_mmcif_detect(host->mmc); | 1346 | INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work); |
| 1347 | |||
| 1348 | mmc_detect_change(host->mmc, 0); | ||
| 1117 | 1349 | ||
| 1118 | dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION); | 1350 | dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION); |
| 1119 | dev_dbg(&pdev->dev, "chip ver H'%04x\n", | 1351 | dev_dbg(&pdev->dev, "chip ver H'%04x\n", |
| @@ -1139,11 +1371,19 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) | |||
| 1139 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); | 1371 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); |
| 1140 | int irq[2]; | 1372 | int irq[2]; |
| 1141 | 1373 | ||
| 1374 | host->dying = true; | ||
| 1142 | pm_runtime_get_sync(&pdev->dev); | 1375 | pm_runtime_get_sync(&pdev->dev); |
| 1143 | 1376 | ||
| 1144 | mmc_remove_host(host->mmc); | 1377 | mmc_remove_host(host->mmc); |
| 1145 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1378 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
| 1146 | 1379 | ||
| 1380 | /* | ||
| 1381 | * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the | ||
| 1382 | * mmc_remove_host() call above. But swapping order doesn't help either | ||
| 1383 | * (a query on the linux-mmc mailing list didn't bring any replies). | ||
| 1384 | */ | ||
| 1385 | cancel_delayed_work_sync(&host->timeout_work); | ||
| 1386 | |||
| 1147 | if (host->addr) | 1387 | if (host->addr) |
| 1148 | iounmap(host->addr); | 1388 | iounmap(host->addr); |
| 1149 | 1389 | ||
| @@ -1206,19 +1446,7 @@ static struct platform_driver sh_mmcif_driver = { | |||
| 1206 | }, | 1446 | }, |
| 1207 | }; | 1447 | }; |
| 1208 | 1448 | ||
| 1209 | static int __init sh_mmcif_init(void) | 1449 | module_platform_driver(sh_mmcif_driver); |
| 1210 | { | ||
| 1211 | return platform_driver_register(&sh_mmcif_driver); | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | static void __exit sh_mmcif_exit(void) | ||
| 1215 | { | ||
| 1216 | platform_driver_unregister(&sh_mmcif_driver); | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | module_init(sh_mmcif_init); | ||
| 1220 | module_exit(sh_mmcif_exit); | ||
| 1221 | |||
| 1222 | 1450 | ||
| 1223 | MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver"); | 1451 | MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver"); |
| 1224 | MODULE_LICENSE("GPL"); | 1452 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 41ae6466bd8..58da3c44acc 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c | |||
| @@ -282,18 +282,7 @@ static struct platform_driver sh_mobile_sdhi_driver = { | |||
| 282 | .remove = __devexit_p(sh_mobile_sdhi_remove), | 282 | .remove = __devexit_p(sh_mobile_sdhi_remove), |
| 283 | }; | 283 | }; |
| 284 | 284 | ||
| 285 | static int __init sh_mobile_sdhi_init(void) | 285 | module_platform_driver(sh_mobile_sdhi_driver); |
| 286 | { | ||
| 287 | return platform_driver_register(&sh_mobile_sdhi_driver); | ||
| 288 | } | ||
| 289 | |||
| 290 | static void __exit sh_mobile_sdhi_exit(void) | ||
| 291 | { | ||
| 292 | platform_driver_unregister(&sh_mobile_sdhi_driver); | ||
| 293 | } | ||
| 294 | |||
| 295 | module_init(sh_mobile_sdhi_init); | ||
| 296 | module_exit(sh_mobile_sdhi_exit); | ||
| 297 | 286 | ||
| 298 | MODULE_DESCRIPTION("SuperH Mobile SDHI driver"); | 287 | MODULE_DESCRIPTION("SuperH Mobile SDHI driver"); |
| 299 | MODULE_AUTHOR("Magnus Damm"); | 288 | MODULE_AUTHOR("Magnus Damm"); |
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index f70d04664ca..fc00081687b 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c | |||
| @@ -118,7 +118,7 @@ static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, | |||
| 118 | unsigned char *buf; | 118 | unsigned char *buf; |
| 119 | unsigned int pos = 0, val; | 119 | unsigned int pos = 0, val; |
| 120 | 120 | ||
| 121 | buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + off; | 121 | buf = kmap_atomic(pg) + off; |
| 122 | if (host->cmd_flags & DATA_CARRY) { | 122 | if (host->cmd_flags & DATA_CARRY) { |
| 123 | buf[pos++] = host->bounce_buf_data[0]; | 123 | buf[pos++] = host->bounce_buf_data[0]; |
| 124 | host->cmd_flags &= ~DATA_CARRY; | 124 | host->cmd_flags &= ~DATA_CARRY; |
| @@ -134,7 +134,7 @@ static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, | |||
| 134 | } | 134 | } |
| 135 | buf[pos++] = (val >> 8) & 0xff; | 135 | buf[pos++] = (val >> 8) & 0xff; |
| 136 | } | 136 | } |
| 137 | kunmap_atomic(buf - off, KM_BIO_DST_IRQ); | 137 | kunmap_atomic(buf - off); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, | 140 | static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, |
| @@ -144,7 +144,7 @@ static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, | |||
| 144 | unsigned char *buf; | 144 | unsigned char *buf; |
| 145 | unsigned int pos = 0, val; | 145 | unsigned int pos = 0, val; |
| 146 | 146 | ||
| 147 | buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + off; | 147 | buf = kmap_atomic(pg) + off; |
| 148 | if (host->cmd_flags & DATA_CARRY) { | 148 | if (host->cmd_flags & DATA_CARRY) { |
| 149 | val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00); | 149 | val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00); |
| 150 | writel(val, sock->addr + SOCK_MMCSD_DATA); | 150 | writel(val, sock->addr + SOCK_MMCSD_DATA); |
| @@ -161,7 +161,7 @@ static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, | |||
| 161 | val |= (buf[pos++] << 8) & 0xff00; | 161 | val |= (buf[pos++] << 8) & 0xff00; |
| 162 | writel(val, sock->addr + SOCK_MMCSD_DATA); | 162 | writel(val, sock->addr + SOCK_MMCSD_DATA); |
| 163 | } | 163 | } |
| 164 | kunmap_atomic(buf - off, KM_BIO_SRC_IRQ); | 164 | kunmap_atomic(buf - off); |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | static void tifm_sd_transfer_data(struct tifm_sd *host) | 167 | static void tifm_sd_transfer_data(struct tifm_sd *host) |
| @@ -212,13 +212,13 @@ static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off, | |||
| 212 | struct page *src, unsigned int src_off, | 212 | struct page *src, unsigned int src_off, |
| 213 | unsigned int count) | 213 | unsigned int count) |
| 214 | { | 214 | { |
| 215 | unsigned char *src_buf = kmap_atomic(src, KM_BIO_SRC_IRQ) + src_off; | 215 | unsigned char *src_buf = kmap_atomic(src) + src_off; |
| 216 | unsigned char *dst_buf = kmap_atomic(dst, KM_BIO_DST_IRQ) + dst_off; | 216 | unsigned char *dst_buf = kmap_atomic(dst) + dst_off; |
| 217 | 217 | ||
| 218 | memcpy(dst_buf, src_buf, count); | 218 | memcpy(dst_buf, src_buf, count); |
| 219 | 219 | ||
| 220 | kunmap_atomic(dst_buf - dst_off, KM_BIO_DST_IRQ); | 220 | kunmap_atomic(dst_buf - dst_off); |
| 221 | kunmap_atomic(src_buf - src_off, KM_BIO_SRC_IRQ); | 221 | kunmap_atomic(src_buf - src_off); |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data) | 224 | static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data) |
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index a4ea1024278..113ce6c9cf3 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
| @@ -138,19 +138,7 @@ static struct platform_driver tmio_mmc_driver = { | |||
| 138 | .resume = tmio_mmc_resume, | 138 | .resume = tmio_mmc_resume, |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | 141 | module_platform_driver(tmio_mmc_driver); | |
| 142 | static int __init tmio_mmc_init(void) | ||
| 143 | { | ||
| 144 | return platform_driver_register(&tmio_mmc_driver); | ||
| 145 | } | ||
| 146 | |||
| 147 | static void __exit tmio_mmc_exit(void) | ||
| 148 | { | ||
| 149 | platform_driver_unregister(&tmio_mmc_driver); | ||
| 150 | } | ||
| 151 | |||
| 152 | module_init(tmio_mmc_init); | ||
| 153 | module_exit(tmio_mmc_exit); | ||
| 154 | 142 | ||
| 155 | MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver"); | 143 | MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver"); |
| 156 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); | 144 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); |
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 3020f98218f..a95e6d90172 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
| @@ -105,13 +105,13 @@ static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg, | |||
| 105 | unsigned long *flags) | 105 | unsigned long *flags) |
| 106 | { | 106 | { |
| 107 | local_irq_save(*flags); | 107 | local_irq_save(*flags); |
| 108 | return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 108 | return kmap_atomic(sg_page(sg)) + sg->offset; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg, | 111 | static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg, |
| 112 | unsigned long *flags, void *virt) | 112 | unsigned long *flags, void *virt) |
| 113 | { | 113 | { |
| 114 | kunmap_atomic(virt - sg->offset, KM_BIO_SRC_IRQ); | 114 | kunmap_atomic(virt - sg->offset); |
| 115 | local_irq_restore(*flags); | 115 | local_irq_restore(*flags); |
| 116 | } | 116 | } |
| 117 | 117 | ||
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 4208b395806..abad01b37cf 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
| @@ -800,8 +800,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 800 | } else if (ios->power_mode != MMC_POWER_UP) { | 800 | } else if (ios->power_mode != MMC_POWER_UP) { |
| 801 | if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) | 801 | if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) |
| 802 | host->set_pwr(host->pdev, 0); | 802 | host->set_pwr(host->pdev, 0); |
| 803 | if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && | 803 | if (pdata->power) { |
| 804 | pdata->power) { | ||
| 805 | pdata->power = false; | 804 | pdata->power = false; |
| 806 | pm_runtime_put(&host->pdev->dev); | 805 | pm_runtime_put(&host->pdev->dev); |
| 807 | } | 806 | } |
| @@ -915,6 +914,23 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
| 915 | if (ret < 0) | 914 | if (ret < 0) |
| 916 | goto pm_disable; | 915 | goto pm_disable; |
| 917 | 916 | ||
| 917 | /* | ||
| 918 | * There are 4 different scenarios for the card detection: | ||
| 919 | * 1) an external gpio irq handles the cd (best for power savings) | ||
| 920 | * 2) internal sdhi irq handles the cd | ||
| 921 | * 3) a worker thread polls the sdhi - indicated by MMC_CAP_NEEDS_POLL | ||
| 922 | * 4) the medium is non-removable - indicated by MMC_CAP_NONREMOVABLE | ||
| 923 | * | ||
| 924 | * While we increment the rtpm counter for all scenarios when the mmc | ||
| 925 | * core activates us by calling an appropriate set_ios(), we must | ||
| 926 | * additionally ensure that in case 2) the tmio mmc hardware stays | ||
| 927 | * powered on during runtime for the card detection to work. | ||
| 928 | */ | ||
| 929 | if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD | ||
| 930 | || mmc->caps & MMC_CAP_NEEDS_POLL | ||
| 931 | || mmc->caps & MMC_CAP_NONREMOVABLE)) | ||
| 932 | pm_runtime_get_noresume(&pdev->dev); | ||
| 933 | |||
| 918 | tmio_mmc_clk_stop(_host); | 934 | tmio_mmc_clk_stop(_host); |
| 919 | tmio_mmc_reset(_host); | 935 | tmio_mmc_reset(_host); |
| 920 | 936 | ||
| @@ -933,12 +949,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
| 933 | /* See if we also get DMA */ | 949 | /* See if we also get DMA */ |
| 934 | tmio_mmc_request_dma(_host, pdata); | 950 | tmio_mmc_request_dma(_host, pdata); |
| 935 | 951 | ||
| 936 | /* We have to keep the device powered for its card detection to work */ | ||
| 937 | if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD)) { | ||
| 938 | pdata->power = true; | ||
| 939 | pm_runtime_get_noresume(&pdev->dev); | ||
| 940 | } | ||
| 941 | |||
| 942 | mmc_add_host(mmc); | 952 | mmc_add_host(mmc); |
| 943 | 953 | ||
| 944 | /* Unmask the IRQs we want to know about */ | 954 | /* Unmask the IRQs we want to know about */ |
| @@ -974,7 +984,9 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host) | |||
| 974 | * the controller, the runtime PM is suspended and pdata->power == false, | 984 | * the controller, the runtime PM is suspended and pdata->power == false, |
| 975 | * so, our .runtime_resume() will not try to detect a card in the slot. | 985 | * so, our .runtime_resume() will not try to detect a card in the slot. |
| 976 | */ | 986 | */ |
| 977 | if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD) | 987 | if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD |
| 988 | || host->mmc->caps & MMC_CAP_NEEDS_POLL | ||
| 989 | || host->mmc->caps & MMC_CAP_NONREMOVABLE) | ||
| 978 | pm_runtime_get_sync(&pdev->dev); | 990 | pm_runtime_get_sync(&pdev->dev); |
| 979 | 991 | ||
| 980 | mmc_remove_host(host->mmc); | 992 | mmc_remove_host(host->mmc); |
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index 21114810c7c..0101e9c17fa 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h | |||
| @@ -30,6 +30,7 @@ struct dma_chan; | |||
| 30 | * @cd_invert: true if the gpio_cd pin value is active low | 30 | * @cd_invert: true if the gpio_cd pin value is active low |
| 31 | * @capabilities: the capabilities of the block as implemented in | 31 | * @capabilities: the capabilities of the block as implemented in |
| 32 | * this platform, signify anything MMC_CAP_* from mmc/host.h | 32 | * this platform, signify anything MMC_CAP_* from mmc/host.h |
| 33 | * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h | ||
| 33 | * @dma_filter: function used to select an appropriate RX and TX | 34 | * @dma_filter: function used to select an appropriate RX and TX |
| 34 | * DMA channel to be used for DMA, if and only if you're deploying the | 35 | * DMA channel to be used for DMA, if and only if you're deploying the |
| 35 | * generic DMA engine | 36 | * generic DMA engine |
| @@ -52,6 +53,7 @@ struct mmci_platform_data { | |||
| 52 | int gpio_cd; | 53 | int gpio_cd; |
| 53 | bool cd_invert; | 54 | bool cd_invert; |
| 54 | unsigned long capabilities; | 55 | unsigned long capabilities; |
| 56 | unsigned long capabilities2; | ||
| 55 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); | 57 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); |
| 56 | void *dma_rx_param; | 58 | void *dma_rx_param; |
| 57 | void *dma_tx_param; | 59 | void *dma_tx_param; |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c8ef9bc54d5..9f22ba572de 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
| @@ -71,6 +71,8 @@ struct mmc_ext_csd { | |||
| 71 | bool hpi_en; /* HPI enablebit */ | 71 | bool hpi_en; /* HPI enablebit */ |
| 72 | bool hpi; /* HPI support bit */ | 72 | bool hpi; /* HPI support bit */ |
| 73 | unsigned int hpi_cmd; /* cmd used as HPI */ | 73 | unsigned int hpi_cmd; /* cmd used as HPI */ |
| 74 | unsigned int boot_ro_lock; /* ro lock support */ | ||
| 75 | bool boot_ro_lockable; | ||
| 74 | u8 raw_partition_support; /* 160 */ | 76 | u8 raw_partition_support; /* 160 */ |
| 75 | u8 raw_erased_mem_count; /* 181 */ | 77 | u8 raw_erased_mem_count; /* 181 */ |
| 76 | u8 raw_ext_csd_structure; /* 194 */ | 78 | u8 raw_ext_csd_structure; /* 194 */ |
| @@ -110,6 +112,7 @@ struct sd_ssr { | |||
| 110 | struct sd_switch_caps { | 112 | struct sd_switch_caps { |
| 111 | unsigned int hs_max_dtr; | 113 | unsigned int hs_max_dtr; |
| 112 | unsigned int uhs_max_dtr; | 114 | unsigned int uhs_max_dtr; |
| 115 | #define HIGH_SPEED_MAX_DTR 50000000 | ||
| 113 | #define UHS_SDR104_MAX_DTR 208000000 | 116 | #define UHS_SDR104_MAX_DTR 208000000 |
| 114 | #define UHS_SDR50_MAX_DTR 100000000 | 117 | #define UHS_SDR50_MAX_DTR 100000000 |
| 115 | #define UHS_DDR50_MAX_DTR 50000000 | 118 | #define UHS_DDR50_MAX_DTR 50000000 |
| @@ -117,11 +120,13 @@ struct sd_switch_caps { | |||
| 117 | #define UHS_SDR12_MAX_DTR 25000000 | 120 | #define UHS_SDR12_MAX_DTR 25000000 |
| 118 | unsigned int sd3_bus_mode; | 121 | unsigned int sd3_bus_mode; |
| 119 | #define UHS_SDR12_BUS_SPEED 0 | 122 | #define UHS_SDR12_BUS_SPEED 0 |
| 123 | #define HIGH_SPEED_BUS_SPEED 1 | ||
| 120 | #define UHS_SDR25_BUS_SPEED 1 | 124 | #define UHS_SDR25_BUS_SPEED 1 |
| 121 | #define UHS_SDR50_BUS_SPEED 2 | 125 | #define UHS_SDR50_BUS_SPEED 2 |
| 122 | #define UHS_SDR104_BUS_SPEED 3 | 126 | #define UHS_SDR104_BUS_SPEED 3 |
| 123 | #define UHS_DDR50_BUS_SPEED 4 | 127 | #define UHS_DDR50_BUS_SPEED 4 |
| 124 | 128 | ||
| 129 | #define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED) | ||
| 125 | #define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED) | 130 | #define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED) |
| 126 | #define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED) | 131 | #define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED) |
| 127 | #define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED) | 132 | #define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED) |
| @@ -184,6 +189,10 @@ struct mmc_part { | |||
| 184 | unsigned int part_cfg; /* partition type */ | 189 | unsigned int part_cfg; /* partition type */ |
| 185 | char name[MAX_MMC_PART_NAME_LEN]; | 190 | char name[MAX_MMC_PART_NAME_LEN]; |
| 186 | bool force_ro; /* to make boot parts RO by default */ | 191 | bool force_ro; /* to make boot parts RO by default */ |
| 192 | unsigned int area_type; | ||
| 193 | #define MMC_BLK_DATA_AREA_MAIN (1<<0) | ||
| 194 | #define MMC_BLK_DATA_AREA_BOOT (1<<1) | ||
| 195 | #define MMC_BLK_DATA_AREA_GP (1<<2) | ||
| 187 | }; | 196 | }; |
| 188 | 197 | ||
| 189 | /* | 198 | /* |
| @@ -206,6 +215,8 @@ struct mmc_card { | |||
| 206 | #define MMC_STATE_HIGHSPEED_DDR (1<<4) /* card is in high speed mode */ | 215 | #define MMC_STATE_HIGHSPEED_DDR (1<<4) /* card is in high speed mode */ |
| 207 | #define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */ | 216 | #define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */ |
| 208 | #define MMC_CARD_SDXC (1<<6) /* card is SDXC */ | 217 | #define MMC_CARD_SDXC (1<<6) /* card is SDXC */ |
| 218 | #define MMC_CARD_REMOVED (1<<7) /* card has been removed */ | ||
| 219 | #define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */ | ||
| 209 | unsigned int quirks; /* card quirks */ | 220 | unsigned int quirks; /* card quirks */ |
| 210 | #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ | 221 | #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ |
| 211 | #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ | 222 | #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ |
| @@ -261,12 +272,14 @@ struct mmc_card { | |||
| 261 | * This function fill contents in mmc_part. | 272 | * This function fill contents in mmc_part. |
| 262 | */ | 273 | */ |
| 263 | static inline void mmc_part_add(struct mmc_card *card, unsigned int size, | 274 | static inline void mmc_part_add(struct mmc_card *card, unsigned int size, |
| 264 | unsigned int part_cfg, char *name, int idx, bool ro) | 275 | unsigned int part_cfg, char *name, int idx, bool ro, |
| 276 | int area_type) | ||
| 265 | { | 277 | { |
| 266 | card->part[card->nr_parts].size = size; | 278 | card->part[card->nr_parts].size = size; |
| 267 | card->part[card->nr_parts].part_cfg = part_cfg; | 279 | card->part[card->nr_parts].part_cfg = part_cfg; |
| 268 | sprintf(card->part[card->nr_parts].name, name, idx); | 280 | sprintf(card->part[card->nr_parts].name, name, idx); |
| 269 | card->part[card->nr_parts].force_ro = ro; | 281 | card->part[card->nr_parts].force_ro = ro; |
| 282 | card->part[card->nr_parts].area_type = area_type; | ||
| 270 | card->nr_parts++; | 283 | card->nr_parts++; |
| 271 | } | 284 | } |
| 272 | 285 | ||
| @@ -362,18 +375,24 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) | |||
| 362 | #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) | 375 | #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) |
| 363 | #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) | 376 | #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) |
| 364 | #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) | 377 | #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) |
| 378 | #define mmc_card_hs200(c) ((c)->state & MMC_STATE_HIGHSPEED_200) | ||
| 365 | #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) | 379 | #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) |
| 366 | #define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR) | 380 | #define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR) |
| 367 | #define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) | 381 | #define mmc_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) |
| 382 | #define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) | ||
| 368 | #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) | 383 | #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) |
| 384 | #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) | ||
| 369 | 385 | ||
| 370 | #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) | 386 | #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) |
| 371 | #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) | 387 | #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) |
| 372 | #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) | 388 | #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) |
| 389 | #define mmc_card_set_hs200(c) ((c)->state |= MMC_STATE_HIGHSPEED_200) | ||
| 373 | #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) | 390 | #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) |
| 374 | #define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR) | 391 | #define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR) |
| 392 | #define mmc_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) | ||
| 375 | #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) | 393 | #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) |
| 376 | #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) | 394 | #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) |
| 395 | #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) | ||
| 377 | 396 | ||
| 378 | /* | 397 | /* |
| 379 | * Quirk add/remove for MMC products. | 398 | * Quirk add/remove for MMC products. |
diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/cd-gpio.h new file mode 100644 index 00000000000..a8e46978331 --- /dev/null +++ b/include/linux/mmc/cd-gpio.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* | ||
| 2 | * Generic GPIO card-detect helper header | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
| 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 version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef MMC_CD_GPIO_H | ||
| 12 | #define MMC_CD_GPIO_H | ||
| 13 | |||
| 14 | struct mmc_host; | ||
| 15 | int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio, | ||
| 16 | unsigned int irq, unsigned long flags); | ||
| 17 | void mmc_cd_gpio_free(struct mmc_host *host); | ||
| 18 | |||
| 19 | #endif | ||
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 174a844a5dd..87a976cc565 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
| @@ -180,6 +180,8 @@ extern int mmc_try_claim_host(struct mmc_host *host); | |||
| 180 | 180 | ||
| 181 | extern int mmc_flush_cache(struct mmc_card *); | 181 | extern int mmc_flush_cache(struct mmc_card *); |
| 182 | 182 | ||
| 183 | extern int mmc_detect_card_removed(struct mmc_host *host); | ||
| 184 | |||
| 183 | /** | 185 | /** |
| 184 | * mmc_claim_host - exclusively claim a host | 186 | * mmc_claim_host - exclusively claim a host |
| 185 | * @host: mmc host to claim | 187 | * @host: mmc host to claim |
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 6dc9b80568a..e8779c6d175 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h | |||
| @@ -214,6 +214,7 @@ struct dw_mci_board { | |||
| 214 | unsigned int bus_hz; /* Bus speed */ | 214 | unsigned int bus_hz; /* Bus speed */ |
| 215 | 215 | ||
| 216 | unsigned int caps; /* Capabilities */ | 216 | unsigned int caps; /* Capabilities */ |
| 217 | unsigned int caps2; /* More capabilities */ | ||
| 217 | /* | 218 | /* |
| 218 | * Override fifo depth. If 0, autodetect it from the FIFOTH register, | 219 | * Override fifo depth. If 0, autodetect it from the FIFOTH register, |
| 219 | * but note that this may not be reliable after a bootloader has used | 220 | * but note that this may not be reliable after a bootloader has used |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index a3ac9c48e5d..dd13e053909 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
| @@ -56,10 +56,13 @@ struct mmc_ios { | |||
| 56 | #define MMC_TIMING_UHS_SDR50 3 | 56 | #define MMC_TIMING_UHS_SDR50 3 |
| 57 | #define MMC_TIMING_UHS_SDR104 4 | 57 | #define MMC_TIMING_UHS_SDR104 4 |
| 58 | #define MMC_TIMING_UHS_DDR50 5 | 58 | #define MMC_TIMING_UHS_DDR50 5 |
| 59 | #define MMC_TIMING_MMC_HS200 6 | ||
| 59 | 60 | ||
| 60 | #define MMC_SDR_MODE 0 | 61 | #define MMC_SDR_MODE 0 |
| 61 | #define MMC_1_2V_DDR_MODE 1 | 62 | #define MMC_1_2V_DDR_MODE 1 |
| 62 | #define MMC_1_8V_DDR_MODE 2 | 63 | #define MMC_1_8V_DDR_MODE 2 |
| 64 | #define MMC_1_2V_SDR_MODE 3 | ||
| 65 | #define MMC_1_8V_SDR_MODE 4 | ||
| 63 | 66 | ||
| 64 | unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ | 67 | unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ |
| 65 | 68 | ||
| @@ -148,7 +151,9 @@ struct mmc_host_ops { | |||
| 148 | void (*init_card)(struct mmc_host *host, struct mmc_card *card); | 151 | void (*init_card)(struct mmc_host *host, struct mmc_card *card); |
| 149 | 152 | ||
| 150 | int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); | 153 | int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); |
| 151 | int (*execute_tuning)(struct mmc_host *host); | 154 | |
| 155 | /* The tuning command opcode value is different for SD and eMMC cards */ | ||
| 156 | int (*execute_tuning)(struct mmc_host *host, u32 opcode); | ||
| 152 | void (*enable_preset_value)(struct mmc_host *host, bool enable); | 157 | void (*enable_preset_value)(struct mmc_host *host, bool enable); |
| 153 | int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); | 158 | int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); |
| 154 | void (*hw_reset)(struct mmc_host *host); | 159 | void (*hw_reset)(struct mmc_host *host); |
| @@ -167,6 +172,11 @@ struct mmc_async_req { | |||
| 167 | int (*err_check) (struct mmc_card *, struct mmc_async_req *); | 172 | int (*err_check) (struct mmc_card *, struct mmc_async_req *); |
| 168 | }; | 173 | }; |
| 169 | 174 | ||
| 175 | struct mmc_hotplug { | ||
| 176 | unsigned int irq; | ||
| 177 | void *handler_priv; | ||
| 178 | }; | ||
| 179 | |||
| 170 | struct mmc_host { | 180 | struct mmc_host { |
| 171 | struct device *parent; | 181 | struct device *parent; |
| 172 | struct device class_dev; | 182 | struct device class_dev; |
| @@ -242,6 +252,11 @@ struct mmc_host { | |||
| 242 | #define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */ | 252 | #define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */ |
| 243 | #define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */ | 253 | #define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */ |
| 244 | #define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */ | 254 | #define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */ |
| 255 | #define MMC_CAP2_NO_SLEEP_CMD (1 << 4) /* Don't allow sleep command */ | ||
| 256 | #define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */ | ||
| 257 | #define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */ | ||
| 258 | #define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \ | ||
| 259 | MMC_CAP2_HS200_1_2V_SDR) | ||
| 245 | 260 | ||
| 246 | mmc_pm_flag_t pm_caps; /* supported pm features */ | 261 | mmc_pm_flag_t pm_caps; /* supported pm features */ |
| 247 | unsigned int power_notify_type; | 262 | unsigned int power_notify_type; |
| @@ -253,10 +268,12 @@ struct mmc_host { | |||
| 253 | int clk_requests; /* internal reference counter */ | 268 | int clk_requests; /* internal reference counter */ |
| 254 | unsigned int clk_delay; /* number of MCI clk hold cycles */ | 269 | unsigned int clk_delay; /* number of MCI clk hold cycles */ |
| 255 | bool clk_gated; /* clock gated */ | 270 | bool clk_gated; /* clock gated */ |
| 256 | struct work_struct clk_gate_work; /* delayed clock gate */ | 271 | struct delayed_work clk_gate_work; /* delayed clock gate */ |
| 257 | unsigned int clk_old; /* old clock value cache */ | 272 | unsigned int clk_old; /* old clock value cache */ |
| 258 | spinlock_t clk_lock; /* lock for clk fields */ | 273 | spinlock_t clk_lock; /* lock for clk fields */ |
| 259 | struct mutex clk_gate_mutex; /* mutex for clock gating */ | 274 | struct mutex clk_gate_mutex; /* mutex for clock gating */ |
| 275 | struct device_attribute clkgate_delay_attr; | ||
| 276 | unsigned long clkgate_delay; | ||
| 260 | #endif | 277 | #endif |
| 261 | 278 | ||
| 262 | /* host specific block data */ | 279 | /* host specific block data */ |
| @@ -297,6 +314,8 @@ struct mmc_host { | |||
| 297 | int claim_cnt; /* "claim" nesting count */ | 314 | int claim_cnt; /* "claim" nesting count */ |
| 298 | 315 | ||
| 299 | struct delayed_work detect; | 316 | struct delayed_work detect; |
| 317 | int detect_change; /* card detect flag */ | ||
| 318 | struct mmc_hotplug hotplug; | ||
| 300 | 319 | ||
| 301 | const struct mmc_bus_ops *bus_ops; /* current bus driver */ | 320 | const struct mmc_bus_ops *bus_ops; /* current bus driver */ |
| 302 | unsigned int bus_refs; /* reference counter */ | 321 | unsigned int bus_refs; /* reference counter */ |
| @@ -323,6 +342,8 @@ struct mmc_host { | |||
| 323 | struct fault_attr fail_mmc_request; | 342 | struct fault_attr fail_mmc_request; |
| 324 | #endif | 343 | #endif |
| 325 | 344 | ||
| 345 | unsigned int actual_clock; /* Actual HC clock rate */ | ||
| 346 | |||
| 326 | unsigned long private[0] ____cacheline_aligned; | 347 | unsigned long private[0] ____cacheline_aligned; |
| 327 | }; | 348 | }; |
| 328 | 349 | ||
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 0e7135697d1..fb9f6e116e1 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ | 51 | #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ |
| 52 | #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ | 52 | #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ |
| 53 | #define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */ | 53 | #define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */ |
| 54 | #define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */ | ||
| 54 | 55 | ||
| 55 | /* class 3 */ | 56 | /* class 3 */ |
| 56 | #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ | 57 | #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ |
| @@ -280,6 +281,7 @@ struct _mmc_csd { | |||
| 280 | #define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ | 281 | #define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ |
| 281 | #define EXT_CSD_SANITIZE_START 165 /* W */ | 282 | #define EXT_CSD_SANITIZE_START 165 /* W */ |
| 282 | #define EXT_CSD_WR_REL_PARAM 166 /* RO */ | 283 | #define EXT_CSD_WR_REL_PARAM 166 /* RO */ |
| 284 | #define EXT_CSD_BOOT_WP 173 /* R/W */ | ||
| 283 | #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ | 285 | #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ |
| 284 | #define EXT_CSD_PART_CONFIG 179 /* R/W */ | 286 | #define EXT_CSD_PART_CONFIG 179 /* R/W */ |
| 285 | #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ | 287 | #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ |
| @@ -321,6 +323,11 @@ struct _mmc_csd { | |||
| 321 | 323 | ||
| 322 | #define EXT_CSD_WR_REL_PARAM_EN (1<<2) | 324 | #define EXT_CSD_WR_REL_PARAM_EN (1<<2) |
| 323 | 325 | ||
| 326 | #define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40) | ||
| 327 | #define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10) | ||
| 328 | #define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04) | ||
| 329 | #define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01) | ||
| 330 | |||
| 324 | #define EXT_CSD_PART_CONFIG_ACC_MASK (0x7) | 331 | #define EXT_CSD_PART_CONFIG_ACC_MASK (0x7) |
| 325 | #define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1) | 332 | #define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1) |
| 326 | #define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4) | 333 | #define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4) |
| @@ -333,13 +340,76 @@ struct _mmc_csd { | |||
| 333 | 340 | ||
| 334 | #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ | 341 | #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ |
| 335 | #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ | 342 | #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ |
| 336 | #define EXT_CSD_CARD_TYPE_MASK 0xF /* Mask out reserved bits */ | 343 | #define EXT_CSD_CARD_TYPE_MASK 0x3F /* Mask out reserved bits */ |
| 337 | #define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */ | 344 | #define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */ |
| 338 | /* DDR mode @1.8V or 3V I/O */ | 345 | /* DDR mode @1.8V or 3V I/O */ |
| 339 | #define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */ | 346 | #define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */ |
| 340 | /* DDR mode @1.2V I/O */ | 347 | /* DDR mode @1.2V I/O */ |
| 341 | #define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \ | 348 | #define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \ |
| 342 | | EXT_CSD_CARD_TYPE_DDR_1_2V) | 349 | | EXT_CSD_CARD_TYPE_DDR_1_2V) |
| 350 | #define EXT_CSD_CARD_TYPE_SDR_1_8V (1<<4) /* Card can run at 200MHz */ | ||
| 351 | #define EXT_CSD_CARD_TYPE_SDR_1_2V (1<<5) /* Card can run at 200MHz */ | ||
| 352 | /* SDR mode @1.2V I/O */ | ||
| 353 | |||
| 354 | #define EXT_CSD_CARD_TYPE_SDR_200 (EXT_CSD_CARD_TYPE_SDR_1_8V | \ | ||
| 355 | EXT_CSD_CARD_TYPE_SDR_1_2V) | ||
| 356 | |||
| 357 | #define EXT_CSD_CARD_TYPE_SDR_ALL (EXT_CSD_CARD_TYPE_SDR_200 | \ | ||
| 358 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 359 | EXT_CSD_CARD_TYPE_26) | ||
| 360 | |||
| 361 | #define EXT_CSD_CARD_TYPE_SDR_1_2V_ALL (EXT_CSD_CARD_TYPE_SDR_1_2V | \ | ||
| 362 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 363 | EXT_CSD_CARD_TYPE_26) | ||
| 364 | |||
| 365 | #define EXT_CSD_CARD_TYPE_SDR_1_8V_ALL (EXT_CSD_CARD_TYPE_SDR_1_8V | \ | ||
| 366 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 367 | EXT_CSD_CARD_TYPE_26) | ||
| 368 | |||
| 369 | #define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_1_2V | \ | ||
| 370 | EXT_CSD_CARD_TYPE_DDR_1_8V | \ | ||
| 371 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 372 | EXT_CSD_CARD_TYPE_26) | ||
| 373 | |||
| 374 | #define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_1_8V | \ | ||
| 375 | EXT_CSD_CARD_TYPE_DDR_1_8V | \ | ||
| 376 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 377 | EXT_CSD_CARD_TYPE_26) | ||
| 378 | |||
| 379 | #define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_1_2V | \ | ||
| 380 | EXT_CSD_CARD_TYPE_DDR_1_2V | \ | ||
| 381 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 382 | EXT_CSD_CARD_TYPE_26) | ||
| 383 | |||
| 384 | #define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_1_8V | \ | ||
| 385 | EXT_CSD_CARD_TYPE_DDR_1_2V | \ | ||
| 386 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 387 | EXT_CSD_CARD_TYPE_26) | ||
| 388 | |||
| 389 | #define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52 (EXT_CSD_CARD_TYPE_SDR_1_2V | \ | ||
| 390 | EXT_CSD_CARD_TYPE_DDR_52 | \ | ||
| 391 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 392 | EXT_CSD_CARD_TYPE_26) | ||
| 393 | |||
| 394 | #define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52 (EXT_CSD_CARD_TYPE_SDR_1_8V | \ | ||
| 395 | EXT_CSD_CARD_TYPE_DDR_52 | \ | ||
| 396 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 397 | EXT_CSD_CARD_TYPE_26) | ||
| 398 | |||
| 399 | #define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_200 | \ | ||
| 400 | EXT_CSD_CARD_TYPE_DDR_1_8V | \ | ||
| 401 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 402 | EXT_CSD_CARD_TYPE_26) | ||
| 403 | |||
| 404 | #define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_200 | \ | ||
| 405 | EXT_CSD_CARD_TYPE_DDR_1_2V | \ | ||
| 406 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 407 | EXT_CSD_CARD_TYPE_26) | ||
| 408 | |||
| 409 | #define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52 (EXT_CSD_CARD_TYPE_SDR_200 | \ | ||
| 410 | EXT_CSD_CARD_TYPE_DDR_52 | \ | ||
| 411 | EXT_CSD_CARD_TYPE_52 | \ | ||
| 412 | EXT_CSD_CARD_TYPE_26) | ||
| 343 | 413 | ||
| 344 | #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ | 414 | #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ |
| 345 | #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ | 415 | #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ |
diff --git a/include/linux/mmc/sdhci-pci-data.h b/include/linux/mmc/sdhci-pci-data.h new file mode 100644 index 00000000000..8959604a13d --- /dev/null +++ b/include/linux/mmc/sdhci-pci-data.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #ifndef LINUX_MMC_SDHCI_PCI_DATA_H | ||
| 2 | #define LINUX_MMC_SDHCI_PCI_DATA_H | ||
| 3 | |||
| 4 | struct pci_dev; | ||
| 5 | |||
| 6 | struct sdhci_pci_data { | ||
| 7 | struct pci_dev *pdev; | ||
| 8 | int slotno; | ||
| 9 | int rst_n_gpio; /* Set to -EINVAL if unused */ | ||
| 10 | int cd_gpio; /* Set to -EINVAL if unused */ | ||
| 11 | int (*setup)(struct sdhci_pci_data *data); | ||
| 12 | void (*cleanup)(struct sdhci_pci_data *data); | ||
| 13 | }; | ||
| 14 | |||
| 15 | extern struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, | ||
| 16 | int slotno); | ||
| 17 | |||
| 18 | #endif | ||
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index e4b69353678..c750f85177d 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h | |||
| @@ -90,8 +90,6 @@ struct sdhci_host { | |||
| 90 | 90 | ||
| 91 | unsigned int quirks2; /* More deviations from spec. */ | 91 | unsigned int quirks2; /* More deviations from spec. */ |
| 92 | 92 | ||
| 93 | #define SDHCI_QUIRK2_OWN_CARD_DETECTION (1<<0) | ||
| 94 | |||
| 95 | int irq; /* Device IRQ */ | 93 | int irq; /* Device IRQ */ |
| 96 | void __iomem *ioaddr; /* Mapped address */ | 94 | void __iomem *ioaddr; /* Mapped address */ |
| 97 | 95 | ||
| @@ -121,6 +119,7 @@ struct sdhci_host { | |||
| 121 | #define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ | 119 | #define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ |
| 122 | #define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */ | 120 | #define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */ |
| 123 | #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ | 121 | #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ |
| 122 | #define SDHCI_HS200_NEEDS_TUNING (1<<10) /* HS200 needs tuning */ | ||
| 124 | 123 | ||
| 125 | unsigned int version; /* SDHCI spec. version */ | 124 | unsigned int version; /* SDHCI spec. version */ |
| 126 | 125 | ||
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h index e0b1123497b..c9fe66c58f8 100644 --- a/include/linux/mmc/sdio.h +++ b/include/linux/mmc/sdio.h | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | * [8:0] Byte/block count | 38 | * [8:0] Byte/block count |
| 39 | */ | 39 | */ |
| 40 | 40 | ||
| 41 | #define R4_18V_PRESENT (1<<24) | ||
| 41 | #define R4_MEMORY_PRESENT (1 << 27) | 42 | #define R4_MEMORY_PRESENT (1 << 27) |
| 42 | 43 | ||
| 43 | /* | 44 | /* |
| @@ -85,6 +86,7 @@ | |||
| 85 | #define SDIO_SD_REV_1_01 0 /* SD Physical Spec Version 1.01 */ | 86 | #define SDIO_SD_REV_1_01 0 /* SD Physical Spec Version 1.01 */ |
| 86 | #define SDIO_SD_REV_1_10 1 /* SD Physical Spec Version 1.10 */ | 87 | #define SDIO_SD_REV_1_10 1 /* SD Physical Spec Version 1.10 */ |
| 87 | #define SDIO_SD_REV_2_00 2 /* SD Physical Spec Version 2.00 */ | 88 | #define SDIO_SD_REV_2_00 2 /* SD Physical Spec Version 2.00 */ |
| 89 | #define SDIO_SD_REV_3_00 3 /* SD Physical Spev Version 3.00 */ | ||
| 88 | 90 | ||
| 89 | #define SDIO_CCCR_IOEx 0x02 | 91 | #define SDIO_CCCR_IOEx 0x02 |
| 90 | #define SDIO_CCCR_IORx 0x03 | 92 | #define SDIO_CCCR_IORx 0x03 |
| @@ -134,8 +136,31 @@ | |||
| 134 | #define SDIO_CCCR_SPEED 0x13 | 136 | #define SDIO_CCCR_SPEED 0x13 |
| 135 | 137 | ||
| 136 | #define SDIO_SPEED_SHS 0x01 /* Supports High-Speed mode */ | 138 | #define SDIO_SPEED_SHS 0x01 /* Supports High-Speed mode */ |
| 137 | #define SDIO_SPEED_EHS 0x02 /* Enable High-Speed mode */ | 139 | #define SDIO_SPEED_BSS_SHIFT 1 |
| 138 | 140 | #define SDIO_SPEED_BSS_MASK (7<<SDIO_SPEED_BSS_SHIFT) | |
| 141 | #define SDIO_SPEED_SDR12 (0<<SDIO_SPEED_BSS_SHIFT) | ||
| 142 | #define SDIO_SPEED_SDR25 (1<<SDIO_SPEED_BSS_SHIFT) | ||
| 143 | #define SDIO_SPEED_SDR50 (2<<SDIO_SPEED_BSS_SHIFT) | ||
| 144 | #define SDIO_SPEED_SDR104 (3<<SDIO_SPEED_BSS_SHIFT) | ||
| 145 | #define SDIO_SPEED_DDR50 (4<<SDIO_SPEED_BSS_SHIFT) | ||
| 146 | #define SDIO_SPEED_EHS SDIO_SPEED_SDR25 /* Enable High-Speed */ | ||
| 147 | |||
| 148 | #define SDIO_CCCR_UHS 0x14 | ||
| 149 | #define SDIO_UHS_SDR50 0x01 | ||
| 150 | #define SDIO_UHS_SDR104 0x02 | ||
| 151 | #define SDIO_UHS_DDR50 0x04 | ||
| 152 | |||
| 153 | #define SDIO_CCCR_DRIVE_STRENGTH 0x15 | ||
| 154 | #define SDIO_SDTx_MASK 0x07 | ||
| 155 | #define SDIO_DRIVE_SDTA (1<<0) | ||
| 156 | #define SDIO_DRIVE_SDTC (1<<1) | ||
| 157 | #define SDIO_DRIVE_SDTD (1<<2) | ||
| 158 | #define SDIO_DRIVE_DTSx_MASK 0x03 | ||
| 159 | #define SDIO_DRIVE_DTSx_SHIFT 4 | ||
| 160 | #define SDIO_DTSx_SET_TYPE_B (0 << SDIO_DRIVE_DTSx_SHIFT) | ||
| 161 | #define SDIO_DTSx_SET_TYPE_A (1 << SDIO_DRIVE_DTSx_SHIFT) | ||
| 162 | #define SDIO_DTSx_SET_TYPE_C (2 << SDIO_DRIVE_DTSx_SHIFT) | ||
| 163 | #define SDIO_DTSx_SET_TYPE_D (3 << SDIO_DRIVE_DTSx_SHIFT) | ||
| 139 | /* | 164 | /* |
| 140 | * Function Basic Registers (FBR) | 165 | * Function Basic Registers (FBR) |
| 141 | */ | 166 | */ |
