summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card/block.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 18:57:31 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 18:57:31 -0700
commit6abd2c860e34add677de50e8b134f5af6f4b0893 (patch)
treed201de170ca4851d66dbd02046fea7d95214fad7 /drivers/mmc/card/block.c
parentd2c75f2f4b8be1c78f275c49e399d5a9b21ce924 (diff)
parent019a5f56ec195aceadada18aaaad0f67294bdaef (diff)
downloadop-kernel-dev-6abd2c860e34add677de50e8b134f5af6f4b0893.zip
op-kernel-dev-6abd2c860e34add677de50e8b134f5af6f4b0893.tar.gz
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc: (67 commits) mmc: don't use weight32() pxamci: support arbitrary block size sdio: make the IRQ thread more resilient in the presence of bad states sdio: fix IRQ diagnostic message sdhci: remove old dma module params sdhci: add SDHCI_QUIRK_BROKEN_DMA quirk sdhci: remove DMA capability check from controller's PCI Class reg sdhci: fix a typo mmc: Disabler for Ricoh MMC controller sdio: adaptive interrupt polling mmc: pxamci: add SDIO card interrupt reporting capability mmc: pxamci: set proper buswidth capabilities according to PXA flavor mmc: pxamci: set proper block capabilities according to PXA flavor mmc: pxamci: better pending IRQ determination arm: i.MX/MX1 SDHC implements SD cards read-only switch read-back mmc: add led trigger mmc_spi host driver MMC core learns about SPI MMC/SD card driver learns SPI MMC headers learn about SPI ...
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r--drivers/mmc/card/block.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 93fe2e5..e38d5a3 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -151,17 +151,19 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
cmd.opcode = MMC_APP_CMD;
cmd.arg = card->rca << 16;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
err = mmc_wait_for_cmd(card->host, &cmd, 0);
- if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD))
+ if (err)
+ return (u32)-1;
+ if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
return (u32)-1;
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = SD_APP_SEND_NUM_WR_BLKS;
cmd.arg = 0;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
memset(&data, 0, sizeof(struct mmc_data));
@@ -192,7 +194,7 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
mmc_wait_for_req(card->host, &mrq);
- if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE)
+ if (cmd.error || data.error)
return (u32)-1;
blocks = ntohl(blocks);
@@ -220,17 +222,15 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.cmd.arg = req->sector;
if (!mmc_card_blockaddr(card))
brq.cmd.arg <<= 9;
- brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+ brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
brq.data.blksz = 1 << md->block_bits;
brq.stop.opcode = MMC_STOP_TRANSMISSION;
brq.stop.arg = 0;
- brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
+ brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
if (brq.data.blocks > card->host->max_blk_count)
brq.data.blocks = card->host->max_blk_count;
- mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
-
/*
* If the host doesn't support multiple block writes, force
* block writes to single block. SD cards are excepted from
@@ -243,8 +243,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.data.blocks = 1;
if (brq.data.blocks > 1) {
- brq.data.flags |= MMC_DATA_MULTI;
- brq.mrq.stop = &brq.stop;
+ /* SPI multiblock writes terminate using a special
+ * token, not a STOP_TRANSMISSION request.
+ */
+ if (!mmc_host_is_spi(card->host)
+ || rq_data_dir(req) == READ)
+ brq.mrq.stop = &brq.stop;
readcmd = MMC_READ_MULTIPLE_BLOCK;
writecmd = MMC_WRITE_MULTIPLE_BLOCK;
} else {
@@ -261,6 +265,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.data.flags |= MMC_DATA_WRITE;
}
+ mmc_set_data_timeout(&brq.data, card);
+
brq.data.sg = mq->sg;
brq.data.sg_len = mmc_queue_map_sg(mq);
@@ -302,7 +308,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
goto cmd_err;
}
- if (rq_data_dir(req) != READ) {
+ if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
do {
int err;
@@ -510,7 +516,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
mmc_claim_host(card->host);
cmd.opcode = MMC_SET_BLOCKLEN;
cmd.arg = 1 << md->block_bits;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
err = mmc_wait_for_cmd(card->host, &cmd, 5);
mmc_release_host(card->host);
OpenPOWER on IntegriCloud