diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/au1xmmc.c | 6 | ||||
| -rw-r--r-- | drivers/mmc/imxmmc.c | 24 | ||||
| -rw-r--r-- | drivers/mmc/mmc.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/mmc_block.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/pxamci.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/wbsd.c | 8 |
6 files changed, 25 insertions, 19 deletions
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index 914d62b24064..5dc4bee7abeb 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c | |||
| @@ -310,7 +310,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) | |||
| 310 | } | 310 | } |
| 311 | else | 311 | else |
| 312 | data->bytes_xfered = | 312 | data->bytes_xfered = |
| 313 | (data->blocks * (1 << data->blksz_bits)) - | 313 | (data->blocks * data->blksz) - |
| 314 | host->pio.len; | 314 | host->pio.len; |
| 315 | } | 315 | } |
| 316 | 316 | ||
| @@ -575,7 +575,7 @@ static int | |||
| 575 | au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) | 575 | au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) |
| 576 | { | 576 | { |
| 577 | 577 | ||
| 578 | int datalen = data->blocks * (1 << data->blksz_bits); | 578 | int datalen = data->blocks * data->blksz; |
| 579 | 579 | ||
| 580 | if (dma != 0) | 580 | if (dma != 0) |
| 581 | host->flags |= HOST_F_DMA; | 581 | host->flags |= HOST_F_DMA; |
| @@ -596,7 +596,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) | |||
| 596 | if (host->dma.len == 0) | 596 | if (host->dma.len == 0) |
| 597 | return MMC_ERR_TIMEOUT; | 597 | return MMC_ERR_TIMEOUT; |
| 598 | 598 | ||
| 599 | au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host)); | 599 | au_writel(data->blksz - 1, HOST_BLKSIZE(host)); |
| 600 | 600 | ||
| 601 | if (host->flags & HOST_F_DMA) { | 601 | if (host->flags & HOST_F_DMA) { |
| 602 | int i; | 602 | int i; |
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c index 79358e223f57..a4eb1d0e7a71 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/imxmmc.c | |||
| @@ -218,8 +218,10 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, | |||
| 218 | if(!loops) | 218 | if(!loops) |
| 219 | return 0; | 219 | return 0; |
| 220 | 220 | ||
| 221 | dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n", | 221 | /* The busy-wait is expected there for clock <8MHz due to SDHC hardware flaws */ |
| 222 | loops, where, *pstat, stat_mask); | 222 | if(!(stat_mask & STATUS_END_CMD_RESP) || (host->mmc->ios.clock>=8000000)) |
| 223 | dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n", | ||
| 224 | loops, where, *pstat, stat_mask); | ||
| 223 | return loops; | 225 | return loops; |
| 224 | } | 226 | } |
| 225 | 227 | ||
| @@ -333,6 +335,9 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, | |||
| 333 | WARN_ON(host->cmd != NULL); | 335 | WARN_ON(host->cmd != NULL); |
| 334 | host->cmd = cmd; | 336 | host->cmd = cmd; |
| 335 | 337 | ||
| 338 | /* Ensure, that clock are stopped else command programming and start fails */ | ||
| 339 | imxmci_stop_clock(host); | ||
| 340 | |||
| 336 | if (cmd->flags & MMC_RSP_BUSY) | 341 | if (cmd->flags & MMC_RSP_BUSY) |
| 337 | cmdat |= CMD_DAT_CONT_BUSY; | 342 | cmdat |= CMD_DAT_CONT_BUSY; |
| 338 | 343 | ||
| @@ -553,7 +558,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) | |||
| 553 | int trans_done = 0; | 558 | int trans_done = 0; |
| 554 | unsigned int stat = *pstat; | 559 | unsigned int stat = *pstat; |
| 555 | 560 | ||
| 556 | if(host->actual_bus_width == MMC_BUS_WIDTH_4) | 561 | if(host->actual_bus_width != MMC_BUS_WIDTH_4) |
| 557 | burst_len = 16; | 562 | burst_len = 16; |
| 558 | else | 563 | else |
| 559 | burst_len = 64; | 564 | burst_len = 64; |
| @@ -591,8 +596,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) | |||
| 591 | stat = MMC_STATUS; | 596 | stat = MMC_STATUS; |
| 592 | 597 | ||
| 593 | /* Flush extra bytes from FIFO */ | 598 | /* Flush extra bytes from FIFO */ |
| 594 | while(flush_len >= 2){ | 599 | while(flush_len && !(stat & STATUS_DATA_TRANS_DONE)){ |
| 595 | flush_len -= 2; | ||
| 596 | i = MMC_BUFFER_ACCESS; | 600 | i = MMC_BUFFER_ACCESS; |
| 597 | stat = MMC_STATUS; | 601 | stat = MMC_STATUS; |
| 598 | stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */ | 602 | stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */ |
| @@ -746,10 +750,6 @@ static void imxmci_tasklet_fnc(unsigned long data) | |||
| 746 | data_dir_mask = STATUS_DATA_TRANS_DONE; | 750 | data_dir_mask = STATUS_DATA_TRANS_DONE; |
| 747 | } | 751 | } |
| 748 | 752 | ||
| 749 | imxmci_busy_wait_for_status(host, &stat, | ||
| 750 | data_dir_mask, | ||
| 751 | 50, "imxmci_tasklet_fnc data"); | ||
| 752 | |||
| 753 | if(stat & data_dir_mask) { | 753 | if(stat & data_dir_mask) { |
| 754 | clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); | 754 | clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events); |
| 755 | imxmci_data_done(host, stat); | 755 | imxmci_data_done(host, stat); |
| @@ -865,7 +865,11 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 865 | 865 | ||
| 866 | imxmci_stop_clock(host); | 866 | imxmci_stop_clock(host); |
| 867 | MMC_CLK_RATE = (prescaler<<3) | clk; | 867 | MMC_CLK_RATE = (prescaler<<3) | clk; |
| 868 | imxmci_start_clock(host); | 868 | /* |
| 869 | * Under my understanding, clock should not be started there, because it would | ||
| 870 | * initiate SDHC sequencer and send last or random command into card | ||
| 871 | */ | ||
| 872 | /*imxmci_start_clock(host);*/ | ||
| 869 | 873 | ||
| 870 | dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE); | 874 | dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE); |
| 871 | } else { | 875 | } else { |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 1ca2c8b9c9b5..6201f3086a02 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
| @@ -951,6 +951,7 @@ static void mmc_read_scrs(struct mmc_host *host) | |||
| 951 | data.timeout_ns = card->csd.tacc_ns * 10; | 951 | data.timeout_ns = card->csd.tacc_ns * 10; |
| 952 | data.timeout_clks = card->csd.tacc_clks * 10; | 952 | data.timeout_clks = card->csd.tacc_clks * 10; |
| 953 | data.blksz_bits = 3; | 953 | data.blksz_bits = 3; |
| 954 | data.blksz = 1 << 3; | ||
| 954 | data.blocks = 1; | 955 | data.blocks = 1; |
| 955 | data.flags = MMC_DATA_READ; | 956 | data.flags = MMC_DATA_READ; |
| 956 | data.sg = &sg; | 957 | data.sg = &sg; |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 06bd1f4cb9b1..e39cc05c64c2 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
| @@ -175,6 +175,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 175 | brq.data.timeout_ns = card->csd.tacc_ns * 10; | 175 | brq.data.timeout_ns = card->csd.tacc_ns * 10; |
| 176 | brq.data.timeout_clks = card->csd.tacc_clks * 10; | 176 | brq.data.timeout_clks = card->csd.tacc_clks * 10; |
| 177 | brq.data.blksz_bits = md->block_bits; | 177 | brq.data.blksz_bits = md->block_bits; |
| 178 | brq.data.blksz = 1 << md->block_bits; | ||
| 178 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); | 179 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); |
| 179 | brq.stop.opcode = MMC_STOP_TRANSMISSION; | 180 | brq.stop.opcode = MMC_STOP_TRANSMISSION; |
| 180 | brq.stop.arg = 0; | 181 | brq.stop.arg = 0; |
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index f97b472085cb..b49368fd96b8 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c | |||
| @@ -119,7 +119,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) | |||
| 119 | nob = 0xffff; | 119 | nob = 0xffff; |
| 120 | 120 | ||
| 121 | writel(nob, host->base + MMC_NOB); | 121 | writel(nob, host->base + MMC_NOB); |
| 122 | writel(1 << data->blksz_bits, host->base + MMC_BLKLEN); | 122 | writel(data->blksz, host->base + MMC_BLKLEN); |
| 123 | 123 | ||
| 124 | clks = (unsigned long long)data->timeout_ns * CLOCKRATE; | 124 | clks = (unsigned long long)data->timeout_ns * CLOCKRATE; |
| 125 | do_div(clks, 1000000000UL); | 125 | do_div(clks, 1000000000UL); |
| @@ -283,7 +283,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) | |||
| 283 | * data blocks as being in error. | 283 | * data blocks as being in error. |
| 284 | */ | 284 | */ |
| 285 | if (data->error == MMC_ERR_NONE) | 285 | if (data->error == MMC_ERR_NONE) |
| 286 | data->bytes_xfered = data->blocks << data->blksz_bits; | 286 | data->bytes_xfered = data->blocks * data->blksz; |
| 287 | else | 287 | else |
| 288 | data->bytes_xfered = 0; | 288 | data->bytes_xfered = 0; |
| 289 | 289 | ||
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 39b3d97f891e..8167332d4013 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
| @@ -662,14 +662,14 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 662 | unsigned long dmaflags; | 662 | unsigned long dmaflags; |
| 663 | 663 | ||
| 664 | DBGF("blksz %04x blks %04x flags %08x\n", | 664 | DBGF("blksz %04x blks %04x flags %08x\n", |
| 665 | 1 << data->blksz_bits, data->blocks, data->flags); | 665 | data->blksz, data->blocks, data->flags); |
| 666 | DBGF("tsac %d ms nsac %d clk\n", | 666 | DBGF("tsac %d ms nsac %d clk\n", |
| 667 | data->timeout_ns / 1000000, data->timeout_clks); | 667 | data->timeout_ns / 1000000, data->timeout_clks); |
| 668 | 668 | ||
| 669 | /* | 669 | /* |
| 670 | * Calculate size. | 670 | * Calculate size. |
| 671 | */ | 671 | */ |
| 672 | host->size = data->blocks << data->blksz_bits; | 672 | host->size = data->blocks * data->blksz; |
| 673 | 673 | ||
| 674 | /* | 674 | /* |
| 675 | * Check timeout values for overflow. | 675 | * Check timeout values for overflow. |
| @@ -696,12 +696,12 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
| 696 | * Two bytes are needed for each data line. | 696 | * Two bytes are needed for each data line. |
| 697 | */ | 697 | */ |
| 698 | if (host->bus_width == MMC_BUS_WIDTH_1) { | 698 | if (host->bus_width == MMC_BUS_WIDTH_1) { |
| 699 | blksize = (1 << data->blksz_bits) + 2; | 699 | blksize = data->blksz + 2; |
| 700 | 700 | ||
| 701 | wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); | 701 | wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); |
| 702 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); | 702 | wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); |
| 703 | } else if (host->bus_width == MMC_BUS_WIDTH_4) { | 703 | } else if (host->bus_width == MMC_BUS_WIDTH_4) { |
| 704 | blksize = (1 << data->blksz_bits) + 2 * 4; | 704 | blksize = data->blksz + 2 * 4; |
| 705 | 705 | ||
| 706 | wbsd_write_index(host, WBSD_IDX_PBSMSB, | 706 | wbsd_write_index(host, WBSD_IDX_PBSMSB, |
| 707 | ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH); | 707 | ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH); |
