diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/Kconfig | 106 | ||||
| -rw-r--r-- | drivers/mmc/Makefile | 33 | ||||
| -rw-r--r-- | drivers/mmc/card/Kconfig | 17 | ||||
| -rw-r--r-- | drivers/mmc/card/Makefile | 11 | ||||
| -rw-r--r-- | drivers/mmc/card/block.c (renamed from drivers/mmc/mmc_block.c) | 55 | ||||
| -rw-r--r-- | drivers/mmc/card/queue.c (renamed from drivers/mmc/mmc_queue.c) | 12 | ||||
| -rw-r--r-- | drivers/mmc/card/queue.h (renamed from drivers/mmc/mmc_queue.h) | 0 | ||||
| -rw-r--r-- | drivers/mmc/core/Kconfig | 17 | ||||
| -rw-r--r-- | drivers/mmc/core/Makefile | 11 | ||||
| -rw-r--r-- | drivers/mmc/core/core.c | 727 | ||||
| -rw-r--r-- | drivers/mmc/core/core.h | 70 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc.c | 537 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc_ops.c | 276 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc_ops.h | 27 | ||||
| -rw-r--r-- | drivers/mmc/core/sd.c | 587 | ||||
| -rw-r--r-- | drivers/mmc/core/sd_ops.c | 316 | ||||
| -rw-r--r-- | drivers/mmc/core/sd_ops.h | 25 | ||||
| -rw-r--r-- | drivers/mmc/core/sysfs.c (renamed from drivers/mmc/mmc_sysfs.c) | 38 | ||||
| -rw-r--r-- | drivers/mmc/core/sysfs.h (renamed from drivers/mmc/mmc.h) | 10 | ||||
| -rw-r--r-- | drivers/mmc/host/Kconfig | 103 | ||||
| -rw-r--r-- | drivers/mmc/host/Makefile | 18 | ||||
| -rw-r--r-- | drivers/mmc/host/at91_mci.c (renamed from drivers/mmc/at91_mci.c) | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/au1xmmc.c (renamed from drivers/mmc/au1xmmc.c) | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/au1xmmc.h (renamed from drivers/mmc/au1xmmc.h) | 0 | ||||
| -rw-r--r-- | drivers/mmc/host/imxmmc.c (renamed from drivers/mmc/imxmmc.c) | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/imxmmc.h (renamed from drivers/mmc/imxmmc.h) | 0 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.c (renamed from drivers/mmc/mmci.c) | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.h (renamed from drivers/mmc/mmci.h) | 0 | ||||
| -rw-r--r-- | drivers/mmc/host/omap.c (renamed from drivers/mmc/omap.c) | 56 | ||||
| -rw-r--r-- | drivers/mmc/host/pxamci.c (renamed from drivers/mmc/pxamci.c) | 5 | ||||
| -rw-r--r-- | drivers/mmc/host/pxamci.h (renamed from drivers/mmc/pxamci.h) | 0 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci.c (renamed from drivers/mmc/sdhci.c) | 43 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci.h (renamed from drivers/mmc/sdhci.h) | 4 | ||||
| -rw-r--r-- | drivers/mmc/host/tifm_sd.c | 1102 | ||||
| -rw-r--r-- | drivers/mmc/host/wbsd.c (renamed from drivers/mmc/wbsd.c) | 205 | ||||
| -rw-r--r-- | drivers/mmc/host/wbsd.h (renamed from drivers/mmc/wbsd.h) | 9 | ||||
| -rw-r--r-- | drivers/mmc/mmc.c | 1724 | ||||
| -rw-r--r-- | drivers/mmc/tifm_sd.c | 987 |
38 files changed, 4019 insertions, 3116 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 12af9c718764..6c97491543db 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
| @@ -19,110 +19,10 @@ config MMC_DEBUG | |||
| 19 | This is an option for use by developers; most people should | 19 | This is an option for use by developers; most people should |
| 20 | say N here. This enables MMC core and driver debugging. | 20 | say N here. This enables MMC core and driver debugging. |
| 21 | 21 | ||
| 22 | config MMC_BLOCK | 22 | source "drivers/mmc/core/Kconfig" |
| 23 | tristate "MMC block device driver" | ||
| 24 | depends on MMC && BLOCK | ||
| 25 | default y | ||
| 26 | help | ||
| 27 | Say Y here to enable the MMC block device driver support. | ||
| 28 | This provides a block device driver, which you can use to | ||
| 29 | mount the filesystem. Almost everyone wishing MMC support | ||
| 30 | should say Y or M here. | ||
| 31 | |||
| 32 | config MMC_ARMMMCI | ||
| 33 | tristate "ARM AMBA Multimedia Card Interface support" | ||
| 34 | depends on ARM_AMBA && MMC | ||
| 35 | help | ||
| 36 | This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card | ||
| 37 | Interface (PL180 and PL181) support. If you have an ARM(R) | ||
| 38 | platform with a Multimedia Card slot, say Y or M here. | ||
| 39 | |||
| 40 | If unsure, say N. | ||
| 41 | |||
| 42 | config MMC_PXA | ||
| 43 | tristate "Intel PXA25x/26x/27x Multimedia Card Interface support" | ||
| 44 | depends on ARCH_PXA && MMC | ||
| 45 | help | ||
| 46 | This selects the Intel(R) PXA(R) Multimedia card Interface. | ||
| 47 | If you have a PXA(R) platform with a Multimedia Card slot, | ||
| 48 | say Y or M here. | ||
| 49 | |||
| 50 | If unsure, say N. | ||
| 51 | |||
| 52 | config MMC_SDHCI | ||
| 53 | tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" | ||
| 54 | depends on PCI && MMC && EXPERIMENTAL | ||
| 55 | help | ||
| 56 | This select the generic Secure Digital Host Controller Interface. | ||
| 57 | It is used by manufacturers such as Texas Instruments(R), Ricoh(R) | ||
| 58 | and Toshiba(R). Most controllers found in laptops are of this type. | ||
| 59 | If you have a controller with this interface, say Y or M here. | ||
| 60 | |||
| 61 | If unsure, say N. | ||
| 62 | |||
| 63 | config MMC_OMAP | ||
| 64 | tristate "TI OMAP Multimedia Card Interface support" | ||
| 65 | depends on ARCH_OMAP && MMC | ||
| 66 | select TPS65010 if MACH_OMAP_H2 | ||
| 67 | help | ||
| 68 | This selects the TI OMAP Multimedia card Interface. | ||
| 69 | If you have an OMAP board with a Multimedia Card slot, | ||
| 70 | say Y or M here. | ||
| 71 | |||
| 72 | If unsure, say N. | ||
| 73 | 23 | ||
| 74 | config MMC_WBSD | 24 | source "drivers/mmc/card/Kconfig" |
| 75 | tristate "Winbond W83L51xD SD/MMC Card Interface support" | ||
| 76 | depends on MMC && ISA_DMA_API | ||
| 77 | help | ||
| 78 | This selects the Winbond(R) W83L51xD Secure digital and | ||
| 79 | Multimedia card Interface. | ||
| 80 | If you have a machine with a integrated W83L518D or W83L519D | ||
| 81 | SD/MMC card reader, say Y or M here. | ||
| 82 | |||
| 83 | If unsure, say N. | ||
| 84 | |||
| 85 | config MMC_AU1X | ||
| 86 | tristate "Alchemy AU1XX0 MMC Card Interface support" | ||
| 87 | depends on MMC && SOC_AU1200 | ||
| 88 | help | ||
| 89 | This selects the AMD Alchemy(R) Multimedia card interface. | ||
| 90 | If you have a Alchemy platform with a MMC slot, say Y or M here. | ||
| 91 | |||
| 92 | If unsure, say N. | ||
| 93 | |||
| 94 | config MMC_AT91 | ||
| 95 | tristate "AT91 SD/MMC Card Interface support" | ||
| 96 | depends on ARCH_AT91 && MMC | ||
| 97 | help | ||
| 98 | This selects the AT91 MCI controller. | ||
| 99 | |||
| 100 | If unsure, say N. | ||
| 101 | |||
| 102 | config MMC_IMX | ||
| 103 | tristate "Motorola i.MX Multimedia Card Interface support" | ||
| 104 | depends on ARCH_IMX && MMC | ||
| 105 | help | ||
| 106 | This selects the Motorola i.MX Multimedia card Interface. | ||
| 107 | If you have a i.MX platform with a Multimedia Card slot, | ||
| 108 | say Y or M here. | ||
| 109 | |||
| 110 | If unsure, say N. | ||
| 111 | |||
| 112 | config MMC_TIFM_SD | ||
| 113 | tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" | ||
| 114 | depends on MMC && EXPERIMENTAL && PCI | ||
| 115 | select TIFM_CORE | ||
| 116 | help | ||
| 117 | Say Y here if you want to be able to access MMC/SD cards with | ||
| 118 | the Texas Instruments(R) Flash Media card reader, found in many | ||
| 119 | laptops. | ||
| 120 | This option 'selects' (turns on, enables) 'TIFM_CORE', but you | ||
| 121 | probably also need appropriate card reader host adapter, such as | ||
| 122 | 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support | ||
| 123 | (TIFM_7XX1)'. | ||
| 124 | 25 | ||
| 125 | To compile this driver as a module, choose M here: the | 26 | source "drivers/mmc/host/Kconfig" |
| 126 | module will be called tifm_sd. | ||
| 127 | 27 | ||
| 128 | endmenu | 28 | endmenu |
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 83ffb9326a54..9979f5e9765b 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile | |||
| @@ -2,32 +2,11 @@ | |||
| 2 | # Makefile for the kernel mmc device drivers. | 2 | # Makefile for the kernel mmc device drivers. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | # | ||
| 6 | # Core | ||
| 7 | # | ||
| 8 | obj-$(CONFIG_MMC) += mmc_core.o | ||
| 9 | |||
| 10 | # | ||
| 11 | # Media drivers | ||
| 12 | # | ||
| 13 | obj-$(CONFIG_MMC_BLOCK) += mmc_block.o | ||
| 14 | |||
| 15 | # | ||
| 16 | # Host drivers | ||
| 17 | # | ||
| 18 | obj-$(CONFIG_MMC_ARMMMCI) += mmci.o | ||
| 19 | obj-$(CONFIG_MMC_PXA) += pxamci.o | ||
| 20 | obj-$(CONFIG_MMC_IMX) += imxmmc.o | ||
| 21 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | ||
| 22 | obj-$(CONFIG_MMC_WBSD) += wbsd.o | ||
| 23 | obj-$(CONFIG_MMC_AU1X) += au1xmmc.o | ||
| 24 | obj-$(CONFIG_MMC_OMAP) += omap.o | ||
| 25 | obj-$(CONFIG_MMC_AT91) += at91_mci.o | ||
| 26 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o | ||
| 27 | |||
| 28 | mmc_core-y := mmc.o mmc_sysfs.o | ||
| 29 | mmc_core-$(CONFIG_BLOCK) += mmc_queue.o | ||
| 30 | |||
| 31 | ifeq ($(CONFIG_MMC_DEBUG),y) | 5 | ifeq ($(CONFIG_MMC_DEBUG),y) |
| 32 | EXTRA_CFLAGS += -DDEBUG | 6 | EXTRA_CFLAGS += -DDEBUG |
| 33 | endif | 7 | endif |
| 8 | |||
| 9 | obj-$(CONFIG_MMC) += core/ | ||
| 10 | obj-$(CONFIG_MMC) += card/ | ||
| 11 | obj-$(CONFIG_MMC) += host/ | ||
| 12 | |||
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig new file mode 100644 index 000000000000..01a9fd376a1f --- /dev/null +++ b/drivers/mmc/card/Kconfig | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # | ||
| 2 | # MMC/SD card drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | comment "MMC/SD Card Drivers" | ||
| 6 | depends MMC | ||
| 7 | |||
| 8 | config MMC_BLOCK | ||
| 9 | tristate "MMC block device driver" | ||
| 10 | depends on MMC && BLOCK | ||
| 11 | default y | ||
| 12 | help | ||
| 13 | Say Y here to enable the MMC block device driver support. | ||
| 14 | This provides a block device driver, which you can use to | ||
| 15 | mount the filesystem. Almost everyone wishing MMC support | ||
| 16 | should say Y or M here. | ||
| 17 | |||
diff --git a/drivers/mmc/card/Makefile b/drivers/mmc/card/Makefile new file mode 100644 index 000000000000..cf8c939867f5 --- /dev/null +++ b/drivers/mmc/card/Makefile | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # | ||
| 2 | # Makefile for MMC/SD card drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | ifeq ($(CONFIG_MMC_DEBUG),y) | ||
| 6 | EXTRA_CFLAGS += -DDEBUG | ||
| 7 | endif | ||
| 8 | |||
| 9 | obj-$(CONFIG_MMC_BLOCK) += mmc_block.o | ||
| 10 | mmc_block-objs := block.o queue.o | ||
| 11 | |||
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/card/block.c index 86439a0bb271..d24ab234394c 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/card/block.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * Block driver for media (i.e., flash cards) | 2 | * Block driver for media (i.e., flash cards) |
| 3 | * | 3 | * |
| 4 | * Copyright 2002 Hewlett-Packard Company | 4 | * Copyright 2002 Hewlett-Packard Company |
| 5 | * Copyright 2005-2007 Pierre Ossman | ||
| 5 | * | 6 | * |
| 6 | * Use consistent with the GNU GPL is permitted, | 7 | * Use consistent with the GNU GPL is permitted, |
| 7 | * provided that this copyright notice is | 8 | * provided that this copyright notice is |
| @@ -31,13 +32,13 @@ | |||
| 31 | 32 | ||
| 32 | #include <linux/mmc/card.h> | 33 | #include <linux/mmc/card.h> |
| 33 | #include <linux/mmc/host.h> | 34 | #include <linux/mmc/host.h> |
| 34 | #include <linux/mmc/protocol.h> | 35 | #include <linux/mmc/mmc.h> |
| 35 | #include <linux/mmc/host.h> | 36 | #include <linux/mmc/sd.h> |
| 36 | 37 | ||
| 37 | #include <asm/system.h> | 38 | #include <asm/system.h> |
| 38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
| 39 | 40 | ||
| 40 | #include "mmc_queue.h" | 41 | #include "queue.h" |
| 41 | 42 | ||
| 42 | /* | 43 | /* |
| 43 | * max 8 partitions per card | 44 | * max 8 partitions per card |
| @@ -223,10 +224,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 223 | struct mmc_blk_data *md = mq->data; | 224 | struct mmc_blk_data *md = mq->data; |
| 224 | struct mmc_card *card = md->queue.card; | 225 | struct mmc_card *card = md->queue.card; |
| 225 | struct mmc_blk_request brq; | 226 | struct mmc_blk_request brq; |
| 226 | int ret = 1; | 227 | int ret = 1, sg_pos, data_size; |
| 227 | 228 | ||
| 228 | if (mmc_card_claim_host(card)) | 229 | mmc_claim_host(card->host); |
| 229 | goto flush_queue; | ||
| 230 | 230 | ||
| 231 | do { | 231 | do { |
| 232 | struct mmc_command cmd; | 232 | struct mmc_command cmd; |
| @@ -283,6 +283,20 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 283 | brq.data.sg = mq->sg; | 283 | brq.data.sg = mq->sg; |
| 284 | brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); | 284 | brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); |
| 285 | 285 | ||
| 286 | if (brq.data.blocks != | ||
| 287 | (req->nr_sectors >> (md->block_bits - 9))) { | ||
| 288 | data_size = brq.data.blocks * brq.data.blksz; | ||
| 289 | for (sg_pos = 0; sg_pos < brq.data.sg_len; sg_pos++) { | ||
| 290 | data_size -= mq->sg[sg_pos].length; | ||
| 291 | if (data_size <= 0) { | ||
| 292 | mq->sg[sg_pos].length += data_size; | ||
| 293 | sg_pos++; | ||
| 294 | break; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | brq.data.sg_len = sg_pos; | ||
| 298 | } | ||
| 299 | |||
| 286 | mmc_wait_for_req(card->host, &brq.mrq); | 300 | mmc_wait_for_req(card->host, &brq.mrq); |
| 287 | if (brq.cmd.error) { | 301 | if (brq.cmd.error) { |
| 288 | printk(KERN_ERR "%s: error %d sending read/write command\n", | 302 | printk(KERN_ERR "%s: error %d sending read/write command\n", |
| @@ -342,7 +356,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 342 | spin_unlock_irq(&md->lock); | 356 | spin_unlock_irq(&md->lock); |
| 343 | } while (ret); | 357 | } while (ret); |
| 344 | 358 | ||
| 345 | mmc_card_release_host(card); | 359 | mmc_release_host(card->host); |
| 346 | 360 | ||
| 347 | return 1; | 361 | return 1; |
| 348 | 362 | ||
| @@ -378,9 +392,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 378 | spin_unlock_irq(&md->lock); | 392 | spin_unlock_irq(&md->lock); |
| 379 | } | 393 | } |
| 380 | 394 | ||
| 381 | flush_queue: | 395 | mmc_release_host(card->host); |
| 382 | |||
| 383 | mmc_card_release_host(card); | ||
| 384 | 396 | ||
| 385 | spin_lock_irq(&md->lock); | 397 | spin_lock_irq(&md->lock); |
| 386 | while (ret) { | 398 | while (ret) { |
| @@ -477,11 +489,20 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
| 477 | 489 | ||
| 478 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); | 490 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); |
| 479 | 491 | ||
| 480 | /* | 492 | if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { |
| 481 | * The CSD capacity field is in units of read_blkbits. | 493 | /* |
| 482 | * set_capacity takes units of 512 bytes. | 494 | * The EXT_CSD sector count is in number or 512 byte |
| 483 | */ | 495 | * sectors. |
| 484 | set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); | 496 | */ |
| 497 | set_capacity(md->disk, card->ext_csd.sectors); | ||
| 498 | } else { | ||
| 499 | /* | ||
| 500 | * The CSD capacity field is in units of read_blkbits. | ||
| 501 | * set_capacity takes units of 512 bytes. | ||
| 502 | */ | ||
| 503 | set_capacity(md->disk, | ||
| 504 | card->csd.capacity << (card->csd.read_blkbits - 9)); | ||
| 505 | } | ||
| 485 | return md; | 506 | return md; |
| 486 | 507 | ||
| 487 | err_putdisk: | 508 | err_putdisk: |
| @@ -502,12 +523,12 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
| 502 | if (mmc_card_blockaddr(card)) | 523 | if (mmc_card_blockaddr(card)) |
| 503 | return 0; | 524 | return 0; |
| 504 | 525 | ||
| 505 | mmc_card_claim_host(card); | 526 | mmc_claim_host(card->host); |
| 506 | cmd.opcode = MMC_SET_BLOCKLEN; | 527 | cmd.opcode = MMC_SET_BLOCKLEN; |
| 507 | cmd.arg = 1 << md->block_bits; | 528 | cmd.arg = 1 << md->block_bits; |
| 508 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 529 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 509 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 530 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
| 510 | mmc_card_release_host(card); | 531 | mmc_release_host(card->host); |
| 511 | 532 | ||
| 512 | if (err) { | 533 | if (err) { |
| 513 | printk(KERN_ERR "%s: unable to set block size to %d: %d\n", | 534 | printk(KERN_ERR "%s: unable to set block size to %d: %d\n", |
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/card/queue.c index c27e42645cdb..2e77963db334 100644 --- a/drivers/mmc/mmc_queue.c +++ b/drivers/mmc/card/queue.c | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mmc/mmc_queue.c | 2 | * linux/drivers/mmc/queue.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
| 5 | * Copyright 2006-2007 Pierre Ossman | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * 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 | * it under the terms of the GNU General Public License version 2 as |
| @@ -14,7 +15,7 @@ | |||
| 14 | 15 | ||
| 15 | #include <linux/mmc/card.h> | 16 | #include <linux/mmc/card.h> |
| 16 | #include <linux/mmc/host.h> | 17 | #include <linux/mmc/host.h> |
| 17 | #include "mmc_queue.h" | 18 | #include "queue.h" |
| 18 | 19 | ||
| 19 | #define MMC_QUEUE_SUSPENDED (1 << 0) | 20 | #define MMC_QUEUE_SUSPENDED (1 << 0) |
| 20 | 21 | ||
| @@ -179,7 +180,6 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
| 179 | blk_cleanup_queue(mq->queue); | 180 | blk_cleanup_queue(mq->queue); |
| 180 | return ret; | 181 | return ret; |
| 181 | } | 182 | } |
| 182 | EXPORT_SYMBOL(mmc_init_queue); | ||
| 183 | 183 | ||
| 184 | void mmc_cleanup_queue(struct mmc_queue *mq) | 184 | void mmc_cleanup_queue(struct mmc_queue *mq) |
| 185 | { | 185 | { |
| @@ -191,6 +191,9 @@ void mmc_cleanup_queue(struct mmc_queue *mq) | |||
| 191 | q->queuedata = NULL; | 191 | q->queuedata = NULL; |
| 192 | spin_unlock_irqrestore(q->queue_lock, flags); | 192 | spin_unlock_irqrestore(q->queue_lock, flags); |
| 193 | 193 | ||
| 194 | /* Make sure the queue isn't suspended, as that will deadlock */ | ||
| 195 | mmc_queue_resume(mq); | ||
| 196 | |||
| 194 | /* Then terminate our worker thread */ | 197 | /* Then terminate our worker thread */ |
| 195 | kthread_stop(mq->thread); | 198 | kthread_stop(mq->thread); |
| 196 | 199 | ||
| @@ -226,7 +229,6 @@ void mmc_queue_suspend(struct mmc_queue *mq) | |||
| 226 | down(&mq->thread_sem); | 229 | down(&mq->thread_sem); |
| 227 | } | 230 | } |
| 228 | } | 231 | } |
| 229 | EXPORT_SYMBOL(mmc_queue_suspend); | ||
| 230 | 232 | ||
| 231 | /** | 233 | /** |
| 232 | * mmc_queue_resume - resume a previously suspended MMC request queue | 234 | * mmc_queue_resume - resume a previously suspended MMC request queue |
| @@ -247,4 +249,4 @@ void mmc_queue_resume(struct mmc_queue *mq) | |||
| 247 | spin_unlock_irqrestore(q->queue_lock, flags); | 249 | spin_unlock_irqrestore(q->queue_lock, flags); |
| 248 | } | 250 | } |
| 249 | } | 251 | } |
| 250 | EXPORT_SYMBOL(mmc_queue_resume); | 252 | |
diff --git a/drivers/mmc/mmc_queue.h b/drivers/mmc/card/queue.h index c9f139e764f6..c9f139e764f6 100644 --- a/drivers/mmc/mmc_queue.h +++ b/drivers/mmc/card/queue.h | |||
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig new file mode 100644 index 000000000000..94222b9a15ea --- /dev/null +++ b/drivers/mmc/core/Kconfig | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # | ||
| 2 | # MMC core configuration | ||
| 3 | # | ||
| 4 | |||
| 5 | config MMC_UNSAFE_RESUME | ||
| 6 | bool "Allow unsafe resume (DANGEROUS)" | ||
| 7 | depends on MMC != n | ||
| 8 | help | ||
| 9 | If you say Y here, the MMC layer will assume that all cards | ||
| 10 | stayed in their respective slots during the suspend. The | ||
| 11 | normal behaviour is to remove them at suspend and | ||
| 12 | redetecting them at resume. Breaking this assumption will | ||
| 13 | in most cases result in data corruption. | ||
| 14 | |||
| 15 | This option is usually just for embedded systems which use | ||
| 16 | a MMC/SD card for rootfs. Most people should say N here. | ||
| 17 | |||
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile new file mode 100644 index 000000000000..1075b02ae754 --- /dev/null +++ b/drivers/mmc/core/Makefile | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the kernel mmc core. | ||
| 3 | # | ||
| 4 | |||
| 5 | ifeq ($(CONFIG_MMC_DEBUG),y) | ||
| 6 | EXTRA_CFLAGS += -DDEBUG | ||
| 7 | endif | ||
| 8 | |||
| 9 | obj-$(CONFIG_MMC) += mmc_core.o | ||
| 10 | mmc_core-y := core.o sysfs.o mmc.o mmc_ops.o sd.o sd_ops.o | ||
| 11 | |||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c new file mode 100644 index 000000000000..72c7cf4a9f9d --- /dev/null +++ b/drivers/mmc/core/core.c | |||
| @@ -0,0 +1,727 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/core/core.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
| 5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
| 6 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
| 7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/interrupt.h> | ||
| 16 | #include <linux/completion.h> | ||
| 17 | #include <linux/device.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/pagemap.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | #include <asm/scatterlist.h> | ||
| 22 | #include <linux/scatterlist.h> | ||
| 23 | |||
| 24 | #include <linux/mmc/card.h> | ||
| 25 | #include <linux/mmc/host.h> | ||
| 26 | #include <linux/mmc/mmc.h> | ||
| 27 | #include <linux/mmc/sd.h> | ||
| 28 | |||
| 29 | #include "core.h" | ||
| 30 | #include "sysfs.h" | ||
| 31 | |||
| 32 | #include "mmc_ops.h" | ||
| 33 | #include "sd_ops.h" | ||
| 34 | |||
| 35 | extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr); | ||
| 36 | extern int mmc_attach_sd(struct mmc_host *host, u32 ocr); | ||
| 37 | |||
| 38 | /** | ||
| 39 | * mmc_request_done - finish processing an MMC request | ||
| 40 | * @host: MMC host which completed request | ||
| 41 | * @mrq: MMC request which request | ||
| 42 | * | ||
| 43 | * MMC drivers should call this function when they have completed | ||
| 44 | * their processing of a request. | ||
| 45 | */ | ||
| 46 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | ||
| 47 | { | ||
| 48 | struct mmc_command *cmd = mrq->cmd; | ||
| 49 | int err = cmd->error; | ||
| 50 | |||
| 51 | pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", | ||
| 52 | mmc_hostname(host), cmd->opcode, err, | ||
| 53 | mrq->data ? mrq->data->error : 0, | ||
| 54 | mrq->stop ? mrq->stop->error : 0, | ||
| 55 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | ||
| 56 | |||
| 57 | if (err && cmd->retries) { | ||
| 58 | cmd->retries--; | ||
| 59 | cmd->error = 0; | ||
| 60 | host->ops->request(host, mrq); | ||
| 61 | } else if (mrq->done) { | ||
| 62 | mrq->done(mrq); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | EXPORT_SYMBOL(mmc_request_done); | ||
| 67 | |||
| 68 | /** | ||
| 69 | * mmc_start_request - start a command on a host | ||
| 70 | * @host: MMC host to start command on | ||
| 71 | * @mrq: MMC request to start | ||
| 72 | * | ||
| 73 | * Queue a command on the specified host. We expect the | ||
| 74 | * caller to be holding the host lock with interrupts disabled. | ||
| 75 | */ | ||
| 76 | void | ||
| 77 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | ||
| 78 | { | ||
| 79 | #ifdef CONFIG_MMC_DEBUG | ||
| 80 | unsigned int i, sz; | ||
| 81 | #endif | ||
| 82 | |||
| 83 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", | ||
| 84 | mmc_hostname(host), mrq->cmd->opcode, | ||
| 85 | mrq->cmd->arg, mrq->cmd->flags); | ||
| 86 | |||
| 87 | WARN_ON(!host->claimed); | ||
| 88 | |||
| 89 | mrq->cmd->error = 0; | ||
| 90 | mrq->cmd->mrq = mrq; | ||
| 91 | if (mrq->data) { | ||
| 92 | BUG_ON(mrq->data->blksz > host->max_blk_size); | ||
| 93 | BUG_ON(mrq->data->blocks > host->max_blk_count); | ||
| 94 | BUG_ON(mrq->data->blocks * mrq->data->blksz > | ||
| 95 | host->max_req_size); | ||
| 96 | |||
| 97 | #ifdef CONFIG_MMC_DEBUG | ||
| 98 | sz = 0; | ||
| 99 | for (i = 0;i < mrq->data->sg_len;i++) | ||
| 100 | sz += mrq->data->sg[i].length; | ||
| 101 | BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); | ||
| 102 | #endif | ||
| 103 | |||
| 104 | mrq->cmd->data = mrq->data; | ||
| 105 | mrq->data->error = 0; | ||
| 106 | mrq->data->mrq = mrq; | ||
| 107 | if (mrq->stop) { | ||
| 108 | mrq->data->stop = mrq->stop; | ||
| 109 | mrq->stop->error = 0; | ||
| 110 | mrq->stop->mrq = mrq; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | host->ops->request(host, mrq); | ||
| 114 | } | ||
| 115 | |||
| 116 | EXPORT_SYMBOL(mmc_start_request); | ||
| 117 | |||
| 118 | static void mmc_wait_done(struct mmc_request *mrq) | ||
| 119 | { | ||
| 120 | complete(mrq->done_data); | ||
| 121 | } | ||
| 122 | |||
| 123 | int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | ||
| 124 | { | ||
| 125 | DECLARE_COMPLETION_ONSTACK(complete); | ||
| 126 | |||
| 127 | mrq->done_data = &complete; | ||
| 128 | mrq->done = mmc_wait_done; | ||
| 129 | |||
| 130 | mmc_start_request(host, mrq); | ||
| 131 | |||
| 132 | wait_for_completion(&complete); | ||
| 133 | |||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | EXPORT_SYMBOL(mmc_wait_for_req); | ||
| 138 | |||
| 139 | /** | ||
| 140 | * mmc_wait_for_cmd - start a command and wait for completion | ||
| 141 | * @host: MMC host to start command | ||
| 142 | * @cmd: MMC command to start | ||
| 143 | * @retries: maximum number of retries | ||
| 144 | * | ||
| 145 | * Start a new MMC command for a host, and wait for the command | ||
| 146 | * to complete. Return any error that occurred while the command | ||
| 147 | * was executing. Do not attempt to parse the response. | ||
| 148 | */ | ||
| 149 | int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) | ||
| 150 | { | ||
| 151 | struct mmc_request mrq; | ||
| 152 | |||
| 153 | BUG_ON(!host->claimed); | ||
| 154 | |||
| 155 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 156 | |||
| 157 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
| 158 | cmd->retries = retries; | ||
| 159 | |||
| 160 | mrq.cmd = cmd; | ||
| 161 | cmd->data = NULL; | ||
| 162 | |||
| 163 | mmc_wait_for_req(host, &mrq); | ||
| 164 | |||
| 165 | return cmd->error; | ||
| 166 | } | ||
| 167 | |||
| 168 | EXPORT_SYMBOL(mmc_wait_for_cmd); | ||
| 169 | |||
| 170 | /** | ||
| 171 | * mmc_set_data_timeout - set the timeout for a data command | ||
| 172 | * @data: data phase for command | ||
| 173 | * @card: the MMC card associated with the data transfer | ||
| 174 | * @write: flag to differentiate reads from writes | ||
| 175 | */ | ||
| 176 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | ||
| 177 | int write) | ||
| 178 | { | ||
| 179 | unsigned int mult; | ||
| 180 | |||
| 181 | /* | ||
| 182 | * SD cards use a 100 multiplier rather than 10 | ||
| 183 | */ | ||
| 184 | mult = mmc_card_sd(card) ? 100 : 10; | ||
| 185 | |||
| 186 | /* | ||
| 187 | * Scale up the multiplier (and therefore the timeout) by | ||
| 188 | * the r2w factor for writes. | ||
| 189 | */ | ||
| 190 | if (write) | ||
| 191 | mult <<= card->csd.r2w_factor; | ||
| 192 | |||
| 193 | data->timeout_ns = card->csd.tacc_ns * mult; | ||
| 194 | data->timeout_clks = card->csd.tacc_clks * mult; | ||
| 195 | |||
| 196 | /* | ||
| 197 | * SD cards also have an upper limit on the timeout. | ||
| 198 | */ | ||
| 199 | if (mmc_card_sd(card)) { | ||
| 200 | unsigned int timeout_us, limit_us; | ||
| 201 | |||
| 202 | timeout_us = data->timeout_ns / 1000; | ||
| 203 | timeout_us += data->timeout_clks * 1000 / | ||
| 204 | (card->host->ios.clock / 1000); | ||
| 205 | |||
| 206 | if (write) | ||
| 207 | limit_us = 250000; | ||
| 208 | else | ||
| 209 | limit_us = 100000; | ||
| 210 | |||
| 211 | /* | ||
| 212 | * SDHC cards always use these fixed values. | ||
| 213 | */ | ||
| 214 | if (timeout_us > limit_us || mmc_card_blockaddr(card)) { | ||
| 215 | data->timeout_ns = limit_us * 1000; | ||
| 216 | data->timeout_clks = 0; | ||
| 217 | } | ||
| 218 | } | ||
| 219 | } | ||
| 220 | EXPORT_SYMBOL(mmc_set_data_timeout); | ||
| 221 | |||
| 222 | /** | ||
| 223 | * __mmc_claim_host - exclusively claim a host | ||
| 224 | * @host: mmc host to claim | ||
| 225 | * @card: mmc card to claim host for | ||
| 226 | * | ||
| 227 | * Claim a host for a set of operations. If a valid card | ||
| 228 | * is passed and this wasn't the last card selected, select | ||
| 229 | * the card before returning. | ||
| 230 | * | ||
| 231 | * Note: you should use mmc_card_claim_host or mmc_claim_host. | ||
| 232 | */ | ||
| 233 | void mmc_claim_host(struct mmc_host *host) | ||
| 234 | { | ||
| 235 | DECLARE_WAITQUEUE(wait, current); | ||
| 236 | unsigned long flags; | ||
| 237 | |||
| 238 | add_wait_queue(&host->wq, &wait); | ||
| 239 | spin_lock_irqsave(&host->lock, flags); | ||
| 240 | while (1) { | ||
| 241 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 242 | if (!host->claimed) | ||
| 243 | break; | ||
| 244 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 245 | schedule(); | ||
| 246 | spin_lock_irqsave(&host->lock, flags); | ||
| 247 | } | ||
| 248 | set_current_state(TASK_RUNNING); | ||
| 249 | host->claimed = 1; | ||
| 250 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 251 | remove_wait_queue(&host->wq, &wait); | ||
| 252 | } | ||
| 253 | |||
| 254 | EXPORT_SYMBOL(mmc_claim_host); | ||
| 255 | |||
| 256 | /** | ||
| 257 | * mmc_release_host - release a host | ||
| 258 | * @host: mmc host to release | ||
| 259 | * | ||
| 260 | * Release a MMC host, allowing others to claim the host | ||
| 261 | * for their operations. | ||
| 262 | */ | ||
| 263 | void mmc_release_host(struct mmc_host *host) | ||
| 264 | { | ||
| 265 | unsigned long flags; | ||
| 266 | |||
| 267 | BUG_ON(!host->claimed); | ||
| 268 | |||
| 269 | spin_lock_irqsave(&host->lock, flags); | ||
| 270 | host->claimed = 0; | ||
| 271 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 272 | |||
| 273 | wake_up(&host->wq); | ||
| 274 | } | ||
| 275 | |||
| 276 | EXPORT_SYMBOL(mmc_release_host); | ||
| 277 | |||
| 278 | /* | ||
| 279 | * Internal function that does the actual ios call to the host driver, | ||
| 280 | * optionally printing some debug output. | ||
| 281 | */ | ||
| 282 | static inline void mmc_set_ios(struct mmc_host *host) | ||
| 283 | { | ||
| 284 | struct mmc_ios *ios = &host->ios; | ||
| 285 | |||
| 286 | pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " | ||
| 287 | "width %u timing %u\n", | ||
| 288 | mmc_hostname(host), ios->clock, ios->bus_mode, | ||
| 289 | ios->power_mode, ios->chip_select, ios->vdd, | ||
| 290 | ios->bus_width, ios->timing); | ||
| 291 | |||
| 292 | host->ops->set_ios(host, ios); | ||
| 293 | } | ||
| 294 | |||
| 295 | /* | ||
| 296 | * Control chip select pin on a host. | ||
| 297 | */ | ||
| 298 | void mmc_set_chip_select(struct mmc_host *host, int mode) | ||
| 299 | { | ||
| 300 | host->ios.chip_select = mode; | ||
| 301 | mmc_set_ios(host); | ||
| 302 | } | ||
| 303 | |||
| 304 | /* | ||
| 305 | * Sets the host clock to the highest possible frequency that | ||
| 306 | * is below "hz". | ||
| 307 | */ | ||
| 308 | void mmc_set_clock(struct mmc_host *host, unsigned int hz) | ||
| 309 | { | ||
| 310 | WARN_ON(hz < host->f_min); | ||
| 311 | |||
| 312 | if (hz > host->f_max) | ||
| 313 | hz = host->f_max; | ||
| 314 | |||
| 315 | host->ios.clock = hz; | ||
| 316 | mmc_set_ios(host); | ||
| 317 | } | ||
| 318 | |||
| 319 | /* | ||
| 320 | * Change the bus mode (open drain/push-pull) of a host. | ||
| 321 | */ | ||
| 322 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) | ||
| 323 | { | ||
| 324 | host->ios.bus_mode = mode; | ||
| 325 | mmc_set_ios(host); | ||
| 326 | } | ||
| 327 | |||
| 328 | /* | ||
| 329 | * Change data bus width of a host. | ||
| 330 | */ | ||
| 331 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width) | ||
| 332 | { | ||
| 333 | host->ios.bus_width = width; | ||
| 334 | mmc_set_ios(host); | ||
| 335 | } | ||
| 336 | |||
| 337 | /* | ||
| 338 | * Mask off any voltages we don't support and select | ||
| 339 | * the lowest voltage | ||
| 340 | */ | ||
| 341 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | ||
| 342 | { | ||
| 343 | int bit; | ||
| 344 | |||
| 345 | ocr &= host->ocr_avail; | ||
| 346 | |||
| 347 | bit = ffs(ocr); | ||
| 348 | if (bit) { | ||
| 349 | bit -= 1; | ||
| 350 | |||
| 351 | ocr &= 3 << bit; | ||
| 352 | |||
| 353 | host->ios.vdd = bit; | ||
| 354 | mmc_set_ios(host); | ||
| 355 | } else { | ||
| 356 | ocr = 0; | ||
| 357 | } | ||
| 358 | |||
| 359 | return ocr; | ||
| 360 | } | ||
| 361 | |||
| 362 | /* | ||
| 363 | * Select timing parameters for host. | ||
| 364 | */ | ||
| 365 | void mmc_set_timing(struct mmc_host *host, unsigned int timing) | ||
| 366 | { | ||
| 367 | host->ios.timing = timing; | ||
| 368 | mmc_set_ios(host); | ||
| 369 | } | ||
| 370 | |||
| 371 | /* | ||
| 372 | * Allocate a new MMC card | ||
| 373 | */ | ||
| 374 | struct mmc_card *mmc_alloc_card(struct mmc_host *host) | ||
| 375 | { | ||
| 376 | struct mmc_card *card; | ||
| 377 | |||
| 378 | card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); | ||
| 379 | if (!card) | ||
| 380 | return ERR_PTR(-ENOMEM); | ||
| 381 | |||
| 382 | mmc_init_card(card, host); | ||
| 383 | |||
| 384 | return card; | ||
| 385 | } | ||
| 386 | |||
| 387 | /* | ||
| 388 | * Apply power to the MMC stack. This is a two-stage process. | ||
| 389 | * First, we enable power to the card without the clock running. | ||
| 390 | * We then wait a bit for the power to stabilise. Finally, | ||
| 391 | * enable the bus drivers and clock to the card. | ||
| 392 | * | ||
| 393 | * We must _NOT_ enable the clock prior to power stablising. | ||
| 394 | * | ||
| 395 | * If a host does all the power sequencing itself, ignore the | ||
| 396 | * initial MMC_POWER_UP stage. | ||
| 397 | */ | ||
| 398 | static void mmc_power_up(struct mmc_host *host) | ||
| 399 | { | ||
| 400 | int bit = fls(host->ocr_avail) - 1; | ||
| 401 | |||
| 402 | host->ios.vdd = bit; | ||
| 403 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
| 404 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
| 405 | host->ios.power_mode = MMC_POWER_UP; | ||
| 406 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
| 407 | host->ios.timing = MMC_TIMING_LEGACY; | ||
| 408 | mmc_set_ios(host); | ||
| 409 | |||
| 410 | mmc_delay(1); | ||
| 411 | |||
| 412 | host->ios.clock = host->f_min; | ||
| 413 | host->ios.power_mode = MMC_POWER_ON; | ||
| 414 | mmc_set_ios(host); | ||
| 415 | |||
| 416 | mmc_delay(2); | ||
| 417 | } | ||
| 418 | |||
| 419 | static void mmc_power_off(struct mmc_host *host) | ||
| 420 | { | ||
| 421 | host->ios.clock = 0; | ||
| 422 | host->ios.vdd = 0; | ||
| 423 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
| 424 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
| 425 | host->ios.power_mode = MMC_POWER_OFF; | ||
| 426 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
| 427 | host->ios.timing = MMC_TIMING_LEGACY; | ||
| 428 | mmc_set_ios(host); | ||
| 429 | } | ||
| 430 | |||
| 431 | /* | ||
| 432 | * Assign a mmc bus handler to a host. Only one bus handler may control a | ||
| 433 | * host at any given time. | ||
| 434 | */ | ||
| 435 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) | ||
| 436 | { | ||
| 437 | unsigned long flags; | ||
| 438 | |||
| 439 | BUG_ON(!host); | ||
| 440 | BUG_ON(!ops); | ||
| 441 | |||
| 442 | BUG_ON(!host->claimed); | ||
| 443 | |||
| 444 | spin_lock_irqsave(&host->lock, flags); | ||
| 445 | |||
| 446 | BUG_ON(host->bus_ops); | ||
| 447 | BUG_ON(host->bus_refs); | ||
| 448 | |||
| 449 | host->bus_ops = ops; | ||
| 450 | host->bus_refs = 1; | ||
| 451 | host->bus_dead = 0; | ||
| 452 | |||
| 453 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 454 | } | ||
| 455 | |||
| 456 | /* | ||
| 457 | * Remove the current bus handler from a host. Assumes that there are | ||
| 458 | * no interesting cards left, so the bus is powered down. | ||
| 459 | */ | ||
| 460 | void mmc_detach_bus(struct mmc_host *host) | ||
| 461 | { | ||
| 462 | unsigned long flags; | ||
| 463 | |||
| 464 | BUG_ON(!host); | ||
| 465 | |||
| 466 | BUG_ON(!host->claimed); | ||
| 467 | BUG_ON(!host->bus_ops); | ||
| 468 | |||
| 469 | spin_lock_irqsave(&host->lock, flags); | ||
| 470 | |||
| 471 | host->bus_dead = 1; | ||
| 472 | |||
| 473 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 474 | |||
| 475 | mmc_power_off(host); | ||
| 476 | |||
| 477 | mmc_bus_put(host); | ||
| 478 | } | ||
| 479 | |||
| 480 | /* | ||
| 481 | * Cleanup when the last reference to the bus operator is dropped. | ||
| 482 | */ | ||
| 483 | void __mmc_release_bus(struct mmc_host *host) | ||
| 484 | { | ||
| 485 | BUG_ON(!host); | ||
| 486 | BUG_ON(host->bus_refs); | ||
| 487 | BUG_ON(!host->bus_dead); | ||
| 488 | |||
| 489 | host->bus_ops = NULL; | ||
| 490 | } | ||
| 491 | |||
| 492 | /** | ||
| 493 | * mmc_detect_change - process change of state on a MMC socket | ||
| 494 | * @host: host which changed state. | ||
| 495 | * @delay: optional delay to wait before detection (jiffies) | ||
| 496 | * | ||
| 497 | * All we know is that card(s) have been inserted or removed | ||
| 498 | * from the socket(s). We don't know which socket or cards. | ||
| 499 | */ | ||
| 500 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) | ||
| 501 | { | ||
| 502 | #ifdef CONFIG_MMC_DEBUG | ||
| 503 | mmc_claim_host(host); | ||
| 504 | BUG_ON(host->removed); | ||
| 505 | mmc_release_host(host); | ||
| 506 | #endif | ||
| 507 | |||
| 508 | mmc_schedule_delayed_work(&host->detect, delay); | ||
| 509 | } | ||
| 510 | |||
| 511 | EXPORT_SYMBOL(mmc_detect_change); | ||
| 512 | |||
| 513 | |||
| 514 | static void mmc_rescan(struct work_struct *work) | ||
| 515 | { | ||
| 516 | struct mmc_host *host = | ||
| 517 | container_of(work, struct mmc_host, detect.work); | ||
| 518 | u32 ocr; | ||
| 519 | int err; | ||
| 520 | |||
| 521 | mmc_bus_get(host); | ||
| 522 | |||
| 523 | if (host->bus_ops == NULL) { | ||
| 524 | /* | ||
| 525 | * Only we can add a new handler, so it's safe to | ||
| 526 | * release the lock here. | ||
| 527 | */ | ||
| 528 | mmc_bus_put(host); | ||
| 529 | |||
| 530 | mmc_claim_host(host); | ||
| 531 | |||
| 532 | mmc_power_up(host); | ||
| 533 | mmc_go_idle(host); | ||
| 534 | |||
| 535 | mmc_send_if_cond(host, host->ocr_avail); | ||
| 536 | |||
| 537 | err = mmc_send_app_op_cond(host, 0, &ocr); | ||
| 538 | if (err == MMC_ERR_NONE) { | ||
| 539 | if (mmc_attach_sd(host, ocr)) | ||
| 540 | mmc_power_off(host); | ||
| 541 | } else { | ||
| 542 | /* | ||
| 543 | * If we fail to detect any SD cards then try | ||
| 544 | * searching for MMC cards. | ||
| 545 | */ | ||
| 546 | err = mmc_send_op_cond(host, 0, &ocr); | ||
| 547 | if (err == MMC_ERR_NONE) { | ||
| 548 | if (mmc_attach_mmc(host, ocr)) | ||
| 549 | mmc_power_off(host); | ||
| 550 | } else { | ||
| 551 | mmc_power_off(host); | ||
| 552 | mmc_release_host(host); | ||
| 553 | } | ||
| 554 | } | ||
| 555 | } else { | ||
| 556 | if (host->bus_ops->detect && !host->bus_dead) | ||
| 557 | host->bus_ops->detect(host); | ||
| 558 | |||
| 559 | mmc_bus_put(host); | ||
| 560 | } | ||
| 561 | } | ||
| 562 | |||
| 563 | |||
| 564 | /** | ||
| 565 | * mmc_alloc_host - initialise the per-host structure. | ||
| 566 | * @extra: sizeof private data structure | ||
| 567 | * @dev: pointer to host device model structure | ||
| 568 | * | ||
| 569 | * Initialise the per-host structure. | ||
| 570 | */ | ||
| 571 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | ||
| 572 | { | ||
| 573 | struct mmc_host *host; | ||
| 574 | |||
| 575 | host = mmc_alloc_host_sysfs(extra, dev); | ||
| 576 | if (host) { | ||
| 577 | spin_lock_init(&host->lock); | ||
| 578 | init_waitqueue_head(&host->wq); | ||
| 579 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); | ||
| 580 | |||
| 581 | /* | ||
| 582 | * By default, hosts do not support SGIO or large requests. | ||
| 583 | * They have to set these according to their abilities. | ||
| 584 | */ | ||
| 585 | host->max_hw_segs = 1; | ||
| 586 | host->max_phys_segs = 1; | ||
| 587 | host->max_seg_size = PAGE_CACHE_SIZE; | ||
| 588 | |||
| 589 | host->max_req_size = PAGE_CACHE_SIZE; | ||
| 590 | host->max_blk_size = 512; | ||
| 591 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | ||
| 592 | } | ||
| 593 | |||
| 594 | return host; | ||
| 595 | } | ||
| 596 | |||
| 597 | EXPORT_SYMBOL(mmc_alloc_host); | ||
| 598 | |||
| 599 | /** | ||
| 600 | * mmc_add_host - initialise host hardware | ||
| 601 | * @host: mmc host | ||
| 602 | */ | ||
| 603 | int mmc_add_host(struct mmc_host *host) | ||
| 604 | { | ||
| 605 | int ret; | ||
| 606 | |||
| 607 | ret = mmc_add_host_sysfs(host); | ||
| 608 | if (ret == 0) { | ||
| 609 | mmc_power_off(host); | ||
| 610 | mmc_detect_change(host, 0); | ||
| 611 | } | ||
| 612 | |||
| 613 | return ret; | ||
| 614 | } | ||
| 615 | |||
| 616 | EXPORT_SYMBOL(mmc_add_host); | ||
| 617 | |||
| 618 | /** | ||
| 619 | * mmc_remove_host - remove host hardware | ||
| 620 | * @host: mmc host | ||
| 621 | * | ||
| 622 | * Unregister and remove all cards associated with this host, | ||
| 623 | * and power down the MMC bus. | ||
| 624 | */ | ||
| 625 | void mmc_remove_host(struct mmc_host *host) | ||
| 626 | { | ||
| 627 | #ifdef CONFIG_MMC_DEBUG | ||
| 628 | mmc_claim_host(host); | ||
| 629 | host->removed = 1; | ||
| 630 | mmc_release_host(host); | ||
| 631 | #endif | ||
| 632 | |||
| 633 | mmc_flush_scheduled_work(); | ||
| 634 | |||
| 635 | mmc_bus_get(host); | ||
| 636 | if (host->bus_ops && !host->bus_dead) { | ||
| 637 | if (host->bus_ops->remove) | ||
| 638 | host->bus_ops->remove(host); | ||
| 639 | |||
| 640 | mmc_claim_host(host); | ||
| 641 | mmc_detach_bus(host); | ||
| 642 | mmc_release_host(host); | ||
| 643 | } | ||
| 644 | mmc_bus_put(host); | ||
| 645 | |||
| 646 | BUG_ON(host->card); | ||
| 647 | |||
| 648 | mmc_power_off(host); | ||
| 649 | mmc_remove_host_sysfs(host); | ||
| 650 | } | ||
| 651 | |||
| 652 | EXPORT_SYMBOL(mmc_remove_host); | ||
| 653 | |||
| 654 | /** | ||
| 655 | * mmc_free_host - free the host structure | ||
| 656 | * @host: mmc host | ||
| 657 | * | ||
| 658 | * Free the host once all references to it have been dropped. | ||
| 659 | */ | ||
| 660 | void mmc_free_host(struct mmc_host *host) | ||
| 661 | { | ||
| 662 | mmc_free_host_sysfs(host); | ||
| 663 | } | ||
| 664 | |||
| 665 | EXPORT_SYMBOL(mmc_free_host); | ||
| 666 | |||
| 667 | #ifdef CONFIG_PM | ||
| 668 | |||
| 669 | /** | ||
| 670 | * mmc_suspend_host - suspend a host | ||
| 671 | * @host: mmc host | ||
| 672 | * @state: suspend mode (PM_SUSPEND_xxx) | ||
| 673 | */ | ||
| 674 | int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | ||
| 675 | { | ||
| 676 | mmc_flush_scheduled_work(); | ||
| 677 | |||
| 678 | mmc_bus_get(host); | ||
| 679 | if (host->bus_ops && !host->bus_dead) { | ||
| 680 | if (host->bus_ops->suspend) | ||
| 681 | host->bus_ops->suspend(host); | ||
| 682 | if (!host->bus_ops->resume) { | ||
| 683 | if (host->bus_ops->remove) | ||
| 684 | host->bus_ops->remove(host); | ||
| 685 | |||
| 686 | mmc_claim_host(host); | ||
| 687 | mmc_detach_bus(host); | ||
| 688 | mmc_release_host(host); | ||
| 689 | } | ||
| 690 | } | ||
| 691 | mmc_bus_put(host); | ||
| 692 | |||
| 693 | mmc_power_off(host); | ||
| 694 | |||
| 695 | return 0; | ||
| 696 | } | ||
| 697 | |||
| 698 | EXPORT_SYMBOL(mmc_suspend_host); | ||
| 699 | |||
| 700 | /** | ||
| 701 | * mmc_resume_host - resume a previously suspended host | ||
| 702 | * @host: mmc host | ||
| 703 | */ | ||
| 704 | int mmc_resume_host(struct mmc_host *host) | ||
| 705 | { | ||
| 706 | mmc_bus_get(host); | ||
| 707 | if (host->bus_ops && !host->bus_dead) { | ||
| 708 | mmc_power_up(host); | ||
| 709 | BUG_ON(!host->bus_ops->resume); | ||
| 710 | host->bus_ops->resume(host); | ||
| 711 | } | ||
| 712 | mmc_bus_put(host); | ||
| 713 | |||
| 714 | /* | ||
| 715 | * We add a slight delay here so that resume can progress | ||
| 716 | * in parallel. | ||
| 717 | */ | ||
| 718 | mmc_detect_change(host, 1); | ||
| 719 | |||
| 720 | return 0; | ||
| 721 | } | ||
| 722 | |||
| 723 | EXPORT_SYMBOL(mmc_resume_host); | ||
| 724 | |||
| 725 | #endif | ||
| 726 | |||
| 727 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h new file mode 100644 index 000000000000..177264d090ac --- /dev/null +++ b/drivers/mmc/core/core.h | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/core/core.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | ||
| 5 | * Copyright 2007 Pierre Ossman | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #ifndef _MMC_CORE_CORE_H | ||
| 12 | #define _MMC_CORE_CORE_H | ||
| 13 | |||
| 14 | #include <linux/delay.h> | ||
| 15 | |||
| 16 | #define MMC_CMD_RETRIES 3 | ||
| 17 | |||
| 18 | struct mmc_bus_ops { | ||
| 19 | void (*remove)(struct mmc_host *); | ||
| 20 | void (*detect)(struct mmc_host *); | ||
| 21 | void (*suspend)(struct mmc_host *); | ||
| 22 | void (*resume)(struct mmc_host *); | ||
| 23 | }; | ||
| 24 | |||
| 25 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | ||
| 26 | void mmc_detach_bus(struct mmc_host *host); | ||
| 27 | |||
| 28 | void __mmc_release_bus(struct mmc_host *host); | ||
| 29 | |||
| 30 | static inline void mmc_bus_get(struct mmc_host *host) | ||
| 31 | { | ||
| 32 | unsigned long flags; | ||
| 33 | |||
| 34 | spin_lock_irqsave(&host->lock, flags); | ||
| 35 | host->bus_refs++; | ||
| 36 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 37 | } | ||
| 38 | |||
| 39 | static inline void mmc_bus_put(struct mmc_host *host) | ||
| 40 | { | ||
| 41 | unsigned long flags; | ||
| 42 | |||
| 43 | spin_lock_irqsave(&host->lock, flags); | ||
| 44 | host->bus_refs--; | ||
| 45 | if ((host->bus_refs == 0) && host->bus_ops) | ||
| 46 | __mmc_release_bus(host); | ||
| 47 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 48 | } | ||
| 49 | |||
| 50 | void mmc_set_chip_select(struct mmc_host *host, int mode); | ||
| 51 | void mmc_set_clock(struct mmc_host *host, unsigned int hz); | ||
| 52 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); | ||
| 53 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width); | ||
| 54 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); | ||
| 55 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | ||
| 56 | |||
| 57 | struct mmc_card *mmc_alloc_card(struct mmc_host *host); | ||
| 58 | |||
| 59 | static inline void mmc_delay(unsigned int ms) | ||
| 60 | { | ||
| 61 | if (ms < 1000 / HZ) { | ||
| 62 | cond_resched(); | ||
| 63 | mdelay(ms); | ||
| 64 | } else { | ||
| 65 | msleep(ms); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | #endif | ||
| 70 | |||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c new file mode 100644 index 000000000000..42cc2867ed7d --- /dev/null +++ b/drivers/mmc/core/mmc.c | |||
| @@ -0,0 +1,537 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/mmc.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
| 5 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
| 6 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/err.h> | ||
| 14 | |||
| 15 | #include <linux/mmc/host.h> | ||
| 16 | #include <linux/mmc/card.h> | ||
| 17 | #include <linux/mmc/mmc.h> | ||
| 18 | |||
| 19 | #include "core.h" | ||
| 20 | #include "sysfs.h" | ||
| 21 | #include "mmc_ops.h" | ||
| 22 | |||
| 23 | static const unsigned int tran_exp[] = { | ||
| 24 | 10000, 100000, 1000000, 10000000, | ||
| 25 | 0, 0, 0, 0 | ||
| 26 | }; | ||
| 27 | |||
| 28 | static const unsigned char tran_mant[] = { | ||
| 29 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
| 30 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
| 31 | }; | ||
| 32 | |||
| 33 | static const unsigned int tacc_exp[] = { | ||
| 34 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static const unsigned int tacc_mant[] = { | ||
| 38 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
| 39 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
| 40 | }; | ||
| 41 | |||
| 42 | #define UNSTUFF_BITS(resp,start,size) \ | ||
| 43 | ({ \ | ||
| 44 | const int __size = size; \ | ||
| 45 | const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ | ||
| 46 | const int __off = 3 - ((start) / 32); \ | ||
| 47 | const int __shft = (start) & 31; \ | ||
| 48 | u32 __res; \ | ||
| 49 | \ | ||
| 50 | __res = resp[__off] >> __shft; \ | ||
| 51 | if (__size + __shft > 32) \ | ||
| 52 | __res |= resp[__off-1] << ((32 - __shft) % 32); \ | ||
| 53 | __res & __mask; \ | ||
| 54 | }) | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | ||
| 58 | */ | ||
| 59 | static int mmc_decode_cid(struct mmc_card *card) | ||
| 60 | { | ||
| 61 | u32 *resp = card->raw_cid; | ||
| 62 | |||
| 63 | /* | ||
| 64 | * The selection of the format here is based upon published | ||
| 65 | * specs from sandisk and from what people have reported. | ||
| 66 | */ | ||
| 67 | switch (card->csd.mmca_vsn) { | ||
| 68 | case 0: /* MMC v1.0 - v1.2 */ | ||
| 69 | case 1: /* MMC v1.4 */ | ||
| 70 | card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); | ||
| 71 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
| 72 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
| 73 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
| 74 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
| 75 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
| 76 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
| 77 | card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); | ||
| 78 | card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); | ||
| 79 | card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); | ||
| 80 | card->cid.serial = UNSTUFF_BITS(resp, 16, 24); | ||
| 81 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
| 82 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
| 83 | break; | ||
| 84 | |||
| 85 | case 2: /* MMC v2.0 - v2.2 */ | ||
| 86 | case 3: /* MMC v3.1 - v3.3 */ | ||
| 87 | case 4: /* MMC v4 */ | ||
| 88 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
| 89 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
| 90 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
| 91 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
| 92 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
| 93 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
| 94 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
| 95 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
| 96 | card->cid.serial = UNSTUFF_BITS(resp, 16, 32); | ||
| 97 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
| 98 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
| 99 | break; | ||
| 100 | |||
| 101 | default: | ||
| 102 | printk("%s: card has unknown MMCA version %d\n", | ||
| 103 | mmc_hostname(card->host), card->csd.mmca_vsn); | ||
| 104 | return -EINVAL; | ||
| 105 | } | ||
| 106 | |||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Given a 128-bit response, decode to our card CSD structure. | ||
| 112 | */ | ||
| 113 | static int mmc_decode_csd(struct mmc_card *card) | ||
| 114 | { | ||
| 115 | struct mmc_csd *csd = &card->csd; | ||
| 116 | unsigned int e, m, csd_struct; | ||
| 117 | u32 *resp = card->raw_csd; | ||
| 118 | |||
| 119 | /* | ||
| 120 | * We only understand CSD structure v1.1 and v1.2. | ||
| 121 | * v1.2 has extra information in bits 15, 11 and 10. | ||
| 122 | */ | ||
| 123 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
| 124 | if (csd_struct != 1 && csd_struct != 2) { | ||
| 125 | printk("%s: unrecognised CSD structure version %d\n", | ||
| 126 | mmc_hostname(card->host), csd_struct); | ||
| 127 | return -EINVAL; | ||
| 128 | } | ||
| 129 | |||
| 130 | csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); | ||
| 131 | m = UNSTUFF_BITS(resp, 115, 4); | ||
| 132 | e = UNSTUFF_BITS(resp, 112, 3); | ||
| 133 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
| 134 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
| 135 | |||
| 136 | m = UNSTUFF_BITS(resp, 99, 4); | ||
| 137 | e = UNSTUFF_BITS(resp, 96, 3); | ||
| 138 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 139 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 140 | |||
| 141 | e = UNSTUFF_BITS(resp, 47, 3); | ||
| 142 | m = UNSTUFF_BITS(resp, 62, 12); | ||
| 143 | csd->capacity = (1 + m) << (e + 2); | ||
| 144 | |||
| 145 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
| 146 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
| 147 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
| 148 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
| 149 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
| 150 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
| 151 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
| 152 | |||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 156 | /* | ||
| 157 | * Read and decode extended CSD. | ||
| 158 | */ | ||
| 159 | static int mmc_read_ext_csd(struct mmc_card *card) | ||
| 160 | { | ||
| 161 | int err; | ||
| 162 | u8 *ext_csd; | ||
| 163 | |||
| 164 | BUG_ON(!card); | ||
| 165 | |||
| 166 | err = MMC_ERR_FAILED; | ||
| 167 | |||
| 168 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
| 169 | return MMC_ERR_NONE; | ||
| 170 | |||
| 171 | /* | ||
| 172 | * As the ext_csd is so large and mostly unused, we don't store the | ||
| 173 | * raw block in mmc_card. | ||
| 174 | */ | ||
| 175 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
| 176 | if (!ext_csd) { | ||
| 177 | printk(KERN_ERR "%s: could not allocate a buffer to " | ||
| 178 | "receive the ext_csd. mmc v4 cards will be " | ||
| 179 | "treated as v3.\n", mmc_hostname(card->host)); | ||
| 180 | return MMC_ERR_FAILED; | ||
| 181 | } | ||
| 182 | |||
| 183 | err = mmc_send_ext_csd(card, ext_csd); | ||
| 184 | if (err != MMC_ERR_NONE) { | ||
| 185 | /* | ||
| 186 | * High capacity cards should have this "magic" size | ||
| 187 | * stored in their CSD. | ||
| 188 | */ | ||
| 189 | if (card->csd.capacity == (4096 * 512)) { | ||
| 190 | printk(KERN_ERR "%s: unable to read EXT_CSD " | ||
| 191 | "on a possible high capacity card. " | ||
| 192 | "Card will be ignored.\n", | ||
| 193 | mmc_hostname(card->host)); | ||
| 194 | } else { | ||
| 195 | printk(KERN_WARNING "%s: unable to read " | ||
| 196 | "EXT_CSD, performance might " | ||
| 197 | "suffer.\n", | ||
| 198 | mmc_hostname(card->host)); | ||
| 199 | err = MMC_ERR_NONE; | ||
| 200 | } | ||
| 201 | goto out; | ||
| 202 | } | ||
| 203 | |||
| 204 | card->ext_csd.sectors = | ||
| 205 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | ||
| 206 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | | ||
| 207 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | | ||
| 208 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; | ||
| 209 | if (card->ext_csd.sectors) | ||
| 210 | mmc_card_set_blockaddr(card); | ||
| 211 | |||
| 212 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | ||
| 213 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | ||
| 214 | card->ext_csd.hs_max_dtr = 52000000; | ||
| 215 | break; | ||
| 216 | case EXT_CSD_CARD_TYPE_26: | ||
| 217 | card->ext_csd.hs_max_dtr = 26000000; | ||
| 218 | break; | ||
| 219 | default: | ||
| 220 | /* MMC v4 spec says this cannot happen */ | ||
| 221 | printk(KERN_WARNING "%s: card is mmc v4 but doesn't " | ||
| 222 | "support any high-speed modes.\n", | ||
| 223 | mmc_hostname(card->host)); | ||
| 224 | goto out; | ||
| 225 | } | ||
| 226 | |||
| 227 | out: | ||
| 228 | kfree(ext_csd); | ||
| 229 | |||
| 230 | return err; | ||
| 231 | } | ||
| 232 | |||
| 233 | /* | ||
| 234 | * Handle the detection and initialisation of a card. | ||
| 235 | * | ||
| 236 | * In the case of a resume, "curcard" will contain the card | ||
| 237 | * we're trying to reinitialise. | ||
| 238 | */ | ||
| 239 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | ||
| 240 | struct mmc_card *oldcard) | ||
| 241 | { | ||
| 242 | struct mmc_card *card; | ||
| 243 | int err; | ||
| 244 | u32 cid[4]; | ||
| 245 | unsigned int max_dtr; | ||
| 246 | |||
| 247 | BUG_ON(!host); | ||
| 248 | BUG_ON(!host->claimed); | ||
| 249 | |||
| 250 | /* | ||
| 251 | * Since we're changing the OCR value, we seem to | ||
| 252 | * need to tell some cards to go back to the idle | ||
| 253 | * state. We wait 1ms to give cards time to | ||
| 254 | * respond. | ||
| 255 | */ | ||
| 256 | mmc_go_idle(host); | ||
| 257 | |||
| 258 | /* The extra bit indicates that we support high capacity */ | ||
| 259 | err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); | ||
| 260 | if (err != MMC_ERR_NONE) | ||
| 261 | goto err; | ||
| 262 | |||
| 263 | /* | ||
| 264 | * Fetch CID from card. | ||
| 265 | */ | ||
| 266 | err = mmc_all_send_cid(host, cid); | ||
| 267 | if (err != MMC_ERR_NONE) | ||
| 268 | goto err; | ||
| 269 | |||
| 270 | if (oldcard) { | ||
| 271 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | ||
| 272 | goto err; | ||
| 273 | |||
| 274 | card = oldcard; | ||
| 275 | } else { | ||
| 276 | /* | ||
| 277 | * Allocate card structure. | ||
| 278 | */ | ||
| 279 | card = mmc_alloc_card(host); | ||
| 280 | if (IS_ERR(card)) | ||
| 281 | goto err; | ||
| 282 | |||
| 283 | card->type = MMC_TYPE_MMC; | ||
| 284 | card->rca = 1; | ||
| 285 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* | ||
| 289 | * Set card RCA. | ||
| 290 | */ | ||
| 291 | err = mmc_set_relative_addr(card); | ||
| 292 | if (err != MMC_ERR_NONE) | ||
| 293 | goto free_card; | ||
| 294 | |||
| 295 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
| 296 | |||
| 297 | if (!oldcard) { | ||
| 298 | /* | ||
| 299 | * Fetch CSD from card. | ||
| 300 | */ | ||
| 301 | err = mmc_send_csd(card, card->raw_csd); | ||
| 302 | if (err != MMC_ERR_NONE) | ||
| 303 | goto free_card; | ||
| 304 | |||
| 305 | err = mmc_decode_csd(card); | ||
| 306 | if (err < 0) | ||
| 307 | goto free_card; | ||
| 308 | err = mmc_decode_cid(card); | ||
| 309 | if (err < 0) | ||
| 310 | goto free_card; | ||
| 311 | } | ||
| 312 | |||
| 313 | /* | ||
| 314 | * Select card, as all following commands rely on that. | ||
| 315 | */ | ||
| 316 | err = mmc_select_card(card); | ||
| 317 | if (err != MMC_ERR_NONE) | ||
| 318 | goto free_card; | ||
| 319 | |||
| 320 | if (!oldcard) { | ||
| 321 | /* | ||
| 322 | * Fetch and process extened CSD. | ||
| 323 | */ | ||
| 324 | err = mmc_read_ext_csd(card); | ||
| 325 | if (err != MMC_ERR_NONE) | ||
| 326 | goto free_card; | ||
| 327 | } | ||
| 328 | |||
| 329 | /* | ||
| 330 | * Activate high speed (if supported) | ||
| 331 | */ | ||
| 332 | if ((card->ext_csd.hs_max_dtr != 0) && | ||
| 333 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { | ||
| 334 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
| 335 | EXT_CSD_HS_TIMING, 1); | ||
| 336 | if (err != MMC_ERR_NONE) | ||
| 337 | goto free_card; | ||
| 338 | |||
| 339 | mmc_card_set_highspeed(card); | ||
| 340 | |||
| 341 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | ||
| 342 | } | ||
| 343 | |||
| 344 | /* | ||
| 345 | * Compute bus speed. | ||
| 346 | */ | ||
| 347 | max_dtr = (unsigned int)-1; | ||
| 348 | |||
| 349 | if (mmc_card_highspeed(card)) { | ||
| 350 | if (max_dtr > card->ext_csd.hs_max_dtr) | ||
| 351 | max_dtr = card->ext_csd.hs_max_dtr; | ||
| 352 | } else if (max_dtr > card->csd.max_dtr) { | ||
| 353 | max_dtr = card->csd.max_dtr; | ||
| 354 | } | ||
| 355 | |||
| 356 | mmc_set_clock(host, max_dtr); | ||
| 357 | |||
| 358 | /* | ||
| 359 | * Activate wide bus (if supported). | ||
| 360 | */ | ||
| 361 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && | ||
| 362 | (host->caps & MMC_CAP_4_BIT_DATA)) { | ||
| 363 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
| 364 | EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); | ||
| 365 | if (err != MMC_ERR_NONE) | ||
| 366 | goto free_card; | ||
| 367 | |||
| 368 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
| 369 | } | ||
| 370 | |||
| 371 | if (!oldcard) | ||
| 372 | host->card = card; | ||
| 373 | |||
| 374 | return MMC_ERR_NONE; | ||
| 375 | |||
| 376 | free_card: | ||
| 377 | if (!oldcard) | ||
| 378 | mmc_remove_card(card); | ||
| 379 | err: | ||
| 380 | |||
| 381 | return MMC_ERR_FAILED; | ||
| 382 | } | ||
| 383 | |||
| 384 | /* | ||
| 385 | * Host is being removed. Free up the current card. | ||
| 386 | */ | ||
| 387 | static void mmc_remove(struct mmc_host *host) | ||
| 388 | { | ||
| 389 | BUG_ON(!host); | ||
| 390 | BUG_ON(!host->card); | ||
| 391 | |||
| 392 | mmc_remove_card(host->card); | ||
| 393 | host->card = NULL; | ||
| 394 | } | ||
| 395 | |||
| 396 | /* | ||
| 397 | * Card detection callback from host. | ||
| 398 | */ | ||
| 399 | static void mmc_detect(struct mmc_host *host) | ||
| 400 | { | ||
| 401 | int err; | ||
| 402 | |||
| 403 | BUG_ON(!host); | ||
| 404 | BUG_ON(!host->card); | ||
| 405 | |||
| 406 | mmc_claim_host(host); | ||
| 407 | |||
| 408 | /* | ||
| 409 | * Just check if our card has been removed. | ||
| 410 | */ | ||
| 411 | err = mmc_send_status(host->card, NULL); | ||
| 412 | |||
| 413 | mmc_release_host(host); | ||
| 414 | |||
| 415 | if (err != MMC_ERR_NONE) { | ||
| 416 | mmc_remove_card(host->card); | ||
| 417 | host->card = NULL; | ||
| 418 | |||
| 419 | mmc_claim_host(host); | ||
| 420 | mmc_detach_bus(host); | ||
| 421 | mmc_release_host(host); | ||
| 422 | } | ||
| 423 | } | ||
| 424 | |||
| 425 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
| 426 | |||
| 427 | /* | ||
| 428 | * Suspend callback from host. | ||
| 429 | */ | ||
| 430 | static void mmc_suspend(struct mmc_host *host) | ||
| 431 | { | ||
| 432 | BUG_ON(!host); | ||
| 433 | BUG_ON(!host->card); | ||
| 434 | |||
| 435 | mmc_claim_host(host); | ||
| 436 | mmc_deselect_cards(host); | ||
| 437 | host->card->state &= ~MMC_STATE_HIGHSPEED; | ||
| 438 | mmc_release_host(host); | ||
| 439 | } | ||
| 440 | |||
| 441 | /* | ||
| 442 | * Resume callback from host. | ||
| 443 | * | ||
| 444 | * This function tries to determine if the same card is still present | ||
| 445 | * and, if so, restore all state to it. | ||
| 446 | */ | ||
| 447 | static void mmc_resume(struct mmc_host *host) | ||
| 448 | { | ||
| 449 | int err; | ||
| 450 | |||
| 451 | BUG_ON(!host); | ||
| 452 | BUG_ON(!host->card); | ||
| 453 | |||
| 454 | mmc_claim_host(host); | ||
| 455 | |||
| 456 | err = mmc_sd_init_card(host, host->ocr, host->card); | ||
| 457 | if (err != MMC_ERR_NONE) { | ||
| 458 | mmc_remove_card(host->card); | ||
| 459 | host->card = NULL; | ||
| 460 | |||
| 461 | mmc_detach_bus(host); | ||
| 462 | } | ||
| 463 | |||
| 464 | mmc_release_host(host); | ||
| 465 | } | ||
| 466 | |||
| 467 | #else | ||
| 468 | |||
| 469 | #define mmc_suspend NULL | ||
| 470 | #define mmc_resume NULL | ||
| 471 | |||
| 472 | #endif | ||
| 473 | |||
| 474 | static const struct mmc_bus_ops mmc_ops = { | ||
| 475 | .remove = mmc_remove, | ||
| 476 | .detect = mmc_detect, | ||
| 477 | .suspend = mmc_suspend, | ||
| 478 | .resume = mmc_resume, | ||
| 479 | }; | ||
| 480 | |||
| 481 | /* | ||
| 482 | * Starting point for MMC card init. | ||
| 483 | */ | ||
| 484 | int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | ||
| 485 | { | ||
| 486 | int err; | ||
| 487 | |||
| 488 | BUG_ON(!host); | ||
| 489 | BUG_ON(!host->claimed); | ||
| 490 | |||
| 491 | mmc_attach_bus(host, &mmc_ops); | ||
| 492 | |||
| 493 | /* | ||
| 494 | * Sanity check the voltages that the card claims to | ||
| 495 | * support. | ||
| 496 | */ | ||
| 497 | if (ocr & 0x7F) { | ||
| 498 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
| 499 | "below the defined range. These will be ignored.\n", | ||
| 500 | mmc_hostname(host)); | ||
| 501 | ocr &= ~0x7F; | ||
| 502 | } | ||
| 503 | |||
| 504 | host->ocr = mmc_select_voltage(host, ocr); | ||
| 505 | |||
| 506 | /* | ||
| 507 | * Can we support the voltage of the card? | ||
| 508 | */ | ||
| 509 | if (!host->ocr) | ||
| 510 | goto err; | ||
| 511 | |||
| 512 | /* | ||
| 513 | * Detect and init the card. | ||
| 514 | */ | ||
| 515 | err = mmc_sd_init_card(host, host->ocr, NULL); | ||
| 516 | if (err != MMC_ERR_NONE) | ||
| 517 | goto err; | ||
| 518 | |||
| 519 | mmc_release_host(host); | ||
| 520 | |||
| 521 | err = mmc_register_card(host->card); | ||
| 522 | if (err) | ||
| 523 | goto reclaim_host; | ||
| 524 | |||
| 525 | return 0; | ||
| 526 | |||
| 527 | reclaim_host: | ||
| 528 | mmc_claim_host(host); | ||
| 529 | mmc_remove_card(host->card); | ||
| 530 | host->card = NULL; | ||
| 531 | err: | ||
| 532 | mmc_detach_bus(host); | ||
| 533 | mmc_release_host(host); | ||
| 534 | |||
| 535 | return 0; | ||
| 536 | } | ||
| 537 | |||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c new file mode 100644 index 000000000000..7dd720fa5895 --- /dev/null +++ b/drivers/mmc/core/mmc_ops.c | |||
| @@ -0,0 +1,276 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/mmc_ops.h | ||
| 3 | * | ||
| 4 | * Copyright 2006-2007 Pierre Ossman | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
| 9 | * your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/types.h> | ||
| 13 | #include <asm/scatterlist.h> | ||
| 14 | #include <linux/scatterlist.h> | ||
| 15 | |||
| 16 | #include <linux/mmc/host.h> | ||
| 17 | #include <linux/mmc/card.h> | ||
| 18 | #include <linux/mmc/mmc.h> | ||
| 19 | |||
| 20 | #include "core.h" | ||
| 21 | #include "mmc_ops.h" | ||
| 22 | |||
| 23 | static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) | ||
| 24 | { | ||
| 25 | int err; | ||
| 26 | struct mmc_command cmd; | ||
| 27 | |||
| 28 | BUG_ON(!host); | ||
| 29 | |||
| 30 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 31 | |||
| 32 | cmd.opcode = MMC_SELECT_CARD; | ||
| 33 | |||
| 34 | if (card) { | ||
| 35 | cmd.arg = card->rca << 16; | ||
| 36 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 37 | } else { | ||
| 38 | cmd.arg = 0; | ||
| 39 | cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; | ||
| 40 | } | ||
| 41 | |||
| 42 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
| 43 | if (err != MMC_ERR_NONE) | ||
| 44 | return err; | ||
| 45 | |||
| 46 | return MMC_ERR_NONE; | ||
| 47 | } | ||
| 48 | |||
| 49 | int mmc_select_card(struct mmc_card *card) | ||
| 50 | { | ||
| 51 | BUG_ON(!card); | ||
| 52 | |||
| 53 | return _mmc_select_card(card->host, card); | ||
| 54 | } | ||
| 55 | |||
| 56 | int mmc_deselect_cards(struct mmc_host *host) | ||
| 57 | { | ||
| 58 | return _mmc_select_card(host, NULL); | ||
| 59 | } | ||
| 60 | |||
| 61 | int mmc_go_idle(struct mmc_host *host) | ||
| 62 | { | ||
| 63 | int err; | ||
| 64 | struct mmc_command cmd; | ||
| 65 | |||
| 66 | mmc_set_chip_select(host, MMC_CS_HIGH); | ||
| 67 | |||
| 68 | mmc_delay(1); | ||
| 69 | |||
| 70 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 71 | |||
| 72 | cmd.opcode = MMC_GO_IDLE_STATE; | ||
| 73 | cmd.arg = 0; | ||
| 74 | cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; | ||
| 75 | |||
| 76 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
| 77 | |||
| 78 | mmc_delay(1); | ||
| 79 | |||
| 80 | mmc_set_chip_select(host, MMC_CS_DONTCARE); | ||
| 81 | |||
| 82 | mmc_delay(1); | ||
| 83 | |||
| 84 | return err; | ||
| 85 | } | ||
| 86 | |||
| 87 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
| 88 | { | ||
| 89 | struct mmc_command cmd; | ||
| 90 | int i, err = 0; | ||
| 91 | |||
| 92 | BUG_ON(!host); | ||
| 93 | |||
| 94 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 95 | |||
| 96 | cmd.opcode = MMC_SEND_OP_COND; | ||
| 97 | cmd.arg = ocr; | ||
| 98 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
| 99 | |||
| 100 | for (i = 100; i; i--) { | ||
| 101 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
| 102 | if (err != MMC_ERR_NONE) | ||
| 103 | break; | ||
| 104 | |||
| 105 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
| 106 | break; | ||
| 107 | |||
| 108 | err = MMC_ERR_TIMEOUT; | ||
| 109 | |||
| 110 | mmc_delay(10); | ||
| 111 | } | ||
| 112 | |||
| 113 | if (rocr) | ||
| 114 | *rocr = cmd.resp[0]; | ||
| 115 | |||
| 116 | return err; | ||
| 117 | } | ||
| 118 | |||
| 119 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | ||
| 120 | { | ||
| 121 | int err; | ||
| 122 | struct mmc_command cmd; | ||
| 123 | |||
| 124 | BUG_ON(!host); | ||
| 125 | BUG_ON(!cid); | ||
| 126 | |||
| 127 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 128 | |||
| 129 | cmd.opcode = MMC_ALL_SEND_CID; | ||
| 130 | cmd.arg = 0; | ||
| 131 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | ||
| 132 | |||
| 133 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
| 134 | if (err != MMC_ERR_NONE) | ||
| 135 | return err; | ||
| 136 | |||
| 137 | memcpy(cid, cmd.resp, sizeof(u32) * 4); | ||
| 138 | |||
| 139 | return MMC_ERR_NONE; | ||
| 140 | } | ||
| 141 | |||
| 142 | int mmc_set_relative_addr(struct mmc_card *card) | ||
| 143 | { | ||
| 144 | int err; | ||
| 145 | struct mmc_command cmd; | ||
| 146 | |||
| 147 | BUG_ON(!card); | ||
| 148 | BUG_ON(!card->host); | ||
| 149 | |||
| 150 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 151 | |||
| 152 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | ||
| 153 | cmd.arg = card->rca << 16; | ||
| 154 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 155 | |||
| 156 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
| 157 | if (err != MMC_ERR_NONE) | ||
| 158 | return err; | ||
| 159 | |||
| 160 | return MMC_ERR_NONE; | ||
| 161 | } | ||
| 162 | |||
| 163 | int mmc_send_csd(struct mmc_card *card, u32 *csd) | ||
| 164 | { | ||
| 165 | int err; | ||
| 166 | struct mmc_command cmd; | ||
| 167 | |||
| 168 | BUG_ON(!card); | ||
| 169 | BUG_ON(!card->host); | ||
| 170 | BUG_ON(!csd); | ||
| 171 | |||
| 172 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 173 | |||
| 174 | cmd.opcode = MMC_SEND_CSD; | ||
| 175 | cmd.arg = card->rca << 16; | ||
| 176 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | ||
| 177 | |||
| 178 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
| 179 | if (err != MMC_ERR_NONE) | ||
| 180 | return err; | ||
| 181 | |||
| 182 | memcpy(csd, cmd.resp, sizeof(u32) * 4); | ||
| 183 | |||
| 184 | return MMC_ERR_NONE; | ||
| 185 | } | ||
| 186 | |||
| 187 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | ||
| 188 | { | ||
| 189 | struct mmc_request mrq; | ||
| 190 | struct mmc_command cmd; | ||
| 191 | struct mmc_data data; | ||
| 192 | struct scatterlist sg; | ||
| 193 | |||
| 194 | BUG_ON(!card); | ||
| 195 | BUG_ON(!card->host); | ||
| 196 | BUG_ON(!ext_csd); | ||
| 197 | |||
| 198 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 199 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 200 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 201 | |||
| 202 | mrq.cmd = &cmd; | ||
| 203 | mrq.data = &data; | ||
| 204 | |||
| 205 | cmd.opcode = MMC_SEND_EXT_CSD; | ||
| 206 | cmd.arg = 0; | ||
| 207 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
| 208 | |||
| 209 | data.blksz = 512; | ||
| 210 | data.blocks = 1; | ||
| 211 | data.flags = MMC_DATA_READ; | ||
| 212 | data.sg = &sg; | ||
| 213 | data.sg_len = 1; | ||
| 214 | |||
| 215 | sg_init_one(&sg, ext_csd, 512); | ||
| 216 | |||
| 217 | mmc_set_data_timeout(&data, card, 0); | ||
| 218 | |||
| 219 | mmc_wait_for_req(card->host, &mrq); | ||
| 220 | |||
| 221 | if (cmd.error != MMC_ERR_NONE) | ||
| 222 | return cmd.error; | ||
| 223 | if (data.error != MMC_ERR_NONE) | ||
| 224 | return data.error; | ||
| 225 | |||
| 226 | return MMC_ERR_NONE; | ||
| 227 | } | ||
| 228 | |||
| 229 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | ||
| 230 | { | ||
| 231 | int err; | ||
| 232 | struct mmc_command cmd; | ||
| 233 | |||
| 234 | BUG_ON(!card); | ||
| 235 | BUG_ON(!card->host); | ||
| 236 | |||
| 237 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 238 | |||
| 239 | cmd.opcode = MMC_SWITCH; | ||
| 240 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
| 241 | (index << 16) | | ||
| 242 | (value << 8) | | ||
| 243 | set; | ||
| 244 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
| 245 | |||
| 246 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
| 247 | if (err != MMC_ERR_NONE) | ||
| 248 | return err; | ||
| 249 | |||
| 250 | return MMC_ERR_NONE; | ||
| 251 | } | ||
| 252 | |||
| 253 | int mmc_send_status(struct mmc_card *card, u32 *status) | ||
| 254 | { | ||
| 255 | int err; | ||
| 256 | struct mmc_command cmd; | ||
| 257 | |||
| 258 | BUG_ON(!card); | ||
| 259 | BUG_ON(!card->host); | ||
| 260 | |||
| 261 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 262 | |||
| 263 | cmd.opcode = MMC_SEND_STATUS; | ||
| 264 | cmd.arg = card->rca << 16; | ||
| 265 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 266 | |||
| 267 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
| 268 | if (err != MMC_ERR_NONE) | ||
| 269 | return err; | ||
| 270 | |||
| 271 | if (status) | ||
| 272 | *status = cmd.resp[0]; | ||
| 273 | |||
| 274 | return MMC_ERR_NONE; | ||
| 275 | } | ||
| 276 | |||
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h new file mode 100644 index 000000000000..7a481e8ca5ea --- /dev/null +++ b/drivers/mmc/core/mmc_ops.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/mmc_ops.h | ||
| 3 | * | ||
| 4 | * Copyright 2006-2007 Pierre Ossman | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
| 9 | * your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _MMC_MMC_OPS_H | ||
| 13 | #define _MMC_MMC_OPS_H | ||
| 14 | |||
| 15 | int mmc_select_card(struct mmc_card *card); | ||
| 16 | int mmc_deselect_cards(struct mmc_host *host); | ||
| 17 | int mmc_go_idle(struct mmc_host *host); | ||
| 18 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | ||
| 19 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid); | ||
| 20 | int mmc_set_relative_addr(struct mmc_card *card); | ||
| 21 | int mmc_send_csd(struct mmc_card *card, u32 *csd); | ||
| 22 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); | ||
| 23 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); | ||
| 24 | int mmc_send_status(struct mmc_card *card, u32 *status); | ||
| 25 | |||
| 26 | #endif | ||
| 27 | |||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c new file mode 100644 index 000000000000..c1dfd03d559a --- /dev/null +++ b/drivers/mmc/core/sd.c | |||
| @@ -0,0 +1,587 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/sd.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
| 5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
| 6 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/err.h> | ||
| 14 | |||
| 15 | #include <linux/mmc/host.h> | ||
| 16 | #include <linux/mmc/card.h> | ||
| 17 | #include <linux/mmc/mmc.h> | ||
| 18 | |||
| 19 | #include "core.h" | ||
| 20 | #include "sysfs.h" | ||
| 21 | #include "mmc_ops.h" | ||
| 22 | #include "sd_ops.h" | ||
| 23 | |||
| 24 | #include "core.h" | ||
| 25 | |||
| 26 | static const unsigned int tran_exp[] = { | ||
| 27 | 10000, 100000, 1000000, 10000000, | ||
| 28 | 0, 0, 0, 0 | ||
| 29 | }; | ||
| 30 | |||
| 31 | static const unsigned char tran_mant[] = { | ||
| 32 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
| 33 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static const unsigned int tacc_exp[] = { | ||
| 37 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||
| 38 | }; | ||
| 39 | |||
| 40 | static const unsigned int tacc_mant[] = { | ||
| 41 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
| 42 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
| 43 | }; | ||
| 44 | |||
| 45 | #define UNSTUFF_BITS(resp,start,size) \ | ||
| 46 | ({ \ | ||
| 47 | const int __size = size; \ | ||
| 48 | const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ | ||
| 49 | const int __off = 3 - ((start) / 32); \ | ||
| 50 | const int __shft = (start) & 31; \ | ||
| 51 | u32 __res; \ | ||
| 52 | \ | ||
| 53 | __res = resp[__off] >> __shft; \ | ||
| 54 | if (__size + __shft > 32) \ | ||
| 55 | __res |= resp[__off-1] << ((32 - __shft) % 32); \ | ||
| 56 | __res & __mask; \ | ||
| 57 | }) | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | ||
| 61 | */ | ||
| 62 | static void mmc_decode_cid(struct mmc_card *card) | ||
| 63 | { | ||
| 64 | u32 *resp = card->raw_cid; | ||
| 65 | |||
| 66 | memset(&card->cid, 0, sizeof(struct mmc_cid)); | ||
| 67 | |||
| 68 | /* | ||
| 69 | * SD doesn't currently have a version field so we will | ||
| 70 | * have to assume we can parse this. | ||
| 71 | */ | ||
| 72 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
| 73 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
| 74 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
| 75 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
| 76 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
| 77 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
| 78 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
| 79 | card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4); | ||
| 80 | card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4); | ||
| 81 | card->cid.serial = UNSTUFF_BITS(resp, 24, 32); | ||
| 82 | card->cid.year = UNSTUFF_BITS(resp, 12, 8); | ||
| 83 | card->cid.month = UNSTUFF_BITS(resp, 8, 4); | ||
| 84 | |||
| 85 | card->cid.year += 2000; /* SD cards year offset */ | ||
| 86 | } | ||
| 87 | |||
| 88 | /* | ||
| 89 | * Given a 128-bit response, decode to our card CSD structure. | ||
| 90 | */ | ||
| 91 | static int mmc_decode_csd(struct mmc_card *card) | ||
| 92 | { | ||
| 93 | struct mmc_csd *csd = &card->csd; | ||
| 94 | unsigned int e, m, csd_struct; | ||
| 95 | u32 *resp = card->raw_csd; | ||
| 96 | |||
| 97 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
| 98 | |||
| 99 | switch (csd_struct) { | ||
| 100 | case 0: | ||
| 101 | m = UNSTUFF_BITS(resp, 115, 4); | ||
| 102 | e = UNSTUFF_BITS(resp, 112, 3); | ||
| 103 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
| 104 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
| 105 | |||
| 106 | m = UNSTUFF_BITS(resp, 99, 4); | ||
| 107 | e = UNSTUFF_BITS(resp, 96, 3); | ||
| 108 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 109 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 110 | |||
| 111 | e = UNSTUFF_BITS(resp, 47, 3); | ||
| 112 | m = UNSTUFF_BITS(resp, 62, 12); | ||
| 113 | csd->capacity = (1 + m) << (e + 2); | ||
| 114 | |||
| 115 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
| 116 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
| 117 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
| 118 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
| 119 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
| 120 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
| 121 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
| 122 | break; | ||
| 123 | case 1: | ||
| 124 | /* | ||
| 125 | * This is a block-addressed SDHC card. Most | ||
| 126 | * interesting fields are unused and have fixed | ||
| 127 | * values. To avoid getting tripped by buggy cards, | ||
| 128 | * we assume those fixed values ourselves. | ||
| 129 | */ | ||
| 130 | mmc_card_set_blockaddr(card); | ||
| 131 | |||
| 132 | csd->tacc_ns = 0; /* Unused */ | ||
| 133 | csd->tacc_clks = 0; /* Unused */ | ||
| 134 | |||
| 135 | m = UNSTUFF_BITS(resp, 99, 4); | ||
| 136 | e = UNSTUFF_BITS(resp, 96, 3); | ||
| 137 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 138 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 139 | |||
| 140 | m = UNSTUFF_BITS(resp, 48, 22); | ||
| 141 | csd->capacity = (1 + m) << 10; | ||
| 142 | |||
| 143 | csd->read_blkbits = 9; | ||
| 144 | csd->read_partial = 0; | ||
| 145 | csd->write_misalign = 0; | ||
| 146 | csd->read_misalign = 0; | ||
| 147 | csd->r2w_factor = 4; /* Unused */ | ||
| 148 | csd->write_blkbits = 9; | ||
| 149 | csd->write_partial = 0; | ||
| 150 | break; | ||
| 151 | default: | ||
| 152 | printk("%s: unrecognised CSD structure version %d\n", | ||
| 153 | mmc_hostname(card->host), csd_struct); | ||
| 154 | return -EINVAL; | ||
| 155 | } | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | /* | ||
| 161 | * Given a 64-bit response, decode to our card SCR structure. | ||
| 162 | */ | ||
| 163 | static int mmc_decode_scr(struct mmc_card *card) | ||
| 164 | { | ||
| 165 | struct sd_scr *scr = &card->scr; | ||
| 166 | unsigned int scr_struct; | ||
| 167 | u32 resp[4]; | ||
| 168 | |||
| 169 | BUG_ON(!mmc_card_sd(card)); | ||
| 170 | |||
| 171 | resp[3] = card->raw_scr[1]; | ||
| 172 | resp[2] = card->raw_scr[0]; | ||
| 173 | |||
| 174 | scr_struct = UNSTUFF_BITS(resp, 60, 4); | ||
| 175 | if (scr_struct != 0) { | ||
| 176 | printk("%s: unrecognised SCR structure version %d\n", | ||
| 177 | mmc_hostname(card->host), scr_struct); | ||
| 178 | return -EINVAL; | ||
| 179 | } | ||
| 180 | |||
| 181 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); | ||
| 182 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); | ||
| 183 | |||
| 184 | return 0; | ||
| 185 | } | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Fetches and decodes switch information | ||
| 189 | */ | ||
| 190 | static int mmc_read_switch(struct mmc_card *card) | ||
| 191 | { | ||
| 192 | int err; | ||
| 193 | u8 *status; | ||
| 194 | |||
| 195 | err = MMC_ERR_FAILED; | ||
| 196 | |||
| 197 | status = kmalloc(64, GFP_KERNEL); | ||
| 198 | if (!status) { | ||
| 199 | printk("%s: could not allocate a buffer for switch " | ||
| 200 | "capabilities.\n", | ||
| 201 | mmc_hostname(card->host)); | ||
| 202 | return err; | ||
| 203 | } | ||
| 204 | |||
| 205 | err = mmc_sd_switch(card, 0, 0, 1, status); | ||
| 206 | if (err != MMC_ERR_NONE) { | ||
| 207 | /* | ||
| 208 | * Card not supporting high-speed will ignore the | ||
| 209 | * command. | ||
| 210 | */ | ||
| 211 | err = MMC_ERR_NONE; | ||
| 212 | goto out; | ||
| 213 | } | ||
| 214 | |||
| 215 | if (status[13] & 0x02) | ||
| 216 | card->sw_caps.hs_max_dtr = 50000000; | ||
| 217 | |||
| 218 | out: | ||
| 219 | kfree(status); | ||
| 220 | |||
| 221 | return err; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * Test if the card supports high-speed mode and, if so, switch to it. | ||
| 226 | */ | ||
| 227 | static int mmc_switch_hs(struct mmc_card *card) | ||
| 228 | { | ||
| 229 | int err; | ||
| 230 | u8 *status; | ||
| 231 | |||
| 232 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
| 233 | return MMC_ERR_NONE; | ||
| 234 | |||
| 235 | if (card->sw_caps.hs_max_dtr == 0) | ||
| 236 | return MMC_ERR_NONE; | ||
| 237 | |||
| 238 | err = MMC_ERR_FAILED; | ||
| 239 | |||
| 240 | status = kmalloc(64, GFP_KERNEL); | ||
| 241 | if (!status) { | ||
| 242 | printk("%s: could not allocate a buffer for switch " | ||
| 243 | "capabilities.\n", | ||
| 244 | mmc_hostname(card->host)); | ||
| 245 | return err; | ||
| 246 | } | ||
| 247 | |||
| 248 | err = mmc_sd_switch(card, 1, 0, 1, status); | ||
| 249 | if (err != MMC_ERR_NONE) | ||
| 250 | goto out; | ||
| 251 | |||
| 252 | if ((status[16] & 0xF) != 1) { | ||
| 253 | printk(KERN_WARNING "%s: Problem switching card " | ||
| 254 | "into high-speed mode!\n", | ||
| 255 | mmc_hostname(card->host)); | ||
| 256 | } else { | ||
| 257 | mmc_card_set_highspeed(card); | ||
| 258 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
| 259 | } | ||
| 260 | |||
| 261 | out: | ||
| 262 | kfree(status); | ||
| 263 | |||
| 264 | return err; | ||
| 265 | } | ||
| 266 | |||
| 267 | /* | ||
| 268 | * Handle the detection and initialisation of a card. | ||
| 269 | * | ||
| 270 | * In the case of a resume, "curcard" will contain the card | ||
| 271 | * we're trying to reinitialise. | ||
| 272 | */ | ||
| 273 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | ||
| 274 | struct mmc_card *oldcard) | ||
| 275 | { | ||
| 276 | struct mmc_card *card; | ||
| 277 | int err; | ||
| 278 | u32 cid[4]; | ||
| 279 | unsigned int max_dtr; | ||
| 280 | |||
| 281 | BUG_ON(!host); | ||
| 282 | BUG_ON(!host->claimed); | ||
| 283 | |||
| 284 | /* | ||
| 285 | * Since we're changing the OCR value, we seem to | ||
| 286 | * need to tell some cards to go back to the idle | ||
| 287 | * state. We wait 1ms to give cards time to | ||
| 288 | * respond. | ||
| 289 | */ | ||
| 290 | mmc_go_idle(host); | ||
| 291 | |||
| 292 | /* | ||
| 293 | * If SD_SEND_IF_COND indicates an SD 2.0 | ||
| 294 | * compliant card and we should set bit 30 | ||
| 295 | * of the ocr to indicate that we can handle | ||
| 296 | * block-addressed SDHC cards. | ||
| 297 | */ | ||
| 298 | err = mmc_send_if_cond(host, ocr); | ||
| 299 | if (err == MMC_ERR_NONE) | ||
| 300 | ocr |= 1 << 30; | ||
| 301 | |||
| 302 | err = mmc_send_app_op_cond(host, ocr, NULL); | ||
| 303 | if (err != MMC_ERR_NONE) | ||
| 304 | goto err; | ||
| 305 | |||
| 306 | /* | ||
| 307 | * Fetch CID from card. | ||
| 308 | */ | ||
| 309 | err = mmc_all_send_cid(host, cid); | ||
| 310 | if (err != MMC_ERR_NONE) | ||
| 311 | goto err; | ||
| 312 | |||
| 313 | if (oldcard) { | ||
| 314 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | ||
| 315 | goto err; | ||
| 316 | |||
| 317 | card = oldcard; | ||
| 318 | } else { | ||
| 319 | /* | ||
| 320 | * Allocate card structure. | ||
| 321 | */ | ||
| 322 | card = mmc_alloc_card(host); | ||
| 323 | if (IS_ERR(card)) | ||
| 324 | goto err; | ||
| 325 | |||
| 326 | card->type = MMC_TYPE_SD; | ||
| 327 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | ||
| 328 | } | ||
| 329 | |||
| 330 | /* | ||
| 331 | * Set card RCA. | ||
| 332 | */ | ||
| 333 | err = mmc_send_relative_addr(host, &card->rca); | ||
| 334 | if (err != MMC_ERR_NONE) | ||
| 335 | goto free_card; | ||
| 336 | |||
| 337 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
| 338 | |||
| 339 | if (!oldcard) { | ||
| 340 | /* | ||
| 341 | * Fetch CSD from card. | ||
| 342 | */ | ||
| 343 | err = mmc_send_csd(card, card->raw_csd); | ||
| 344 | if (err != MMC_ERR_NONE) | ||
| 345 | goto free_card; | ||
| 346 | |||
| 347 | err = mmc_decode_csd(card); | ||
| 348 | if (err < 0) | ||
| 349 | goto free_card; | ||
| 350 | |||
| 351 | mmc_decode_cid(card); | ||
| 352 | } | ||
| 353 | |||
| 354 | /* | ||
| 355 | * Select card, as all following commands rely on that. | ||
| 356 | */ | ||
| 357 | err = mmc_select_card(card); | ||
| 358 | if (err != MMC_ERR_NONE) | ||
| 359 | goto free_card; | ||
| 360 | |||
| 361 | if (!oldcard) { | ||
| 362 | /* | ||
| 363 | * Fetch SCR from card. | ||
| 364 | */ | ||
| 365 | err = mmc_app_send_scr(card, card->raw_scr); | ||
| 366 | if (err != MMC_ERR_NONE) | ||
| 367 | goto free_card; | ||
| 368 | |||
| 369 | err = mmc_decode_scr(card); | ||
| 370 | if (err < 0) | ||
| 371 | goto free_card; | ||
| 372 | |||
| 373 | /* | ||
| 374 | * Fetch switch information from card. | ||
| 375 | */ | ||
| 376 | err = mmc_read_switch(card); | ||
| 377 | if (err != MMC_ERR_NONE) | ||
| 378 | goto free_card; | ||
| 379 | } | ||
| 380 | |||
| 381 | /* | ||
| 382 | * Attempt to change to high-speed (if supported) | ||
| 383 | */ | ||
| 384 | err = mmc_switch_hs(card); | ||
| 385 | if (err != MMC_ERR_NONE) | ||
| 386 | goto free_card; | ||
| 387 | |||
| 388 | /* | ||
| 389 | * Compute bus speed. | ||
| 390 | */ | ||
| 391 | max_dtr = (unsigned int)-1; | ||
| 392 | |||
| 393 | if (mmc_card_highspeed(card)) { | ||
| 394 | if (max_dtr > card->sw_caps.hs_max_dtr) | ||
| 395 | max_dtr = card->sw_caps.hs_max_dtr; | ||
| 396 | } else if (max_dtr > card->csd.max_dtr) { | ||
| 397 | max_dtr = card->csd.max_dtr; | ||
| 398 | } | ||
| 399 | |||
| 400 | mmc_set_clock(host, max_dtr); | ||
| 401 | |||
| 402 | /* | ||
| 403 | * Switch to wider bus (if supported). | ||
| 404 | */ | ||
| 405 | if ((host->caps && MMC_CAP_4_BIT_DATA) && | ||
| 406 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
| 407 | err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); | ||
| 408 | if (err != MMC_ERR_NONE) | ||
| 409 | goto free_card; | ||
| 410 | |||
| 411 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | ||
| 412 | } | ||
| 413 | |||
| 414 | if (!oldcard) | ||
| 415 | host->card = card; | ||
| 416 | |||
| 417 | return MMC_ERR_NONE; | ||
| 418 | |||
| 419 | free_card: | ||
| 420 | if (!oldcard) | ||
| 421 | mmc_remove_card(card); | ||
| 422 | err: | ||
| 423 | |||
| 424 | return MMC_ERR_FAILED; | ||
| 425 | } | ||
| 426 | |||
| 427 | /* | ||
| 428 | * Host is being removed. Free up the current card. | ||
| 429 | */ | ||
| 430 | static void mmc_sd_remove(struct mmc_host *host) | ||
| 431 | { | ||
| 432 | BUG_ON(!host); | ||
| 433 | BUG_ON(!host->card); | ||
| 434 | |||
| 435 | mmc_remove_card(host->card); | ||
| 436 | host->card = NULL; | ||
| 437 | } | ||
| 438 | |||
| 439 | /* | ||
| 440 | * Card detection callback from host. | ||
| 441 | */ | ||
| 442 | static void mmc_sd_detect(struct mmc_host *host) | ||
| 443 | { | ||
| 444 | int err; | ||
| 445 | |||
| 446 | BUG_ON(!host); | ||
| 447 | BUG_ON(!host->card); | ||
| 448 | |||
| 449 | mmc_claim_host(host); | ||
| 450 | |||
| 451 | /* | ||
| 452 | * Just check if our card has been removed. | ||
| 453 | */ | ||
| 454 | err = mmc_send_status(host->card, NULL); | ||
| 455 | |||
| 456 | mmc_release_host(host); | ||
| 457 | |||
| 458 | if (err != MMC_ERR_NONE) { | ||
| 459 | mmc_remove_card(host->card); | ||
| 460 | host->card = NULL; | ||
| 461 | |||
| 462 | mmc_claim_host(host); | ||
| 463 | mmc_detach_bus(host); | ||
| 464 | mmc_release_host(host); | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
| 469 | |||
| 470 | /* | ||
| 471 | * Suspend callback from host. | ||
| 472 | */ | ||
| 473 | static void mmc_sd_suspend(struct mmc_host *host) | ||
| 474 | { | ||
| 475 | BUG_ON(!host); | ||
| 476 | BUG_ON(!host->card); | ||
| 477 | |||
| 478 | mmc_claim_host(host); | ||
| 479 | mmc_deselect_cards(host); | ||
| 480 | host->card->state &= ~MMC_STATE_HIGHSPEED; | ||
| 481 | mmc_release_host(host); | ||
| 482 | } | ||
| 483 | |||
| 484 | /* | ||
| 485 | * Resume callback from host. | ||
| 486 | * | ||
| 487 | * This function tries to determine if the same card is still present | ||
| 488 | * and, if so, restore all state to it. | ||
| 489 | */ | ||
| 490 | static void mmc_sd_resume(struct mmc_host *host) | ||
| 491 | { | ||
| 492 | int err; | ||
| 493 | |||
| 494 | BUG_ON(!host); | ||
| 495 | BUG_ON(!host->card); | ||
| 496 | |||
| 497 | mmc_claim_host(host); | ||
| 498 | |||
| 499 | err = mmc_sd_init_card(host, host->ocr, host->card); | ||
| 500 | if (err != MMC_ERR_NONE) { | ||
| 501 | mmc_remove_card(host->card); | ||
| 502 | host->card = NULL; | ||
| 503 | |||
| 504 | mmc_detach_bus(host); | ||
| 505 | } | ||
| 506 | |||
| 507 | mmc_release_host(host); | ||
| 508 | } | ||
| 509 | |||
| 510 | #else | ||
| 511 | |||
| 512 | #define mmc_sd_suspend NULL | ||
| 513 | #define mmc_sd_resume NULL | ||
| 514 | |||
| 515 | #endif | ||
| 516 | |||
| 517 | static const struct mmc_bus_ops mmc_sd_ops = { | ||
| 518 | .remove = mmc_sd_remove, | ||
| 519 | .detect = mmc_sd_detect, | ||
| 520 | .suspend = mmc_sd_suspend, | ||
| 521 | .resume = mmc_sd_resume, | ||
| 522 | }; | ||
| 523 | |||
| 524 | /* | ||
| 525 | * Starting point for SD card init. | ||
| 526 | */ | ||
| 527 | int mmc_attach_sd(struct mmc_host *host, u32 ocr) | ||
| 528 | { | ||
| 529 | int err; | ||
| 530 | |||
| 531 | BUG_ON(!host); | ||
| 532 | BUG_ON(!host->claimed); | ||
| 533 | |||
| 534 | mmc_attach_bus(host, &mmc_sd_ops); | ||
| 535 | |||
| 536 | /* | ||
| 537 | * Sanity check the voltages that the card claims to | ||
| 538 | * support. | ||
| 539 | */ | ||
| 540 | if (ocr & 0x7F) { | ||
| 541 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
| 542 | "below the defined range. These will be ignored.\n", | ||
| 543 | mmc_hostname(host)); | ||
| 544 | ocr &= ~0x7F; | ||
| 545 | } | ||
| 546 | |||
| 547 | if (ocr & MMC_VDD_165_195) { | ||
| 548 | printk(KERN_WARNING "%s: SD card claims to support the " | ||
| 549 | "incompletely defined 'low voltage range'. This " | ||
| 550 | "will be ignored.\n", mmc_hostname(host)); | ||
| 551 | ocr &= ~MMC_VDD_165_195; | ||
| 552 | } | ||
| 553 | |||
| 554 | host->ocr = mmc_select_voltage(host, ocr); | ||
| 555 | |||
| 556 | /* | ||
| 557 | * Can we support the voltage(s) of the card(s)? | ||
| 558 | */ | ||
| 559 | if (!host->ocr) | ||
| 560 | goto err; | ||
| 561 | |||
| 562 | /* | ||
| 563 | * Detect and init the card. | ||
| 564 | */ | ||
| 565 | err = mmc_sd_init_card(host, host->ocr, NULL); | ||
| 566 | if (err != MMC_ERR_NONE) | ||
| 567 | goto err; | ||
| 568 | |||
| 569 | mmc_release_host(host); | ||
| 570 | |||
| 571 | err = mmc_register_card(host->card); | ||
| 572 | if (err) | ||
| 573 | goto reclaim_host; | ||
| 574 | |||
| 575 | return 0; | ||
| 576 | |||
| 577 | reclaim_host: | ||
| 578 | mmc_claim_host(host); | ||
| 579 | mmc_remove_card(host->card); | ||
| 580 | host->card = NULL; | ||
| 581 | err: | ||
| 582 | mmc_detach_bus(host); | ||
| 583 | mmc_release_host(host); | ||
| 584 | |||
| 585 | return 0; | ||
| 586 | } | ||
| 587 | |||
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c new file mode 100644 index 000000000000..9697ce581101 --- /dev/null +++ b/drivers/mmc/core/sd_ops.c | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/sd_ops.h | ||
| 3 | * | ||
| 4 | * Copyright 2006-2007 Pierre Ossman | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
| 9 | * your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/types.h> | ||
| 13 | #include <asm/scatterlist.h> | ||
| 14 | #include <linux/scatterlist.h> | ||
| 15 | |||
| 16 | #include <linux/mmc/host.h> | ||
| 17 | #include <linux/mmc/card.h> | ||
| 18 | #include <linux/mmc/mmc.h> | ||
| 19 | #include <linux/mmc/sd.h> | ||
| 20 | |||
| 21 | #include "core.h" | ||
| 22 | #include "sd_ops.h" | ||
| 23 | |||
| 24 | /** | ||
| 25 | * mmc_wait_for_app_cmd - start an application command and wait for | ||
| 26 | completion | ||
| 27 | * @host: MMC host to start command | ||
| 28 | * @rca: RCA to send MMC_APP_CMD to | ||
| 29 | * @cmd: MMC command to start | ||
| 30 | * @retries: maximum number of retries | ||
| 31 | * | ||
| 32 | * Sends a MMC_APP_CMD, checks the card response, sends the command | ||
| 33 | * in the parameter and waits for it to complete. Return any error | ||
| 34 | * that occurred while the command was executing. Do not attempt to | ||
| 35 | * parse the response. | ||
| 36 | */ | ||
| 37 | int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | ||
| 38 | struct mmc_command *cmd, int retries) | ||
| 39 | { | ||
| 40 | struct mmc_request mrq; | ||
| 41 | |||
| 42 | int i, err; | ||
| 43 | |||
| 44 | BUG_ON(!cmd); | ||
| 45 | BUG_ON(retries < 0); | ||
| 46 | |||
| 47 | err = MMC_ERR_INVALID; | ||
| 48 | |||
| 49 | /* | ||
| 50 | * We have to resend MMC_APP_CMD for each attempt so | ||
| 51 | * we cannot use the retries field in mmc_command. | ||
| 52 | */ | ||
| 53 | for (i = 0;i <= retries;i++) { | ||
| 54 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 55 | |||
| 56 | err = mmc_app_cmd(host, card); | ||
| 57 | if (err != MMC_ERR_NONE) | ||
| 58 | continue; | ||
| 59 | |||
| 60 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 61 | |||
| 62 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
| 63 | cmd->retries = 0; | ||
| 64 | |||
| 65 | mrq.cmd = cmd; | ||
| 66 | cmd->data = NULL; | ||
| 67 | |||
| 68 | mmc_wait_for_req(host, &mrq); | ||
| 69 | |||
| 70 | err = cmd->error; | ||
| 71 | if (cmd->error == MMC_ERR_NONE) | ||
| 72 | break; | ||
| 73 | } | ||
| 74 | |||
| 75 | return err; | ||
| 76 | } | ||
| 77 | |||
| 78 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); | ||
| 79 | |||
| 80 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) | ||
| 81 | { | ||
| 82 | int err; | ||
| 83 | struct mmc_command cmd; | ||
| 84 | |||
| 85 | BUG_ON(!host); | ||
| 86 | BUG_ON(card && (card->host != host)); | ||
| 87 | |||
| 88 | cmd.opcode = MMC_APP_CMD; | ||
| 89 | |||
| 90 | if (card) { | ||
| 91 | cmd.arg = card->rca << 16; | ||
| 92 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 93 | } else { | ||
| 94 | cmd.arg = 0; | ||
| 95 | cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR; | ||
| 96 | } | ||
| 97 | |||
| 98 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
| 99 | if (err != MMC_ERR_NONE) | ||
| 100 | return err; | ||
| 101 | |||
| 102 | /* Check that card supported application commands */ | ||
| 103 | if (!(cmd.resp[0] & R1_APP_CMD)) | ||
| 104 | return MMC_ERR_FAILED; | ||
| 105 | |||
| 106 | return MMC_ERR_NONE; | ||
| 107 | } | ||
| 108 | |||
| 109 | int mmc_app_set_bus_width(struct mmc_card *card, int width) | ||
| 110 | { | ||
| 111 | int err; | ||
| 112 | struct mmc_command cmd; | ||
| 113 | |||
| 114 | BUG_ON(!card); | ||
| 115 | BUG_ON(!card->host); | ||
| 116 | |||
| 117 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 118 | |||
| 119 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | ||
| 120 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 121 | |||
| 122 | switch (width) { | ||
| 123 | case MMC_BUS_WIDTH_1: | ||
| 124 | cmd.arg = SD_BUS_WIDTH_1; | ||
| 125 | break; | ||
| 126 | case MMC_BUS_WIDTH_4: | ||
| 127 | cmd.arg = SD_BUS_WIDTH_4; | ||
| 128 | break; | ||
| 129 | default: | ||
| 130 | return MMC_ERR_INVALID; | ||
| 131 | } | ||
| 132 | |||
| 133 | err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); | ||
| 134 | if (err != MMC_ERR_NONE) | ||
| 135 | return err; | ||
| 136 | |||
| 137 | return MMC_ERR_NONE; | ||
| 138 | } | ||
| 139 | |||
| 140 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
| 141 | { | ||
| 142 | struct mmc_command cmd; | ||
| 143 | int i, err = 0; | ||
| 144 | |||
| 145 | BUG_ON(!host); | ||
| 146 | |||
| 147 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 148 | |||
| 149 | cmd.opcode = SD_APP_OP_COND; | ||
| 150 | cmd.arg = ocr; | ||
| 151 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
| 152 | |||
| 153 | for (i = 100; i; i--) { | ||
| 154 | err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); | ||
| 155 | if (err != MMC_ERR_NONE) | ||
| 156 | break; | ||
| 157 | |||
| 158 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
| 159 | break; | ||
| 160 | |||
| 161 | err = MMC_ERR_TIMEOUT; | ||
| 162 | |||
| 163 | mmc_delay(10); | ||
| 164 | } | ||
| 165 | |||
| 166 | if (rocr) | ||
| 167 | *rocr = cmd.resp[0]; | ||
| 168 | |||
| 169 | return err; | ||
| 170 | } | ||
| 171 | |||
| 172 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr) | ||
| 173 | { | ||
| 174 | struct mmc_command cmd; | ||
| 175 | int err; | ||
| 176 | static const u8 test_pattern = 0xAA; | ||
| 177 | |||
| 178 | /* | ||
| 179 | * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND | ||
| 180 | * before SD_APP_OP_COND. This command will harmlessly fail for | ||
| 181 | * SD 1.0 cards. | ||
| 182 | */ | ||
| 183 | cmd.opcode = SD_SEND_IF_COND; | ||
| 184 | cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; | ||
| 185 | cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; | ||
| 186 | |||
| 187 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
| 188 | if (err != MMC_ERR_NONE) | ||
| 189 | return err; | ||
| 190 | |||
| 191 | if ((cmd.resp[0] & 0xFF) != test_pattern) | ||
| 192 | return MMC_ERR_FAILED; | ||
| 193 | |||
| 194 | return MMC_ERR_NONE; | ||
| 195 | } | ||
| 196 | |||
| 197 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) | ||
| 198 | { | ||
| 199 | int err; | ||
| 200 | struct mmc_command cmd; | ||
| 201 | |||
| 202 | BUG_ON(!host); | ||
| 203 | BUG_ON(!rca); | ||
| 204 | |||
| 205 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 206 | |||
| 207 | cmd.opcode = SD_SEND_RELATIVE_ADDR; | ||
| 208 | cmd.arg = 0; | ||
| 209 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; | ||
| 210 | |||
| 211 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
| 212 | if (err != MMC_ERR_NONE) | ||
| 213 | return err; | ||
| 214 | |||
| 215 | *rca = cmd.resp[0] >> 16; | ||
| 216 | |||
| 217 | return MMC_ERR_NONE; | ||
| 218 | } | ||
| 219 | |||
| 220 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | ||
| 221 | { | ||
| 222 | int err; | ||
| 223 | struct mmc_request mrq; | ||
| 224 | struct mmc_command cmd; | ||
| 225 | struct mmc_data data; | ||
| 226 | struct scatterlist sg; | ||
| 227 | |||
| 228 | BUG_ON(!card); | ||
| 229 | BUG_ON(!card->host); | ||
| 230 | BUG_ON(!scr); | ||
| 231 | |||
| 232 | err = mmc_app_cmd(card->host, card); | ||
| 233 | if (err != MMC_ERR_NONE) | ||
| 234 | return err; | ||
| 235 | |||
| 236 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 237 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 238 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 239 | |||
| 240 | mrq.cmd = &cmd; | ||
| 241 | mrq.data = &data; | ||
| 242 | |||
| 243 | cmd.opcode = SD_APP_SEND_SCR; | ||
| 244 | cmd.arg = 0; | ||
| 245 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
| 246 | |||
| 247 | data.blksz = 8; | ||
| 248 | data.blocks = 1; | ||
| 249 | data.flags = MMC_DATA_READ; | ||
| 250 | data.sg = &sg; | ||
| 251 | data.sg_len = 1; | ||
| 252 | |||
| 253 | sg_init_one(&sg, scr, 8); | ||
| 254 | |||
| 255 | mmc_set_data_timeout(&data, card, 0); | ||
| 256 | |||
| 257 | mmc_wait_for_req(card->host, &mrq); | ||
| 258 | |||
| 259 | if (cmd.error != MMC_ERR_NONE) | ||
| 260 | return cmd.error; | ||
| 261 | if (data.error != MMC_ERR_NONE) | ||
| 262 | return data.error; | ||
| 263 | |||
| 264 | scr[0] = ntohl(scr[0]); | ||
| 265 | scr[1] = ntohl(scr[1]); | ||
| 266 | |||
| 267 | return MMC_ERR_NONE; | ||
| 268 | } | ||
| 269 | |||
| 270 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | ||
| 271 | u8 value, u8 *resp) | ||
| 272 | { | ||
| 273 | struct mmc_request mrq; | ||
| 274 | struct mmc_command cmd; | ||
| 275 | struct mmc_data data; | ||
| 276 | struct scatterlist sg; | ||
| 277 | |||
| 278 | BUG_ON(!card); | ||
| 279 | BUG_ON(!card->host); | ||
| 280 | |||
| 281 | mode = !!mode; | ||
| 282 | value &= 0xF; | ||
| 283 | |||
| 284 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 285 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 286 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 287 | |||
| 288 | mrq.cmd = &cmd; | ||
| 289 | mrq.data = &data; | ||
| 290 | |||
| 291 | cmd.opcode = SD_SWITCH; | ||
| 292 | cmd.arg = mode << 31 | 0x00FFFFFF; | ||
| 293 | cmd.arg &= ~(0xF << (group * 4)); | ||
| 294 | cmd.arg |= value << (group * 4); | ||
| 295 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
| 296 | |||
| 297 | data.blksz = 64; | ||
| 298 | data.blocks = 1; | ||
| 299 | data.flags = MMC_DATA_READ; | ||
| 300 | data.sg = &sg; | ||
| 301 | data.sg_len = 1; | ||
| 302 | |||
| 303 | sg_init_one(&sg, resp, 64); | ||
| 304 | |||
| 305 | mmc_set_data_timeout(&data, card, 0); | ||
| 306 | |||
| 307 | mmc_wait_for_req(card->host, &mrq); | ||
| 308 | |||
| 309 | if (cmd.error != MMC_ERR_NONE) | ||
| 310 | return cmd.error; | ||
| 311 | if (data.error != MMC_ERR_NONE) | ||
| 312 | return data.error; | ||
| 313 | |||
| 314 | return MMC_ERR_NONE; | ||
| 315 | } | ||
| 316 | |||
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h new file mode 100644 index 000000000000..1240fddba5e3 --- /dev/null +++ b/drivers/mmc/core/sd_ops.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/sd_ops.h | ||
| 3 | * | ||
| 4 | * Copyright 2006-2007 Pierre Ossman | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
| 9 | * your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _MMC_SD_OPS_H | ||
| 13 | #define _MMC_SD_OPS_H | ||
| 14 | |||
| 15 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); | ||
| 16 | int mmc_app_set_bus_width(struct mmc_card *card, int width); | ||
| 17 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | ||
| 18 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr); | ||
| 19 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca); | ||
| 20 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr); | ||
| 21 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | ||
| 22 | u8 value, u8 *resp); | ||
| 23 | |||
| 24 | #endif | ||
| 25 | |||
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/core/sysfs.c index d32698b02d7f..843b1fbba557 100644 --- a/drivers/mmc/mmc_sysfs.c +++ b/drivers/mmc/core/sysfs.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mmc/mmc_sysfs.c | 2 | * linux/drivers/mmc/core/sysfs.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
| 5 | * | 5 | * |
| @@ -18,7 +18,7 @@ | |||
| 18 | #include <linux/mmc/card.h> | 18 | #include <linux/mmc/card.h> |
| 19 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
| 20 | 20 | ||
| 21 | #include "mmc.h" | 21 | #include "sysfs.h" |
| 22 | 22 | ||
| 23 | #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) | 23 | #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) |
| 24 | #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) | 24 | #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) |
| @@ -72,12 +72,11 @@ static void mmc_release_card(struct device *dev) | |||
| 72 | /* | 72 | /* |
| 73 | * This currently matches any MMC driver to any MMC card - drivers | 73 | * This currently matches any MMC driver to any MMC card - drivers |
| 74 | * themselves make the decision whether to drive this card in their | 74 | * themselves make the decision whether to drive this card in their |
| 75 | * probe method. However, we force "bad" cards to fail. | 75 | * probe method. |
| 76 | */ | 76 | */ |
| 77 | static int mmc_bus_match(struct device *dev, struct device_driver *drv) | 77 | static int mmc_bus_match(struct device *dev, struct device_driver *drv) |
| 78 | { | 78 | { |
| 79 | struct mmc_card *card = dev_to_mmc_card(dev); | 79 | return 1; |
| 80 | return !mmc_card_bad(card); | ||
| 81 | } | 80 | } |
| 82 | 81 | ||
| 83 | static int | 82 | static int |
| @@ -86,31 +85,26 @@ mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, | |||
| 86 | { | 85 | { |
| 87 | struct mmc_card *card = dev_to_mmc_card(dev); | 86 | struct mmc_card *card = dev_to_mmc_card(dev); |
| 88 | char ccc[13]; | 87 | char ccc[13]; |
| 89 | int i = 0; | 88 | int retval = 0, i = 0, length = 0; |
| 90 | 89 | ||
| 91 | #define add_env(fmt,val) \ | 90 | #define add_env(fmt,val) do { \ |
| 92 | ({ \ | 91 | retval = add_uevent_var(envp, num_envp, &i, \ |
| 93 | int len, ret = -ENOMEM; \ | 92 | buf, buf_size, &length, \ |
| 94 | if (i < num_envp) { \ | 93 | fmt, val); \ |
| 95 | envp[i++] = buf; \ | 94 | if (retval) \ |
| 96 | len = snprintf(buf, buf_size, fmt, val) + 1; \ | 95 | return retval; \ |
| 97 | buf_size -= len; \ | 96 | } while (0); |
| 98 | buf += len; \ | ||
| 99 | if (buf_size >= 0) \ | ||
| 100 | ret = 0; \ | ||
| 101 | } \ | ||
| 102 | ret; \ | ||
| 103 | }) | ||
| 104 | 97 | ||
| 105 | for (i = 0; i < 12; i++) | 98 | for (i = 0; i < 12; i++) |
| 106 | ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0'; | 99 | ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0'; |
| 107 | ccc[12] = '\0'; | 100 | ccc[12] = '\0'; |
| 108 | 101 | ||
| 109 | i = 0; | ||
| 110 | add_env("MMC_CCC=%s", ccc); | 102 | add_env("MMC_CCC=%s", ccc); |
| 111 | add_env("MMC_MANFID=%06x", card->cid.manfid); | 103 | add_env("MMC_MANFID=%06x", card->cid.manfid); |
| 112 | add_env("MMC_NAME=%s", mmc_card_name(card)); | 104 | add_env("MMC_NAME=%s", mmc_card_name(card)); |
| 113 | add_env("MMC_OEMID=%04x", card->cid.oemid); | 105 | add_env("MMC_OEMID=%04x", card->cid.oemid); |
| 106 | #undef add_env | ||
| 107 | envp[i] = NULL; | ||
| 114 | 108 | ||
| 115 | return 0; | 109 | return 0; |
| 116 | } | 110 | } |
| @@ -222,6 +216,8 @@ int mmc_register_card(struct mmc_card *card) | |||
| 222 | device_del(&card->dev); | 216 | device_del(&card->dev); |
| 223 | } | 217 | } |
| 224 | } | 218 | } |
| 219 | if (ret == 0) | ||
| 220 | mmc_card_set_present(card); | ||
| 225 | return ret; | 221 | return ret; |
| 226 | } | 222 | } |
| 227 | 223 | ||
diff --git a/drivers/mmc/mmc.h b/drivers/mmc/core/sysfs.h index 149affe0b686..80e29b358282 100644 --- a/drivers/mmc/mmc.h +++ b/drivers/mmc/core/sysfs.h | |||
| @@ -1,15 +1,16 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mmc/mmc.h | 2 | * linux/drivers/mmc/core/sysfs.h |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
| 5 | * Copyright 2007 Pierre Ossman | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * 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 | * it under the terms of the GNU General Public License version 2 as |
| 8 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
| 9 | */ | 10 | */ |
| 10 | #ifndef _MMC_H | 11 | #ifndef _MMC_CORE_SYSFS_H |
| 11 | #define _MMC_H | 12 | #define _MMC_CORE_SYSFS_H |
| 12 | /* core-internal functions */ | 13 | |
| 13 | void mmc_init_card(struct mmc_card *card, struct mmc_host *host); | 14 | void mmc_init_card(struct mmc_card *card, struct mmc_host *host); |
| 14 | int mmc_register_card(struct mmc_card *card); | 15 | int mmc_register_card(struct mmc_card *card); |
| 15 | void mmc_remove_card(struct mmc_card *card); | 16 | void mmc_remove_card(struct mmc_card *card); |
| @@ -22,4 +23,5 @@ void mmc_free_host_sysfs(struct mmc_host *host); | |||
| 22 | int mmc_schedule_work(struct work_struct *work); | 23 | int mmc_schedule_work(struct work_struct *work); |
| 23 | int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); | 24 | int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); |
| 24 | void mmc_flush_scheduled_work(void); | 25 | void mmc_flush_scheduled_work(void); |
| 26 | |||
| 25 | #endif | 27 | #endif |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig new file mode 100644 index 000000000000..ed4deab2203d --- /dev/null +++ b/drivers/mmc/host/Kconfig | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | # | ||
| 2 | # MMC/SD host controller drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | comment "MMC/SD Host Controller Drivers" | ||
| 6 | depends on MMC | ||
| 7 | |||
| 8 | config MMC_ARMMMCI | ||
| 9 | tristate "ARM AMBA Multimedia Card Interface support" | ||
| 10 | depends on ARM_AMBA && MMC | ||
| 11 | help | ||
| 12 | This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card | ||
| 13 | Interface (PL180 and PL181) support. If you have an ARM(R) | ||
| 14 | platform with a Multimedia Card slot, say Y or M here. | ||
| 15 | |||
| 16 | If unsure, say N. | ||
| 17 | |||
| 18 | config MMC_PXA | ||
| 19 | tristate "Intel PXA25x/26x/27x Multimedia Card Interface support" | ||
| 20 | depends on ARCH_PXA && MMC | ||
| 21 | help | ||
| 22 | This selects the Intel(R) PXA(R) Multimedia card Interface. | ||
| 23 | If you have a PXA(R) platform with a Multimedia Card slot, | ||
| 24 | say Y or M here. | ||
| 25 | |||
| 26 | If unsure, say N. | ||
| 27 | |||
| 28 | config MMC_SDHCI | ||
| 29 | tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" | ||
| 30 | depends on PCI && MMC && EXPERIMENTAL | ||
| 31 | help | ||
| 32 | This select the generic Secure Digital Host Controller Interface. | ||
| 33 | It is used by manufacturers such as Texas Instruments(R), Ricoh(R) | ||
| 34 | and Toshiba(R). Most controllers found in laptops are of this type. | ||
| 35 | If you have a controller with this interface, say Y or M here. | ||
| 36 | |||
| 37 | If unsure, say N. | ||
| 38 | |||
| 39 | config MMC_OMAP | ||
| 40 | tristate "TI OMAP Multimedia Card Interface support" | ||
| 41 | depends on ARCH_OMAP && MMC | ||
| 42 | select TPS65010 if MACH_OMAP_H2 | ||
| 43 | help | ||
| 44 | This selects the TI OMAP Multimedia card Interface. | ||
| 45 | If you have an OMAP board with a Multimedia Card slot, | ||
| 46 | say Y or M here. | ||
| 47 | |||
| 48 | If unsure, say N. | ||
| 49 | |||
| 50 | config MMC_WBSD | ||
| 51 | tristate "Winbond W83L51xD SD/MMC Card Interface support" | ||
| 52 | depends on MMC && ISA_DMA_API | ||
| 53 | help | ||
| 54 | This selects the Winbond(R) W83L51xD Secure digital and | ||
| 55 | Multimedia card Interface. | ||
| 56 | If you have a machine with a integrated W83L518D or W83L519D | ||
| 57 | SD/MMC card reader, say Y or M here. | ||
| 58 | |||
| 59 | If unsure, say N. | ||
| 60 | |||
| 61 | config MMC_AU1X | ||
| 62 | tristate "Alchemy AU1XX0 MMC Card Interface support" | ||
| 63 | depends on MMC && SOC_AU1200 | ||
| 64 | help | ||
| 65 | This selects the AMD Alchemy(R) Multimedia card interface. | ||
| 66 | If you have a Alchemy platform with a MMC slot, say Y or M here. | ||
| 67 | |||
| 68 | If unsure, say N. | ||
| 69 | |||
| 70 | config MMC_AT91 | ||
| 71 | tristate "AT91 SD/MMC Card Interface support" | ||
| 72 | depends on ARCH_AT91 && MMC | ||
| 73 | help | ||
| 74 | This selects the AT91 MCI controller. | ||
| 75 | |||
| 76 | If unsure, say N. | ||
| 77 | |||
| 78 | config MMC_IMX | ||
| 79 | tristate "Motorola i.MX Multimedia Card Interface support" | ||
| 80 | depends on ARCH_IMX && MMC | ||
| 81 | help | ||
| 82 | This selects the Motorola i.MX Multimedia card Interface. | ||
| 83 | If you have a i.MX platform with a Multimedia Card slot, | ||
| 84 | say Y or M here. | ||
| 85 | |||
| 86 | If unsure, say N. | ||
| 87 | |||
| 88 | config MMC_TIFM_SD | ||
| 89 | tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" | ||
| 90 | depends on MMC && EXPERIMENTAL && PCI | ||
| 91 | select TIFM_CORE | ||
| 92 | help | ||
| 93 | Say Y here if you want to be able to access MMC/SD cards with | ||
| 94 | the Texas Instruments(R) Flash Media card reader, found in many | ||
| 95 | laptops. | ||
| 96 | This option 'selects' (turns on, enables) 'TIFM_CORE', but you | ||
| 97 | probably also need appropriate card reader host adapter, such as | ||
| 98 | 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support | ||
| 99 | (TIFM_7XX1)'. | ||
| 100 | |||
| 101 | To compile this driver as a module, choose M here: the | ||
| 102 | module will be called tifm_sd. | ||
| 103 | |||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile new file mode 100644 index 000000000000..6685f64345b4 --- /dev/null +++ b/drivers/mmc/host/Makefile | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | # | ||
| 2 | # Makefile for MMC/SD host controller drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | ifeq ($(CONFIG_MMC_DEBUG),y) | ||
| 6 | EXTRA_CFLAGS += -DDEBUG | ||
| 7 | endif | ||
| 8 | |||
| 9 | obj-$(CONFIG_MMC_ARMMMCI) += mmci.o | ||
| 10 | obj-$(CONFIG_MMC_PXA) += pxamci.o | ||
| 11 | obj-$(CONFIG_MMC_IMX) += imxmmc.o | ||
| 12 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | ||
| 13 | obj-$(CONFIG_MMC_WBSD) += wbsd.o | ||
| 14 | obj-$(CONFIG_MMC_AU1X) += au1xmmc.o | ||
| 15 | obj-$(CONFIG_MMC_OMAP) += omap.o | ||
| 16 | obj-$(CONFIG_MMC_AT91) += at91_mci.o | ||
| 17 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o | ||
| 18 | |||
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/host/at91_mci.c index 459f4b4feded..e37943c314cb 100644 --- a/drivers/mmc/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
| @@ -67,7 +67,6 @@ | |||
| 67 | #include <linux/atmel_pdc.h> | 67 | #include <linux/atmel_pdc.h> |
| 68 | 68 | ||
| 69 | #include <linux/mmc/host.h> | 69 | #include <linux/mmc/host.h> |
| 70 | #include <linux/mmc/protocol.h> | ||
| 71 | 70 | ||
| 72 | #include <asm/io.h> | 71 | #include <asm/io.h> |
| 73 | #include <asm/irq.h> | 72 | #include <asm/irq.h> |
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index b834be261ab7..b7156a4555b5 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
| @@ -42,7 +42,6 @@ | |||
| 42 | #include <linux/dma-mapping.h> | 42 | #include <linux/dma-mapping.h> |
| 43 | 43 | ||
| 44 | #include <linux/mmc/host.h> | 44 | #include <linux/mmc/host.h> |
| 45 | #include <linux/mmc/protocol.h> | ||
| 46 | #include <asm/io.h> | 45 | #include <asm/io.h> |
| 47 | #include <asm/mach-au1x00/au1000.h> | 46 | #include <asm/mach-au1x00/au1000.h> |
| 48 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 47 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
diff --git a/drivers/mmc/au1xmmc.h b/drivers/mmc/host/au1xmmc.h index 341cbdf0baca..341cbdf0baca 100644 --- a/drivers/mmc/au1xmmc.h +++ b/drivers/mmc/host/au1xmmc.h | |||
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/host/imxmmc.c index 0de5c9e94e74..7ee2045acbef 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
| 42 | #include <linux/mmc/host.h> | 42 | #include <linux/mmc/host.h> |
| 43 | #include <linux/mmc/card.h> | 43 | #include <linux/mmc/card.h> |
| 44 | #include <linux/mmc/protocol.h> | ||
| 45 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
| 46 | 45 | ||
| 47 | #include <asm/dma.h> | 46 | #include <asm/dma.h> |
diff --git a/drivers/mmc/imxmmc.h b/drivers/mmc/host/imxmmc.h index e5339e334dbb..e5339e334dbb 100644 --- a/drivers/mmc/imxmmc.h +++ b/drivers/mmc/host/imxmmc.h | |||
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/host/mmci.c index 5941dd951e82..d11c2d23ceea 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
| 18 | #include <linux/highmem.h> | 18 | #include <linux/highmem.h> |
| 19 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
| 20 | #include <linux/mmc/protocol.h> | ||
| 21 | #include <linux/amba/bus.h> | 20 | #include <linux/amba/bus.h> |
| 22 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
| 23 | 22 | ||
diff --git a/drivers/mmc/mmci.h b/drivers/mmc/host/mmci.h index 6d7eadc9a678..6d7eadc9a678 100644 --- a/drivers/mmc/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
diff --git a/drivers/mmc/omap.c b/drivers/mmc/host/omap.c index 1e96a2f65022..1914e65d4db1 100644 --- a/drivers/mmc/omap.c +++ b/drivers/mmc/host/omap.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
| 23 | #include <linux/timer.h> | 23 | #include <linux/timer.h> |
| 24 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
| 25 | #include <linux/mmc/protocol.h> | ||
| 26 | #include <linux/mmc/card.h> | 25 | #include <linux/mmc/card.h> |
| 27 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
| 28 | 27 | ||
| @@ -605,7 +604,7 @@ static void mmc_omap_switch_handler(struct work_struct *work) | |||
| 605 | } | 604 | } |
| 606 | if (mmc_omap_cover_is_open(host)) { | 605 | if (mmc_omap_cover_is_open(host)) { |
| 607 | if (!complained) { | 606 | if (!complained) { |
| 608 | dev_info(mmc_dev(host->mmc), "cover is open"); | 607 | dev_info(mmc_dev(host->mmc), "cover is open\n"); |
| 609 | complained = 1; | 608 | complained = 1; |
| 610 | } | 609 | } |
| 611 | if (mmc_omap_enable_poll) | 610 | if (mmc_omap_enable_poll) |
| @@ -937,48 +936,55 @@ static void mmc_omap_power(struct mmc_omap_host *host, int on) | |||
| 937 | } | 936 | } |
| 938 | } | 937 | } |
| 939 | 938 | ||
| 940 | static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 939 | static int mmc_omap_calc_divisor(struct mmc_host *mmc, struct mmc_ios *ios) |
| 941 | { | 940 | { |
| 942 | struct mmc_omap_host *host = mmc_priv(mmc); | 941 | struct mmc_omap_host *host = mmc_priv(mmc); |
| 942 | int func_clk_rate = clk_get_rate(host->fclk); | ||
| 943 | int dsor; | 943 | int dsor; |
| 944 | int realclock, i; | ||
| 945 | |||
| 946 | realclock = ios->clock; | ||
| 947 | 944 | ||
| 948 | if (ios->clock == 0) | 945 | if (ios->clock == 0) |
| 949 | dsor = 0; | 946 | return 0; |
| 950 | else { | ||
| 951 | int func_clk_rate = clk_get_rate(host->fclk); | ||
| 952 | |||
| 953 | dsor = func_clk_rate / realclock; | ||
| 954 | if (dsor < 1) | ||
| 955 | dsor = 1; | ||
| 956 | 947 | ||
| 957 | if (func_clk_rate / dsor > realclock) | 948 | dsor = func_clk_rate / ios->clock; |
| 958 | dsor++; | 949 | if (dsor < 1) |
| 950 | dsor = 1; | ||
| 959 | 951 | ||
| 960 | if (dsor > 250) | 952 | if (func_clk_rate / dsor > ios->clock) |
| 961 | dsor = 250; | ||
| 962 | dsor++; | 953 | dsor++; |
| 963 | 954 | ||
| 964 | if (ios->bus_width == MMC_BUS_WIDTH_4) | 955 | if (dsor > 250) |
| 965 | dsor |= 1 << 15; | 956 | dsor = 250; |
| 966 | } | 957 | dsor++; |
| 958 | |||
| 959 | if (ios->bus_width == MMC_BUS_WIDTH_4) | ||
| 960 | dsor |= 1 << 15; | ||
| 961 | |||
| 962 | return dsor; | ||
| 963 | } | ||
| 964 | |||
| 965 | static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
| 966 | { | ||
| 967 | struct mmc_omap_host *host = mmc_priv(mmc); | ||
| 968 | int dsor; | ||
| 969 | int i; | ||
| 970 | |||
| 971 | dsor = mmc_omap_calc_divisor(mmc, ios); | ||
| 972 | host->bus_mode = ios->bus_mode; | ||
| 973 | host->hw_bus_mode = host->bus_mode; | ||
| 967 | 974 | ||
| 968 | switch (ios->power_mode) { | 975 | switch (ios->power_mode) { |
| 969 | case MMC_POWER_OFF: | 976 | case MMC_POWER_OFF: |
| 970 | mmc_omap_power(host, 0); | 977 | mmc_omap_power(host, 0); |
| 971 | break; | 978 | break; |
| 972 | case MMC_POWER_UP: | 979 | case MMC_POWER_UP: |
| 973 | case MMC_POWER_ON: | 980 | /* Cannot touch dsor yet, just power up MMC */ |
| 974 | mmc_omap_power(host, 1); | 981 | mmc_omap_power(host, 1); |
| 982 | return; | ||
| 983 | case MMC_POWER_ON: | ||
| 975 | dsor |= 1 << 11; | 984 | dsor |= 1 << 11; |
| 976 | break; | 985 | break; |
| 977 | } | 986 | } |
| 978 | 987 | ||
| 979 | host->bus_mode = ios->bus_mode; | ||
| 980 | host->hw_bus_mode = host->bus_mode; | ||
| 981 | |||
| 982 | clk_enable(host->fclk); | 988 | clk_enable(host->fclk); |
| 983 | 989 | ||
| 984 | /* On insanely high arm_per frequencies something sometimes | 990 | /* On insanely high arm_per frequencies something sometimes |
| @@ -987,7 +993,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 987 | * Writing to the CON register twice seems to do the trick. */ | 993 | * Writing to the CON register twice seems to do the trick. */ |
| 988 | for (i = 0; i < 2; i++) | 994 | for (i = 0; i < 2; i++) |
| 989 | OMAP_MMC_WRITE(host, CON, dsor); | 995 | OMAP_MMC_WRITE(host, CON, dsor); |
| 990 | if (ios->power_mode == MMC_POWER_UP) { | 996 | if (ios->power_mode == MMC_POWER_ON) { |
| 991 | /* Send clock cycles, poll completion */ | 997 | /* Send clock cycles, poll completion */ |
| 992 | OMAP_MMC_WRITE(host, IE, 0); | 998 | OMAP_MMC_WRITE(host, IE, 0); |
| 993 | OMAP_MMC_WRITE(host, STAT, 0xffff); | 999 | OMAP_MMC_WRITE(host, STAT, 0xffff); |
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/host/pxamci.c index 9774fc68b61a..d97d3864b57f 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
| 25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
| 26 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
| 27 | #include <linux/mmc/protocol.h> | ||
| 28 | 27 | ||
| 29 | #include <asm/dma.h> | 28 | #include <asm/dma.h> |
| 30 | #include <asm/io.h> | 29 | #include <asm/io.h> |
| @@ -369,14 +368,14 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 369 | if (CLOCKRATE / clk > ios->clock) | 368 | if (CLOCKRATE / clk > ios->clock) |
| 370 | clk <<= 1; | 369 | clk <<= 1; |
| 371 | host->clkrt = fls(clk) - 1; | 370 | host->clkrt = fls(clk) - 1; |
| 372 | pxa_set_cken(CKEN12_MMC, 1); | 371 | pxa_set_cken(CKEN_MMC, 1); |
| 373 | 372 | ||
| 374 | /* | 373 | /* |
| 375 | * we write clkrt on the next command | 374 | * we write clkrt on the next command |
| 376 | */ | 375 | */ |
| 377 | } else { | 376 | } else { |
| 378 | pxamci_stop_clock(host); | 377 | pxamci_stop_clock(host); |
| 379 | pxa_set_cken(CKEN12_MMC, 0); | 378 | pxa_set_cken(CKEN_MMC, 0); |
| 380 | } | 379 | } |
| 381 | 380 | ||
| 382 | if (host->power_mode != ios->power_mode) { | 381 | if (host->power_mode != ios->power_mode) { |
diff --git a/drivers/mmc/pxamci.h b/drivers/mmc/host/pxamci.h index 1b163220df2b..1b163220df2b 100644 --- a/drivers/mmc/pxamci.h +++ b/drivers/mmc/host/pxamci.h | |||
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/host/sdhci.c index d749f08601b8..ff5bf73cdd25 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mmc/sdhci.c - Secure Digital Host Controller Interface driver | 2 | * linux/drivers/mmc/sdhci.c - Secure Digital Host Controller Interface driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005-2006 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
| 16 | 16 | ||
| 17 | #include <linux/mmc/host.h> | 17 | #include <linux/mmc/host.h> |
| 18 | #include <linux/mmc/protocol.h> | ||
| 19 | 18 | ||
| 20 | #include <asm/scatterlist.h> | 19 | #include <asm/scatterlist.h> |
| 21 | 20 | ||
| @@ -247,14 +246,13 @@ static void sdhci_read_block_pio(struct sdhci_host *host) | |||
| 247 | chunk_remain = min(blksize, 4); | 246 | chunk_remain = min(blksize, 4); |
| 248 | } | 247 | } |
| 249 | 248 | ||
| 250 | size = min(host->size, host->remain); | 249 | size = min(host->remain, chunk_remain); |
| 251 | size = min(size, chunk_remain); | ||
| 252 | 250 | ||
| 253 | chunk_remain -= size; | 251 | chunk_remain -= size; |
| 254 | blksize -= size; | 252 | blksize -= size; |
| 255 | host->offset += size; | 253 | host->offset += size; |
| 256 | host->remain -= size; | 254 | host->remain -= size; |
| 257 | host->size -= size; | 255 | |
| 258 | while (size) { | 256 | while (size) { |
| 259 | *buffer = data & 0xFF; | 257 | *buffer = data & 0xFF; |
| 260 | buffer++; | 258 | buffer++; |
| @@ -289,14 +287,13 @@ static void sdhci_write_block_pio(struct sdhci_host *host) | |||
| 289 | buffer = sdhci_sg_to_buffer(host) + host->offset; | 287 | buffer = sdhci_sg_to_buffer(host) + host->offset; |
| 290 | 288 | ||
| 291 | while (blksize) { | 289 | while (blksize) { |
| 292 | size = min(host->size, host->remain); | 290 | size = min(host->remain, chunk_remain); |
| 293 | size = min(size, chunk_remain); | ||
| 294 | 291 | ||
| 295 | chunk_remain -= size; | 292 | chunk_remain -= size; |
| 296 | blksize -= size; | 293 | blksize -= size; |
| 297 | host->offset += size; | 294 | host->offset += size; |
| 298 | host->remain -= size; | 295 | host->remain -= size; |
| 299 | host->size -= size; | 296 | |
| 300 | while (size) { | 297 | while (size) { |
| 301 | data >>= 8; | 298 | data >>= 8; |
| 302 | data |= (u32)*buffer << 24; | 299 | data |= (u32)*buffer << 24; |
| @@ -325,7 +322,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host) | |||
| 325 | 322 | ||
| 326 | BUG_ON(!host->data); | 323 | BUG_ON(!host->data); |
| 327 | 324 | ||
| 328 | if (host->size == 0) | 325 | if (host->num_sg == 0) |
| 329 | return; | 326 | return; |
| 330 | 327 | ||
| 331 | if (host->data->flags & MMC_DATA_READ) | 328 | if (host->data->flags & MMC_DATA_READ) |
| @@ -339,10 +336,8 @@ static void sdhci_transfer_pio(struct sdhci_host *host) | |||
| 339 | else | 336 | else |
| 340 | sdhci_write_block_pio(host); | 337 | sdhci_write_block_pio(host); |
| 341 | 338 | ||
| 342 | if (host->size == 0) | 339 | if (host->num_sg == 0) |
| 343 | break; | 340 | break; |
| 344 | |||
| 345 | BUG_ON(host->num_sg == 0); | ||
| 346 | } | 341 | } |
| 347 | 342 | ||
| 348 | DBG("PIO transfer complete.\n"); | 343 | DBG("PIO transfer complete.\n"); |
| @@ -408,8 +403,6 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) | |||
| 408 | 403 | ||
| 409 | writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); | 404 | writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); |
| 410 | } else { | 405 | } else { |
| 411 | host->size = data->blksz * data->blocks; | ||
| 412 | |||
| 413 | host->cur_sg = data->sg; | 406 | host->cur_sg = data->sg; |
| 414 | host->num_sg = data->sg_len; | 407 | host->num_sg = data->sg_len; |
| 415 | 408 | ||
| @@ -473,10 +466,6 @@ static void sdhci_finish_data(struct sdhci_host *host) | |||
| 473 | "though there were blocks left.\n", | 466 | "though there were blocks left.\n", |
| 474 | mmc_hostname(host->mmc)); | 467 | mmc_hostname(host->mmc)); |
| 475 | data->error = MMC_ERR_FAILED; | 468 | data->error = MMC_ERR_FAILED; |
| 476 | } else if (host->size != 0) { | ||
| 477 | printk(KERN_ERR "%s: %d bytes were left untransferred.\n", | ||
| 478 | mmc_hostname(host->mmc), host->size); | ||
| 479 | data->error = MMC_ERR_FAILED; | ||
| 480 | } | 469 | } |
| 481 | 470 | ||
| 482 | DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); | 471 | DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); |
| @@ -669,20 +658,16 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
| 669 | 658 | ||
| 670 | pwr = SDHCI_POWER_ON; | 659 | pwr = SDHCI_POWER_ON; |
| 671 | 660 | ||
| 672 | switch (power) { | 661 | switch (1 << power) { |
| 673 | case MMC_VDD_170: | 662 | case MMC_VDD_165_195: |
| 674 | case MMC_VDD_180: | ||
| 675 | case MMC_VDD_190: | ||
| 676 | pwr |= SDHCI_POWER_180; | 663 | pwr |= SDHCI_POWER_180; |
| 677 | break; | 664 | break; |
| 678 | case MMC_VDD_290: | 665 | case MMC_VDD_29_30: |
| 679 | case MMC_VDD_300: | 666 | case MMC_VDD_30_31: |
| 680 | case MMC_VDD_310: | ||
| 681 | pwr |= SDHCI_POWER_300; | 667 | pwr |= SDHCI_POWER_300; |
| 682 | break; | 668 | break; |
| 683 | case MMC_VDD_320: | 669 | case MMC_VDD_32_33: |
| 684 | case MMC_VDD_330: | 670 | case MMC_VDD_33_34: |
| 685 | case MMC_VDD_340: | ||
| 686 | pwr |= SDHCI_POWER_330; | 671 | pwr |= SDHCI_POWER_330; |
| 687 | break; | 672 | break; |
| 688 | default: | 673 | default: |
| @@ -1294,7 +1279,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
| 1294 | if (caps & SDHCI_CAN_VDD_300) | 1279 | if (caps & SDHCI_CAN_VDD_300) |
| 1295 | mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; | 1280 | mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; |
| 1296 | if (caps & SDHCI_CAN_VDD_180) | 1281 | if (caps & SDHCI_CAN_VDD_180) |
| 1297 | mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; | 1282 | mmc->ocr_avail |= MMC_VDD_165_195; |
| 1298 | 1283 | ||
| 1299 | if (mmc->ocr_avail == 0) { | 1284 | if (mmc->ocr_avail == 0) { |
| 1300 | printk(KERN_ERR "%s: Hardware doesn't report any " | 1285 | printk(KERN_ERR "%s: Hardware doesn't report any " |
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/host/sdhci.h index e324f0a623dc..7400f4bc114f 100644 --- a/drivers/mmc/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mmc/sdhci.h - Secure Digital Host Controller Interface driver | 2 | * linux/drivers/mmc/sdhci.h - Secure Digital Host Controller Interface driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| @@ -187,8 +187,6 @@ struct sdhci_host { | |||
| 187 | int offset; /* Offset into current sg */ | 187 | int offset; /* Offset into current sg */ |
| 188 | int remain; /* Bytes left in current */ | 188 | int remain; /* Bytes left in current */ |
| 189 | 189 | ||
| 190 | int size; /* Remaining bytes in transfer */ | ||
| 191 | |||
| 192 | char slot_descr[20]; /* Name for reservations */ | 190 | char slot_descr[20]; /* Name for reservations */ |
| 193 | 191 | ||
| 194 | int irq; /* Device IRQ */ | 192 | int irq; /* Device IRQ */ |
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c new file mode 100644 index 000000000000..7511f961c67b --- /dev/null +++ b/drivers/mmc/host/tifm_sd.c | |||
| @@ -0,0 +1,1102 @@ | |||
| 1 | /* | ||
| 2 | * tifm_sd.c - TI FlashMedia driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com> | ||
| 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 | * Special thanks to Brad Campbell for extensive testing of this driver. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | |||
| 15 | #include <linux/tifm.h> | ||
| 16 | #include <linux/mmc/host.h> | ||
| 17 | #include <linux/highmem.h> | ||
| 18 | #include <linux/scatterlist.h> | ||
| 19 | #include <asm/io.h> | ||
| 20 | |||
| 21 | #define DRIVER_NAME "tifm_sd" | ||
| 22 | #define DRIVER_VERSION "0.8" | ||
| 23 | |||
| 24 | static int no_dma = 0; | ||
| 25 | static int fixed_timeout = 0; | ||
| 26 | module_param(no_dma, bool, 0644); | ||
| 27 | module_param(fixed_timeout, bool, 0644); | ||
| 28 | |||
| 29 | /* Constants here are mostly from OMAP5912 datasheet */ | ||
| 30 | #define TIFM_MMCSD_RESET 0x0002 | ||
| 31 | #define TIFM_MMCSD_CLKMASK 0x03ff | ||
| 32 | #define TIFM_MMCSD_POWER 0x0800 | ||
| 33 | #define TIFM_MMCSD_4BBUS 0x8000 | ||
| 34 | #define TIFM_MMCSD_RXDE 0x8000 /* rx dma enable */ | ||
| 35 | #define TIFM_MMCSD_TXDE 0x0080 /* tx dma enable */ | ||
| 36 | #define TIFM_MMCSD_BUFINT 0x0c00 /* set bits: AE, AF */ | ||
| 37 | #define TIFM_MMCSD_DPE 0x0020 /* data timeout counted in kilocycles */ | ||
| 38 | #define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */ | ||
| 39 | #define TIFM_MMCSD_READ 0x8000 | ||
| 40 | |||
| 41 | #define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */ | ||
| 42 | #define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ | ||
| 43 | #define TIFM_MMCSD_CD 0x0002 /* card detect */ | ||
| 44 | #define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ | ||
| 45 | #define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ | ||
| 46 | #define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */ | ||
| 47 | #define TIFM_MMCSD_DTO 0x0020 /* data time-out */ | ||
| 48 | #define TIFM_MMCSD_DCRC 0x0040 /* data crc error */ | ||
| 49 | #define TIFM_MMCSD_CTO 0x0080 /* command time-out */ | ||
| 50 | #define TIFM_MMCSD_CCRC 0x0100 /* command crc error */ | ||
| 51 | #define TIFM_MMCSD_AF 0x0400 /* fifo almost full */ | ||
| 52 | #define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */ | ||
| 53 | #define TIFM_MMCSD_OCRB 0x1000 /* OCR busy */ | ||
| 54 | #define TIFM_MMCSD_CIRQ 0x2000 /* card irq (cmd40/sdio) */ | ||
| 55 | #define TIFM_MMCSD_CERR 0x4000 /* card status error */ | ||
| 56 | |||
| 57 | #define TIFM_MMCSD_ODTO 0x0040 /* open drain / extended timeout */ | ||
| 58 | #define TIFM_MMCSD_CARD_RO 0x0200 /* card is read-only */ | ||
| 59 | |||
| 60 | #define TIFM_MMCSD_FIFO_SIZE 0x0020 | ||
| 61 | |||
| 62 | #define TIFM_MMCSD_RSP_R0 0x0000 | ||
| 63 | #define TIFM_MMCSD_RSP_R1 0x0100 | ||
| 64 | #define TIFM_MMCSD_RSP_R2 0x0200 | ||
| 65 | #define TIFM_MMCSD_RSP_R3 0x0300 | ||
| 66 | #define TIFM_MMCSD_RSP_R4 0x0400 | ||
| 67 | #define TIFM_MMCSD_RSP_R5 0x0500 | ||
| 68 | #define TIFM_MMCSD_RSP_R6 0x0600 | ||
| 69 | |||
| 70 | #define TIFM_MMCSD_RSP_BUSY 0x0800 | ||
| 71 | |||
| 72 | #define TIFM_MMCSD_CMD_BC 0x0000 | ||
| 73 | #define TIFM_MMCSD_CMD_BCR 0x1000 | ||
| 74 | #define TIFM_MMCSD_CMD_AC 0x2000 | ||
| 75 | #define TIFM_MMCSD_CMD_ADTC 0x3000 | ||
| 76 | |||
| 77 | #define TIFM_MMCSD_MAX_BLOCK_SIZE 0x0800UL | ||
| 78 | |||
| 79 | enum { | ||
| 80 | CMD_READY = 0x0001, | ||
| 81 | FIFO_READY = 0x0002, | ||
| 82 | BRS_READY = 0x0004, | ||
| 83 | SCMD_ACTIVE = 0x0008, | ||
| 84 | SCMD_READY = 0x0010, | ||
| 85 | CARD_BUSY = 0x0020, | ||
| 86 | DATA_CARRY = 0x0040 | ||
| 87 | }; | ||
| 88 | |||
| 89 | struct tifm_sd { | ||
| 90 | struct tifm_dev *dev; | ||
| 91 | |||
| 92 | unsigned short eject:1, | ||
| 93 | open_drain:1, | ||
| 94 | no_dma:1; | ||
| 95 | unsigned short cmd_flags; | ||
| 96 | |||
| 97 | unsigned int clk_freq; | ||
| 98 | unsigned int clk_div; | ||
| 99 | unsigned long timeout_jiffies; | ||
| 100 | |||
| 101 | struct tasklet_struct finish_tasklet; | ||
| 102 | struct timer_list timer; | ||
| 103 | struct mmc_request *req; | ||
| 104 | |||
| 105 | int sg_len; | ||
| 106 | int sg_pos; | ||
| 107 | unsigned int block_pos; | ||
| 108 | struct scatterlist bounce_buf; | ||
| 109 | unsigned char bounce_buf_data[TIFM_MMCSD_MAX_BLOCK_SIZE]; | ||
| 110 | }; | ||
| 111 | |||
| 112 | /* for some reason, host won't respond correctly to readw/writew */ | ||
| 113 | static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, | ||
| 114 | unsigned int off, unsigned int cnt) | ||
| 115 | { | ||
| 116 | struct tifm_dev *sock = host->dev; | ||
| 117 | unsigned char *buf; | ||
| 118 | unsigned int pos = 0, val; | ||
| 119 | |||
| 120 | buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + off; | ||
| 121 | if (host->cmd_flags & DATA_CARRY) { | ||
| 122 | buf[pos++] = host->bounce_buf_data[0]; | ||
| 123 | host->cmd_flags &= ~DATA_CARRY; | ||
| 124 | } | ||
| 125 | |||
| 126 | while (pos < cnt) { | ||
| 127 | val = readl(sock->addr + SOCK_MMCSD_DATA); | ||
| 128 | buf[pos++] = val & 0xff; | ||
| 129 | if (pos == cnt) { | ||
| 130 | host->bounce_buf_data[0] = (val >> 8) & 0xff; | ||
| 131 | host->cmd_flags |= DATA_CARRY; | ||
| 132 | break; | ||
| 133 | } | ||
| 134 | buf[pos++] = (val >> 8) & 0xff; | ||
| 135 | } | ||
| 136 | kunmap_atomic(buf - off, KM_BIO_DST_IRQ); | ||
| 137 | } | ||
| 138 | |||
| 139 | static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, | ||
| 140 | unsigned int off, unsigned int cnt) | ||
| 141 | { | ||
| 142 | struct tifm_dev *sock = host->dev; | ||
| 143 | unsigned char *buf; | ||
| 144 | unsigned int pos = 0, val; | ||
| 145 | |||
| 146 | buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + off; | ||
| 147 | if (host->cmd_flags & DATA_CARRY) { | ||
| 148 | val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00); | ||
| 149 | writel(val, sock->addr + SOCK_MMCSD_DATA); | ||
| 150 | host->cmd_flags &= ~DATA_CARRY; | ||
| 151 | } | ||
| 152 | |||
| 153 | while (pos < cnt) { | ||
| 154 | val = buf[pos++]; | ||
| 155 | if (pos == cnt) { | ||
| 156 | host->bounce_buf_data[0] = val & 0xff; | ||
| 157 | host->cmd_flags |= DATA_CARRY; | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | val |= (buf[pos++] << 8) & 0xff00; | ||
| 161 | writel(val, sock->addr + SOCK_MMCSD_DATA); | ||
| 162 | } | ||
| 163 | kunmap_atomic(buf - off, KM_BIO_SRC_IRQ); | ||
| 164 | } | ||
| 165 | |||
| 166 | static void tifm_sd_transfer_data(struct tifm_sd *host) | ||
| 167 | { | ||
| 168 | struct mmc_data *r_data = host->req->cmd->data; | ||
| 169 | struct scatterlist *sg = r_data->sg; | ||
| 170 | unsigned int off, cnt, t_size = TIFM_MMCSD_FIFO_SIZE * 2; | ||
| 171 | unsigned int p_off, p_cnt; | ||
| 172 | struct page *pg; | ||
| 173 | |||
| 174 | if (host->sg_pos == host->sg_len) | ||
| 175 | return; | ||
| 176 | while (t_size) { | ||
| 177 | cnt = sg[host->sg_pos].length - host->block_pos; | ||
| 178 | if (!cnt) { | ||
| 179 | host->block_pos = 0; | ||
| 180 | host->sg_pos++; | ||
| 181 | if (host->sg_pos == host->sg_len) { | ||
| 182 | if ((r_data->flags & MMC_DATA_WRITE) | ||
| 183 | && DATA_CARRY) | ||
| 184 | writel(host->bounce_buf_data[0], | ||
| 185 | host->dev->addr | ||
| 186 | + SOCK_MMCSD_DATA); | ||
| 187 | |||
| 188 | return; | ||
| 189 | } | ||
| 190 | cnt = sg[host->sg_pos].length; | ||
| 191 | } | ||
| 192 | off = sg[host->sg_pos].offset + host->block_pos; | ||
| 193 | |||
| 194 | pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT); | ||
| 195 | p_off = offset_in_page(off); | ||
| 196 | p_cnt = PAGE_SIZE - p_off; | ||
| 197 | p_cnt = min(p_cnt, cnt); | ||
| 198 | p_cnt = min(p_cnt, t_size); | ||
| 199 | |||
| 200 | if (r_data->flags & MMC_DATA_READ) | ||
| 201 | tifm_sd_read_fifo(host, pg, p_off, p_cnt); | ||
| 202 | else if (r_data->flags & MMC_DATA_WRITE) | ||
| 203 | tifm_sd_write_fifo(host, pg, p_off, p_cnt); | ||
| 204 | |||
| 205 | t_size -= p_cnt; | ||
| 206 | host->block_pos += p_cnt; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off, | ||
| 211 | struct page *src, unsigned int src_off, | ||
| 212 | unsigned int count) | ||
| 213 | { | ||
| 214 | unsigned char *src_buf = kmap_atomic(src, KM_BIO_SRC_IRQ) + src_off; | ||
| 215 | unsigned char *dst_buf = kmap_atomic(dst, KM_BIO_DST_IRQ) + dst_off; | ||
| 216 | |||
| 217 | memcpy(dst_buf, src_buf, count); | ||
| 218 | |||
| 219 | kunmap_atomic(dst_buf - dst_off, KM_BIO_DST_IRQ); | ||
| 220 | kunmap_atomic(src_buf - src_off, KM_BIO_SRC_IRQ); | ||
| 221 | } | ||
| 222 | |||
| 223 | static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data) | ||
| 224 | { | ||
| 225 | struct scatterlist *sg = r_data->sg; | ||
| 226 | unsigned int t_size = r_data->blksz; | ||
| 227 | unsigned int off, cnt; | ||
| 228 | unsigned int p_off, p_cnt; | ||
| 229 | struct page *pg; | ||
| 230 | |||
| 231 | dev_dbg(&host->dev->dev, "bouncing block\n"); | ||
| 232 | while (t_size) { | ||
| 233 | cnt = sg[host->sg_pos].length - host->block_pos; | ||
| 234 | if (!cnt) { | ||
| 235 | host->block_pos = 0; | ||
| 236 | host->sg_pos++; | ||
| 237 | if (host->sg_pos == host->sg_len) | ||
| 238 | return; | ||
| 239 | cnt = sg[host->sg_pos].length; | ||
| 240 | } | ||
| 241 | off = sg[host->sg_pos].offset + host->block_pos; | ||
| 242 | |||
| 243 | pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT); | ||
| 244 | p_off = offset_in_page(off); | ||
| 245 | p_cnt = PAGE_SIZE - p_off; | ||
| 246 | p_cnt = min(p_cnt, cnt); | ||
| 247 | p_cnt = min(p_cnt, t_size); | ||
| 248 | |||
| 249 | if (r_data->flags & MMC_DATA_WRITE) | ||
| 250 | tifm_sd_copy_page(host->bounce_buf.page, | ||
| 251 | r_data->blksz - t_size, | ||
| 252 | pg, p_off, p_cnt); | ||
| 253 | else if (r_data->flags & MMC_DATA_READ) | ||
| 254 | tifm_sd_copy_page(pg, p_off, host->bounce_buf.page, | ||
| 255 | r_data->blksz - t_size, p_cnt); | ||
| 256 | |||
| 257 | t_size -= p_cnt; | ||
| 258 | host->block_pos += p_cnt; | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | static int tifm_sd_set_dma_data(struct tifm_sd *host, struct mmc_data *r_data) | ||
| 263 | { | ||
| 264 | struct tifm_dev *sock = host->dev; | ||
| 265 | unsigned int t_size = TIFM_DMA_TSIZE * r_data->blksz; | ||
| 266 | unsigned int dma_len, dma_blk_cnt, dma_off; | ||
| 267 | struct scatterlist *sg = NULL; | ||
| 268 | unsigned long flags; | ||
| 269 | |||
| 270 | if (host->sg_pos == host->sg_len) | ||
| 271 | return 1; | ||
| 272 | |||
| 273 | if (host->cmd_flags & DATA_CARRY) { | ||
| 274 | host->cmd_flags &= ~DATA_CARRY; | ||
| 275 | local_irq_save(flags); | ||
| 276 | tifm_sd_bounce_block(host, r_data); | ||
| 277 | local_irq_restore(flags); | ||
| 278 | if (host->sg_pos == host->sg_len) | ||
| 279 | return 1; | ||
| 280 | } | ||
| 281 | |||
| 282 | dma_len = sg_dma_len(&r_data->sg[host->sg_pos]) - host->block_pos; | ||
| 283 | if (!dma_len) { | ||
| 284 | host->block_pos = 0; | ||
| 285 | host->sg_pos++; | ||
| 286 | if (host->sg_pos == host->sg_len) | ||
| 287 | return 1; | ||
| 288 | dma_len = sg_dma_len(&r_data->sg[host->sg_pos]); | ||
| 289 | } | ||
| 290 | |||
| 291 | if (dma_len < t_size) { | ||
| 292 | dma_blk_cnt = dma_len / r_data->blksz; | ||
| 293 | dma_off = host->block_pos; | ||
| 294 | host->block_pos += dma_blk_cnt * r_data->blksz; | ||
| 295 | } else { | ||
| 296 | dma_blk_cnt = TIFM_DMA_TSIZE; | ||
| 297 | dma_off = host->block_pos; | ||
| 298 | host->block_pos += t_size; | ||
| 299 | } | ||
| 300 | |||
| 301 | if (dma_blk_cnt) | ||
| 302 | sg = &r_data->sg[host->sg_pos]; | ||
| 303 | else if (dma_len) { | ||
| 304 | if (r_data->flags & MMC_DATA_WRITE) { | ||
| 305 | local_irq_save(flags); | ||
| 306 | tifm_sd_bounce_block(host, r_data); | ||
| 307 | local_irq_restore(flags); | ||
| 308 | } else | ||
| 309 | host->cmd_flags |= DATA_CARRY; | ||
| 310 | |||
| 311 | sg = &host->bounce_buf; | ||
| 312 | dma_off = 0; | ||
| 313 | dma_blk_cnt = 1; | ||
| 314 | } else | ||
| 315 | return 1; | ||
| 316 | |||
| 317 | dev_dbg(&sock->dev, "setting dma for %d blocks\n", dma_blk_cnt); | ||
| 318 | writel(sg_dma_address(sg) + dma_off, sock->addr + SOCK_DMA_ADDRESS); | ||
| 319 | if (r_data->flags & MMC_DATA_WRITE) | ||
| 320 | writel((dma_blk_cnt << 8) | TIFM_DMA_TX | TIFM_DMA_EN, | ||
| 321 | sock->addr + SOCK_DMA_CONTROL); | ||
| 322 | else | ||
| 323 | writel((dma_blk_cnt << 8) | TIFM_DMA_EN, | ||
| 324 | sock->addr + SOCK_DMA_CONTROL); | ||
| 325 | |||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | |||
| 329 | static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) | ||
| 330 | { | ||
| 331 | unsigned int rc = 0; | ||
| 332 | |||
| 333 | switch (mmc_resp_type(cmd)) { | ||
| 334 | case MMC_RSP_NONE: | ||
| 335 | rc |= TIFM_MMCSD_RSP_R0; | ||
| 336 | break; | ||
| 337 | case MMC_RSP_R1B: | ||
| 338 | rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through | ||
| 339 | case MMC_RSP_R1: | ||
| 340 | rc |= TIFM_MMCSD_RSP_R1; | ||
| 341 | break; | ||
| 342 | case MMC_RSP_R2: | ||
| 343 | rc |= TIFM_MMCSD_RSP_R2; | ||
| 344 | break; | ||
| 345 | case MMC_RSP_R3: | ||
| 346 | rc |= TIFM_MMCSD_RSP_R3; | ||
| 347 | break; | ||
| 348 | default: | ||
| 349 | BUG(); | ||
| 350 | } | ||
| 351 | |||
| 352 | switch (mmc_cmd_type(cmd)) { | ||
| 353 | case MMC_CMD_BC: | ||
| 354 | rc |= TIFM_MMCSD_CMD_BC; | ||
| 355 | break; | ||
| 356 | case MMC_CMD_BCR: | ||
| 357 | rc |= TIFM_MMCSD_CMD_BCR; | ||
| 358 | break; | ||
| 359 | case MMC_CMD_AC: | ||
| 360 | rc |= TIFM_MMCSD_CMD_AC; | ||
| 361 | break; | ||
| 362 | case MMC_CMD_ADTC: | ||
| 363 | rc |= TIFM_MMCSD_CMD_ADTC; | ||
| 364 | break; | ||
| 365 | default: | ||
| 366 | BUG(); | ||
| 367 | } | ||
| 368 | return rc; | ||
| 369 | } | ||
| 370 | |||
| 371 | static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) | ||
| 372 | { | ||
| 373 | struct tifm_dev *sock = host->dev; | ||
| 374 | unsigned int cmd_mask = tifm_sd_op_flags(cmd); | ||
| 375 | |||
| 376 | if (host->open_drain) | ||
| 377 | cmd_mask |= TIFM_MMCSD_ODTO; | ||
| 378 | |||
| 379 | if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) | ||
| 380 | cmd_mask |= TIFM_MMCSD_READ; | ||
| 381 | |||
| 382 | dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", | ||
| 383 | cmd->opcode, cmd->arg, cmd_mask); | ||
| 384 | |||
| 385 | writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); | ||
| 386 | writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); | ||
| 387 | writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND); | ||
| 388 | } | ||
| 389 | |||
| 390 | static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock) | ||
| 391 | { | ||
| 392 | cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16) | ||
| 393 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18); | ||
| 394 | cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16) | ||
| 395 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10); | ||
| 396 | cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16) | ||
| 397 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08); | ||
| 398 | cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16) | ||
| 399 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00); | ||
| 400 | } | ||
| 401 | |||
| 402 | static void tifm_sd_check_status(struct tifm_sd *host) | ||
| 403 | { | ||
| 404 | struct tifm_dev *sock = host->dev; | ||
| 405 | struct mmc_command *cmd = host->req->cmd; | ||
| 406 | |||
| 407 | if (cmd->error != MMC_ERR_NONE) | ||
| 408 | goto finish_request; | ||
| 409 | |||
| 410 | if (!(host->cmd_flags & CMD_READY)) | ||
| 411 | return; | ||
| 412 | |||
| 413 | if (cmd->data) { | ||
| 414 | if (cmd->data->error != MMC_ERR_NONE) { | ||
| 415 | if ((host->cmd_flags & SCMD_ACTIVE) | ||
| 416 | && !(host->cmd_flags & SCMD_READY)) | ||
| 417 | return; | ||
| 418 | |||
| 419 | goto finish_request; | ||
| 420 | } | ||
| 421 | |||
| 422 | if (!(host->cmd_flags & BRS_READY)) | ||
| 423 | return; | ||
| 424 | |||
| 425 | if (!(host->no_dma || (host->cmd_flags & FIFO_READY))) | ||
| 426 | return; | ||
| 427 | |||
| 428 | if (cmd->data->flags & MMC_DATA_WRITE) { | ||
| 429 | if (host->req->stop) { | ||
| 430 | if (!(host->cmd_flags & SCMD_ACTIVE)) { | ||
| 431 | host->cmd_flags |= SCMD_ACTIVE; | ||
| 432 | writel(TIFM_MMCSD_EOFB | ||
| 433 | | readl(sock->addr | ||
| 434 | + SOCK_MMCSD_INT_ENABLE), | ||
| 435 | sock->addr | ||
| 436 | + SOCK_MMCSD_INT_ENABLE); | ||
| 437 | tifm_sd_exec(host, host->req->stop); | ||
| 438 | return; | ||
| 439 | } else { | ||
| 440 | if (!(host->cmd_flags & SCMD_READY) | ||
| 441 | || (host->cmd_flags & CARD_BUSY)) | ||
| 442 | return; | ||
| 443 | writel((~TIFM_MMCSD_EOFB) | ||
| 444 | & readl(sock->addr | ||
| 445 | + SOCK_MMCSD_INT_ENABLE), | ||
| 446 | sock->addr | ||
| 447 | + SOCK_MMCSD_INT_ENABLE); | ||
| 448 | } | ||
| 449 | } else { | ||
| 450 | if (host->cmd_flags & CARD_BUSY) | ||
| 451 | return; | ||
| 452 | writel((~TIFM_MMCSD_EOFB) | ||
| 453 | & readl(sock->addr | ||
| 454 | + SOCK_MMCSD_INT_ENABLE), | ||
| 455 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 456 | } | ||
| 457 | } else { | ||
| 458 | if (host->req->stop) { | ||
| 459 | if (!(host->cmd_flags & SCMD_ACTIVE)) { | ||
| 460 | host->cmd_flags |= SCMD_ACTIVE; | ||
| 461 | tifm_sd_exec(host, host->req->stop); | ||
| 462 | return; | ||
| 463 | } else { | ||
| 464 | if (!(host->cmd_flags & SCMD_READY)) | ||
| 465 | return; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | } | ||
| 469 | } | ||
| 470 | finish_request: | ||
| 471 | tasklet_schedule(&host->finish_tasklet); | ||
| 472 | } | ||
| 473 | |||
| 474 | /* Called from interrupt handler */ | ||
| 475 | static void tifm_sd_data_event(struct tifm_dev *sock) | ||
| 476 | { | ||
| 477 | struct tifm_sd *host; | ||
| 478 | unsigned int fifo_status = 0; | ||
| 479 | struct mmc_data *r_data = NULL; | ||
| 480 | |||
| 481 | spin_lock(&sock->lock); | ||
| 482 | host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); | ||
| 483 | fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); | ||
| 484 | dev_dbg(&sock->dev, "data event: fifo_status %x, flags %x\n", | ||
| 485 | fifo_status, host->cmd_flags); | ||
| 486 | |||
| 487 | if (host->req) { | ||
| 488 | r_data = host->req->cmd->data; | ||
| 489 | |||
| 490 | if (r_data && (fifo_status & TIFM_FIFO_READY)) { | ||
| 491 | if (tifm_sd_set_dma_data(host, r_data)) { | ||
| 492 | host->cmd_flags |= FIFO_READY; | ||
| 493 | tifm_sd_check_status(host); | ||
| 494 | } | ||
| 495 | } | ||
| 496 | } | ||
| 497 | |||
| 498 | writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS); | ||
| 499 | spin_unlock(&sock->lock); | ||
| 500 | } | ||
| 501 | |||
| 502 | /* Called from interrupt handler */ | ||
| 503 | static void tifm_sd_card_event(struct tifm_dev *sock) | ||
| 504 | { | ||
| 505 | struct tifm_sd *host; | ||
| 506 | unsigned int host_status = 0; | ||
| 507 | int cmd_error = MMC_ERR_NONE; | ||
| 508 | struct mmc_command *cmd = NULL; | ||
| 509 | unsigned long flags; | ||
| 510 | |||
| 511 | spin_lock(&sock->lock); | ||
| 512 | host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); | ||
| 513 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
| 514 | dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n", | ||
| 515 | host_status, host->cmd_flags); | ||
| 516 | |||
| 517 | if (host->req) { | ||
| 518 | cmd = host->req->cmd; | ||
| 519 | |||
| 520 | if (host_status & TIFM_MMCSD_ERRMASK) { | ||
| 521 | writel(host_status & TIFM_MMCSD_ERRMASK, | ||
| 522 | sock->addr + SOCK_MMCSD_STATUS); | ||
| 523 | if (host_status & TIFM_MMCSD_CTO) | ||
| 524 | cmd_error = MMC_ERR_TIMEOUT; | ||
| 525 | else if (host_status & TIFM_MMCSD_CCRC) | ||
| 526 | cmd_error = MMC_ERR_BADCRC; | ||
| 527 | |||
| 528 | if (cmd->data) { | ||
| 529 | if (host_status & TIFM_MMCSD_DTO) | ||
| 530 | cmd->data->error = MMC_ERR_TIMEOUT; | ||
| 531 | else if (host_status & TIFM_MMCSD_DCRC) | ||
| 532 | cmd->data->error = MMC_ERR_BADCRC; | ||
| 533 | } | ||
| 534 | |||
| 535 | writel(TIFM_FIFO_INT_SETALL, | ||
| 536 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
| 537 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); | ||
| 538 | |||
| 539 | if (host->req->stop) { | ||
| 540 | if (host->cmd_flags & SCMD_ACTIVE) { | ||
| 541 | host->req->stop->error = cmd_error; | ||
| 542 | host->cmd_flags |= SCMD_READY; | ||
| 543 | } else { | ||
| 544 | cmd->error = cmd_error; | ||
| 545 | host->cmd_flags |= SCMD_ACTIVE; | ||
| 546 | tifm_sd_exec(host, host->req->stop); | ||
| 547 | goto done; | ||
| 548 | } | ||
| 549 | } else | ||
| 550 | cmd->error = cmd_error; | ||
| 551 | } else { | ||
| 552 | if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) { | ||
| 553 | if (!(host->cmd_flags & CMD_READY)) { | ||
| 554 | host->cmd_flags |= CMD_READY; | ||
| 555 | tifm_sd_fetch_resp(cmd, sock); | ||
| 556 | } else if (host->cmd_flags & SCMD_ACTIVE) { | ||
| 557 | host->cmd_flags |= SCMD_READY; | ||
| 558 | tifm_sd_fetch_resp(host->req->stop, | ||
| 559 | sock); | ||
| 560 | } | ||
| 561 | } | ||
| 562 | if (host_status & TIFM_MMCSD_BRS) | ||
| 563 | host->cmd_flags |= BRS_READY; | ||
| 564 | } | ||
| 565 | |||
| 566 | if (host->no_dma && cmd->data) { | ||
| 567 | if (host_status & TIFM_MMCSD_AE) | ||
| 568 | writel(host_status & TIFM_MMCSD_AE, | ||
| 569 | sock->addr + SOCK_MMCSD_STATUS); | ||
| 570 | |||
| 571 | if (host_status & (TIFM_MMCSD_AE | TIFM_MMCSD_AF | ||
| 572 | | TIFM_MMCSD_BRS)) { | ||
| 573 | local_irq_save(flags); | ||
| 574 | tifm_sd_transfer_data(host); | ||
| 575 | local_irq_restore(flags); | ||
| 576 | host_status &= ~TIFM_MMCSD_AE; | ||
| 577 | } | ||
| 578 | } | ||
| 579 | |||
| 580 | if (host_status & TIFM_MMCSD_EOFB) | ||
| 581 | host->cmd_flags &= ~CARD_BUSY; | ||
| 582 | else if (host_status & TIFM_MMCSD_CB) | ||
| 583 | host->cmd_flags |= CARD_BUSY; | ||
| 584 | |||
| 585 | tifm_sd_check_status(host); | ||
| 586 | } | ||
| 587 | done: | ||
| 588 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
| 589 | spin_unlock(&sock->lock); | ||
| 590 | } | ||
| 591 | |||
| 592 | static void tifm_sd_set_data_timeout(struct tifm_sd *host, | ||
| 593 | struct mmc_data *data) | ||
| 594 | { | ||
| 595 | struct tifm_dev *sock = host->dev; | ||
| 596 | unsigned int data_timeout = data->timeout_clks; | ||
| 597 | |||
| 598 | if (fixed_timeout) | ||
| 599 | return; | ||
| 600 | |||
| 601 | data_timeout += data->timeout_ns / | ||
| 602 | ((1000000000UL / host->clk_freq) * host->clk_div); | ||
| 603 | |||
| 604 | if (data_timeout < 0xffff) { | ||
| 605 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
| 606 | writel((~TIFM_MMCSD_DPE) | ||
| 607 | & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
| 608 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
| 609 | } else { | ||
| 610 | data_timeout = (data_timeout >> 10) + 1; | ||
| 611 | if (data_timeout > 0xffff) | ||
| 612 | data_timeout = 0; /* set to unlimited */ | ||
| 613 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
| 614 | writel(TIFM_MMCSD_DPE | ||
| 615 | | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
| 616 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 620 | static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
| 621 | { | ||
| 622 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 623 | struct tifm_dev *sock = host->dev; | ||
| 624 | unsigned long flags; | ||
| 625 | struct mmc_data *r_data = mrq->cmd->data; | ||
| 626 | |||
| 627 | spin_lock_irqsave(&sock->lock, flags); | ||
| 628 | if (host->eject) { | ||
| 629 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 630 | goto err_out; | ||
| 631 | } | ||
| 632 | |||
| 633 | if (host->req) { | ||
| 634 | printk(KERN_ERR "%s : unfinished request detected\n", | ||
| 635 | sock->dev.bus_id); | ||
| 636 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 637 | goto err_out; | ||
| 638 | } | ||
| 639 | |||
| 640 | host->cmd_flags = 0; | ||
| 641 | host->block_pos = 0; | ||
| 642 | host->sg_pos = 0; | ||
| 643 | |||
| 644 | if (r_data) { | ||
| 645 | tifm_sd_set_data_timeout(host, r_data); | ||
| 646 | |||
| 647 | if ((r_data->flags & MMC_DATA_WRITE) && !mrq->stop) | ||
| 648 | writel(TIFM_MMCSD_EOFB | ||
| 649 | | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
| 650 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 651 | |||
| 652 | if (host->no_dma) { | ||
| 653 | writel(TIFM_MMCSD_BUFINT | ||
| 654 | | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
| 655 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 656 | writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) | ||
| 657 | | (TIFM_MMCSD_FIFO_SIZE - 1), | ||
| 658 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
| 659 | |||
| 660 | host->sg_len = r_data->sg_len; | ||
| 661 | } else { | ||
| 662 | sg_init_one(&host->bounce_buf, host->bounce_buf_data, | ||
| 663 | r_data->blksz); | ||
| 664 | |||
| 665 | if(1 != tifm_map_sg(sock, &host->bounce_buf, 1, | ||
| 666 | r_data->flags & MMC_DATA_WRITE | ||
| 667 | ? PCI_DMA_TODEVICE | ||
| 668 | : PCI_DMA_FROMDEVICE)) { | ||
| 669 | printk(KERN_ERR "%s : scatterlist map failed\n", | ||
| 670 | sock->dev.bus_id); | ||
| 671 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 672 | goto err_out; | ||
| 673 | } | ||
| 674 | host->sg_len = tifm_map_sg(sock, r_data->sg, | ||
| 675 | r_data->sg_len, | ||
| 676 | r_data->flags | ||
| 677 | & MMC_DATA_WRITE | ||
| 678 | ? PCI_DMA_TODEVICE | ||
| 679 | : PCI_DMA_FROMDEVICE); | ||
| 680 | if (host->sg_len < 1) { | ||
| 681 | printk(KERN_ERR "%s : scatterlist map failed\n", | ||
| 682 | sock->dev.bus_id); | ||
| 683 | tifm_unmap_sg(sock, &host->bounce_buf, 1, | ||
| 684 | r_data->flags & MMC_DATA_WRITE | ||
| 685 | ? PCI_DMA_TODEVICE | ||
| 686 | : PCI_DMA_FROMDEVICE); | ||
| 687 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 688 | goto err_out; | ||
| 689 | } | ||
| 690 | |||
| 691 | writel(TIFM_FIFO_INT_SETALL, | ||
| 692 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
| 693 | writel(ilog2(r_data->blksz) - 2, | ||
| 694 | sock->addr + SOCK_FIFO_PAGE_SIZE); | ||
| 695 | writel(TIFM_FIFO_ENABLE, | ||
| 696 | sock->addr + SOCK_FIFO_CONTROL); | ||
| 697 | writel(TIFM_FIFO_INTMASK, | ||
| 698 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
| 699 | |||
| 700 | if (r_data->flags & MMC_DATA_WRITE) | ||
| 701 | writel(TIFM_MMCSD_TXDE, | ||
| 702 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
| 703 | else | ||
| 704 | writel(TIFM_MMCSD_RXDE, | ||
| 705 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
| 706 | |||
| 707 | tifm_sd_set_dma_data(host, r_data); | ||
| 708 | } | ||
| 709 | |||
| 710 | writel(r_data->blocks - 1, | ||
| 711 | sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
| 712 | writel(r_data->blksz - 1, | ||
| 713 | sock->addr + SOCK_MMCSD_BLOCK_LEN); | ||
| 714 | } | ||
| 715 | |||
| 716 | host->req = mrq; | ||
| 717 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | ||
| 718 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | ||
| 719 | sock->addr + SOCK_CONTROL); | ||
| 720 | tifm_sd_exec(host, mrq->cmd); | ||
| 721 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 722 | return; | ||
| 723 | |||
| 724 | err_out: | ||
| 725 | mrq->cmd->error = MMC_ERR_TIMEOUT; | ||
| 726 | mmc_request_done(mmc, mrq); | ||
| 727 | } | ||
| 728 | |||
| 729 | static void tifm_sd_end_cmd(unsigned long data) | ||
| 730 | { | ||
| 731 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
| 732 | struct tifm_dev *sock = host->dev; | ||
| 733 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 734 | struct mmc_request *mrq; | ||
| 735 | struct mmc_data *r_data = NULL; | ||
| 736 | unsigned long flags; | ||
| 737 | |||
| 738 | spin_lock_irqsave(&sock->lock, flags); | ||
| 739 | |||
| 740 | del_timer(&host->timer); | ||
| 741 | mrq = host->req; | ||
| 742 | host->req = NULL; | ||
| 743 | |||
| 744 | if (!mrq) { | ||
| 745 | printk(KERN_ERR " %s : no request to complete?\n", | ||
| 746 | sock->dev.bus_id); | ||
| 747 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 748 | return; | ||
| 749 | } | ||
| 750 | |||
| 751 | r_data = mrq->cmd->data; | ||
| 752 | if (r_data) { | ||
| 753 | if (host->no_dma) { | ||
| 754 | writel((~TIFM_MMCSD_BUFINT) | ||
| 755 | & readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
| 756 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 757 | } else { | ||
| 758 | tifm_unmap_sg(sock, &host->bounce_buf, 1, | ||
| 759 | (r_data->flags & MMC_DATA_WRITE) | ||
| 760 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
| 761 | tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, | ||
| 762 | (r_data->flags & MMC_DATA_WRITE) | ||
| 763 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
| 764 | } | ||
| 765 | |||
| 766 | r_data->bytes_xfered = r_data->blocks | ||
| 767 | - readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | ||
| 768 | r_data->bytes_xfered *= r_data->blksz; | ||
| 769 | r_data->bytes_xfered += r_data->blksz | ||
| 770 | - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; | ||
| 771 | } | ||
| 772 | |||
| 773 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | ||
| 774 | sock->addr + SOCK_CONTROL); | ||
| 775 | |||
| 776 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 777 | mmc_request_done(mmc, mrq); | ||
| 778 | } | ||
| 779 | |||
| 780 | static void tifm_sd_abort(unsigned long data) | ||
| 781 | { | ||
| 782 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
| 783 | |||
| 784 | printk(KERN_ERR | ||
| 785 | "%s : card failed to respond for a long period of time " | ||
| 786 | "(%x, %x)\n", | ||
| 787 | host->dev->dev.bus_id, host->req->cmd->opcode, host->cmd_flags); | ||
| 788 | |||
| 789 | tifm_eject(host->dev); | ||
| 790 | } | ||
| 791 | |||
| 792 | static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
| 793 | { | ||
| 794 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 795 | struct tifm_dev *sock = host->dev; | ||
| 796 | unsigned int clk_div1, clk_div2; | ||
| 797 | unsigned long flags; | ||
| 798 | |||
| 799 | spin_lock_irqsave(&sock->lock, flags); | ||
| 800 | |||
| 801 | dev_dbg(&sock->dev, "ios: clock = %u, vdd = %x, bus_mode = %x, " | ||
| 802 | "chip_select = %x, power_mode = %x, bus_width = %x\n", | ||
| 803 | ios->clock, ios->vdd, ios->bus_mode, ios->chip_select, | ||
| 804 | ios->power_mode, ios->bus_width); | ||
| 805 | |||
| 806 | if (ios->bus_width == MMC_BUS_WIDTH_4) { | ||
| 807 | writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
| 808 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 809 | } else { | ||
| 810 | writel((~TIFM_MMCSD_4BBUS) | ||
| 811 | & readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
| 812 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 813 | } | ||
| 814 | |||
| 815 | if (ios->clock) { | ||
| 816 | clk_div1 = 20000000 / ios->clock; | ||
| 817 | if (!clk_div1) | ||
| 818 | clk_div1 = 1; | ||
| 819 | |||
| 820 | clk_div2 = 24000000 / ios->clock; | ||
| 821 | if (!clk_div2) | ||
| 822 | clk_div2 = 1; | ||
| 823 | |||
| 824 | if ((20000000 / clk_div1) > ios->clock) | ||
| 825 | clk_div1++; | ||
| 826 | if ((24000000 / clk_div2) > ios->clock) | ||
| 827 | clk_div2++; | ||
| 828 | if ((20000000 / clk_div1) > (24000000 / clk_div2)) { | ||
| 829 | host->clk_freq = 20000000; | ||
| 830 | host->clk_div = clk_div1; | ||
| 831 | writel((~TIFM_CTRL_FAST_CLK) | ||
| 832 | & readl(sock->addr + SOCK_CONTROL), | ||
| 833 | sock->addr + SOCK_CONTROL); | ||
| 834 | } else { | ||
| 835 | host->clk_freq = 24000000; | ||
| 836 | host->clk_div = clk_div2; | ||
| 837 | writel(TIFM_CTRL_FAST_CLK | ||
| 838 | | readl(sock->addr + SOCK_CONTROL), | ||
| 839 | sock->addr + SOCK_CONTROL); | ||
| 840 | } | ||
| 841 | } else { | ||
| 842 | host->clk_div = 0; | ||
| 843 | } | ||
| 844 | host->clk_div &= TIFM_MMCSD_CLKMASK; | ||
| 845 | writel(host->clk_div | ||
| 846 | | ((~TIFM_MMCSD_CLKMASK) | ||
| 847 | & readl(sock->addr + SOCK_MMCSD_CONFIG)), | ||
| 848 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 849 | |||
| 850 | host->open_drain = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN); | ||
| 851 | |||
| 852 | /* chip_select : maybe later */ | ||
| 853 | //vdd | ||
| 854 | //power is set before probe / after remove | ||
| 855 | |||
| 856 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 857 | } | ||
| 858 | |||
| 859 | static int tifm_sd_ro(struct mmc_host *mmc) | ||
| 860 | { | ||
| 861 | int rc = 0; | ||
| 862 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 863 | struct tifm_dev *sock = host->dev; | ||
| 864 | unsigned long flags; | ||
| 865 | |||
| 866 | spin_lock_irqsave(&sock->lock, flags); | ||
| 867 | if (TIFM_MMCSD_CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE)) | ||
| 868 | rc = 1; | ||
| 869 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 870 | return rc; | ||
| 871 | } | ||
| 872 | |||
| 873 | static const struct mmc_host_ops tifm_sd_ops = { | ||
| 874 | .request = tifm_sd_request, | ||
| 875 | .set_ios = tifm_sd_ios, | ||
| 876 | .get_ro = tifm_sd_ro | ||
| 877 | }; | ||
| 878 | |||
| 879 | static int tifm_sd_initialize_host(struct tifm_sd *host) | ||
| 880 | { | ||
| 881 | int rc; | ||
| 882 | unsigned int host_status = 0; | ||
| 883 | struct tifm_dev *sock = host->dev; | ||
| 884 | |||
| 885 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 886 | mmiowb(); | ||
| 887 | host->clk_div = 61; | ||
| 888 | host->clk_freq = 20000000; | ||
| 889 | writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); | ||
| 890 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
| 891 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 892 | |||
| 893 | /* wait up to 0.51 sec for reset */ | ||
| 894 | for (rc = 32; rc <= 256; rc <<= 1) { | ||
| 895 | if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) { | ||
| 896 | rc = 0; | ||
| 897 | break; | ||
| 898 | } | ||
| 899 | msleep(rc); | ||
| 900 | } | ||
| 901 | |||
| 902 | if (rc) { | ||
| 903 | printk(KERN_ERR "%s : controller failed to reset\n", | ||
| 904 | sock->dev.bus_id); | ||
| 905 | return -ENODEV; | ||
| 906 | } | ||
| 907 | |||
| 908 | writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
| 909 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
| 910 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 911 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
| 912 | |||
| 913 | // command timeout fixed to 64 clocks for now | ||
| 914 | writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); | ||
| 915 | writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND); | ||
| 916 | |||
| 917 | for (rc = 16; rc <= 64; rc <<= 1) { | ||
| 918 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
| 919 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
| 920 | if (!(host_status & TIFM_MMCSD_ERRMASK) | ||
| 921 | && (host_status & TIFM_MMCSD_EOC)) { | ||
| 922 | rc = 0; | ||
| 923 | break; | ||
| 924 | } | ||
| 925 | msleep(rc); | ||
| 926 | } | ||
| 927 | |||
| 928 | if (rc) { | ||
| 929 | printk(KERN_ERR | ||
| 930 | "%s : card not ready - probe failed on initialization\n", | ||
| 931 | sock->dev.bus_id); | ||
| 932 | return -ENODEV; | ||
| 933 | } | ||
| 934 | |||
| 935 | writel(TIFM_MMCSD_CERR | TIFM_MMCSD_BRS | TIFM_MMCSD_EOC | ||
| 936 | | TIFM_MMCSD_ERRMASK, | ||
| 937 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 938 | mmiowb(); | ||
| 939 | |||
| 940 | return 0; | ||
| 941 | } | ||
| 942 | |||
| 943 | static int tifm_sd_probe(struct tifm_dev *sock) | ||
| 944 | { | ||
| 945 | struct mmc_host *mmc; | ||
| 946 | struct tifm_sd *host; | ||
| 947 | int rc = -EIO; | ||
| 948 | |||
| 949 | if (!(TIFM_SOCK_STATE_OCCUPIED | ||
| 950 | & readl(sock->addr + SOCK_PRESENT_STATE))) { | ||
| 951 | printk(KERN_WARNING "%s : card gone, unexpectedly\n", | ||
| 952 | sock->dev.bus_id); | ||
| 953 | return rc; | ||
| 954 | } | ||
| 955 | |||
| 956 | mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev); | ||
| 957 | if (!mmc) | ||
| 958 | return -ENOMEM; | ||
| 959 | |||
| 960 | host = mmc_priv(mmc); | ||
| 961 | host->no_dma = no_dma; | ||
| 962 | tifm_set_drvdata(sock, mmc); | ||
| 963 | host->dev = sock; | ||
| 964 | host->timeout_jiffies = msecs_to_jiffies(1000); | ||
| 965 | |||
| 966 | tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd, | ||
| 967 | (unsigned long)host); | ||
| 968 | setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); | ||
| 969 | |||
| 970 | mmc->ops = &tifm_sd_ops; | ||
| 971 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
| 972 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; | ||
| 973 | mmc->f_min = 20000000 / 60; | ||
| 974 | mmc->f_max = 24000000; | ||
| 975 | |||
| 976 | mmc->max_blk_count = 2048; | ||
| 977 | mmc->max_hw_segs = mmc->max_blk_count; | ||
| 978 | mmc->max_blk_size = min(TIFM_MMCSD_MAX_BLOCK_SIZE, PAGE_SIZE); | ||
| 979 | mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size; | ||
| 980 | mmc->max_req_size = mmc->max_seg_size; | ||
| 981 | mmc->max_phys_segs = mmc->max_hw_segs; | ||
| 982 | |||
| 983 | sock->card_event = tifm_sd_card_event; | ||
| 984 | sock->data_event = tifm_sd_data_event; | ||
| 985 | rc = tifm_sd_initialize_host(host); | ||
| 986 | |||
| 987 | if (!rc) | ||
| 988 | rc = mmc_add_host(mmc); | ||
| 989 | if (!rc) | ||
| 990 | return 0; | ||
| 991 | |||
| 992 | mmc_free_host(mmc); | ||
| 993 | return rc; | ||
| 994 | } | ||
| 995 | |||
| 996 | static void tifm_sd_remove(struct tifm_dev *sock) | ||
| 997 | { | ||
| 998 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 999 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 1000 | unsigned long flags; | ||
| 1001 | |||
| 1002 | spin_lock_irqsave(&sock->lock, flags); | ||
| 1003 | host->eject = 1; | ||
| 1004 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 1005 | mmiowb(); | ||
| 1006 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 1007 | |||
| 1008 | tasklet_kill(&host->finish_tasklet); | ||
| 1009 | |||
| 1010 | spin_lock_irqsave(&sock->lock, flags); | ||
| 1011 | if (host->req) { | ||
| 1012 | writel(TIFM_FIFO_INT_SETALL, | ||
| 1013 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
| 1014 | writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
| 1015 | host->req->cmd->error = MMC_ERR_TIMEOUT; | ||
| 1016 | if (host->req->stop) | ||
| 1017 | host->req->stop->error = MMC_ERR_TIMEOUT; | ||
| 1018 | tasklet_schedule(&host->finish_tasklet); | ||
| 1019 | } | ||
| 1020 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 1021 | mmc_remove_host(mmc); | ||
| 1022 | dev_dbg(&sock->dev, "after remove\n"); | ||
| 1023 | |||
| 1024 | /* The meaning of the bit majority in this constant is unknown. */ | ||
| 1025 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
| 1026 | sock->addr + SOCK_CONTROL); | ||
| 1027 | |||
| 1028 | mmc_free_host(mmc); | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | #ifdef CONFIG_PM | ||
| 1032 | |||
| 1033 | static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state) | ||
| 1034 | { | ||
| 1035 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 1036 | int rc; | ||
| 1037 | |||
| 1038 | rc = mmc_suspend_host(mmc, state); | ||
| 1039 | /* The meaning of the bit majority in this constant is unknown. */ | ||
| 1040 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
| 1041 | sock->addr + SOCK_CONTROL); | ||
| 1042 | return rc; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | static int tifm_sd_resume(struct tifm_dev *sock) | ||
| 1046 | { | ||
| 1047 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 1048 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 1049 | int rc; | ||
| 1050 | |||
| 1051 | rc = tifm_sd_initialize_host(host); | ||
| 1052 | dev_dbg(&sock->dev, "resume initialize %d\n", rc); | ||
| 1053 | |||
| 1054 | if (rc) | ||
| 1055 | host->eject = 1; | ||
| 1056 | else | ||
| 1057 | rc = mmc_resume_host(mmc); | ||
| 1058 | |||
| 1059 | return rc; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | #else | ||
| 1063 | |||
| 1064 | #define tifm_sd_suspend NULL | ||
| 1065 | #define tifm_sd_resume NULL | ||
| 1066 | |||
| 1067 | #endif /* CONFIG_PM */ | ||
| 1068 | |||
| 1069 | static struct tifm_device_id tifm_sd_id_tbl[] = { | ||
| 1070 | { TIFM_TYPE_SD }, { } | ||
| 1071 | }; | ||
| 1072 | |||
| 1073 | static struct tifm_driver tifm_sd_driver = { | ||
| 1074 | .driver = { | ||
| 1075 | .name = DRIVER_NAME, | ||
| 1076 | .owner = THIS_MODULE | ||
| 1077 | }, | ||
| 1078 | .id_table = tifm_sd_id_tbl, | ||
| 1079 | .probe = tifm_sd_probe, | ||
| 1080 | .remove = tifm_sd_remove, | ||
| 1081 | .suspend = tifm_sd_suspend, | ||
| 1082 | .resume = tifm_sd_resume | ||
| 1083 | }; | ||
| 1084 | |||
| 1085 | static int __init tifm_sd_init(void) | ||
| 1086 | { | ||
| 1087 | return tifm_register_driver(&tifm_sd_driver); | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | static void __exit tifm_sd_exit(void) | ||
| 1091 | { | ||
| 1092 | tifm_unregister_driver(&tifm_sd_driver); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | MODULE_AUTHOR("Alex Dubov"); | ||
| 1096 | MODULE_DESCRIPTION("TI FlashMedia SD driver"); | ||
| 1097 | MODULE_LICENSE("GPL"); | ||
| 1098 | MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl); | ||
| 1099 | MODULE_VERSION(DRIVER_VERSION); | ||
| 1100 | |||
| 1101 | module_init(tifm_sd_init); | ||
| 1102 | module_exit(tifm_sd_exit); | ||
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/host/wbsd.c index 05ccfc43168f..867ca6a69298 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver | 2 | * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2004-2006 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| @@ -33,7 +33,6 @@ | |||
| 33 | #include <linux/pnp.h> | 33 | #include <linux/pnp.h> |
| 34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
| 35 | #include <linux/mmc/host.h> | 35 | #include <linux/mmc/host.h> |
| 36 | #include <linux/mmc/protocol.h> | ||
| 37 | 36 | ||
| 38 | #include <asm/io.h> | 37 | #include <asm/io.h> |
| 39 | #include <asm/dma.h> | 38 | #include <asm/dma.h> |
| @@ -178,9 +177,8 @@ static void wbsd_init_device(struct wbsd_host *host) | |||
| 178 | ier = 0; | 177 | ier = 0; |
| 179 | ier |= WBSD_EINT_CARD; | 178 | ier |= WBSD_EINT_CARD; |
| 180 | ier |= WBSD_EINT_FIFO_THRE; | 179 | ier |= WBSD_EINT_FIFO_THRE; |
| 181 | ier |= WBSD_EINT_CCRC; | ||
| 182 | ier |= WBSD_EINT_TIMEOUT; | ||
| 183 | ier |= WBSD_EINT_CRC; | 180 | ier |= WBSD_EINT_CRC; |
| 181 | ier |= WBSD_EINT_TIMEOUT; | ||
| 184 | ier |= WBSD_EINT_TC; | 182 | ier |= WBSD_EINT_TC; |
| 185 | 183 | ||
| 186 | outb(ier, host->base + WBSD_EIR); | 184 | outb(ier, host->base + WBSD_EIR); |
| @@ -278,90 +276,36 @@ static inline char *wbsd_sg_to_buffer(struct wbsd_host *host) | |||
| 278 | 276 | ||
| 279 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) | 277 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) |
| 280 | { | 278 | { |
| 281 | unsigned int len, i, size; | 279 | unsigned int len, i; |
| 282 | struct scatterlist *sg; | 280 | struct scatterlist *sg; |
| 283 | char *dmabuf = host->dma_buffer; | 281 | char *dmabuf = host->dma_buffer; |
| 284 | char *sgbuf; | 282 | char *sgbuf; |
| 285 | 283 | ||
| 286 | size = host->size; | ||
| 287 | |||
| 288 | sg = data->sg; | 284 | sg = data->sg; |
| 289 | len = data->sg_len; | 285 | len = data->sg_len; |
| 290 | 286 | ||
| 291 | /* | ||
| 292 | * Just loop through all entries. Size might not | ||
| 293 | * be the entire list though so make sure that | ||
| 294 | * we do not transfer too much. | ||
| 295 | */ | ||
| 296 | for (i = 0; i < len; i++) { | 287 | for (i = 0; i < len; i++) { |
| 297 | sgbuf = page_address(sg[i].page) + sg[i].offset; | 288 | sgbuf = page_address(sg[i].page) + sg[i].offset; |
| 298 | if (size < sg[i].length) | 289 | memcpy(dmabuf, sgbuf, sg[i].length); |
| 299 | memcpy(dmabuf, sgbuf, size); | ||
| 300 | else | ||
| 301 | memcpy(dmabuf, sgbuf, sg[i].length); | ||
| 302 | dmabuf += sg[i].length; | 290 | dmabuf += sg[i].length; |
| 303 | |||
| 304 | if (size < sg[i].length) | ||
| 305 | size = 0; | ||
| 306 | else | ||
| 307 | size -= sg[i].length; | ||
| 308 | |||
| 309 | if (size == 0) | ||
| 310 | break; | ||
| 311 | } | 291 | } |
| 312 | |||
| 313 | /* | ||
| 314 | * Check that we didn't get a request to transfer | ||
| 315 | * more data than can fit into the SG list. | ||
| 316 | */ | ||
| 317 | |||
| 318 | BUG_ON(size != 0); | ||
| 319 | |||
| 320 | host->size -= size; | ||
| 321 | } | 292 | } |
| 322 | 293 | ||
| 323 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) | 294 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) |
| 324 | { | 295 | { |
| 325 | unsigned int len, i, size; | 296 | unsigned int len, i; |
| 326 | struct scatterlist *sg; | 297 | struct scatterlist *sg; |
| 327 | char *dmabuf = host->dma_buffer; | 298 | char *dmabuf = host->dma_buffer; |
| 328 | char *sgbuf; | 299 | char *sgbuf; |
| 329 | 300 | ||
| 330 | size = host->size; | ||
| 331 | |||
| 332 | sg = data->sg; | 301 | sg = data->sg; |
| 333 | len = data->sg_len; | 302 | len = data->sg_len; |
| 334 | 303 | ||
| 335 | /* | ||
| 336 | * Just loop through all entries. Size might not | ||
| 337 | * be the entire list though so make sure that | ||
| 338 | * we do not transfer too much. | ||
| 339 | */ | ||
| 340 | for (i = 0; i < len; i++) { | 304 | for (i = 0; i < len; i++) { |
| 341 | sgbuf = page_address(sg[i].page) + sg[i].offset; | 305 | sgbuf = page_address(sg[i].page) + sg[i].offset; |
| 342 | if (size < sg[i].length) | 306 | memcpy(sgbuf, dmabuf, sg[i].length); |
| 343 | memcpy(sgbuf, dmabuf, size); | ||
| 344 | else | ||
| 345 | memcpy(sgbuf, dmabuf, sg[i].length); | ||
| 346 | dmabuf += sg[i].length; | 307 | dmabuf += sg[i].length; |
| 347 | |||
| 348 | if (size < sg[i].length) | ||
| 349 | size = 0; | ||
| 350 | else | ||
| 351 | size -= sg[i].length; | ||
| 352 | |||
| 353 | if (size == 0) | ||
| 354 | break; | ||
| 355 | } | 308 | } |
| 356 | |||
| 357 | /* | ||
| 358 | * Check that we didn't get a request to transfer | ||
| 359 | * more data than can fit into the SG list. | ||
| 360 | */ | ||
| 361 | |||
| 362 | BUG_ON(size != 0); | ||
| 363 | |||
| 364 | host->size -= size; | ||
| 365 | } | 309 | } |
| 366 | 310 | ||
| 367 | /* | 311 | /* |
| @@ -484,7 +428,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
| 484 | /* | 428 | /* |
| 485 | * Handle excessive data. | 429 | * Handle excessive data. |
| 486 | */ | 430 | */ |
| 487 | if (data->bytes_xfered == host->size) | 431 | if (host->num_sg == 0) |
| 488 | return; | 432 | return; |
| 489 | 433 | ||
| 490 | buffer = wbsd_sg_to_buffer(host) + host->offset; | 434 | buffer = wbsd_sg_to_buffer(host) + host->offset; |
| @@ -514,31 +458,14 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
| 514 | data->bytes_xfered++; | 458 | data->bytes_xfered++; |
| 515 | 459 | ||
| 516 | /* | 460 | /* |
| 517 | * Transfer done? | ||
| 518 | */ | ||
| 519 | if (data->bytes_xfered == host->size) | ||
| 520 | return; | ||
| 521 | |||
| 522 | /* | ||
| 523 | * End of scatter list entry? | 461 | * End of scatter list entry? |
| 524 | */ | 462 | */ |
| 525 | if (host->remain == 0) { | 463 | if (host->remain == 0) { |
| 526 | /* | 464 | /* |
| 527 | * Get next entry. Check if last. | 465 | * Get next entry. Check if last. |
| 528 | */ | 466 | */ |
| 529 | if (!wbsd_next_sg(host)) { | 467 | if (!wbsd_next_sg(host)) |
| 530 | /* | ||
| 531 | * We should never reach this point. | ||
| 532 | * It means that we're trying to | ||
| 533 | * transfer more blocks than can fit | ||
| 534 | * into the scatter list. | ||
| 535 | */ | ||
| 536 | BUG_ON(1); | ||
| 537 | |||
| 538 | host->size = data->bytes_xfered; | ||
| 539 | |||
| 540 | return; | 468 | return; |
| 541 | } | ||
| 542 | 469 | ||
| 543 | buffer = wbsd_sg_to_buffer(host); | 470 | buffer = wbsd_sg_to_buffer(host); |
| 544 | } | 471 | } |
| @@ -550,7 +477,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
| 550 | * hardware problem. The chip doesn't trigger | 477 | * hardware problem. The chip doesn't trigger |
| 551 | * FIFO threshold interrupts properly. | 478 | * FIFO threshold interrupts properly. |
| 552 | */ | 479 | */ |
| 553 | if ((host->size - data->bytes_xfered) < 16) | 480 | if ((data->blocks * data->blksz - data->bytes_xfered) < 16) |
| 554 | tasklet_schedule(&host->fifo_tasklet); | 481 | tasklet_schedule(&host->fifo_tasklet); |
| 555 | } | 482 | } |
| 556 | 483 | ||
| @@ -564,7 +491,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
| 564 | * Check that we aren't being called after the | 491 | * Check that we aren't being called after the |
| 565 | * entire buffer has been transfered. | 492 | * entire buffer has been transfered. |
| 566 | */ | 493 | */ |
| 567 | if (data->bytes_xfered == host->size) | 494 | if (host->num_sg == 0) |
| 568 | return; | 495 | return; |
| 569 | 496 | ||
| 570 | buffer = wbsd_sg_to_buffer(host) + host->offset; | 497 | buffer = wbsd_sg_to_buffer(host) + host->offset; |
| @@ -594,31 +521,14 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
| 594 | data->bytes_xfered++; | 521 | data->bytes_xfered++; |
| 595 | 522 | ||
| 596 | /* | 523 | /* |
| 597 | * Transfer done? | ||
| 598 | */ | ||
| 599 | if (data->bytes_xfered == host->size) | ||
| 600 | return; | ||
| 601 | |||
| 602 | /* | ||
| 603 | * End of scatter list entry? | 524 | * End of scatter list entry? |
| 604 | */ | 525 | */ |
| 605 | if (host->remain == 0) { | 526 | if (host->remain == 0) { |
| 606 | /* | 527 | /* |
| 607 | * Get next entry. Check if last. | 528 | * Get next entry. Check if last. |
| 608 | */ | 529 | */ |
| 609 | if (!wbsd_next_sg(host)) { | 530 | if (!wbsd_next_sg(host)) |
| 610 | /* | ||
| 611 | * We should never reach this point. | ||
| 612 | * It means that we're trying to | ||
| 613 | * transfer more blocks than can fit | ||
| 614 | * into the scatter list. | ||
| 615 | */ | ||
| 616 | BUG_ON(1); | ||
| 617 | |||
| 618 | host->size = data->bytes_xfered; | ||
| 619 | |||
| 620 | return; | 531 | return; |
| 621 | } | ||
| 622 | 532 | ||
| 623 | buffer = wbsd_sg_to_buffer(host); | 533 | buffer = wbsd_sg_to_buffer(host); |
| 624 | } | 534 | } |
| @@ -638,6 +548,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 638 | u16 blksize; | 548 | u16 blksize; |
| 639 | u8 setup; | 549 | u8 setup; |
| 640 | unsigned long dmaflags; | 550 | unsigned long dmaflags; |
| 551 | unsigned int size; | ||
| 641 | 552 | ||
| 642 | DBGF("blksz %04x blks %04x flags %08x\n", | 553 | DBGF("blksz %04x blks %04x flags %08x\n", |
| 643 | data->blksz, data->blocks, data->flags); | 554 | data->blksz, data->blocks, data->flags); |
| @@ -647,7 +558,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 647 | /* | 558 | /* |
| 648 | * Calculate size. | 559 | * Calculate size. |
| 649 | */ | 560 | */ |
| 650 | host->size = data->blocks * data->blksz; | 561 | size = data->blocks * data->blksz; |
| 651 | 562 | ||
| 652 | /* | 563 | /* |
| 653 | * Check timeout values for overflow. | 564 | * Check timeout values for overflow. |
| @@ -705,8 +616,8 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 705 | /* | 616 | /* |
| 706 | * The buffer for DMA is only 64 kB. | 617 | * The buffer for DMA is only 64 kB. |
| 707 | */ | 618 | */ |
| 708 | BUG_ON(host->size > 0x10000); | 619 | BUG_ON(size > 0x10000); |
| 709 | if (host->size > 0x10000) { | 620 | if (size > 0x10000) { |
| 710 | data->error = MMC_ERR_INVALID; | 621 | data->error = MMC_ERR_INVALID; |
| 711 | return; | 622 | return; |
| 712 | } | 623 | } |
| @@ -729,7 +640,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 729 | else | 640 | else |
| 730 | set_dma_mode(host->dma, DMA_MODE_WRITE & ~0x40); | 641 | set_dma_mode(host->dma, DMA_MODE_WRITE & ~0x40); |
| 731 | set_dma_addr(host->dma, host->dma_addr); | 642 | set_dma_addr(host->dma, host->dma_addr); |
| 732 | set_dma_count(host->dma, host->size); | 643 | set_dma_count(host->dma, size); |
| 733 | 644 | ||
| 734 | enable_dma(host->dma); | 645 | enable_dma(host->dma); |
| 735 | release_dma_lock(dmaflags); | 646 | release_dma_lock(dmaflags); |
| @@ -812,6 +723,10 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 812 | count = get_dma_residue(host->dma); | 723 | count = get_dma_residue(host->dma); |
| 813 | release_dma_lock(dmaflags); | 724 | release_dma_lock(dmaflags); |
| 814 | 725 | ||
| 726 | data->bytes_xfered = host->mrq->data->blocks * | ||
| 727 | host->mrq->data->blksz - count; | ||
| 728 | data->bytes_xfered -= data->bytes_xfered % data->blksz; | ||
| 729 | |||
| 815 | /* | 730 | /* |
| 816 | * Any leftover data? | 731 | * Any leftover data? |
| 817 | */ | 732 | */ |
| @@ -820,7 +735,8 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 820 | "%d bytes left.\n", | 735 | "%d bytes left.\n", |
| 821 | mmc_hostname(host->mmc), count); | 736 | mmc_hostname(host->mmc), count); |
| 822 | 737 | ||
| 823 | data->error = MMC_ERR_FAILED; | 738 | if (data->error == MMC_ERR_NONE) |
| 739 | data->error = MMC_ERR_FAILED; | ||
| 824 | } else { | 740 | } else { |
| 825 | /* | 741 | /* |
| 826 | * Transfer data from DMA buffer to | 742 | * Transfer data from DMA buffer to |
| @@ -828,8 +744,11 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 828 | */ | 744 | */ |
| 829 | if (data->flags & MMC_DATA_READ) | 745 | if (data->flags & MMC_DATA_READ) |
| 830 | wbsd_dma_to_sg(host, data); | 746 | wbsd_dma_to_sg(host, data); |
| 747 | } | ||
| 831 | 748 | ||
| 832 | data->bytes_xfered = host->size; | 749 | if (data->error != MMC_ERR_NONE) { |
| 750 | if (data->bytes_xfered) | ||
| 751 | data->bytes_xfered -= data->blksz; | ||
| 833 | } | 752 | } |
| 834 | } | 753 | } |
| 835 | 754 | ||
| @@ -869,24 +788,7 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 869 | goto done; | 788 | goto done; |
| 870 | } | 789 | } |
| 871 | 790 | ||
| 872 | /* | ||
| 873 | * Does the request include data? | ||
| 874 | */ | ||
| 875 | if (cmd->data) { | 791 | if (cmd->data) { |
| 876 | wbsd_prepare_data(host, cmd->data); | ||
| 877 | |||
| 878 | if (cmd->data->error != MMC_ERR_NONE) | ||
| 879 | goto done; | ||
| 880 | } | ||
| 881 | |||
| 882 | wbsd_send_command(host, cmd); | ||
| 883 | |||
| 884 | /* | ||
| 885 | * If this is a data transfer the request | ||
| 886 | * will be finished after the data has | ||
| 887 | * transfered. | ||
| 888 | */ | ||
| 889 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) { | ||
| 890 | /* | 792 | /* |
| 891 | * The hardware is so delightfully stupid that it has a list | 793 | * The hardware is so delightfully stupid that it has a list |
| 892 | * of "data" commands. If a command isn't on this list, it'll | 794 | * of "data" commands. If a command isn't on this list, it'll |
| @@ -918,14 +820,30 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 918 | "supported by this controller.\n", | 820 | "supported by this controller.\n", |
| 919 | mmc_hostname(host->mmc), cmd->opcode); | 821 | mmc_hostname(host->mmc), cmd->opcode); |
| 920 | #endif | 822 | #endif |
| 921 | cmd->data->error = MMC_ERR_INVALID; | 823 | cmd->error = MMC_ERR_INVALID; |
| 922 | |||
| 923 | if (cmd->data->stop) | ||
| 924 | wbsd_send_command(host, cmd->data->stop); | ||
| 925 | 824 | ||
| 926 | goto done; | 825 | goto done; |
| 927 | }; | 826 | }; |
| 827 | } | ||
| 828 | |||
| 829 | /* | ||
| 830 | * Does the request include data? | ||
| 831 | */ | ||
| 832 | if (cmd->data) { | ||
| 833 | wbsd_prepare_data(host, cmd->data); | ||
| 834 | |||
| 835 | if (cmd->data->error != MMC_ERR_NONE) | ||
| 836 | goto done; | ||
| 837 | } | ||
| 838 | |||
| 839 | wbsd_send_command(host, cmd); | ||
| 928 | 840 | ||
| 841 | /* | ||
| 842 | * If this is a data transfer the request | ||
| 843 | * will be finished after the data has | ||
| 844 | * transfered. | ||
| 845 | */ | ||
| 846 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) { | ||
| 929 | /* | 847 | /* |
| 930 | * Dirty fix for hardware bug. | 848 | * Dirty fix for hardware bug. |
| 931 | */ | 849 | */ |
| @@ -1167,7 +1085,7 @@ static void wbsd_tasklet_fifo(unsigned long param) | |||
| 1167 | /* | 1085 | /* |
| 1168 | * Done? | 1086 | * Done? |
| 1169 | */ | 1087 | */ |
| 1170 | if (host->size == data->bytes_xfered) { | 1088 | if (host->num_sg == 0) { |
| 1171 | wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); | 1089 | wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); |
| 1172 | tasklet_schedule(&host->finish_tasklet); | 1090 | tasklet_schedule(&host->finish_tasklet); |
| 1173 | } | 1091 | } |
| @@ -1245,30 +1163,6 @@ end: | |||
| 1245 | spin_unlock(&host->lock); | 1163 | spin_unlock(&host->lock); |
| 1246 | } | 1164 | } |
| 1247 | 1165 | ||
| 1248 | static void wbsd_tasklet_block(unsigned long param) | ||
| 1249 | { | ||
| 1250 | struct wbsd_host *host = (struct wbsd_host *)param; | ||
| 1251 | struct mmc_data *data; | ||
| 1252 | |||
| 1253 | spin_lock(&host->lock); | ||
| 1254 | |||
| 1255 | if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != | ||
| 1256 | WBSD_CRC_OK) { | ||
| 1257 | data = wbsd_get_data(host); | ||
| 1258 | if (!data) | ||
| 1259 | goto end; | ||
| 1260 | |||
| 1261 | DBGF("CRC error\n"); | ||
| 1262 | |||
| 1263 | data->error = MMC_ERR_BADCRC; | ||
| 1264 | |||
| 1265 | tasklet_schedule(&host->finish_tasklet); | ||
| 1266 | } | ||
| 1267 | |||
| 1268 | end: | ||
| 1269 | spin_unlock(&host->lock); | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | /* | 1166 | /* |
| 1273 | * Interrupt handling | 1167 | * Interrupt handling |
| 1274 | */ | 1168 | */ |
| @@ -1299,8 +1193,6 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id) | |||
| 1299 | tasklet_hi_schedule(&host->crc_tasklet); | 1193 | tasklet_hi_schedule(&host->crc_tasklet); |
| 1300 | if (isr & WBSD_INT_TIMEOUT) | 1194 | if (isr & WBSD_INT_TIMEOUT) |
| 1301 | tasklet_hi_schedule(&host->timeout_tasklet); | 1195 | tasklet_hi_schedule(&host->timeout_tasklet); |
| 1302 | if (isr & WBSD_INT_BUSYEND) | ||
| 1303 | tasklet_hi_schedule(&host->block_tasklet); | ||
| 1304 | if (isr & WBSD_INT_TC) | 1196 | if (isr & WBSD_INT_TC) |
| 1305 | tasklet_schedule(&host->finish_tasklet); | 1197 | tasklet_schedule(&host->finish_tasklet); |
| 1306 | 1198 | ||
| @@ -1601,8 +1493,6 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) | |||
| 1601 | (unsigned long)host); | 1493 | (unsigned long)host); |
| 1602 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, | 1494 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, |
| 1603 | (unsigned long)host); | 1495 | (unsigned long)host); |
| 1604 | tasklet_init(&host->block_tasklet, wbsd_tasklet_block, | ||
| 1605 | (unsigned long)host); | ||
| 1606 | 1496 | ||
| 1607 | return 0; | 1497 | return 0; |
| 1608 | } | 1498 | } |
| @@ -1621,7 +1511,6 @@ static void __devexit wbsd_release_irq(struct wbsd_host *host) | |||
| 1621 | tasklet_kill(&host->crc_tasklet); | 1511 | tasklet_kill(&host->crc_tasklet); |
| 1622 | tasklet_kill(&host->timeout_tasklet); | 1512 | tasklet_kill(&host->timeout_tasklet); |
| 1623 | tasklet_kill(&host->finish_tasklet); | 1513 | tasklet_kill(&host->finish_tasklet); |
| 1624 | tasklet_kill(&host->block_tasklet); | ||
| 1625 | } | 1514 | } |
| 1626 | 1515 | ||
| 1627 | /* | 1516 | /* |
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/host/wbsd.h index d06718b0e2ab..873bda1e59b4 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/host/wbsd.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mmc/wbsd.h - Winbond W83L51xD SD/MMC driver | 2 | * linux/drivers/mmc/wbsd.h - Winbond W83L51xD SD/MMC driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2004-2005 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| @@ -46,10 +46,10 @@ | |||
| 46 | 46 | ||
| 47 | #define WBSD_EINT_CARD 0x40 | 47 | #define WBSD_EINT_CARD 0x40 |
| 48 | #define WBSD_EINT_FIFO_THRE 0x20 | 48 | #define WBSD_EINT_FIFO_THRE 0x20 |
| 49 | #define WBSD_EINT_CCRC 0x10 | 49 | #define WBSD_EINT_CRC 0x10 |
| 50 | #define WBSD_EINT_TIMEOUT 0x08 | 50 | #define WBSD_EINT_TIMEOUT 0x08 |
| 51 | #define WBSD_EINT_PROGEND 0x04 | 51 | #define WBSD_EINT_PROGEND 0x04 |
| 52 | #define WBSD_EINT_CRC 0x02 | 52 | #define WBSD_EINT_BUSYEND 0x02 |
| 53 | #define WBSD_EINT_TC 0x01 | 53 | #define WBSD_EINT_TC 0x01 |
| 54 | 54 | ||
| 55 | #define WBSD_INT_PENDING 0x80 | 55 | #define WBSD_INT_PENDING 0x80 |
| @@ -158,8 +158,6 @@ struct wbsd_host | |||
| 158 | unsigned int offset; /* Offset into current entry */ | 158 | unsigned int offset; /* Offset into current entry */ |
| 159 | unsigned int remain; /* Data left in curren entry */ | 159 | unsigned int remain; /* Data left in curren entry */ |
| 160 | 160 | ||
| 161 | int size; /* Total size of transfer */ | ||
| 162 | |||
| 163 | char* dma_buffer; /* ISA DMA buffer */ | 161 | char* dma_buffer; /* ISA DMA buffer */ |
| 164 | dma_addr_t dma_addr; /* Physical address for same */ | 162 | dma_addr_t dma_addr; /* Physical address for same */ |
| 165 | 163 | ||
| @@ -182,7 +180,6 @@ struct wbsd_host | |||
| 182 | struct tasklet_struct crc_tasklet; | 180 | struct tasklet_struct crc_tasklet; |
| 183 | struct tasklet_struct timeout_tasklet; | 181 | struct tasklet_struct timeout_tasklet; |
| 184 | struct tasklet_struct finish_tasklet; | 182 | struct tasklet_struct finish_tasklet; |
| 185 | struct tasklet_struct block_tasklet; | ||
| 186 | 183 | ||
| 187 | struct timer_list ignore_timer; /* Ignore detection timer */ | 184 | struct timer_list ignore_timer; /* Ignore detection timer */ |
| 188 | }; | 185 | }; |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c deleted file mode 100644 index 4a73e8b2428d..000000000000 --- a/drivers/mmc/mmc.c +++ /dev/null | |||
| @@ -1,1724 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/mmc/mmc.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
| 5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
| 6 | * SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved. | ||
| 7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/interrupt.h> | ||
| 16 | #include <linux/completion.h> | ||
| 17 | #include <linux/device.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/pagemap.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | #include <asm/scatterlist.h> | ||
| 22 | #include <linux/scatterlist.h> | ||
| 23 | |||
| 24 | #include <linux/mmc/card.h> | ||
| 25 | #include <linux/mmc/host.h> | ||
| 26 | #include <linux/mmc/protocol.h> | ||
| 27 | |||
| 28 | #include "mmc.h" | ||
| 29 | |||
| 30 | #define CMD_RETRIES 3 | ||
| 31 | |||
| 32 | /* | ||
| 33 | * OCR Bit positions to 10s of Vdd mV. | ||
| 34 | */ | ||
| 35 | static const unsigned short mmc_ocr_bit_to_vdd[] = { | ||
| 36 | 150, 155, 160, 165, 170, 180, 190, 200, | ||
| 37 | 210, 220, 230, 240, 250, 260, 270, 280, | ||
| 38 | 290, 300, 310, 320, 330, 340, 350, 360 | ||
| 39 | }; | ||
| 40 | |||
| 41 | static const unsigned int tran_exp[] = { | ||
| 42 | 10000, 100000, 1000000, 10000000, | ||
| 43 | 0, 0, 0, 0 | ||
| 44 | }; | ||
| 45 | |||
| 46 | static const unsigned char tran_mant[] = { | ||
| 47 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
| 48 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static const unsigned int tacc_exp[] = { | ||
| 52 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||
| 53 | }; | ||
| 54 | |||
| 55 | static const unsigned int tacc_mant[] = { | ||
| 56 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
| 57 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
| 58 | }; | ||
| 59 | |||
| 60 | |||
| 61 | /** | ||
| 62 | * mmc_request_done - finish processing an MMC request | ||
| 63 | * @host: MMC host which completed request | ||
| 64 | * @mrq: MMC request which request | ||
| 65 | * | ||
| 66 | * MMC drivers should call this function when they have completed | ||
| 67 | * their processing of a request. | ||
| 68 | */ | ||
| 69 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | ||
| 70 | { | ||
| 71 | struct mmc_command *cmd = mrq->cmd; | ||
| 72 | int err = cmd->error; | ||
| 73 | |||
| 74 | pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", | ||
| 75 | mmc_hostname(host), cmd->opcode, err, | ||
| 76 | mrq->data ? mrq->data->error : 0, | ||
| 77 | mrq->stop ? mrq->stop->error : 0, | ||
| 78 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | ||
| 79 | |||
| 80 | if (err && cmd->retries) { | ||
| 81 | cmd->retries--; | ||
| 82 | cmd->error = 0; | ||
| 83 | host->ops->request(host, mrq); | ||
| 84 | } else if (mrq->done) { | ||
| 85 | mrq->done(mrq); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | EXPORT_SYMBOL(mmc_request_done); | ||
| 90 | |||
| 91 | /** | ||
| 92 | * mmc_start_request - start a command on a host | ||
| 93 | * @host: MMC host to start command on | ||
| 94 | * @mrq: MMC request to start | ||
| 95 | * | ||
| 96 | * Queue a command on the specified host. We expect the | ||
| 97 | * caller to be holding the host lock with interrupts disabled. | ||
| 98 | */ | ||
| 99 | void | ||
| 100 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | ||
| 101 | { | ||
| 102 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", | ||
| 103 | mmc_hostname(host), mrq->cmd->opcode, | ||
| 104 | mrq->cmd->arg, mrq->cmd->flags); | ||
| 105 | |||
| 106 | WARN_ON(!host->claimed); | ||
| 107 | |||
| 108 | mrq->cmd->error = 0; | ||
| 109 | mrq->cmd->mrq = mrq; | ||
| 110 | if (mrq->data) { | ||
| 111 | BUG_ON(mrq->data->blksz > host->max_blk_size); | ||
| 112 | BUG_ON(mrq->data->blocks > host->max_blk_count); | ||
| 113 | BUG_ON(mrq->data->blocks * mrq->data->blksz > | ||
| 114 | host->max_req_size); | ||
| 115 | |||
| 116 | mrq->cmd->data = mrq->data; | ||
| 117 | mrq->data->error = 0; | ||
| 118 | mrq->data->mrq = mrq; | ||
| 119 | if (mrq->stop) { | ||
| 120 | mrq->data->stop = mrq->stop; | ||
| 121 | mrq->stop->error = 0; | ||
| 122 | mrq->stop->mrq = mrq; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | host->ops->request(host, mrq); | ||
| 126 | } | ||
| 127 | |||
| 128 | EXPORT_SYMBOL(mmc_start_request); | ||
| 129 | |||
| 130 | static void mmc_wait_done(struct mmc_request *mrq) | ||
| 131 | { | ||
| 132 | complete(mrq->done_data); | ||
| 133 | } | ||
| 134 | |||
| 135 | int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | ||
| 136 | { | ||
| 137 | DECLARE_COMPLETION_ONSTACK(complete); | ||
| 138 | |||
| 139 | mrq->done_data = &complete; | ||
| 140 | mrq->done = mmc_wait_done; | ||
| 141 | |||
| 142 | mmc_start_request(host, mrq); | ||
| 143 | |||
| 144 | wait_for_completion(&complete); | ||
| 145 | |||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | EXPORT_SYMBOL(mmc_wait_for_req); | ||
| 150 | |||
| 151 | /** | ||
| 152 | * mmc_wait_for_cmd - start a command and wait for completion | ||
| 153 | * @host: MMC host to start command | ||
| 154 | * @cmd: MMC command to start | ||
| 155 | * @retries: maximum number of retries | ||
| 156 | * | ||
| 157 | * Start a new MMC command for a host, and wait for the command | ||
| 158 | * to complete. Return any error that occurred while the command | ||
| 159 | * was executing. Do not attempt to parse the response. | ||
| 160 | */ | ||
| 161 | int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) | ||
| 162 | { | ||
| 163 | struct mmc_request mrq; | ||
| 164 | |||
| 165 | BUG_ON(!host->claimed); | ||
| 166 | |||
| 167 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 168 | |||
| 169 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
| 170 | cmd->retries = retries; | ||
| 171 | |||
| 172 | mrq.cmd = cmd; | ||
| 173 | cmd->data = NULL; | ||
| 174 | |||
| 175 | mmc_wait_for_req(host, &mrq); | ||
| 176 | |||
| 177 | return cmd->error; | ||
| 178 | } | ||
| 179 | |||
| 180 | EXPORT_SYMBOL(mmc_wait_for_cmd); | ||
| 181 | |||
| 182 | /** | ||
| 183 | * mmc_wait_for_app_cmd - start an application command and wait for | ||
| 184 | completion | ||
| 185 | * @host: MMC host to start command | ||
| 186 | * @rca: RCA to send MMC_APP_CMD to | ||
| 187 | * @cmd: MMC command to start | ||
| 188 | * @retries: maximum number of retries | ||
| 189 | * | ||
| 190 | * Sends a MMC_APP_CMD, checks the card response, sends the command | ||
| 191 | * in the parameter and waits for it to complete. Return any error | ||
| 192 | * that occurred while the command was executing. Do not attempt to | ||
| 193 | * parse the response. | ||
| 194 | */ | ||
| 195 | int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, | ||
| 196 | struct mmc_command *cmd, int retries) | ||
| 197 | { | ||
| 198 | struct mmc_request mrq; | ||
| 199 | struct mmc_command appcmd; | ||
| 200 | |||
| 201 | int i, err; | ||
| 202 | |||
| 203 | BUG_ON(!host->claimed); | ||
| 204 | BUG_ON(retries < 0); | ||
| 205 | |||
| 206 | err = MMC_ERR_INVALID; | ||
| 207 | |||
| 208 | /* | ||
| 209 | * We have to resend MMC_APP_CMD for each attempt so | ||
| 210 | * we cannot use the retries field in mmc_command. | ||
| 211 | */ | ||
| 212 | for (i = 0;i <= retries;i++) { | ||
| 213 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 214 | |||
| 215 | appcmd.opcode = MMC_APP_CMD; | ||
| 216 | appcmd.arg = rca << 16; | ||
| 217 | appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 218 | appcmd.retries = 0; | ||
| 219 | memset(appcmd.resp, 0, sizeof(appcmd.resp)); | ||
| 220 | appcmd.data = NULL; | ||
| 221 | |||
| 222 | mrq.cmd = &appcmd; | ||
| 223 | appcmd.data = NULL; | ||
| 224 | |||
| 225 | mmc_wait_for_req(host, &mrq); | ||
| 226 | |||
| 227 | if (appcmd.error) { | ||
| 228 | err = appcmd.error; | ||
| 229 | continue; | ||
| 230 | } | ||
| 231 | |||
| 232 | /* Check that card supported application commands */ | ||
| 233 | if (!(appcmd.resp[0] & R1_APP_CMD)) | ||
| 234 | return MMC_ERR_FAILED; | ||
| 235 | |||
| 236 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 237 | |||
| 238 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
| 239 | cmd->retries = 0; | ||
| 240 | |||
| 241 | mrq.cmd = cmd; | ||
| 242 | cmd->data = NULL; | ||
| 243 | |||
| 244 | mmc_wait_for_req(host, &mrq); | ||
| 245 | |||
| 246 | err = cmd->error; | ||
| 247 | if (cmd->error == MMC_ERR_NONE) | ||
| 248 | break; | ||
| 249 | } | ||
| 250 | |||
| 251 | return err; | ||
| 252 | } | ||
| 253 | |||
| 254 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); | ||
| 255 | |||
| 256 | /** | ||
| 257 | * mmc_set_data_timeout - set the timeout for a data command | ||
| 258 | * @data: data phase for command | ||
| 259 | * @card: the MMC card associated with the data transfer | ||
| 260 | * @write: flag to differentiate reads from writes | ||
| 261 | */ | ||
| 262 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | ||
| 263 | int write) | ||
| 264 | { | ||
| 265 | unsigned int mult; | ||
| 266 | |||
| 267 | /* | ||
| 268 | * SD cards use a 100 multiplier rather than 10 | ||
| 269 | */ | ||
| 270 | mult = mmc_card_sd(card) ? 100 : 10; | ||
| 271 | |||
| 272 | /* | ||
| 273 | * Scale up the multiplier (and therefore the timeout) by | ||
| 274 | * the r2w factor for writes. | ||
| 275 | */ | ||
| 276 | if (write) | ||
| 277 | mult <<= card->csd.r2w_factor; | ||
| 278 | |||
| 279 | data->timeout_ns = card->csd.tacc_ns * mult; | ||
| 280 | data->timeout_clks = card->csd.tacc_clks * mult; | ||
| 281 | |||
| 282 | /* | ||
| 283 | * SD cards also have an upper limit on the timeout. | ||
| 284 | */ | ||
| 285 | if (mmc_card_sd(card)) { | ||
| 286 | unsigned int timeout_us, limit_us; | ||
| 287 | |||
| 288 | timeout_us = data->timeout_ns / 1000; | ||
| 289 | timeout_us += data->timeout_clks * 1000 / | ||
| 290 | (card->host->ios.clock / 1000); | ||
| 291 | |||
| 292 | if (write) | ||
| 293 | limit_us = 250000; | ||
| 294 | else | ||
| 295 | limit_us = 100000; | ||
| 296 | |||
| 297 | /* | ||
| 298 | * SDHC cards always use these fixed values. | ||
| 299 | */ | ||
| 300 | if (timeout_us > limit_us || mmc_card_blockaddr(card)) { | ||
| 301 | data->timeout_ns = limit_us * 1000; | ||
| 302 | data->timeout_clks = 0; | ||
| 303 | } | ||
| 304 | } | ||
| 305 | } | ||
| 306 | EXPORT_SYMBOL(mmc_set_data_timeout); | ||
| 307 | |||
| 308 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card); | ||
| 309 | |||
| 310 | /** | ||
| 311 | * __mmc_claim_host - exclusively claim a host | ||
| 312 | * @host: mmc host to claim | ||
| 313 | * @card: mmc card to claim host for | ||
| 314 | * | ||
| 315 | * Claim a host for a set of operations. If a valid card | ||
| 316 | * is passed and this wasn't the last card selected, select | ||
| 317 | * the card before returning. | ||
| 318 | * | ||
| 319 | * Note: you should use mmc_card_claim_host or mmc_claim_host. | ||
| 320 | */ | ||
| 321 | int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card) | ||
| 322 | { | ||
| 323 | DECLARE_WAITQUEUE(wait, current); | ||
| 324 | unsigned long flags; | ||
| 325 | int err = 0; | ||
| 326 | |||
| 327 | add_wait_queue(&host->wq, &wait); | ||
| 328 | spin_lock_irqsave(&host->lock, flags); | ||
| 329 | while (1) { | ||
| 330 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 331 | if (!host->claimed) | ||
| 332 | break; | ||
| 333 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 334 | schedule(); | ||
| 335 | spin_lock_irqsave(&host->lock, flags); | ||
| 336 | } | ||
| 337 | set_current_state(TASK_RUNNING); | ||
| 338 | host->claimed = 1; | ||
| 339 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 340 | remove_wait_queue(&host->wq, &wait); | ||
| 341 | |||
| 342 | if (card != (void *)-1) { | ||
| 343 | err = mmc_select_card(host, card); | ||
| 344 | if (err != MMC_ERR_NONE) | ||
| 345 | return err; | ||
| 346 | } | ||
| 347 | |||
| 348 | return err; | ||
| 349 | } | ||
| 350 | |||
| 351 | EXPORT_SYMBOL(__mmc_claim_host); | ||
| 352 | |||
| 353 | /** | ||
| 354 | * mmc_release_host - release a host | ||
| 355 | * @host: mmc host to release | ||
| 356 | * | ||
| 357 | * Release a MMC host, allowing others to claim the host | ||
| 358 | * for their operations. | ||
| 359 | */ | ||
| 360 | void mmc_release_host(struct mmc_host *host) | ||
| 361 | { | ||
| 362 | unsigned long flags; | ||
| 363 | |||
| 364 | BUG_ON(!host->claimed); | ||
| 365 | |||
| 366 | spin_lock_irqsave(&host->lock, flags); | ||
| 367 | host->claimed = 0; | ||
| 368 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 369 | |||
| 370 | wake_up(&host->wq); | ||
| 371 | } | ||
| 372 | |||
| 373 | EXPORT_SYMBOL(mmc_release_host); | ||
| 374 | |||
| 375 | static inline void mmc_set_ios(struct mmc_host *host) | ||
| 376 | { | ||
| 377 | struct mmc_ios *ios = &host->ios; | ||
| 378 | |||
| 379 | pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " | ||
| 380 | "width %u timing %u\n", | ||
| 381 | mmc_hostname(host), ios->clock, ios->bus_mode, | ||
| 382 | ios->power_mode, ios->chip_select, ios->vdd, | ||
| 383 | ios->bus_width, ios->timing); | ||
| 384 | |||
| 385 | host->ops->set_ios(host, ios); | ||
| 386 | } | ||
| 387 | |||
| 388 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | ||
| 389 | { | ||
| 390 | int err; | ||
| 391 | struct mmc_command cmd; | ||
| 392 | |||
| 393 | BUG_ON(!host->claimed); | ||
| 394 | |||
| 395 | if (host->card_selected == card) | ||
| 396 | return MMC_ERR_NONE; | ||
| 397 | |||
| 398 | host->card_selected = card; | ||
| 399 | |||
| 400 | cmd.opcode = MMC_SELECT_CARD; | ||
| 401 | cmd.arg = card->rca << 16; | ||
| 402 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 403 | |||
| 404 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 405 | if (err != MMC_ERR_NONE) | ||
| 406 | return err; | ||
| 407 | |||
| 408 | /* | ||
| 409 | * We can only change the bus width of SD cards when | ||
| 410 | * they are selected so we have to put the handling | ||
| 411 | * here. | ||
| 412 | * | ||
| 413 | * The card is in 1 bit mode by default so | ||
| 414 | * we only need to change if it supports the | ||
| 415 | * wider version. | ||
| 416 | */ | ||
| 417 | if (mmc_card_sd(card) && | ||
| 418 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
| 419 | |||
| 420 | /* | ||
| 421 | * Default bus width is 1 bit. | ||
| 422 | */ | ||
| 423 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
| 424 | |||
| 425 | if (host->caps & MMC_CAP_4_BIT_DATA) { | ||
| 426 | struct mmc_command cmd; | ||
| 427 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | ||
| 428 | cmd.arg = SD_BUS_WIDTH_4; | ||
| 429 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 430 | |||
| 431 | err = mmc_wait_for_app_cmd(host, card->rca, &cmd, | ||
| 432 | CMD_RETRIES); | ||
| 433 | if (err != MMC_ERR_NONE) | ||
| 434 | return err; | ||
| 435 | |||
| 436 | host->ios.bus_width = MMC_BUS_WIDTH_4; | ||
| 437 | } | ||
| 438 | } | ||
| 439 | |||
| 440 | mmc_set_ios(host); | ||
| 441 | |||
| 442 | return MMC_ERR_NONE; | ||
| 443 | } | ||
| 444 | |||
| 445 | /* | ||
| 446 | * Ensure that no card is selected. | ||
| 447 | */ | ||
| 448 | static void mmc_deselect_cards(struct mmc_host *host) | ||
| 449 | { | ||
| 450 | struct mmc_command cmd; | ||
| 451 | |||
| 452 | if (host->card_selected) { | ||
| 453 | host->card_selected = NULL; | ||
| 454 | |||
| 455 | cmd.opcode = MMC_SELECT_CARD; | ||
| 456 | cmd.arg = 0; | ||
| 457 | cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; | ||
| 458 | |||
| 459 | mmc_wait_for_cmd(host, &cmd, 0); | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 463 | |||
| 464 | static inline void mmc_delay(unsigned int ms) | ||
| 465 | { | ||
| 466 | if (ms < 1000 / HZ) { | ||
| 467 | cond_resched(); | ||
| 468 | mdelay(ms); | ||
| 469 | } else { | ||
| 470 | msleep(ms); | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | /* | ||
| 475 | * Mask off any voltages we don't support and select | ||
| 476 | * the lowest voltage | ||
| 477 | */ | ||
| 478 | static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | ||
| 479 | { | ||
| 480 | int bit; | ||
| 481 | |||
| 482 | ocr &= host->ocr_avail; | ||
| 483 | |||
| 484 | bit = ffs(ocr); | ||
| 485 | if (bit) { | ||
| 486 | bit -= 1; | ||
| 487 | |||
| 488 | ocr &= 3 << bit; | ||
| 489 | |||
| 490 | host->ios.vdd = bit; | ||
| 491 | mmc_set_ios(host); | ||
| 492 | } else { | ||
| 493 | ocr = 0; | ||
| 494 | } | ||
| 495 | |||
| 496 | return ocr; | ||
| 497 | } | ||
| 498 | |||
| 499 | #define UNSTUFF_BITS(resp,start,size) \ | ||
| 500 | ({ \ | ||
| 501 | const int __size = size; \ | ||
| 502 | const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ | ||
| 503 | const int __off = 3 - ((start) / 32); \ | ||
| 504 | const int __shft = (start) & 31; \ | ||
| 505 | u32 __res; \ | ||
| 506 | \ | ||
| 507 | __res = resp[__off] >> __shft; \ | ||
| 508 | if (__size + __shft > 32) \ | ||
| 509 | __res |= resp[__off-1] << ((32 - __shft) % 32); \ | ||
| 510 | __res & __mask; \ | ||
| 511 | }) | ||
| 512 | |||
| 513 | /* | ||
| 514 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | ||
| 515 | */ | ||
| 516 | static void mmc_decode_cid(struct mmc_card *card) | ||
| 517 | { | ||
| 518 | u32 *resp = card->raw_cid; | ||
| 519 | |||
| 520 | memset(&card->cid, 0, sizeof(struct mmc_cid)); | ||
| 521 | |||
| 522 | if (mmc_card_sd(card)) { | ||
| 523 | /* | ||
| 524 | * SD doesn't currently have a version field so we will | ||
| 525 | * have to assume we can parse this. | ||
| 526 | */ | ||
| 527 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
| 528 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
| 529 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
| 530 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
| 531 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
| 532 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
| 533 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
| 534 | card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4); | ||
| 535 | card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4); | ||
| 536 | card->cid.serial = UNSTUFF_BITS(resp, 24, 32); | ||
| 537 | card->cid.year = UNSTUFF_BITS(resp, 12, 8); | ||
| 538 | card->cid.month = UNSTUFF_BITS(resp, 8, 4); | ||
| 539 | |||
| 540 | card->cid.year += 2000; /* SD cards year offset */ | ||
| 541 | } else { | ||
| 542 | /* | ||
| 543 | * The selection of the format here is based upon published | ||
| 544 | * specs from sandisk and from what people have reported. | ||
| 545 | */ | ||
| 546 | switch (card->csd.mmca_vsn) { | ||
| 547 | case 0: /* MMC v1.0 - v1.2 */ | ||
| 548 | case 1: /* MMC v1.4 */ | ||
| 549 | card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); | ||
| 550 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
| 551 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
| 552 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
| 553 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
| 554 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
| 555 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
| 556 | card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); | ||
| 557 | card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); | ||
| 558 | card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); | ||
| 559 | card->cid.serial = UNSTUFF_BITS(resp, 16, 24); | ||
| 560 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
| 561 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
| 562 | break; | ||
| 563 | |||
| 564 | case 2: /* MMC v2.0 - v2.2 */ | ||
| 565 | case 3: /* MMC v3.1 - v3.3 */ | ||
| 566 | case 4: /* MMC v4 */ | ||
| 567 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
| 568 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
| 569 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
| 570 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
| 571 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
| 572 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
| 573 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
| 574 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
| 575 | card->cid.serial = UNSTUFF_BITS(resp, 16, 32); | ||
| 576 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
| 577 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
| 578 | break; | ||
| 579 | |||
| 580 | default: | ||
| 581 | printk("%s: card has unknown MMCA version %d\n", | ||
| 582 | mmc_hostname(card->host), card->csd.mmca_vsn); | ||
| 583 | mmc_card_set_bad(card); | ||
| 584 | break; | ||
| 585 | } | ||
| 586 | } | ||
| 587 | } | ||
| 588 | |||
| 589 | /* | ||
| 590 | * Given a 128-bit response, decode to our card CSD structure. | ||
| 591 | */ | ||
| 592 | static void mmc_decode_csd(struct mmc_card *card) | ||
| 593 | { | ||
| 594 | struct mmc_csd *csd = &card->csd; | ||
| 595 | unsigned int e, m, csd_struct; | ||
| 596 | u32 *resp = card->raw_csd; | ||
| 597 | |||
| 598 | if (mmc_card_sd(card)) { | ||
| 599 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
| 600 | |||
| 601 | switch (csd_struct) { | ||
| 602 | case 0: | ||
| 603 | m = UNSTUFF_BITS(resp, 115, 4); | ||
| 604 | e = UNSTUFF_BITS(resp, 112, 3); | ||
| 605 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
| 606 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
| 607 | |||
| 608 | m = UNSTUFF_BITS(resp, 99, 4); | ||
| 609 | e = UNSTUFF_BITS(resp, 96, 3); | ||
| 610 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 611 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 612 | |||
| 613 | e = UNSTUFF_BITS(resp, 47, 3); | ||
| 614 | m = UNSTUFF_BITS(resp, 62, 12); | ||
| 615 | csd->capacity = (1 + m) << (e + 2); | ||
| 616 | |||
| 617 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
| 618 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
| 619 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
| 620 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
| 621 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
| 622 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
| 623 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
| 624 | break; | ||
| 625 | case 1: | ||
| 626 | /* | ||
| 627 | * This is a block-addressed SDHC card. Most | ||
| 628 | * interesting fields are unused and have fixed | ||
| 629 | * values. To avoid getting tripped by buggy cards, | ||
| 630 | * we assume those fixed values ourselves. | ||
| 631 | */ | ||
| 632 | mmc_card_set_blockaddr(card); | ||
| 633 | |||
| 634 | csd->tacc_ns = 0; /* Unused */ | ||
| 635 | csd->tacc_clks = 0; /* Unused */ | ||
| 636 | |||
| 637 | m = UNSTUFF_BITS(resp, 99, 4); | ||
| 638 | e = UNSTUFF_BITS(resp, 96, 3); | ||
| 639 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 640 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 641 | |||
| 642 | m = UNSTUFF_BITS(resp, 48, 22); | ||
| 643 | csd->capacity = (1 + m) << 10; | ||
| 644 | |||
| 645 | csd->read_blkbits = 9; | ||
| 646 | csd->read_partial = 0; | ||
| 647 | csd->write_misalign = 0; | ||
| 648 | csd->read_misalign = 0; | ||
| 649 | csd->r2w_factor = 4; /* Unused */ | ||
| 650 | csd->write_blkbits = 9; | ||
| 651 | csd->write_partial = 0; | ||
| 652 | break; | ||
| 653 | default: | ||
| 654 | printk("%s: unrecognised CSD structure version %d\n", | ||
| 655 | mmc_hostname(card->host), csd_struct); | ||
| 656 | mmc_card_set_bad(card); | ||
| 657 | return; | ||
| 658 | } | ||
| 659 | } else { | ||
| 660 | /* | ||
| 661 | * We only understand CSD structure v1.1 and v1.2. | ||
| 662 | * v1.2 has extra information in bits 15, 11 and 10. | ||
| 663 | */ | ||
| 664 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
| 665 | if (csd_struct != 1 && csd_struct != 2) { | ||
| 666 | printk("%s: unrecognised CSD structure version %d\n", | ||
| 667 | mmc_hostname(card->host), csd_struct); | ||
| 668 | mmc_card_set_bad(card); | ||
| 669 | return; | ||
| 670 | } | ||
| 671 | |||
| 672 | csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); | ||
| 673 | m = UNSTUFF_BITS(resp, 115, 4); | ||
| 674 | e = UNSTUFF_BITS(resp, 112, 3); | ||
| 675 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
| 676 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
| 677 | |||
| 678 | m = UNSTUFF_BITS(resp, 99, 4); | ||
| 679 | e = UNSTUFF_BITS(resp, 96, 3); | ||
| 680 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
| 681 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
| 682 | |||
| 683 | e = UNSTUFF_BITS(resp, 47, 3); | ||
| 684 | m = UNSTUFF_BITS(resp, 62, 12); | ||
| 685 | csd->capacity = (1 + m) << (e + 2); | ||
| 686 | |||
| 687 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
| 688 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
| 689 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
| 690 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
| 691 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
| 692 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
| 693 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
| 694 | } | ||
| 695 | } | ||
| 696 | |||
| 697 | /* | ||
| 698 | * Given a 64-bit response, decode to our card SCR structure. | ||
| 699 | */ | ||
| 700 | static void mmc_decode_scr(struct mmc_card *card) | ||
| 701 | { | ||
| 702 | struct sd_scr *scr = &card->scr; | ||
| 703 | unsigned int scr_struct; | ||
| 704 | u32 resp[4]; | ||
| 705 | |||
| 706 | BUG_ON(!mmc_card_sd(card)); | ||
| 707 | |||
| 708 | resp[3] = card->raw_scr[1]; | ||
| 709 | resp[2] = card->raw_scr[0]; | ||
| 710 | |||
| 711 | scr_struct = UNSTUFF_BITS(resp, 60, 4); | ||
| 712 | if (scr_struct != 0) { | ||
| 713 | printk("%s: unrecognised SCR structure version %d\n", | ||
| 714 | mmc_hostname(card->host), scr_struct); | ||
| 715 | mmc_card_set_bad(card); | ||
| 716 | return; | ||
| 717 | } | ||
| 718 | |||
| 719 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); | ||
| 720 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); | ||
| 721 | } | ||
| 722 | |||
| 723 | /* | ||
| 724 | * Locate a MMC card on this MMC host given a raw CID. | ||
| 725 | */ | ||
| 726 | static struct mmc_card *mmc_find_card(struct mmc_host *host, u32 *raw_cid) | ||
| 727 | { | ||
| 728 | struct mmc_card *card; | ||
| 729 | |||
| 730 | list_for_each_entry(card, &host->cards, node) { | ||
| 731 | if (memcmp(card->raw_cid, raw_cid, sizeof(card->raw_cid)) == 0) | ||
| 732 | return card; | ||
| 733 | } | ||
| 734 | return NULL; | ||
| 735 | } | ||
| 736 | |||
| 737 | /* | ||
| 738 | * Allocate a new MMC card, and assign a unique RCA. | ||
| 739 | */ | ||
| 740 | static struct mmc_card * | ||
| 741 | mmc_alloc_card(struct mmc_host *host, u32 *raw_cid, unsigned int *frca) | ||
| 742 | { | ||
| 743 | struct mmc_card *card, *c; | ||
| 744 | unsigned int rca = *frca; | ||
| 745 | |||
| 746 | card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); | ||
| 747 | if (!card) | ||
| 748 | return ERR_PTR(-ENOMEM); | ||
| 749 | |||
| 750 | mmc_init_card(card, host); | ||
| 751 | memcpy(card->raw_cid, raw_cid, sizeof(card->raw_cid)); | ||
| 752 | |||
| 753 | again: | ||
| 754 | list_for_each_entry(c, &host->cards, node) | ||
| 755 | if (c->rca == rca) { | ||
| 756 | rca++; | ||
| 757 | goto again; | ||
| 758 | } | ||
| 759 | |||
| 760 | card->rca = rca; | ||
| 761 | |||
| 762 | *frca = rca; | ||
| 763 | |||
| 764 | return card; | ||
| 765 | } | ||
| 766 | |||
| 767 | /* | ||
| 768 | * Tell attached cards to go to IDLE state | ||
| 769 | */ | ||
| 770 | static void mmc_idle_cards(struct mmc_host *host) | ||
| 771 | { | ||
| 772 | struct mmc_command cmd; | ||
| 773 | |||
| 774 | host->ios.chip_select = MMC_CS_HIGH; | ||
| 775 | mmc_set_ios(host); | ||
| 776 | |||
| 777 | mmc_delay(1); | ||
| 778 | |||
| 779 | cmd.opcode = MMC_GO_IDLE_STATE; | ||
| 780 | cmd.arg = 0; | ||
| 781 | cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; | ||
| 782 | |||
| 783 | mmc_wait_for_cmd(host, &cmd, 0); | ||
| 784 | |||
| 785 | mmc_delay(1); | ||
| 786 | |||
| 787 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
| 788 | mmc_set_ios(host); | ||
| 789 | |||
| 790 | mmc_delay(1); | ||
| 791 | } | ||
| 792 | |||
| 793 | /* | ||
| 794 | * Apply power to the MMC stack. This is a two-stage process. | ||
| 795 | * First, we enable power to the card without the clock running. | ||
| 796 | * We then wait a bit for the power to stabilise. Finally, | ||
| 797 | * enable the bus drivers and clock to the card. | ||
| 798 | * | ||
| 799 | * We must _NOT_ enable the clock prior to power stablising. | ||
| 800 | * | ||
| 801 | * If a host does all the power sequencing itself, ignore the | ||
| 802 | * initial MMC_POWER_UP stage. | ||
| 803 | */ | ||
| 804 | static void mmc_power_up(struct mmc_host *host) | ||
| 805 | { | ||
| 806 | int bit = fls(host->ocr_avail) - 1; | ||
| 807 | |||
| 808 | host->ios.vdd = bit; | ||
| 809 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
| 810 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
| 811 | host->ios.power_mode = MMC_POWER_UP; | ||
| 812 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
| 813 | host->ios.timing = MMC_TIMING_LEGACY; | ||
| 814 | mmc_set_ios(host); | ||
| 815 | |||
| 816 | mmc_delay(1); | ||
| 817 | |||
| 818 | host->ios.clock = host->f_min; | ||
| 819 | host->ios.power_mode = MMC_POWER_ON; | ||
| 820 | mmc_set_ios(host); | ||
| 821 | |||
| 822 | mmc_delay(2); | ||
| 823 | } | ||
| 824 | |||
| 825 | static void mmc_power_off(struct mmc_host *host) | ||
| 826 | { | ||
| 827 | host->ios.clock = 0; | ||
| 828 | host->ios.vdd = 0; | ||
| 829 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
| 830 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
| 831 | host->ios.power_mode = MMC_POWER_OFF; | ||
| 832 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
| 833 | host->ios.timing = MMC_TIMING_LEGACY; | ||
| 834 | mmc_set_ios(host); | ||
| 835 | } | ||
| 836 | |||
| 837 | static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
| 838 | { | ||
| 839 | struct mmc_command cmd; | ||
| 840 | int i, err = 0; | ||
| 841 | |||
| 842 | cmd.opcode = MMC_SEND_OP_COND; | ||
| 843 | cmd.arg = ocr; | ||
| 844 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
| 845 | |||
| 846 | for (i = 100; i; i--) { | ||
| 847 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
| 848 | if (err != MMC_ERR_NONE) | ||
| 849 | break; | ||
| 850 | |||
| 851 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
| 852 | break; | ||
| 853 | |||
| 854 | err = MMC_ERR_TIMEOUT; | ||
| 855 | |||
| 856 | mmc_delay(10); | ||
| 857 | } | ||
| 858 | |||
| 859 | if (rocr) | ||
| 860 | *rocr = cmd.resp[0]; | ||
| 861 | |||
| 862 | return err; | ||
| 863 | } | ||
| 864 | |||
| 865 | static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
| 866 | { | ||
| 867 | struct mmc_command cmd; | ||
| 868 | int i, err = 0; | ||
| 869 | |||
| 870 | cmd.opcode = SD_APP_OP_COND; | ||
| 871 | cmd.arg = ocr; | ||
| 872 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
| 873 | |||
| 874 | for (i = 100; i; i--) { | ||
| 875 | err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); | ||
| 876 | if (err != MMC_ERR_NONE) | ||
| 877 | break; | ||
| 878 | |||
| 879 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
| 880 | break; | ||
| 881 | |||
| 882 | err = MMC_ERR_TIMEOUT; | ||
| 883 | |||
| 884 | mmc_delay(10); | ||
| 885 | } | ||
| 886 | |||
| 887 | if (rocr) | ||
| 888 | *rocr = cmd.resp[0]; | ||
| 889 | |||
| 890 | return err; | ||
| 891 | } | ||
| 892 | |||
| 893 | static int mmc_send_if_cond(struct mmc_host *host, u32 ocr, int *rsd2) | ||
| 894 | { | ||
| 895 | struct mmc_command cmd; | ||
| 896 | int err, sd2; | ||
| 897 | static const u8 test_pattern = 0xAA; | ||
| 898 | |||
| 899 | /* | ||
| 900 | * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND | ||
| 901 | * before SD_APP_OP_COND. This command will harmlessly fail for | ||
| 902 | * SD 1.0 cards. | ||
| 903 | */ | ||
| 904 | cmd.opcode = SD_SEND_IF_COND; | ||
| 905 | cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; | ||
| 906 | cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; | ||
| 907 | |||
| 908 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
| 909 | if (err == MMC_ERR_NONE) { | ||
| 910 | if ((cmd.resp[0] & 0xFF) == test_pattern) { | ||
| 911 | sd2 = 1; | ||
| 912 | } else { | ||
| 913 | sd2 = 0; | ||
| 914 | err = MMC_ERR_FAILED; | ||
| 915 | } | ||
| 916 | } else { | ||
| 917 | /* | ||
| 918 | * Treat errors as SD 1.0 card. | ||
| 919 | */ | ||
| 920 | sd2 = 0; | ||
| 921 | err = MMC_ERR_NONE; | ||
| 922 | } | ||
| 923 | if (rsd2) | ||
| 924 | *rsd2 = sd2; | ||
| 925 | return err; | ||
| 926 | } | ||
| 927 | |||
| 928 | /* | ||
| 929 | * Discover cards by requesting their CID. If this command | ||
| 930 | * times out, it is not an error; there are no further cards | ||
| 931 | * to be discovered. Add new cards to the list. | ||
| 932 | * | ||
| 933 | * Create a mmc_card entry for each discovered card, assigning | ||
| 934 | * it an RCA, and save the raw CID for decoding later. | ||
| 935 | */ | ||
| 936 | static void mmc_discover_cards(struct mmc_host *host) | ||
| 937 | { | ||
| 938 | struct mmc_card *card; | ||
| 939 | unsigned int first_rca = 1, err; | ||
| 940 | |||
| 941 | while (1) { | ||
| 942 | struct mmc_command cmd; | ||
| 943 | |||
| 944 | cmd.opcode = MMC_ALL_SEND_CID; | ||
| 945 | cmd.arg = 0; | ||
| 946 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | ||
| 947 | |||
| 948 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 949 | if (err == MMC_ERR_TIMEOUT) { | ||
| 950 | err = MMC_ERR_NONE; | ||
| 951 | break; | ||
| 952 | } | ||
| 953 | if (err != MMC_ERR_NONE) { | ||
| 954 | printk(KERN_ERR "%s: error requesting CID: %d\n", | ||
| 955 | mmc_hostname(host), err); | ||
| 956 | break; | ||
| 957 | } | ||
| 958 | |||
| 959 | card = mmc_find_card(host, cmd.resp); | ||
| 960 | if (!card) { | ||
| 961 | card = mmc_alloc_card(host, cmd.resp, &first_rca); | ||
| 962 | if (IS_ERR(card)) { | ||
| 963 | err = PTR_ERR(card); | ||
| 964 | break; | ||
| 965 | } | ||
| 966 | list_add(&card->node, &host->cards); | ||
| 967 | } | ||
| 968 | |||
| 969 | card->state &= ~MMC_STATE_DEAD; | ||
| 970 | |||
| 971 | if (host->mode == MMC_MODE_SD) { | ||
| 972 | mmc_card_set_sd(card); | ||
| 973 | |||
| 974 | cmd.opcode = SD_SEND_RELATIVE_ADDR; | ||
| 975 | cmd.arg = 0; | ||
| 976 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; | ||
| 977 | |||
| 978 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 979 | if (err != MMC_ERR_NONE) | ||
| 980 | mmc_card_set_dead(card); | ||
| 981 | else { | ||
| 982 | card->rca = cmd.resp[0] >> 16; | ||
| 983 | |||
| 984 | if (!host->ops->get_ro) { | ||
| 985 | printk(KERN_WARNING "%s: host does not " | ||
| 986 | "support reading read-only " | ||
| 987 | "switch. assuming write-enable.\n", | ||
| 988 | mmc_hostname(host)); | ||
| 989 | } else { | ||
| 990 | if (host->ops->get_ro(host)) | ||
| 991 | mmc_card_set_readonly(card); | ||
| 992 | } | ||
| 993 | } | ||
| 994 | } else { | ||
| 995 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | ||
| 996 | cmd.arg = card->rca << 16; | ||
| 997 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 998 | |||
| 999 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 1000 | if (err != MMC_ERR_NONE) | ||
| 1001 | mmc_card_set_dead(card); | ||
| 1002 | } | ||
| 1003 | } | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | static void mmc_read_csds(struct mmc_host *host) | ||
| 1007 | { | ||
| 1008 | struct mmc_card *card; | ||
| 1009 | |||
| 1010 | list_for_each_entry(card, &host->cards, node) { | ||
| 1011 | struct mmc_command cmd; | ||
| 1012 | int err; | ||
| 1013 | |||
| 1014 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
| 1015 | continue; | ||
| 1016 | |||
| 1017 | cmd.opcode = MMC_SEND_CSD; | ||
| 1018 | cmd.arg = card->rca << 16; | ||
| 1019 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | ||
| 1020 | |||
| 1021 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 1022 | if (err != MMC_ERR_NONE) { | ||
| 1023 | mmc_card_set_dead(card); | ||
| 1024 | continue; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | memcpy(card->raw_csd, cmd.resp, sizeof(card->raw_csd)); | ||
| 1028 | |||
| 1029 | mmc_decode_csd(card); | ||
| 1030 | mmc_decode_cid(card); | ||
| 1031 | } | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | static void mmc_process_ext_csds(struct mmc_host *host) | ||
| 1035 | { | ||
| 1036 | int err; | ||
| 1037 | struct mmc_card *card; | ||
| 1038 | |||
| 1039 | struct mmc_request mrq; | ||
| 1040 | struct mmc_command cmd; | ||
| 1041 | struct mmc_data data; | ||
| 1042 | |||
| 1043 | struct scatterlist sg; | ||
| 1044 | |||
| 1045 | /* | ||
| 1046 | * As the ext_csd is so large and mostly unused, we don't store the | ||
| 1047 | * raw block in mmc_card. | ||
| 1048 | */ | ||
| 1049 | u8 *ext_csd; | ||
| 1050 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
| 1051 | if (!ext_csd) { | ||
| 1052 | printk("%s: could not allocate a buffer to receive the ext_csd." | ||
| 1053 | "mmc v4 cards will be treated as v3.\n", | ||
| 1054 | mmc_hostname(host)); | ||
| 1055 | return; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | list_for_each_entry(card, &host->cards, node) { | ||
| 1059 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
| 1060 | continue; | ||
| 1061 | if (mmc_card_sd(card)) | ||
| 1062 | continue; | ||
| 1063 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
| 1064 | continue; | ||
| 1065 | |||
| 1066 | err = mmc_select_card(host, card); | ||
| 1067 | if (err != MMC_ERR_NONE) { | ||
| 1068 | mmc_card_set_dead(card); | ||
| 1069 | continue; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1073 | |||
| 1074 | cmd.opcode = MMC_SEND_EXT_CSD; | ||
| 1075 | cmd.arg = 0; | ||
| 1076 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
| 1077 | |||
| 1078 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 1079 | |||
| 1080 | mmc_set_data_timeout(&data, card, 0); | ||
| 1081 | |||
| 1082 | data.blksz = 512; | ||
| 1083 | data.blocks = 1; | ||
| 1084 | data.flags = MMC_DATA_READ; | ||
| 1085 | data.sg = &sg; | ||
| 1086 | data.sg_len = 1; | ||
| 1087 | |||
| 1088 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 1089 | |||
| 1090 | mrq.cmd = &cmd; | ||
| 1091 | mrq.data = &data; | ||
| 1092 | |||
| 1093 | sg_init_one(&sg, ext_csd, 512); | ||
| 1094 | |||
| 1095 | mmc_wait_for_req(host, &mrq); | ||
| 1096 | |||
| 1097 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
| 1098 | printk("%s: unable to read EXT_CSD, performance " | ||
| 1099 | "might suffer.\n", mmc_hostname(card->host)); | ||
| 1100 | continue; | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | ||
| 1104 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | ||
| 1105 | card->ext_csd.hs_max_dtr = 52000000; | ||
| 1106 | break; | ||
| 1107 | case EXT_CSD_CARD_TYPE_26: | ||
| 1108 | card->ext_csd.hs_max_dtr = 26000000; | ||
| 1109 | break; | ||
| 1110 | default: | ||
| 1111 | /* MMC v4 spec says this cannot happen */ | ||
| 1112 | printk("%s: card is mmc v4 but doesn't support " | ||
| 1113 | "any high-speed modes.\n", | ||
| 1114 | mmc_hostname(card->host)); | ||
| 1115 | continue; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | if (host->caps & MMC_CAP_MMC_HIGHSPEED) { | ||
| 1119 | /* Activate highspeed support. */ | ||
| 1120 | cmd.opcode = MMC_SWITCH; | ||
| 1121 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
| 1122 | (EXT_CSD_HS_TIMING << 16) | | ||
| 1123 | (1 << 8) | | ||
| 1124 | EXT_CSD_CMD_SET_NORMAL; | ||
| 1125 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
| 1126 | |||
| 1127 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 1128 | if (err != MMC_ERR_NONE) { | ||
| 1129 | printk("%s: failed to switch card to mmc v4 " | ||
| 1130 | "high-speed mode.\n", | ||
| 1131 | mmc_hostname(card->host)); | ||
| 1132 | continue; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | mmc_card_set_highspeed(card); | ||
| 1136 | |||
| 1137 | host->ios.timing = MMC_TIMING_SD_HS; | ||
| 1138 | mmc_set_ios(host); | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | /* Check for host support for wide-bus modes. */ | ||
| 1142 | if (host->caps & MMC_CAP_4_BIT_DATA) { | ||
| 1143 | /* Activate 4-bit support. */ | ||
| 1144 | cmd.opcode = MMC_SWITCH; | ||
| 1145 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
| 1146 | (EXT_CSD_BUS_WIDTH << 16) | | ||
| 1147 | (EXT_CSD_BUS_WIDTH_4 << 8) | | ||
| 1148 | EXT_CSD_CMD_SET_NORMAL; | ||
| 1149 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
| 1150 | |||
| 1151 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 1152 | if (err != MMC_ERR_NONE) { | ||
| 1153 | printk("%s: failed to switch card to " | ||
| 1154 | "mmc v4 4-bit bus mode.\n", | ||
| 1155 | mmc_hostname(card->host)); | ||
| 1156 | continue; | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | host->ios.bus_width = MMC_BUS_WIDTH_4; | ||
| 1160 | mmc_set_ios(host); | ||
| 1161 | } | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | kfree(ext_csd); | ||
| 1165 | |||
| 1166 | mmc_deselect_cards(host); | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | static void mmc_read_scrs(struct mmc_host *host) | ||
| 1170 | { | ||
| 1171 | int err; | ||
| 1172 | struct mmc_card *card; | ||
| 1173 | struct mmc_request mrq; | ||
| 1174 | struct mmc_command cmd; | ||
| 1175 | struct mmc_data data; | ||
| 1176 | struct scatterlist sg; | ||
| 1177 | |||
| 1178 | list_for_each_entry(card, &host->cards, node) { | ||
| 1179 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
| 1180 | continue; | ||
| 1181 | if (!mmc_card_sd(card)) | ||
| 1182 | continue; | ||
| 1183 | |||
| 1184 | err = mmc_select_card(host, card); | ||
| 1185 | if (err != MMC_ERR_NONE) { | ||
| 1186 | mmc_card_set_dead(card); | ||
| 1187 | continue; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1191 | |||
| 1192 | cmd.opcode = MMC_APP_CMD; | ||
| 1193 | cmd.arg = card->rca << 16; | ||
| 1194 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 1195 | |||
| 1196 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
| 1197 | if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { | ||
| 1198 | mmc_card_set_dead(card); | ||
| 1199 | continue; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1203 | |||
| 1204 | cmd.opcode = SD_APP_SEND_SCR; | ||
| 1205 | cmd.arg = 0; | ||
| 1206 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
| 1207 | |||
| 1208 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 1209 | |||
| 1210 | mmc_set_data_timeout(&data, card, 0); | ||
| 1211 | |||
| 1212 | data.blksz = 1 << 3; | ||
| 1213 | data.blocks = 1; | ||
| 1214 | data.flags = MMC_DATA_READ; | ||
| 1215 | data.sg = &sg; | ||
| 1216 | data.sg_len = 1; | ||
| 1217 | |||
| 1218 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 1219 | |||
| 1220 | mrq.cmd = &cmd; | ||
| 1221 | mrq.data = &data; | ||
| 1222 | |||
| 1223 | sg_init_one(&sg, (u8*)card->raw_scr, 8); | ||
| 1224 | |||
| 1225 | mmc_wait_for_req(host, &mrq); | ||
| 1226 | |||
| 1227 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
| 1228 | mmc_card_set_dead(card); | ||
| 1229 | continue; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | card->raw_scr[0] = ntohl(card->raw_scr[0]); | ||
| 1233 | card->raw_scr[1] = ntohl(card->raw_scr[1]); | ||
| 1234 | |||
| 1235 | mmc_decode_scr(card); | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | mmc_deselect_cards(host); | ||
| 1239 | } | ||
| 1240 | |||
| 1241 | static void mmc_read_switch_caps(struct mmc_host *host) | ||
| 1242 | { | ||
| 1243 | int err; | ||
| 1244 | struct mmc_card *card; | ||
| 1245 | struct mmc_request mrq; | ||
| 1246 | struct mmc_command cmd; | ||
| 1247 | struct mmc_data data; | ||
| 1248 | unsigned char *status; | ||
| 1249 | struct scatterlist sg; | ||
| 1250 | |||
| 1251 | if (!(host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
| 1252 | return; | ||
| 1253 | |||
| 1254 | status = kmalloc(64, GFP_KERNEL); | ||
| 1255 | if (!status) { | ||
| 1256 | printk(KERN_WARNING "%s: Unable to allocate buffer for " | ||
| 1257 | "reading switch capabilities.\n", | ||
| 1258 | mmc_hostname(host)); | ||
| 1259 | return; | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | list_for_each_entry(card, &host->cards, node) { | ||
| 1263 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
| 1264 | continue; | ||
| 1265 | if (!mmc_card_sd(card)) | ||
| 1266 | continue; | ||
| 1267 | if (card->scr.sda_vsn < SCR_SPEC_VER_1) | ||
| 1268 | continue; | ||
| 1269 | |||
| 1270 | err = mmc_select_card(host, card); | ||
| 1271 | if (err != MMC_ERR_NONE) { | ||
| 1272 | mmc_card_set_dead(card); | ||
| 1273 | continue; | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1277 | |||
| 1278 | cmd.opcode = SD_SWITCH; | ||
| 1279 | cmd.arg = 0x00FFFFF1; | ||
| 1280 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
| 1281 | |||
| 1282 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 1283 | |||
| 1284 | mmc_set_data_timeout(&data, card, 0); | ||
| 1285 | |||
| 1286 | data.blksz = 64; | ||
| 1287 | data.blocks = 1; | ||
| 1288 | data.flags = MMC_DATA_READ; | ||
| 1289 | data.sg = &sg; | ||
| 1290 | data.sg_len = 1; | ||
| 1291 | |||
| 1292 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 1293 | |||
| 1294 | mrq.cmd = &cmd; | ||
| 1295 | mrq.data = &data; | ||
| 1296 | |||
| 1297 | sg_init_one(&sg, status, 64); | ||
| 1298 | |||
| 1299 | mmc_wait_for_req(host, &mrq); | ||
| 1300 | |||
| 1301 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
| 1302 | printk("%s: unable to read switch capabilities, " | ||
| 1303 | "performance might suffer.\n", | ||
| 1304 | mmc_hostname(card->host)); | ||
| 1305 | continue; | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | if (status[13] & 0x02) | ||
| 1309 | card->sw_caps.hs_max_dtr = 50000000; | ||
| 1310 | |||
| 1311 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
| 1312 | |||
| 1313 | cmd.opcode = SD_SWITCH; | ||
| 1314 | cmd.arg = 0x80FFFFF1; | ||
| 1315 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
| 1316 | |||
| 1317 | memset(&data, 0, sizeof(struct mmc_data)); | ||
| 1318 | |||
| 1319 | mmc_set_data_timeout(&data, card, 0); | ||
| 1320 | |||
| 1321 | data.blksz = 64; | ||
| 1322 | data.blocks = 1; | ||
| 1323 | data.flags = MMC_DATA_READ; | ||
| 1324 | data.sg = &sg; | ||
| 1325 | data.sg_len = 1; | ||
| 1326 | |||
| 1327 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
| 1328 | |||
| 1329 | mrq.cmd = &cmd; | ||
| 1330 | mrq.data = &data; | ||
| 1331 | |||
| 1332 | sg_init_one(&sg, status, 64); | ||
| 1333 | |||
| 1334 | mmc_wait_for_req(host, &mrq); | ||
| 1335 | |||
| 1336 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE || | ||
| 1337 | (status[16] & 0xF) != 1) { | ||
| 1338 | printk(KERN_WARNING "%s: Problem switching card " | ||
| 1339 | "into high-speed mode!\n", | ||
| 1340 | mmc_hostname(host)); | ||
| 1341 | continue; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | mmc_card_set_highspeed(card); | ||
| 1345 | |||
| 1346 | host->ios.timing = MMC_TIMING_SD_HS; | ||
| 1347 | mmc_set_ios(host); | ||
| 1348 | } | ||
| 1349 | |||
| 1350 | kfree(status); | ||
| 1351 | |||
| 1352 | mmc_deselect_cards(host); | ||
| 1353 | } | ||
| 1354 | |||
| 1355 | static unsigned int mmc_calculate_clock(struct mmc_host *host) | ||
| 1356 | { | ||
| 1357 | struct mmc_card *card; | ||
| 1358 | unsigned int max_dtr = host->f_max; | ||
| 1359 | |||
| 1360 | list_for_each_entry(card, &host->cards, node) | ||
| 1361 | if (!mmc_card_dead(card)) { | ||
| 1362 | if (mmc_card_highspeed(card) && mmc_card_sd(card)) { | ||
| 1363 | if (max_dtr > card->sw_caps.hs_max_dtr) | ||
| 1364 | max_dtr = card->sw_caps.hs_max_dtr; | ||
| 1365 | } else if (mmc_card_highspeed(card) && !mmc_card_sd(card)) { | ||
| 1366 | if (max_dtr > card->ext_csd.hs_max_dtr) | ||
| 1367 | max_dtr = card->ext_csd.hs_max_dtr; | ||
| 1368 | } else if (max_dtr > card->csd.max_dtr) { | ||
| 1369 | max_dtr = card->csd.max_dtr; | ||
| 1370 | } | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | pr_debug("%s: selected %d.%03dMHz transfer rate\n", | ||
| 1374 | mmc_hostname(host), | ||
| 1375 | max_dtr / 1000000, (max_dtr / 1000) % 1000); | ||
| 1376 | |||
| 1377 | return max_dtr; | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | /* | ||
| 1381 | * Check whether cards we already know about are still present. | ||
| 1382 | * We do this by requesting status, and checking whether a card | ||
| 1383 | * responds. | ||
| 1384 | * | ||
| 1385 | * A request for status does not cause a state change in data | ||
| 1386 | * transfer mode. | ||
| 1387 | */ | ||
| 1388 | static void mmc_check_cards(struct mmc_host *host) | ||
| 1389 | { | ||
| 1390 | struct list_head *l, *n; | ||
| 1391 | |||
| 1392 | mmc_deselect_cards(host); | ||
| 1393 | |||
| 1394 | list_for_each_safe(l, n, &host->cards) { | ||
| 1395 | struct mmc_card *card = mmc_list_to_card(l); | ||
| 1396 | struct mmc_command cmd; | ||
| 1397 | int err; | ||
| 1398 | |||
| 1399 | cmd.opcode = MMC_SEND_STATUS; | ||
| 1400 | cmd.arg = card->rca << 16; | ||
| 1401 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
| 1402 | |||
| 1403 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
| 1404 | if (err == MMC_ERR_NONE) | ||
| 1405 | continue; | ||
| 1406 | |||
| 1407 | mmc_card_set_dead(card); | ||
| 1408 | } | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | static void mmc_setup(struct mmc_host *host) | ||
| 1412 | { | ||
| 1413 | if (host->ios.power_mode != MMC_POWER_ON) { | ||
| 1414 | int err; | ||
| 1415 | u32 ocr; | ||
| 1416 | |||
| 1417 | host->mode = MMC_MODE_SD; | ||
| 1418 | |||
| 1419 | mmc_power_up(host); | ||
| 1420 | mmc_idle_cards(host); | ||
| 1421 | |||
| 1422 | err = mmc_send_if_cond(host, host->ocr_avail, NULL); | ||
| 1423 | if (err != MMC_ERR_NONE) { | ||
| 1424 | return; | ||
| 1425 | } | ||
| 1426 | err = mmc_send_app_op_cond(host, 0, &ocr); | ||
| 1427 | |||
| 1428 | /* | ||
| 1429 | * If we fail to detect any SD cards then try | ||
| 1430 | * searching for MMC cards. | ||
| 1431 | */ | ||
| 1432 | if (err != MMC_ERR_NONE) { | ||
| 1433 | host->mode = MMC_MODE_MMC; | ||
| 1434 | |||
| 1435 | err = mmc_send_op_cond(host, 0, &ocr); | ||
| 1436 | if (err != MMC_ERR_NONE) | ||
| 1437 | return; | ||
| 1438 | } | ||
| 1439 | |||
| 1440 | host->ocr = mmc_select_voltage(host, ocr); | ||
| 1441 | |||
| 1442 | /* | ||
| 1443 | * Since we're changing the OCR value, we seem to | ||
| 1444 | * need to tell some cards to go back to the idle | ||
| 1445 | * state. We wait 1ms to give cards time to | ||
| 1446 | * respond. | ||
| 1447 | */ | ||
| 1448 | if (host->ocr) | ||
| 1449 | mmc_idle_cards(host); | ||
| 1450 | } else { | ||
| 1451 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
| 1452 | host->ios.clock = host->f_min; | ||
| 1453 | mmc_set_ios(host); | ||
| 1454 | |||
| 1455 | /* | ||
| 1456 | * We should remember the OCR mask from the existing | ||
| 1457 | * cards, and detect the new cards OCR mask, combine | ||
| 1458 | * the two and re-select the VDD. However, if we do | ||
| 1459 | * change VDD, we should do an idle, and then do a | ||
| 1460 | * full re-initialisation. We would need to notify | ||
| 1461 | * drivers so that they can re-setup the cards as | ||
| 1462 | * well, while keeping their queues at bay. | ||
| 1463 | * | ||
| 1464 | * For the moment, we take the easy way out - if the | ||
| 1465 | * new cards don't like our currently selected VDD, | ||
| 1466 | * they drop off the bus. | ||
| 1467 | */ | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | if (host->ocr == 0) | ||
| 1471 | return; | ||
| 1472 | |||
| 1473 | /* | ||
| 1474 | * Send the selected OCR multiple times... until the cards | ||
| 1475 | * all get the idea that they should be ready for CMD2. | ||
| 1476 | * (My SanDisk card seems to need this.) | ||
| 1477 | */ | ||
| 1478 | if (host->mode == MMC_MODE_SD) { | ||
| 1479 | int err, sd2; | ||
| 1480 | err = mmc_send_if_cond(host, host->ocr, &sd2); | ||
| 1481 | if (err == MMC_ERR_NONE) { | ||
| 1482 | /* | ||
| 1483 | * If SD_SEND_IF_COND indicates an SD 2.0 | ||
| 1484 | * compliant card and we should set bit 30 | ||
| 1485 | * of the ocr to indicate that we can handle | ||
| 1486 | * block-addressed SDHC cards. | ||
| 1487 | */ | ||
| 1488 | mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL); | ||
| 1489 | } | ||
| 1490 | } else { | ||
| 1491 | mmc_send_op_cond(host, host->ocr, NULL); | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | mmc_discover_cards(host); | ||
| 1495 | |||
| 1496 | /* | ||
| 1497 | * Ok, now switch to push-pull mode. | ||
| 1498 | */ | ||
| 1499 | host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; | ||
| 1500 | mmc_set_ios(host); | ||
| 1501 | |||
| 1502 | mmc_read_csds(host); | ||
| 1503 | |||
| 1504 | if (host->mode == MMC_MODE_SD) { | ||
| 1505 | mmc_read_scrs(host); | ||
| 1506 | mmc_read_switch_caps(host); | ||
| 1507 | } else | ||
| 1508 | mmc_process_ext_csds(host); | ||
| 1509 | } | ||
| 1510 | |||
| 1511 | |||
| 1512 | /** | ||
| 1513 | * mmc_detect_change - process change of state on a MMC socket | ||
| 1514 | * @host: host which changed state. | ||
| 1515 | * @delay: optional delay to wait before detection (jiffies) | ||
| 1516 | * | ||
| 1517 | * All we know is that card(s) have been inserted or removed | ||
| 1518 | * from the socket(s). We don't know which socket or cards. | ||
| 1519 | */ | ||
| 1520 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) | ||
| 1521 | { | ||
| 1522 | mmc_schedule_delayed_work(&host->detect, delay); | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | EXPORT_SYMBOL(mmc_detect_change); | ||
| 1526 | |||
| 1527 | |||
| 1528 | static void mmc_rescan(struct work_struct *work) | ||
| 1529 | { | ||
| 1530 | struct mmc_host *host = | ||
| 1531 | container_of(work, struct mmc_host, detect.work); | ||
| 1532 | struct list_head *l, *n; | ||
| 1533 | unsigned char power_mode; | ||
| 1534 | |||
| 1535 | mmc_claim_host(host); | ||
| 1536 | |||
| 1537 | /* | ||
| 1538 | * Check for removed cards and newly inserted ones. We check for | ||
| 1539 | * removed cards first so we can intelligently re-select the VDD. | ||
| 1540 | */ | ||
| 1541 | power_mode = host->ios.power_mode; | ||
| 1542 | if (power_mode == MMC_POWER_ON) | ||
| 1543 | mmc_check_cards(host); | ||
| 1544 | |||
| 1545 | mmc_setup(host); | ||
| 1546 | |||
| 1547 | /* | ||
| 1548 | * Some broken cards process CMD1 even in stand-by state. There is | ||
| 1549 | * no reply, but an ILLEGAL_COMMAND error is cached and returned | ||
| 1550 | * after next command. We poll for card status here to clear any | ||
| 1551 | * possibly pending error. | ||
| 1552 | */ | ||
| 1553 | if (power_mode == MMC_POWER_ON) | ||
| 1554 | mmc_check_cards(host); | ||
| 1555 | |||
| 1556 | if (!list_empty(&host->cards)) { | ||
| 1557 | /* | ||
| 1558 | * (Re-)calculate the fastest clock rate which the | ||
| 1559 | * attached cards and the host support. | ||
| 1560 | */ | ||
| 1561 | host->ios.clock = mmc_calculate_clock(host); | ||
| 1562 | mmc_set_ios(host); | ||
| 1563 | } | ||
| 1564 | |||
| 1565 | mmc_release_host(host); | ||
| 1566 | |||
| 1567 | list_for_each_safe(l, n, &host->cards) { | ||
| 1568 | struct mmc_card *card = mmc_list_to_card(l); | ||
| 1569 | |||
| 1570 | /* | ||
| 1571 | * If this is a new and good card, register it. | ||
| 1572 | */ | ||
| 1573 | if (!mmc_card_present(card) && !mmc_card_dead(card)) { | ||
| 1574 | if (mmc_register_card(card)) | ||
| 1575 | mmc_card_set_dead(card); | ||
| 1576 | else | ||
| 1577 | mmc_card_set_present(card); | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | /* | ||
| 1581 | * If this card is dead, destroy it. | ||
| 1582 | */ | ||
| 1583 | if (mmc_card_dead(card)) { | ||
| 1584 | list_del(&card->node); | ||
| 1585 | mmc_remove_card(card); | ||
| 1586 | } | ||
| 1587 | } | ||
| 1588 | |||
| 1589 | /* | ||
| 1590 | * If we discover that there are no cards on the | ||
| 1591 | * bus, turn off the clock and power down. | ||
| 1592 | */ | ||
| 1593 | if (list_empty(&host->cards)) | ||
| 1594 | mmc_power_off(host); | ||
| 1595 | } | ||
| 1596 | |||
| 1597 | |||
| 1598 | /** | ||
| 1599 | * mmc_alloc_host - initialise the per-host structure. | ||
| 1600 | * @extra: sizeof private data structure | ||
| 1601 | * @dev: pointer to host device model structure | ||
| 1602 | * | ||
| 1603 | * Initialise the per-host structure. | ||
| 1604 | */ | ||
| 1605 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | ||
| 1606 | { | ||
| 1607 | struct mmc_host *host; | ||
| 1608 | |||
| 1609 | host = mmc_alloc_host_sysfs(extra, dev); | ||
| 1610 | if (host) { | ||
| 1611 | spin_lock_init(&host->lock); | ||
| 1612 | init_waitqueue_head(&host->wq); | ||
| 1613 | INIT_LIST_HEAD(&host->cards); | ||
| 1614 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); | ||
| 1615 | |||
| 1616 | /* | ||
| 1617 | * By default, hosts do not support SGIO or large requests. | ||
| 1618 | * They have to set these according to their abilities. | ||
| 1619 | */ | ||
| 1620 | host->max_hw_segs = 1; | ||
| 1621 | host->max_phys_segs = 1; | ||
| 1622 | host->max_seg_size = PAGE_CACHE_SIZE; | ||
| 1623 | |||
| 1624 | host->max_req_size = PAGE_CACHE_SIZE; | ||
| 1625 | host->max_blk_size = 512; | ||
| 1626 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | return host; | ||
| 1630 | } | ||
| 1631 | |||
| 1632 | EXPORT_SYMBOL(mmc_alloc_host); | ||
| 1633 | |||
| 1634 | /** | ||
| 1635 | * mmc_add_host - initialise host hardware | ||
| 1636 | * @host: mmc host | ||
| 1637 | */ | ||
| 1638 | int mmc_add_host(struct mmc_host *host) | ||
| 1639 | { | ||
| 1640 | int ret; | ||
| 1641 | |||
| 1642 | ret = mmc_add_host_sysfs(host); | ||
| 1643 | if (ret == 0) { | ||
| 1644 | mmc_power_off(host); | ||
| 1645 | mmc_detect_change(host, 0); | ||
| 1646 | } | ||
| 1647 | |||
| 1648 | return ret; | ||
| 1649 | } | ||
| 1650 | |||
| 1651 | EXPORT_SYMBOL(mmc_add_host); | ||
| 1652 | |||
| 1653 | /** | ||
| 1654 | * mmc_remove_host - remove host hardware | ||
| 1655 | * @host: mmc host | ||
| 1656 | * | ||
| 1657 | * Unregister and remove all cards associated with this host, | ||
| 1658 | * and power down the MMC bus. | ||
| 1659 | */ | ||
| 1660 | void mmc_remove_host(struct mmc_host *host) | ||
| 1661 | { | ||
| 1662 | struct list_head *l, *n; | ||
| 1663 | |||
| 1664 | list_for_each_safe(l, n, &host->cards) { | ||
| 1665 | struct mmc_card *card = mmc_list_to_card(l); | ||
| 1666 | |||
| 1667 | mmc_remove_card(card); | ||
| 1668 | } | ||
| 1669 | |||
| 1670 | mmc_power_off(host); | ||
| 1671 | mmc_remove_host_sysfs(host); | ||
| 1672 | } | ||
| 1673 | |||
| 1674 | EXPORT_SYMBOL(mmc_remove_host); | ||
| 1675 | |||
| 1676 | /** | ||
| 1677 | * mmc_free_host - free the host structure | ||
| 1678 | * @host: mmc host | ||
| 1679 | * | ||
| 1680 | * Free the host once all references to it have been dropped. | ||
| 1681 | */ | ||
| 1682 | void mmc_free_host(struct mmc_host *host) | ||
| 1683 | { | ||
| 1684 | mmc_flush_scheduled_work(); | ||
| 1685 | mmc_free_host_sysfs(host); | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | EXPORT_SYMBOL(mmc_free_host); | ||
| 1689 | |||
| 1690 | #ifdef CONFIG_PM | ||
| 1691 | |||
| 1692 | /** | ||
| 1693 | * mmc_suspend_host - suspend a host | ||
| 1694 | * @host: mmc host | ||
| 1695 | * @state: suspend mode (PM_SUSPEND_xxx) | ||
| 1696 | */ | ||
| 1697 | int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | ||
| 1698 | { | ||
| 1699 | mmc_claim_host(host); | ||
| 1700 | mmc_deselect_cards(host); | ||
| 1701 | mmc_power_off(host); | ||
| 1702 | mmc_release_host(host); | ||
| 1703 | |||
| 1704 | return 0; | ||
| 1705 | } | ||
| 1706 | |||
| 1707 | EXPORT_SYMBOL(mmc_suspend_host); | ||
| 1708 | |||
| 1709 | /** | ||
| 1710 | * mmc_resume_host - resume a previously suspended host | ||
| 1711 | * @host: mmc host | ||
| 1712 | */ | ||
| 1713 | int mmc_resume_host(struct mmc_host *host) | ||
| 1714 | { | ||
| 1715 | mmc_rescan(&host->detect.work); | ||
| 1716 | |||
| 1717 | return 0; | ||
| 1718 | } | ||
| 1719 | |||
| 1720 | EXPORT_SYMBOL(mmc_resume_host); | ||
| 1721 | |||
| 1722 | #endif | ||
| 1723 | |||
| 1724 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c deleted file mode 100644 index 0581d09c58fc..000000000000 --- a/drivers/mmc/tifm_sd.c +++ /dev/null | |||
| @@ -1,987 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * tifm_sd.c - TI FlashMedia driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com> | ||
| 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 | |||
| 12 | |||
| 13 | #include <linux/tifm.h> | ||
| 14 | #include <linux/mmc/protocol.h> | ||
| 15 | #include <linux/mmc/host.h> | ||
| 16 | #include <linux/highmem.h> | ||
| 17 | #include <asm/io.h> | ||
| 18 | |||
| 19 | #define DRIVER_NAME "tifm_sd" | ||
| 20 | #define DRIVER_VERSION "0.7" | ||
| 21 | |||
| 22 | static int no_dma = 0; | ||
| 23 | static int fixed_timeout = 0; | ||
| 24 | module_param(no_dma, bool, 0644); | ||
| 25 | module_param(fixed_timeout, bool, 0644); | ||
| 26 | |||
| 27 | /* Constants here are mostly from OMAP5912 datasheet */ | ||
| 28 | #define TIFM_MMCSD_RESET 0x0002 | ||
| 29 | #define TIFM_MMCSD_CLKMASK 0x03ff | ||
| 30 | #define TIFM_MMCSD_POWER 0x0800 | ||
| 31 | #define TIFM_MMCSD_4BBUS 0x8000 | ||
| 32 | #define TIFM_MMCSD_RXDE 0x8000 /* rx dma enable */ | ||
| 33 | #define TIFM_MMCSD_TXDE 0x0080 /* tx dma enable */ | ||
| 34 | #define TIFM_MMCSD_BUFINT 0x0c00 /* set bits: AE, AF */ | ||
| 35 | #define TIFM_MMCSD_DPE 0x0020 /* data timeout counted in kilocycles */ | ||
| 36 | #define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */ | ||
| 37 | #define TIFM_MMCSD_READ 0x8000 | ||
| 38 | |||
| 39 | #define TIFM_MMCSD_DATAMASK 0x401d /* set bits: CERR, EOFB, BRS, CB, EOC */ | ||
| 40 | #define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */ | ||
| 41 | #define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ | ||
| 42 | #define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ | ||
| 43 | #define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ | ||
| 44 | #define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */ | ||
| 45 | #define TIFM_MMCSD_DTO 0x0020 /* data time-out */ | ||
| 46 | #define TIFM_MMCSD_DCRC 0x0040 /* data crc error */ | ||
| 47 | #define TIFM_MMCSD_CTO 0x0080 /* command time-out */ | ||
| 48 | #define TIFM_MMCSD_CCRC 0x0100 /* command crc error */ | ||
| 49 | #define TIFM_MMCSD_AF 0x0400 /* fifo almost full */ | ||
| 50 | #define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */ | ||
| 51 | #define TIFM_MMCSD_CERR 0x4000 /* card status error */ | ||
| 52 | |||
| 53 | #define TIFM_MMCSD_FIFO_SIZE 0x0020 | ||
| 54 | |||
| 55 | #define TIFM_MMCSD_RSP_R0 0x0000 | ||
| 56 | #define TIFM_MMCSD_RSP_R1 0x0100 | ||
| 57 | #define TIFM_MMCSD_RSP_R2 0x0200 | ||
| 58 | #define TIFM_MMCSD_RSP_R3 0x0300 | ||
| 59 | #define TIFM_MMCSD_RSP_R4 0x0400 | ||
| 60 | #define TIFM_MMCSD_RSP_R5 0x0500 | ||
| 61 | #define TIFM_MMCSD_RSP_R6 0x0600 | ||
| 62 | |||
| 63 | #define TIFM_MMCSD_RSP_BUSY 0x0800 | ||
| 64 | |||
| 65 | #define TIFM_MMCSD_CMD_BC 0x0000 | ||
| 66 | #define TIFM_MMCSD_CMD_BCR 0x1000 | ||
| 67 | #define TIFM_MMCSD_CMD_AC 0x2000 | ||
| 68 | #define TIFM_MMCSD_CMD_ADTC 0x3000 | ||
| 69 | |||
| 70 | typedef enum { | ||
| 71 | IDLE = 0, | ||
| 72 | CMD, /* main command ended */ | ||
| 73 | BRS, /* block transfer finished */ | ||
| 74 | SCMD, /* stop command ended */ | ||
| 75 | CARD, /* card left busy state */ | ||
| 76 | FIFO, /* FIFO operation completed (uncertain) */ | ||
| 77 | READY | ||
| 78 | } card_state_t; | ||
| 79 | |||
| 80 | enum { | ||
| 81 | FIFO_RDY = 0x0001, /* hardware dependent value */ | ||
| 82 | EJECT = 0x0004, | ||
| 83 | EJECT_DONE = 0x0008, | ||
| 84 | CARD_BUSY = 0x0010, | ||
| 85 | OPENDRAIN = 0x0040, /* hardware dependent value */ | ||
| 86 | CARD_EVENT = 0x0100, /* hardware dependent value */ | ||
| 87 | CARD_RO = 0x0200, /* hardware dependent value */ | ||
| 88 | FIFO_EVENT = 0x10000 }; /* hardware dependent value */ | ||
| 89 | |||
| 90 | struct tifm_sd { | ||
| 91 | struct tifm_dev *dev; | ||
| 92 | |||
| 93 | unsigned int flags; | ||
| 94 | card_state_t state; | ||
| 95 | unsigned int clk_freq; | ||
| 96 | unsigned int clk_div; | ||
| 97 | unsigned long timeout_jiffies; | ||
| 98 | |||
| 99 | struct tasklet_struct finish_tasklet; | ||
| 100 | struct timer_list timer; | ||
| 101 | struct mmc_request *req; | ||
| 102 | wait_queue_head_t notify; | ||
| 103 | |||
| 104 | size_t written_blocks; | ||
| 105 | size_t buffer_size; | ||
| 106 | size_t buffer_pos; | ||
| 107 | |||
| 108 | }; | ||
| 109 | |||
| 110 | static char* tifm_sd_data_buffer(struct mmc_data *data) | ||
| 111 | { | ||
| 112 | return page_address(data->sg->page) + data->sg->offset; | ||
| 113 | } | ||
| 114 | |||
| 115 | static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, | ||
| 116 | unsigned int host_status) | ||
| 117 | { | ||
| 118 | struct mmc_command *cmd = host->req->cmd; | ||
| 119 | unsigned int t_val = 0, cnt = 0; | ||
| 120 | char *buffer; | ||
| 121 | |||
| 122 | if (host_status & TIFM_MMCSD_BRS) { | ||
| 123 | /* in non-dma rx mode BRS fires when fifo is still not empty */ | ||
| 124 | if (no_dma && (cmd->data->flags & MMC_DATA_READ)) { | ||
| 125 | buffer = tifm_sd_data_buffer(host->req->data); | ||
| 126 | while (host->buffer_size > host->buffer_pos) { | ||
| 127 | t_val = readl(sock->addr + SOCK_MMCSD_DATA); | ||
| 128 | buffer[host->buffer_pos++] = t_val & 0xff; | ||
| 129 | buffer[host->buffer_pos++] = | ||
| 130 | (t_val >> 8) & 0xff; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | return 1; | ||
| 134 | } else if (no_dma) { | ||
| 135 | buffer = tifm_sd_data_buffer(host->req->data); | ||
| 136 | if ((cmd->data->flags & MMC_DATA_READ) && | ||
| 137 | (host_status & TIFM_MMCSD_AF)) { | ||
| 138 | for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { | ||
| 139 | t_val = readl(sock->addr + SOCK_MMCSD_DATA); | ||
| 140 | if (host->buffer_size > host->buffer_pos) { | ||
| 141 | buffer[host->buffer_pos++] = | ||
| 142 | t_val & 0xff; | ||
| 143 | buffer[host->buffer_pos++] = | ||
| 144 | (t_val >> 8) & 0xff; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } else if ((cmd->data->flags & MMC_DATA_WRITE) | ||
| 148 | && (host_status & TIFM_MMCSD_AE)) { | ||
| 149 | for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { | ||
| 150 | if (host->buffer_size > host->buffer_pos) { | ||
| 151 | t_val = buffer[host->buffer_pos++] | ||
| 152 | & 0x00ff; | ||
| 153 | t_val |= ((buffer[host->buffer_pos++]) | ||
| 154 | << 8) & 0xff00; | ||
| 155 | writel(t_val, | ||
| 156 | sock->addr + SOCK_MMCSD_DATA); | ||
| 157 | } | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) | ||
| 165 | { | ||
| 166 | unsigned int rc = 0; | ||
| 167 | |||
| 168 | switch (mmc_resp_type(cmd)) { | ||
| 169 | case MMC_RSP_NONE: | ||
| 170 | rc |= TIFM_MMCSD_RSP_R0; | ||
| 171 | break; | ||
| 172 | case MMC_RSP_R1B: | ||
| 173 | rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through | ||
| 174 | case MMC_RSP_R1: | ||
| 175 | rc |= TIFM_MMCSD_RSP_R1; | ||
| 176 | break; | ||
| 177 | case MMC_RSP_R2: | ||
| 178 | rc |= TIFM_MMCSD_RSP_R2; | ||
| 179 | break; | ||
| 180 | case MMC_RSP_R3: | ||
| 181 | rc |= TIFM_MMCSD_RSP_R3; | ||
| 182 | break; | ||
| 183 | default: | ||
| 184 | BUG(); | ||
| 185 | } | ||
| 186 | |||
| 187 | switch (mmc_cmd_type(cmd)) { | ||
| 188 | case MMC_CMD_BC: | ||
| 189 | rc |= TIFM_MMCSD_CMD_BC; | ||
| 190 | break; | ||
| 191 | case MMC_CMD_BCR: | ||
| 192 | rc |= TIFM_MMCSD_CMD_BCR; | ||
| 193 | break; | ||
| 194 | case MMC_CMD_AC: | ||
| 195 | rc |= TIFM_MMCSD_CMD_AC; | ||
| 196 | break; | ||
| 197 | case MMC_CMD_ADTC: | ||
| 198 | rc |= TIFM_MMCSD_CMD_ADTC; | ||
| 199 | break; | ||
| 200 | default: | ||
| 201 | BUG(); | ||
| 202 | } | ||
| 203 | return rc; | ||
| 204 | } | ||
| 205 | |||
| 206 | static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) | ||
| 207 | { | ||
| 208 | struct tifm_dev *sock = host->dev; | ||
| 209 | unsigned int cmd_mask = tifm_sd_op_flags(cmd) | | ||
| 210 | (host->flags & OPENDRAIN); | ||
| 211 | |||
| 212 | if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) | ||
| 213 | cmd_mask |= TIFM_MMCSD_READ; | ||
| 214 | |||
| 215 | dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", | ||
| 216 | cmd->opcode, cmd->arg, cmd_mask); | ||
| 217 | |||
| 218 | writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); | ||
| 219 | writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); | ||
| 220 | writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND); | ||
| 221 | } | ||
| 222 | |||
| 223 | static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock) | ||
| 224 | { | ||
| 225 | cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16) | ||
| 226 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18); | ||
| 227 | cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16) | ||
| 228 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10); | ||
| 229 | cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16) | ||
| 230 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08); | ||
| 231 | cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16) | ||
| 232 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00); | ||
| 233 | } | ||
| 234 | |||
| 235 | static void tifm_sd_process_cmd(struct tifm_dev *sock, struct tifm_sd *host, | ||
| 236 | unsigned int host_status) | ||
| 237 | { | ||
| 238 | struct mmc_command *cmd = host->req->cmd; | ||
| 239 | |||
| 240 | change_state: | ||
| 241 | switch (host->state) { | ||
| 242 | case IDLE: | ||
| 243 | return; | ||
| 244 | case CMD: | ||
| 245 | if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) { | ||
| 246 | tifm_sd_fetch_resp(cmd, sock); | ||
| 247 | if (cmd->data) { | ||
| 248 | host->state = BRS; | ||
| 249 | } else { | ||
| 250 | host->state = READY; | ||
| 251 | } | ||
| 252 | goto change_state; | ||
| 253 | } | ||
| 254 | break; | ||
| 255 | case BRS: | ||
| 256 | if (tifm_sd_transfer_data(sock, host, host_status)) { | ||
| 257 | if (cmd->data->flags & MMC_DATA_WRITE) { | ||
| 258 | host->state = CARD; | ||
| 259 | } else { | ||
| 260 | if (no_dma) { | ||
| 261 | if (host->req->stop) { | ||
| 262 | tifm_sd_exec(host, host->req->stop); | ||
| 263 | host->state = SCMD; | ||
| 264 | } else { | ||
| 265 | host->state = READY; | ||
| 266 | } | ||
| 267 | } else { | ||
| 268 | host->state = FIFO; | ||
| 269 | } | ||
| 270 | } | ||
| 271 | goto change_state; | ||
| 272 | } | ||
| 273 | break; | ||
| 274 | case SCMD: | ||
| 275 | if (host_status & TIFM_MMCSD_EOC) { | ||
| 276 | tifm_sd_fetch_resp(host->req->stop, sock); | ||
| 277 | host->state = READY; | ||
| 278 | goto change_state; | ||
| 279 | } | ||
| 280 | break; | ||
| 281 | case CARD: | ||
| 282 | dev_dbg(&sock->dev, "waiting for CARD, have %zd blocks\n", | ||
| 283 | host->written_blocks); | ||
| 284 | if (!(host->flags & CARD_BUSY) | ||
| 285 | && (host->written_blocks == cmd->data->blocks)) { | ||
| 286 | if (no_dma) { | ||
| 287 | if (host->req->stop) { | ||
| 288 | tifm_sd_exec(host, host->req->stop); | ||
| 289 | host->state = SCMD; | ||
| 290 | } else { | ||
| 291 | host->state = READY; | ||
| 292 | } | ||
| 293 | } else { | ||
| 294 | host->state = FIFO; | ||
| 295 | } | ||
| 296 | goto change_state; | ||
| 297 | } | ||
| 298 | break; | ||
| 299 | case FIFO: | ||
| 300 | if (host->flags & FIFO_RDY) { | ||
| 301 | host->flags &= ~FIFO_RDY; | ||
| 302 | if (host->req->stop) { | ||
| 303 | tifm_sd_exec(host, host->req->stop); | ||
| 304 | host->state = SCMD; | ||
| 305 | } else { | ||
| 306 | host->state = READY; | ||
| 307 | } | ||
| 308 | goto change_state; | ||
| 309 | } | ||
| 310 | break; | ||
| 311 | case READY: | ||
| 312 | tasklet_schedule(&host->finish_tasklet); | ||
| 313 | return; | ||
| 314 | } | ||
| 315 | |||
| 316 | } | ||
| 317 | |||
| 318 | /* Called from interrupt handler */ | ||
| 319 | static void tifm_sd_signal_irq(struct tifm_dev *sock, | ||
| 320 | unsigned int sock_irq_status) | ||
| 321 | { | ||
| 322 | struct tifm_sd *host; | ||
| 323 | unsigned int host_status = 0, fifo_status = 0; | ||
| 324 | int error_code = 0; | ||
| 325 | |||
| 326 | spin_lock(&sock->lock); | ||
| 327 | host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); | ||
| 328 | |||
| 329 | if (sock_irq_status & FIFO_EVENT) { | ||
| 330 | fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); | ||
| 331 | writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS); | ||
| 332 | |||
| 333 | host->flags |= fifo_status & FIFO_RDY; | ||
| 334 | } | ||
| 335 | |||
| 336 | if (sock_irq_status & CARD_EVENT) { | ||
| 337 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
| 338 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
| 339 | |||
| 340 | if (!host->req) | ||
| 341 | goto done; | ||
| 342 | |||
| 343 | if (host_status & TIFM_MMCSD_ERRMASK) { | ||
| 344 | if (host_status & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) | ||
| 345 | error_code = MMC_ERR_TIMEOUT; | ||
| 346 | else if (host_status | ||
| 347 | & (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC)) | ||
| 348 | error_code = MMC_ERR_BADCRC; | ||
| 349 | |||
| 350 | writel(TIFM_FIFO_INT_SETALL, | ||
| 351 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
| 352 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); | ||
| 353 | |||
| 354 | if (host->req->stop) { | ||
| 355 | if (host->state == SCMD) { | ||
| 356 | host->req->stop->error = error_code; | ||
| 357 | } else if (host->state == BRS | ||
| 358 | || host->state == CARD | ||
| 359 | || host->state == FIFO) { | ||
| 360 | host->req->cmd->error = error_code; | ||
| 361 | tifm_sd_exec(host, host->req->stop); | ||
| 362 | host->state = SCMD; | ||
| 363 | goto done; | ||
| 364 | } else { | ||
| 365 | host->req->cmd->error = error_code; | ||
| 366 | } | ||
| 367 | } else { | ||
| 368 | host->req->cmd->error = error_code; | ||
| 369 | } | ||
| 370 | host->state = READY; | ||
| 371 | } | ||
| 372 | |||
| 373 | if (host_status & TIFM_MMCSD_CB) | ||
| 374 | host->flags |= CARD_BUSY; | ||
| 375 | if ((host_status & TIFM_MMCSD_EOFB) | ||
| 376 | && (host->flags & CARD_BUSY)) { | ||
| 377 | host->written_blocks++; | ||
| 378 | host->flags &= ~CARD_BUSY; | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 382 | if (host->req) | ||
| 383 | tifm_sd_process_cmd(sock, host, host_status); | ||
| 384 | done: | ||
| 385 | dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n", | ||
| 386 | host_status, fifo_status); | ||
| 387 | spin_unlock(&sock->lock); | ||
| 388 | } | ||
| 389 | |||
| 390 | static void tifm_sd_prepare_data(struct tifm_sd *host, struct mmc_command *cmd) | ||
| 391 | { | ||
| 392 | struct tifm_dev *sock = host->dev; | ||
| 393 | unsigned int dest_cnt; | ||
| 394 | |||
| 395 | /* DMA style IO */ | ||
| 396 | dev_dbg(&sock->dev, "setting dma for %d blocks\n", | ||
| 397 | cmd->data->blocks); | ||
| 398 | writel(TIFM_FIFO_INT_SETALL, | ||
| 399 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
| 400 | writel(ilog2(cmd->data->blksz) - 2, | ||
| 401 | sock->addr + SOCK_FIFO_PAGE_SIZE); | ||
| 402 | writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL); | ||
| 403 | writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
| 404 | |||
| 405 | dest_cnt = (cmd->data->blocks) << 8; | ||
| 406 | |||
| 407 | writel(sg_dma_address(cmd->data->sg), sock->addr + SOCK_DMA_ADDRESS); | ||
| 408 | |||
| 409 | writel(cmd->data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
| 410 | writel(cmd->data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN); | ||
| 411 | |||
| 412 | if (cmd->data->flags & MMC_DATA_WRITE) { | ||
| 413 | writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
| 414 | writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN, | ||
| 415 | sock->addr + SOCK_DMA_CONTROL); | ||
| 416 | } else { | ||
| 417 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
| 418 | writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL); | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | static void tifm_sd_set_data_timeout(struct tifm_sd *host, | ||
| 423 | struct mmc_data *data) | ||
| 424 | { | ||
| 425 | struct tifm_dev *sock = host->dev; | ||
| 426 | unsigned int data_timeout = data->timeout_clks; | ||
| 427 | |||
| 428 | if (fixed_timeout) | ||
| 429 | return; | ||
| 430 | |||
| 431 | data_timeout += data->timeout_ns / | ||
| 432 | ((1000000000UL / host->clk_freq) * host->clk_div); | ||
| 433 | |||
| 434 | if (data_timeout < 0xffff) { | ||
| 435 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
| 436 | writel((~TIFM_MMCSD_DPE) | ||
| 437 | & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
| 438 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
| 439 | } else { | ||
| 440 | data_timeout = (data_timeout >> 10) + 1; | ||
| 441 | if (data_timeout > 0xffff) | ||
| 442 | data_timeout = 0; /* set to unlimited */ | ||
| 443 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
| 444 | writel(TIFM_MMCSD_DPE | ||
| 445 | | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
| 446 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
| 447 | } | ||
| 448 | } | ||
| 449 | |||
| 450 | static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
| 451 | { | ||
| 452 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 453 | struct tifm_dev *sock = host->dev; | ||
| 454 | unsigned long flags; | ||
| 455 | int sg_count = 0; | ||
| 456 | struct mmc_data *r_data = mrq->cmd->data; | ||
| 457 | |||
| 458 | spin_lock_irqsave(&sock->lock, flags); | ||
| 459 | if (host->flags & EJECT) { | ||
| 460 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 461 | goto err_out; | ||
| 462 | } | ||
| 463 | |||
| 464 | if (host->req) { | ||
| 465 | printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); | ||
| 466 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 467 | goto err_out; | ||
| 468 | } | ||
| 469 | |||
| 470 | if (r_data) { | ||
| 471 | tifm_sd_set_data_timeout(host, r_data); | ||
| 472 | |||
| 473 | sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len, | ||
| 474 | mrq->cmd->flags & MMC_DATA_WRITE | ||
| 475 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
| 476 | if (sg_count != 1) { | ||
| 477 | printk(KERN_ERR DRIVER_NAME | ||
| 478 | ": scatterlist map failed\n"); | ||
| 479 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 480 | goto err_out; | ||
| 481 | } | ||
| 482 | |||
| 483 | host->written_blocks = 0; | ||
| 484 | host->flags &= ~CARD_BUSY; | ||
| 485 | tifm_sd_prepare_data(host, mrq->cmd); | ||
| 486 | } | ||
| 487 | |||
| 488 | host->req = mrq; | ||
| 489 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | ||
| 490 | host->state = CMD; | ||
| 491 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | ||
| 492 | sock->addr + SOCK_CONTROL); | ||
| 493 | tifm_sd_exec(host, mrq->cmd); | ||
| 494 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 495 | return; | ||
| 496 | |||
| 497 | err_out: | ||
| 498 | if (sg_count > 0) | ||
| 499 | tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, | ||
| 500 | (r_data->flags & MMC_DATA_WRITE) | ||
| 501 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
| 502 | |||
| 503 | mrq->cmd->error = MMC_ERR_TIMEOUT; | ||
| 504 | mmc_request_done(mmc, mrq); | ||
| 505 | } | ||
| 506 | |||
| 507 | static void tifm_sd_end_cmd(unsigned long data) | ||
| 508 | { | ||
| 509 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
| 510 | struct tifm_dev *sock = host->dev; | ||
| 511 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 512 | struct mmc_request *mrq; | ||
| 513 | struct mmc_data *r_data = NULL; | ||
| 514 | unsigned long flags; | ||
| 515 | |||
| 516 | spin_lock_irqsave(&sock->lock, flags); | ||
| 517 | |||
| 518 | del_timer(&host->timer); | ||
| 519 | mrq = host->req; | ||
| 520 | host->req = NULL; | ||
| 521 | host->state = IDLE; | ||
| 522 | |||
| 523 | if (!mrq) { | ||
| 524 | printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); | ||
| 525 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 526 | return; | ||
| 527 | } | ||
| 528 | |||
| 529 | r_data = mrq->cmd->data; | ||
| 530 | if (r_data) { | ||
| 531 | if (r_data->flags & MMC_DATA_WRITE) { | ||
| 532 | r_data->bytes_xfered = host->written_blocks | ||
| 533 | * r_data->blksz; | ||
| 534 | } else { | ||
| 535 | r_data->bytes_xfered = r_data->blocks - | ||
| 536 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | ||
| 537 | r_data->bytes_xfered *= r_data->blksz; | ||
| 538 | r_data->bytes_xfered += r_data->blksz - | ||
| 539 | readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; | ||
| 540 | } | ||
| 541 | tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, | ||
| 542 | (r_data->flags & MMC_DATA_WRITE) | ||
| 543 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
| 544 | } | ||
| 545 | |||
| 546 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | ||
| 547 | sock->addr + SOCK_CONTROL); | ||
| 548 | |||
| 549 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 550 | mmc_request_done(mmc, mrq); | ||
| 551 | } | ||
| 552 | |||
| 553 | static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq) | ||
| 554 | { | ||
| 555 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 556 | struct tifm_dev *sock = host->dev; | ||
| 557 | unsigned long flags; | ||
| 558 | struct mmc_data *r_data = mrq->cmd->data; | ||
| 559 | |||
| 560 | spin_lock_irqsave(&sock->lock, flags); | ||
| 561 | if (host->flags & EJECT) { | ||
| 562 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 563 | goto err_out; | ||
| 564 | } | ||
| 565 | |||
| 566 | if (host->req) { | ||
| 567 | printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); | ||
| 568 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 569 | goto err_out; | ||
| 570 | } | ||
| 571 | |||
| 572 | if (r_data) { | ||
| 573 | tifm_sd_set_data_timeout(host, r_data); | ||
| 574 | |||
| 575 | host->buffer_size = mrq->cmd->data->blocks | ||
| 576 | * mrq->cmd->data->blksz; | ||
| 577 | |||
| 578 | writel(TIFM_MMCSD_BUFINT | ||
| 579 | | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
| 580 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 581 | writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) | ||
| 582 | | (TIFM_MMCSD_FIFO_SIZE - 1), | ||
| 583 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
| 584 | |||
| 585 | host->written_blocks = 0; | ||
| 586 | host->flags &= ~CARD_BUSY; | ||
| 587 | host->buffer_pos = 0; | ||
| 588 | writel(r_data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
| 589 | writel(r_data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN); | ||
| 590 | } | ||
| 591 | |||
| 592 | host->req = mrq; | ||
| 593 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | ||
| 594 | host->state = CMD; | ||
| 595 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | ||
| 596 | sock->addr + SOCK_CONTROL); | ||
| 597 | tifm_sd_exec(host, mrq->cmd); | ||
| 598 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 599 | return; | ||
| 600 | |||
| 601 | err_out: | ||
| 602 | mrq->cmd->error = MMC_ERR_TIMEOUT; | ||
| 603 | mmc_request_done(mmc, mrq); | ||
| 604 | } | ||
| 605 | |||
| 606 | static void tifm_sd_end_cmd_nodma(unsigned long data) | ||
| 607 | { | ||
| 608 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
| 609 | struct tifm_dev *sock = host->dev; | ||
| 610 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 611 | struct mmc_request *mrq; | ||
| 612 | struct mmc_data *r_data = NULL; | ||
| 613 | unsigned long flags; | ||
| 614 | |||
| 615 | spin_lock_irqsave(&sock->lock, flags); | ||
| 616 | |||
| 617 | del_timer(&host->timer); | ||
| 618 | mrq = host->req; | ||
| 619 | host->req = NULL; | ||
| 620 | host->state = IDLE; | ||
| 621 | |||
| 622 | if (!mrq) { | ||
| 623 | printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); | ||
| 624 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 625 | return; | ||
| 626 | } | ||
| 627 | |||
| 628 | r_data = mrq->cmd->data; | ||
| 629 | if (r_data) { | ||
| 630 | writel((~TIFM_MMCSD_BUFINT) & | ||
| 631 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
| 632 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 633 | |||
| 634 | if (r_data->flags & MMC_DATA_WRITE) { | ||
| 635 | r_data->bytes_xfered = host->written_blocks | ||
| 636 | * r_data->blksz; | ||
| 637 | } else { | ||
| 638 | r_data->bytes_xfered = r_data->blocks - | ||
| 639 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | ||
| 640 | r_data->bytes_xfered *= r_data->blksz; | ||
| 641 | r_data->bytes_xfered += r_data->blksz - | ||
| 642 | readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; | ||
| 643 | } | ||
| 644 | host->buffer_pos = 0; | ||
| 645 | host->buffer_size = 0; | ||
| 646 | } | ||
| 647 | |||
| 648 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | ||
| 649 | sock->addr + SOCK_CONTROL); | ||
| 650 | |||
| 651 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 652 | |||
| 653 | mmc_request_done(mmc, mrq); | ||
| 654 | } | ||
| 655 | |||
| 656 | static void tifm_sd_terminate(struct tifm_sd *host) | ||
| 657 | { | ||
| 658 | struct tifm_dev *sock = host->dev; | ||
| 659 | unsigned long flags; | ||
| 660 | |||
| 661 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 662 | mmiowb(); | ||
| 663 | spin_lock_irqsave(&sock->lock, flags); | ||
| 664 | host->flags |= EJECT; | ||
| 665 | if (host->req) { | ||
| 666 | writel(TIFM_FIFO_INT_SETALL, | ||
| 667 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
| 668 | writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
| 669 | tasklet_schedule(&host->finish_tasklet); | ||
| 670 | } | ||
| 671 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 672 | } | ||
| 673 | |||
| 674 | static void tifm_sd_abort(unsigned long data) | ||
| 675 | { | ||
| 676 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
| 677 | |||
| 678 | printk(KERN_ERR DRIVER_NAME | ||
| 679 | ": card failed to respond for a long period of time"); | ||
| 680 | |||
| 681 | tifm_sd_terminate(host); | ||
| 682 | tifm_eject(host->dev); | ||
| 683 | } | ||
| 684 | |||
| 685 | static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
| 686 | { | ||
| 687 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 688 | struct tifm_dev *sock = host->dev; | ||
| 689 | unsigned int clk_div1, clk_div2; | ||
| 690 | unsigned long flags; | ||
| 691 | |||
| 692 | spin_lock_irqsave(&sock->lock, flags); | ||
| 693 | |||
| 694 | dev_dbg(&sock->dev, "Setting bus width %d, power %d\n", ios->bus_width, | ||
| 695 | ios->power_mode); | ||
| 696 | if (ios->bus_width == MMC_BUS_WIDTH_4) { | ||
| 697 | writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
| 698 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 699 | } else { | ||
| 700 | writel((~TIFM_MMCSD_4BBUS) | ||
| 701 | & readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
| 702 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 703 | } | ||
| 704 | |||
| 705 | if (ios->clock) { | ||
| 706 | clk_div1 = 20000000 / ios->clock; | ||
| 707 | if (!clk_div1) | ||
| 708 | clk_div1 = 1; | ||
| 709 | |||
| 710 | clk_div2 = 24000000 / ios->clock; | ||
| 711 | if (!clk_div2) | ||
| 712 | clk_div2 = 1; | ||
| 713 | |||
| 714 | if ((20000000 / clk_div1) > ios->clock) | ||
| 715 | clk_div1++; | ||
| 716 | if ((24000000 / clk_div2) > ios->clock) | ||
| 717 | clk_div2++; | ||
| 718 | if ((20000000 / clk_div1) > (24000000 / clk_div2)) { | ||
| 719 | host->clk_freq = 20000000; | ||
| 720 | host->clk_div = clk_div1; | ||
| 721 | writel((~TIFM_CTRL_FAST_CLK) | ||
| 722 | & readl(sock->addr + SOCK_CONTROL), | ||
| 723 | sock->addr + SOCK_CONTROL); | ||
| 724 | } else { | ||
| 725 | host->clk_freq = 24000000; | ||
| 726 | host->clk_div = clk_div2; | ||
| 727 | writel(TIFM_CTRL_FAST_CLK | ||
| 728 | | readl(sock->addr + SOCK_CONTROL), | ||
| 729 | sock->addr + SOCK_CONTROL); | ||
| 730 | } | ||
| 731 | } else { | ||
| 732 | host->clk_div = 0; | ||
| 733 | } | ||
| 734 | host->clk_div &= TIFM_MMCSD_CLKMASK; | ||
| 735 | writel(host->clk_div | ||
| 736 | | ((~TIFM_MMCSD_CLKMASK) | ||
| 737 | & readl(sock->addr + SOCK_MMCSD_CONFIG)), | ||
| 738 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 739 | |||
| 740 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) | ||
| 741 | host->flags |= OPENDRAIN; | ||
| 742 | else | ||
| 743 | host->flags &= ~OPENDRAIN; | ||
| 744 | |||
| 745 | /* chip_select : maybe later */ | ||
| 746 | //vdd | ||
| 747 | //power is set before probe / after remove | ||
| 748 | //I believe, power_off when already marked for eject is sufficient to | ||
| 749 | // allow removal. | ||
| 750 | if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) { | ||
| 751 | host->flags |= EJECT_DONE; | ||
| 752 | wake_up_all(&host->notify); | ||
| 753 | } | ||
| 754 | |||
| 755 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 756 | } | ||
| 757 | |||
| 758 | static int tifm_sd_ro(struct mmc_host *mmc) | ||
| 759 | { | ||
| 760 | int rc; | ||
| 761 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 762 | struct tifm_dev *sock = host->dev; | ||
| 763 | unsigned long flags; | ||
| 764 | |||
| 765 | spin_lock_irqsave(&sock->lock, flags); | ||
| 766 | |||
| 767 | host->flags |= (CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE)); | ||
| 768 | rc = (host->flags & CARD_RO) ? 1 : 0; | ||
| 769 | |||
| 770 | spin_unlock_irqrestore(&sock->lock, flags); | ||
| 771 | return rc; | ||
| 772 | } | ||
| 773 | |||
| 774 | static struct mmc_host_ops tifm_sd_ops = { | ||
| 775 | .request = tifm_sd_request, | ||
| 776 | .set_ios = tifm_sd_ios, | ||
| 777 | .get_ro = tifm_sd_ro | ||
| 778 | }; | ||
| 779 | |||
| 780 | static int tifm_sd_initialize_host(struct tifm_sd *host) | ||
| 781 | { | ||
| 782 | int rc; | ||
| 783 | unsigned int host_status = 0; | ||
| 784 | struct tifm_dev *sock = host->dev; | ||
| 785 | |||
| 786 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 787 | mmiowb(); | ||
| 788 | host->clk_div = 61; | ||
| 789 | host->clk_freq = 20000000; | ||
| 790 | writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); | ||
| 791 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
| 792 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 793 | |||
| 794 | /* wait up to 0.51 sec for reset */ | ||
| 795 | for (rc = 2; rc <= 256; rc <<= 1) { | ||
| 796 | if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) { | ||
| 797 | rc = 0; | ||
| 798 | break; | ||
| 799 | } | ||
| 800 | msleep(rc); | ||
| 801 | } | ||
| 802 | |||
| 803 | if (rc) { | ||
| 804 | printk(KERN_ERR DRIVER_NAME | ||
| 805 | ": controller failed to reset\n"); | ||
| 806 | return -ENODEV; | ||
| 807 | } | ||
| 808 | |||
| 809 | writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
| 810 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
| 811 | sock->addr + SOCK_MMCSD_CONFIG); | ||
| 812 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
| 813 | |||
| 814 | // command timeout fixed to 64 clocks for now | ||
| 815 | writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); | ||
| 816 | writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND); | ||
| 817 | |||
| 818 | /* INAB should take much less than reset */ | ||
| 819 | for (rc = 1; rc <= 16; rc <<= 1) { | ||
| 820 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
| 821 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
| 822 | if (!(host_status & TIFM_MMCSD_ERRMASK) | ||
| 823 | && (host_status & TIFM_MMCSD_EOC)) { | ||
| 824 | rc = 0; | ||
| 825 | break; | ||
| 826 | } | ||
| 827 | msleep(rc); | ||
| 828 | } | ||
| 829 | |||
| 830 | if (rc) { | ||
| 831 | printk(KERN_ERR DRIVER_NAME | ||
| 832 | ": card not ready - probe failed on initialization\n"); | ||
| 833 | return -ENODEV; | ||
| 834 | } | ||
| 835 | |||
| 836 | writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK, | ||
| 837 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
| 838 | mmiowb(); | ||
| 839 | |||
| 840 | return 0; | ||
| 841 | } | ||
| 842 | |||
| 843 | static int tifm_sd_probe(struct tifm_dev *sock) | ||
| 844 | { | ||
| 845 | struct mmc_host *mmc; | ||
| 846 | struct tifm_sd *host; | ||
| 847 | int rc = -EIO; | ||
| 848 | |||
| 849 | if (!(TIFM_SOCK_STATE_OCCUPIED | ||
| 850 | & readl(sock->addr + SOCK_PRESENT_STATE))) { | ||
| 851 | printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n"); | ||
| 852 | return rc; | ||
| 853 | } | ||
| 854 | |||
| 855 | mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev); | ||
| 856 | if (!mmc) | ||
| 857 | return -ENOMEM; | ||
| 858 | |||
| 859 | host = mmc_priv(mmc); | ||
| 860 | tifm_set_drvdata(sock, mmc); | ||
| 861 | host->dev = sock; | ||
| 862 | host->timeout_jiffies = msecs_to_jiffies(1000); | ||
| 863 | |||
| 864 | init_waitqueue_head(&host->notify); | ||
| 865 | tasklet_init(&host->finish_tasklet, | ||
| 866 | no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd, | ||
| 867 | (unsigned long)host); | ||
| 868 | setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); | ||
| 869 | |||
| 870 | tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request; | ||
| 871 | mmc->ops = &tifm_sd_ops; | ||
| 872 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
| 873 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; | ||
| 874 | mmc->f_min = 20000000 / 60; | ||
| 875 | mmc->f_max = 24000000; | ||
| 876 | mmc->max_hw_segs = 1; | ||
| 877 | mmc->max_phys_segs = 1; | ||
| 878 | // limited by DMA counter - it's safer to stick with | ||
| 879 | // block counter has 11 bits though | ||
| 880 | mmc->max_blk_count = 256; | ||
| 881 | // 2k maximum hw block length | ||
| 882 | mmc->max_blk_size = 2048; | ||
| 883 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | ||
| 884 | mmc->max_seg_size = mmc->max_req_size; | ||
| 885 | sock->signal_irq = tifm_sd_signal_irq; | ||
| 886 | rc = tifm_sd_initialize_host(host); | ||
| 887 | |||
| 888 | if (!rc) | ||
| 889 | rc = mmc_add_host(mmc); | ||
| 890 | if (rc) | ||
| 891 | goto out_free_mmc; | ||
| 892 | |||
| 893 | return 0; | ||
| 894 | out_free_mmc: | ||
| 895 | mmc_free_host(mmc); | ||
| 896 | return rc; | ||
| 897 | } | ||
| 898 | |||
| 899 | static void tifm_sd_remove(struct tifm_dev *sock) | ||
| 900 | { | ||
| 901 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 902 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 903 | |||
| 904 | del_timer_sync(&host->timer); | ||
| 905 | tifm_sd_terminate(host); | ||
| 906 | wait_event_timeout(host->notify, host->flags & EJECT_DONE, | ||
| 907 | host->timeout_jiffies); | ||
| 908 | tasklet_kill(&host->finish_tasklet); | ||
| 909 | mmc_remove_host(mmc); | ||
| 910 | |||
| 911 | /* The meaning of the bit majority in this constant is unknown. */ | ||
| 912 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
| 913 | sock->addr + SOCK_CONTROL); | ||
| 914 | |||
| 915 | tifm_set_drvdata(sock, NULL); | ||
| 916 | mmc_free_host(mmc); | ||
| 917 | } | ||
| 918 | |||
| 919 | #ifdef CONFIG_PM | ||
| 920 | |||
| 921 | static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state) | ||
| 922 | { | ||
| 923 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 924 | int rc; | ||
| 925 | |||
| 926 | rc = mmc_suspend_host(mmc, state); | ||
| 927 | /* The meaning of the bit majority in this constant is unknown. */ | ||
| 928 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
| 929 | sock->addr + SOCK_CONTROL); | ||
| 930 | return rc; | ||
| 931 | } | ||
| 932 | |||
| 933 | static int tifm_sd_resume(struct tifm_dev *sock) | ||
| 934 | { | ||
| 935 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
| 936 | struct tifm_sd *host = mmc_priv(mmc); | ||
| 937 | |||
| 938 | if (sock->media_id != FM_SD | ||
| 939 | || tifm_sd_initialize_host(host)) { | ||
| 940 | tifm_eject(sock); | ||
| 941 | return 0; | ||
| 942 | } else { | ||
| 943 | return mmc_resume_host(mmc); | ||
| 944 | } | ||
| 945 | } | ||
| 946 | |||
| 947 | #else | ||
| 948 | |||
| 949 | #define tifm_sd_suspend NULL | ||
| 950 | #define tifm_sd_resume NULL | ||
| 951 | |||
| 952 | #endif /* CONFIG_PM */ | ||
| 953 | |||
| 954 | static tifm_media_id tifm_sd_id_tbl[] = { | ||
| 955 | FM_SD, 0 | ||
| 956 | }; | ||
| 957 | |||
| 958 | static struct tifm_driver tifm_sd_driver = { | ||
| 959 | .driver = { | ||
| 960 | .name = DRIVER_NAME, | ||
| 961 | .owner = THIS_MODULE | ||
| 962 | }, | ||
| 963 | .id_table = tifm_sd_id_tbl, | ||
| 964 | .probe = tifm_sd_probe, | ||
| 965 | .remove = tifm_sd_remove, | ||
| 966 | .suspend = tifm_sd_suspend, | ||
| 967 | .resume = tifm_sd_resume | ||
| 968 | }; | ||
| 969 | |||
| 970 | static int __init tifm_sd_init(void) | ||
| 971 | { | ||
| 972 | return tifm_register_driver(&tifm_sd_driver); | ||
| 973 | } | ||
| 974 | |||
| 975 | static void __exit tifm_sd_exit(void) | ||
| 976 | { | ||
| 977 | tifm_unregister_driver(&tifm_sd_driver); | ||
| 978 | } | ||
| 979 | |||
| 980 | MODULE_AUTHOR("Alex Dubov"); | ||
| 981 | MODULE_DESCRIPTION("TI FlashMedia SD driver"); | ||
| 982 | MODULE_LICENSE("GPL"); | ||
| 983 | MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl); | ||
| 984 | MODULE_VERSION(DRIVER_VERSION); | ||
| 985 | |||
| 986 | module_init(tifm_sd_init); | ||
| 987 | module_exit(tifm_sd_exit); | ||
