diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-04 17:52:27 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-04 17:52:27 -0400 |
| commit | 6fc56ccfe44c8bc3fb47d6346c12c3b865756ef8 (patch) | |
| tree | e7e9dabd9d5bcf547946b3ae68e64ea68525e9d0 /drivers | |
| parent | cbdf811c77cf2906a099b8da92e9f6f335b68a73 (diff) | |
| parent | 920e70c5c603ada05dd480ca0ccc0ae12a5fdc39 (diff) | |
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
* master.kernel.org:/home/rmk/linux-2.6-mmc:
[MMC] Move set_ios debugging into mmc.c
[MMC] Correct mmc_request_done comments
[MMC] PXA: reduce the number of lines PXAMCI debug uses
[MMC] PXA and i.MX: don't avoid sending stop command on error
[MMC] extend data timeout for writes
[ARM] 3485/1: i.MX: MX1 SD/MMC fix of unintentional double start possibility
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/mmc/at91_mci.c | 3 | ||||
| -rw-r--r-- | drivers/mmc/au1xmmc.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/imxmmc.c | 60 | ||||
| -rw-r--r-- | drivers/mmc/mmc.c | 62 | ||||
| -rw-r--r-- | drivers/mmc/mmc_block.c | 6 | ||||
| -rw-r--r-- | drivers/mmc/mmci.c | 3 | ||||
| -rw-r--r-- | drivers/mmc/pxamci.c | 13 | ||||
| -rw-r--r-- | drivers/mmc/sdhci.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/wbsd.c | 4 |
9 files changed, 93 insertions, 66 deletions
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c index 6061c2d101a0..88f0eef9cf33 100644 --- a/drivers/mmc/at91_mci.c +++ b/drivers/mmc/at91_mci.c | |||
| @@ -621,9 +621,6 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 621 | struct at91mci_host *host = mmc_priv(mmc); | 621 | struct at91mci_host *host = mmc_priv(mmc); |
| 622 | unsigned long at91_master_clock = clk_get_rate(mci_clk); | 622 | unsigned long at91_master_clock = clk_get_rate(mci_clk); |
| 623 | 623 | ||
| 624 | DBG("Clock %uHz, busmode %u, powermode %u, Vdd %u\n", | ||
| 625 | ios->clock, ios->bus_mode, ios->power_mode, ios->vdd); | ||
| 626 | |||
| 627 | if (host) | 624 | if (host) |
| 628 | host->bus_mode = ios->bus_mode; | 625 | host->bus_mode = ios->bus_mode; |
| 629 | else | 626 | else |
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index c0326bbc5f28..914d62b24064 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c | |||
| @@ -720,10 +720,6 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
| 720 | { | 720 | { |
| 721 | struct au1xmmc_host *host = mmc_priv(mmc); | 721 | struct au1xmmc_host *host = mmc_priv(mmc); |
| 722 | 722 | ||
| 723 | DBG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", | ||
| 724 | host->id, ios->power_mode, ios->clock, ios->vdd, | ||
| 725 | ios->bus_mode); | ||
| 726 | |||
| 727 | if (ios->power_mode == MMC_POWER_OFF) | 723 | if (ios->power_mode == MMC_POWER_OFF) |
| 728 | au1xmmc_set_power(host, 0); | 724 | au1xmmc_set_power(host, 0); |
| 729 | else if (ios->power_mode == MMC_POWER_ON) { | 725 | else if (ios->power_mode == MMC_POWER_ON) { |
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c index ffb7f55d3467..79358e223f57 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/imxmmc.c | |||
| @@ -102,6 +102,7 @@ struct imxmci_host { | |||
| 102 | #define IMXMCI_PEND_CPU_DATA_b 5 | 102 | #define IMXMCI_PEND_CPU_DATA_b 5 |
| 103 | #define IMXMCI_PEND_CARD_XCHG_b 6 | 103 | #define IMXMCI_PEND_CARD_XCHG_b 6 |
| 104 | #define IMXMCI_PEND_SET_INIT_b 7 | 104 | #define IMXMCI_PEND_SET_INIT_b 7 |
| 105 | #define IMXMCI_PEND_STARTED_b 8 | ||
| 105 | 106 | ||
| 106 | #define IMXMCI_PEND_IRQ_m (1 << IMXMCI_PEND_IRQ_b) | 107 | #define IMXMCI_PEND_IRQ_m (1 << IMXMCI_PEND_IRQ_b) |
| 107 | #define IMXMCI_PEND_DMA_END_m (1 << IMXMCI_PEND_DMA_END_b) | 108 | #define IMXMCI_PEND_DMA_END_m (1 << IMXMCI_PEND_DMA_END_b) |
| @@ -111,6 +112,7 @@ struct imxmci_host { | |||
| 111 | #define IMXMCI_PEND_CPU_DATA_m (1 << IMXMCI_PEND_CPU_DATA_b) | 112 | #define IMXMCI_PEND_CPU_DATA_m (1 << IMXMCI_PEND_CPU_DATA_b) |
| 112 | #define IMXMCI_PEND_CARD_XCHG_m (1 << IMXMCI_PEND_CARD_XCHG_b) | 113 | #define IMXMCI_PEND_CARD_XCHG_m (1 << IMXMCI_PEND_CARD_XCHG_b) |
| 113 | #define IMXMCI_PEND_SET_INIT_m (1 << IMXMCI_PEND_SET_INIT_b) | 114 | #define IMXMCI_PEND_SET_INIT_m (1 << IMXMCI_PEND_SET_INIT_b) |
| 115 | #define IMXMCI_PEND_STARTED_m (1 << IMXMCI_PEND_STARTED_b) | ||
| 114 | 116 | ||
| 115 | static void imxmci_stop_clock(struct imxmci_host *host) | 117 | static void imxmci_stop_clock(struct imxmci_host *host) |
| 116 | { | 118 | { |
| @@ -131,23 +133,52 @@ static void imxmci_stop_clock(struct imxmci_host *host) | |||
| 131 | dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n"); | 133 | dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n"); |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | static void imxmci_start_clock(struct imxmci_host *host) | 136 | static int imxmci_start_clock(struct imxmci_host *host) |
| 135 | { | 137 | { |
| 136 | int i = 0; | 138 | unsigned int trials = 0; |
| 139 | unsigned int delay_limit = 128; | ||
| 140 | unsigned long flags; | ||
| 141 | |||
| 137 | MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK; | 142 | MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK; |
| 138 | while(i < 0x1000) { | ||
| 139 | if(!(i & 0x7f)) | ||
| 140 | MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; | ||
| 141 | 143 | ||
| 142 | if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) { | 144 | clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); |
| 143 | /* Check twice before cut */ | 145 | |
| 146 | /* | ||
| 147 | * Command start of the clock, this usually succeeds in less | ||
| 148 | * then 6 delay loops, but during card detection (low clockrate) | ||
| 149 | * it takes up to 5000 delay loops and sometimes fails for the first time | ||
| 150 | */ | ||
| 151 | MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; | ||
| 152 | |||
| 153 | do { | ||
| 154 | unsigned int delay = delay_limit; | ||
| 155 | |||
| 156 | while(delay--){ | ||
| 144 | if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) | 157 | if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) |
| 145 | return; | 158 | /* Check twice before cut */ |
| 159 | if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) | ||
| 160 | return 0; | ||
| 161 | |||
| 162 | if(test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) | ||
| 163 | return 0; | ||
| 146 | } | 164 | } |
| 147 | 165 | ||
| 148 | i++; | 166 | local_irq_save(flags); |
| 149 | } | 167 | /* |
| 150 | dev_dbg(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n"); | 168 | * Ensure, that request is not doubled under all possible circumstances. |
| 169 | * It is possible, that cock running state is missed, because some other | ||
| 170 | * IRQ or schedule delays this function execution and the clocks has | ||
| 171 | * been already stopped by other means (response processing, SDHC HW) | ||
| 172 | */ | ||
| 173 | if(!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) | ||
| 174 | MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; | ||
| 175 | local_irq_restore(flags); | ||
| 176 | |||
| 177 | } while(++trials<256); | ||
| 178 | |||
| 179 | dev_err(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n"); | ||
| 180 | |||
| 181 | return -1; | ||
| 151 | } | 182 | } |
| 152 | 183 | ||
| 153 | static void imxmci_softreset(void) | 184 | static void imxmci_softreset(void) |
| @@ -498,7 +529,7 @@ static int imxmci_data_done(struct imxmci_host *host, unsigned int stat) | |||
| 498 | 529 | ||
| 499 | data_error = imxmci_finish_data(host, stat); | 530 | data_error = imxmci_finish_data(host, stat); |
| 500 | 531 | ||
| 501 | if (host->req->stop && (data_error == MMC_ERR_NONE)) { | 532 | if (host->req->stop) { |
| 502 | imxmci_stop_clock(host); | 533 | imxmci_stop_clock(host); |
| 503 | imxmci_start_cmd(host, host->req->stop, 0); | 534 | imxmci_start_cmd(host, host->req->stop, 0); |
| 504 | } else { | 535 | } else { |
| @@ -622,6 +653,7 @@ static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs) | |||
| 622 | atomic_set(&host->stuck_timeout, 0); | 653 | atomic_set(&host->stuck_timeout, 0); |
| 623 | host->status_reg = stat; | 654 | host->status_reg = stat; |
| 624 | set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); | 655 | set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); |
| 656 | set_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); | ||
| 625 | tasklet_schedule(&host->tasklet); | 657 | tasklet_schedule(&host->tasklet); |
| 626 | 658 | ||
| 627 | return IRQ_RETVAL(handled);; | 659 | return IRQ_RETVAL(handled);; |
| @@ -775,10 +807,6 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 775 | struct imxmci_host *host = mmc_priv(mmc); | 807 | struct imxmci_host *host = mmc_priv(mmc); |
| 776 | int prescaler; | 808 | int prescaler; |
| 777 | 809 | ||
| 778 | dev_dbg(mmc_dev(host->mmc), "clock %u power %u vdd %u width %u\n", | ||
| 779 | ios->clock, ios->power_mode, ios->vdd, | ||
| 780 | (ios->bus_width==MMC_BUS_WIDTH_4)?4:1); | ||
| 781 | |||
| 782 | if( ios->bus_width==MMC_BUS_WIDTH_4 ) { | 810 | if( ios->bus_width==MMC_BUS_WIDTH_4 ) { |
| 783 | host->actual_bus_width = MMC_BUS_WIDTH_4; | 811 | host->actual_bus_width = MMC_BUS_WIDTH_4; |
| 784 | imx_gpio_mode(PB11_PF_SD_DAT3); | 812 | imx_gpio_mode(PB11_PF_SD_DAT3); |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index da6ddd910fc5..1ca2c8b9c9b5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
| @@ -59,21 +59,23 @@ static const unsigned int tacc_mant[] = { | |||
| 59 | 59 | ||
| 60 | 60 | ||
| 61 | /** | 61 | /** |
| 62 | * mmc_request_done - finish processing an MMC command | 62 | * mmc_request_done - finish processing an MMC request |
| 63 | * @host: MMC host which completed command | 63 | * @host: MMC host which completed request |
| 64 | * @mrq: MMC request which completed | 64 | * @mrq: MMC request which request |
| 65 | * | 65 | * |
| 66 | * MMC drivers should call this function when they have completed | 66 | * MMC drivers should call this function when they have completed |
| 67 | * their processing of a command. This should be called before the | 67 | * their processing of a request. |
| 68 | * data part of the command has completed. | ||
| 69 | */ | 68 | */ |
| 70 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | 69 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) |
| 71 | { | 70 | { |
| 72 | struct mmc_command *cmd = mrq->cmd; | 71 | struct mmc_command *cmd = mrq->cmd; |
| 73 | int err = mrq->cmd->error; | ||
