* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc: sdhci-of: Fix the wrong accessor to HOSTVER register mvsdio: fix config failure with some high speed SDHC cards mvsdio: ignore high speed timing requests from the core mmc/omap: Use disable_irq_nosync() from within irq handlers. sdhci-of: Add fsl,esdhc as a valid compatible to bind against mvsdio: allow automatic loading when modular mxcmmc: Fix missing return value checking in DMA setup code. mxcmmc : Reset the SDHC hardware if software timeout occurs. omap_hsmmc: Trivial fix for a typo in comment mxcmmc: decrease minimum frequency to make MMC cards work
Unified · Split
| @@ -64,6 +64,31 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data) · 63 unmodified lines | ||
| 64 | 64 | unsigned int tmout; |
| 65 | 65 | int tmout_index; |
| 66 | 66 | |
| 67 | + /* | |
| 68 | + * Hardware weirdness. The FIFO_EMPTY bit of the HW_STATE | |
| 69 | + * register is sometimes not set before a while when some | |
| 70 | + * "unusual" data block sizes are used (such as with the SWITCH | |
| 71 | + * command), even despite the fact that the XFER_DONE interrupt | |
| 72 | + * was raised. And if another data transfer starts before | |
| 73 | + * this bit comes to good sense (which eventually happens by | |
| 74 | + * itself) then the new transfer simply fails with a timeout. | |
| 75 | + */ | |
| 76 | + if (!(mvsd_read(MVSD_HW_STATE) & (1 << 13))) { | |
| 77 | + unsigned long t = jiffies + HZ; | |
| 78 | + unsigned int hw_state, count = 0; | |
| 79 | + do { | |
| 80 | + if (time_after(jiffies, t)) { | |
| 81 | + dev_warn(host->dev, "FIFO_EMPTY bit missing\n"); | |
| 82 | + break; | |
| 83 | + } | |
| 84 | + hw_state = mvsd_read(MVSD_HW_STATE); | |
| 85 | + count++; | |
| 86 | + } while (!(hw_state & (1 << 13))); | |
| 87 | + dev_dbg(host->dev, "*** wait for FIFO_EMPTY bit " | |
| 88 | + "(hw=0x%04x, count=%d, jiffies=%ld)\n", | |
| 89 | + hw_state, count, jiffies - (t - HZ)); | |
| 90 | + } | |
| 91 | + | |
| 67 | 92 | /* If timeout=0 then maximum timeout index is used. */ |
| 68 | 93 | tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk); |
| 69 | 94 | tmout += data->timeout_clks; |
| @@ -620,9 +645,18 @@ static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 550 unmodified lines | ||
| 620 | 645 | if (ios->bus_width == MMC_BUS_WIDTH_4) |
| 621 | 646 | ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS; |
| 622 | 647 | |
| 648 | + /* | |
| 649 | + * The HI_SPEED_EN bit is causing trouble with many (but not all) | |
| 650 | + * high speed SD, SDHC and SDIO cards. Not enabling that bit | |
| 651 | + * makes all cards work. So let's just ignore that bit for now | |
| 652 | + * and revisit this issue if problems for not enabling this bit | |
| 653 | + * are ever reported. | |
| 654 | + */ | |
| 655 | +#if 0 | |
| 623 | 656 | if (ios->timing == MMC_TIMING_MMC_HS || |
| 624 | 657 | ios->timing == MMC_TIMING_SD_HS) |
| 625 | 658 | ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN; |
| 659 | +#endif | |
| 626 | 660 | |
| 627 | 661 | host->ctrl = ctrl_reg; |
| 628 | 662 | mvsd_write(MVSD_HOST_CTRL, ctrl_reg); |
| @@ -882,3 +916,4 @@ module_param(nodma, int, 0); · 253 unmodified lines | ||
| 882 | 916 | MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre"); |
| 883 | 917 | MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver"); |
| 884 | 918 | MODULE_LICENSE("GPL"); |
| 919 | +MODULE_ALIAS("platform:mvsdio"); | |
| @@ -140,6 +140,8 @@ struct mxcmci_host { · 139 unmodified lines | ||
| 140 | 140 | struct work_struct datawork; |
| 141 | 141 | }; |
| 142 | 142 | |
| 143 | +static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); | |
| 144 | + | |
| 143 | 145 | static inline int mxcmci_use_dma(struct mxcmci_host *host) |
| 144 | 146 | { |
| 145 | 147 | return host->do_dma; |
| @@ -160,7 +162,7 @@ static void mxcmci_softreset(struct mxcmci_host *host) · 14 unmodified lines | ||
| 160 | 162 | writew(0xff, host->base + MMC_REG_RES_TO); |
| 161 | 163 | } |
| 162 | 164 | |
| 163 | −static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) | |
| 165 | +static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) | |
| 164 | 166 | { |
| 165 | 167 | unsigned int nob = data->blocks; |
| 166 | 168 | unsigned int blksz = data->blksz; |
| @@ -168,6 +170,7 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) · 1 unmodified line | ||
| 168 | 170 | #ifdef HAS_DMA |
| 169 | 171 | struct scatterlist *sg; |
| 170 | 172 | int i; |
| 173 | + int ret; | |
| 171 | 174 | #endif |
| 172 | 175 | if (data->flags & MMC_DATA_STREAM) |
| 173 | 176 | nob = 0xffff; |
| @@ -183,7 +186,7 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) · 9 unmodified lines | ||
| 183 | 186 | for_each_sg(data->sg, sg, data->sg_len, i) { |
| 184 | 187 | if (sg->offset & 3 || sg->length & 3) { |
| 185 | 188 | host->do_dma = 0; |
| 186 | − return; | |
| 189 | + return 0; | |
| 187 | 190 | } |
| 188 | 191 | } |
| 189 | 192 | |
| @@ -192,23 +195,30 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) · 2 unmodified lines | ||
| 192 | 195 | host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, |
| 193 | 196 | data->sg_len, host->dma_dir); |
| 194 | 197 | |
| 195 | − imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize, | |
| 196 | − host->res->start + MMC_REG_BUFFER_ACCESS, | |
| 197 | − DMA_MODE_READ); | |
| 198 | + ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, | |
| 199 | + datasize, | |
| 200 | + host->res->start + MMC_REG_BUFFER_ACCESS, | |
| 201 | + DMA_MODE_READ); | |
| 198 | 202 | } else { |
| 199 | 203 | host->dma_dir = DMA_TO_DEVICE; |
| 200 | 204 | host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, |
| 201 | 205 | data->sg_len, host->dma_dir); |
| 202 | 206 | |
| 203 | − imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize, | |
| 204 | − host->res->start + MMC_REG_BUFFER_ACCESS, | |
| 205 | − DMA_MODE_WRITE); | |
| 207 | + ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, | |
| 208 | + datasize, | |
| 209 | + host->res->start + MMC_REG_BUFFER_ACCESS, | |
| 210 | + DMA_MODE_WRITE); | |
| 206 | 211 | } |
| 207 | 212 | |
| 213 | + if (ret) { | |
| 214 | + dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret); | |
| 215 | + return ret; | |
| 216 | + } | |
| 208 | 217 | wmb(); |
| 209 | 218 | |
| 210 | 219 | imx_dma_enable(host->dma); |
| 211 | 220 | #endif /* HAS_DMA */ |
| 221 | + return 0; | |
| 212 | 222 | } |
| 213 | 223 | |
| 214 | 224 | static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, |
| @@ -345,8 +355,11 @@ static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask) · 130 unmodified lines | ||
| 345 | 355 | stat = readl(host->base + MMC_REG_STATUS); |
| 346 | 356 | if (stat & STATUS_ERR_MASK) |
| 347 | 357 | return stat; |
| 348 | − if (time_after(jiffies, timeout)) | |
| 358 | + if (time_after(jiffies, timeout)) { | |
| 359 | + mxcmci_softreset(host); | |
| 360 | + mxcmci_set_clk_rate(host, host->clock); | |
| 349 | 361 | return STATUS_TIME_OUT_READ; |
| 362 | + } | |
| 350 | 363 | if (stat & mask) |
| 351 | 364 | return 0; |
| 352 | 365 | cpu_relax(); |
| @@ -531,6 +544,7 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) · 178 unmodified lines | ||
| 531 | 544 | { |
| 532 | 545 | struct mxcmci_host *host = mmc_priv(mmc); |
| 533 | 546 | unsigned int cmdat = host->cmdat; |
| 547 | + int error; | |
| 534 | 548 | |
| 535 | 549 | WARN_ON(host->req != NULL); |
| 536 | 550 | |
| @@ -540,7 +554,12 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) · 3 unmodified lines | ||
| 540 | 554 | host->do_dma = 1; |
| 541 | 555 | #endif |
| 542 | 556 | if (req->data) { |
| 543 | − mxcmci_setup_data(host, req->data); | |
| 557 | + error = mxcmci_setup_data(host, req->data); | |
| 558 | + if (error) { | |
| 559 | + req->cmd->error = error; | |
| 560 | + goto out; | |
| 561 | + } | |
| 562 | + | |
| 544 | 563 | |
| 545 | 564 | cmdat |= CMD_DAT_CONT_DATA_ENABLE; |
| 546 | 565 | |
| @@ -548,7 +567,9 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) · 1 unmodified line | ||
| 548 | 567 | cmdat |= CMD_DAT_CONT_WRITE; |
| 549 | 568 | } |
| 550 | 569 | |
| 551 | − if (mxcmci_start_cmd(host, req->cmd, cmdat)) | |
| 570 | + error = mxcmci_start_cmd(host, req->cmd, cmdat); | |
| 571 | +out: | |
| 572 | + if (error) | |
| 552 | 573 | mxcmci_finish_request(host, req); |
| 553 | 574 | } |
| 554 | 575 | |
| @@ -724,7 +745,9 @@ static int mxcmci_probe(struct platform_device *pdev) · 169 unmodified lines | ||
| 724 | 745 | goto out_clk_put; |
| 725 | 746 | } |
| 726 | 747 | |
| 727 | − mmc->f_min = clk_get_rate(host->clk) >> 7; | |
| 748 | + mmc->f_min = clk_get_rate(host->clk) >> 16; | |
| 749 | + if (mmc->f_min < 400000) | |
| 750 | + mmc->f_min = 400000; | |
| 728 | 751 | mmc->f_max = clk_get_rate(host->clk) >> 1; |
| 729 | 752 | |
| 730 | 753 | /* recommended in data sheet */ |
| @@ -822,7 +822,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) · 821 unmodified lines | ||
| 822 | 822 | del_timer(&host->cmd_abort_timer); |
| 823 | 823 | host->abort = 1; |
| 824 | 824 | OMAP_MMC_WRITE(host, IE, 0); |
| 825 | − disable_irq(host->irq); | |
| 825 | + disable_irq_nosync(host->irq); | |
| 826 | 826 | schedule_work(&host->cmd_abort_work); |
| 827 | 827 | return IRQ_HANDLED; |
| 828 | 828 | } |
| @@ -680,7 +680,7 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) · 679 unmodified lines | ||
| 680 | 680 | host->dma_ch = -1; |
| 681 | 681 | /* |
| 682 | 682 | * DMA Callback: run in interrupt context. |
| 683 | − * mutex_unlock will through a kernel warning if used. | |
| 683 | + * mutex_unlock will throw a kernel warning if used. | |
| 684 | 684 | */ |
| 685 | 685 | up(&host->sem); |
| 686 | 686 | } |
| @@ -55,7 +55,13 @@ static u32 esdhc_readl(struct sdhci_host *host, int reg) · 54 unmodified lines | ||
| 55 | 55 | |
| 56 | 56 | static u16 esdhc_readw(struct sdhci_host *host, int reg) |
| 57 | 57 | { |
| 58 | − return in_be16(host->ioaddr + (reg ^ 0x2)); | |
| 58 | + u16 ret; | |
| 59 | + | |
| 60 | + if (unlikely(reg == SDHCI_HOST_VERSION)) | |
| 61 | + ret = in_be16(host->ioaddr + reg); | |
| 62 | + else | |
| 63 | + ret = in_be16(host->ioaddr + (reg ^ 0x2)); | |
| 64 | + return ret; | |
| 59 | 65 | } |
| 60 | 66 | |
| 61 | 67 | static u8 esdhc_readb(struct sdhci_host *host, int reg) |
| @@ -277,6 +283,7 @@ static int __devexit sdhci_of_remove(struct of_device *ofdev) · 215 unmodified lines | ||
| 277 | 283 | static const struct of_device_id sdhci_of_match[] = { |
| 278 | 284 | { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, |
| 279 | 285 | { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, |
| 286 | + { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, | |
| 280 | 287 | { .compatible = "generic-sdhci", }, |
| 281 | 288 | {}, |
| 282 | 289 | }; |