History

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: 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

Linus Torvalds committed 17 years ago

Commit 33fa1082 parents ccc0d38 fbf6a5f5 files · +80 −15Browse files

Unified · Split

5 files
  1. drivers/mmc/host/mvsdio.c +35 −0
  2. drivers/mmc/host/mxcmmc.c +35 −12
  3. drivers/mmc/host/omap.c +1 −1
  4. drivers/mmc/host/omap_hsmmc.c +1 −1
  5. drivers/mmc/host/sdhci-of.c +8 −1
drivers/mmc/host/mvsdio.c+35−0
@@ -64,6 +64,31 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data) · 63 unmodified lines
64 unsigned int tmout;64 unsigned int tmout;
65 int tmout_index;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 /* If timeout=0 then maximum timeout index is used. */92 /* If timeout=0 then maximum timeout index is used. */
68 tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);93 tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);
69 tmout += data->timeout_clks;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 if (ios->bus_width == MMC_BUS_WIDTH_4)645 if (ios->bus_width == MMC_BUS_WIDTH_4)
621 ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS;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 if (ios->timing == MMC_TIMING_MMC_HS ||656 if (ios->timing == MMC_TIMING_MMC_HS ||
624 ios->timing == MMC_TIMING_SD_HS)657 ios->timing == MMC_TIMING_SD_HS)
625 ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN;658 ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN;
659#endif
626 660
627 host->ctrl = ctrl_reg;661 host->ctrl = ctrl_reg;
628 mvsd_write(MVSD_HOST_CTRL, ctrl_reg);662 mvsd_write(MVSD_HOST_CTRL, ctrl_reg);
@@ -882,3 +916,4 @@ module_param(nodma, int, 0); · 253 unmodified lines
882MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre");916MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre");
883MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver");917MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver");
884MODULE_LICENSE("GPL");918MODULE_LICENSE("GPL");
919MODULE_ALIAS("platform:mvsdio");
drivers/mmc/host/mxcmmc.c+35−12
@@ -140,6 +140,8 @@ struct mxcmci_host { · 139 unmodified lines
140 struct work_struct datawork;140 struct work_struct datawork;
141};141};
142 142
143static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
144
143static inline int mxcmci_use_dma(struct mxcmci_host *host)145static inline int mxcmci_use_dma(struct mxcmci_host *host)
144{146{
145 return host->do_dma;147 return host->do_dma;
@@ -160,7 +162,7 @@ static void mxcmci_softreset(struct mxcmci_host *host) · 14 unmodified lines
160 writew(0xff, host->base + MMC_REG_RES_TO);162 writew(0xff, host->base + MMC_REG_RES_TO);
161}163}
162 164
163static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)165static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
164{166{
165 unsigned int nob = data->blocks;167 unsigned int nob = data->blocks;
166 unsigned int blksz = data->blksz;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#ifdef HAS_DMA170#ifdef HAS_DMA
169 struct scatterlist *sg;171 struct scatterlist *sg;
170 int i;172 int i;
173 int ret;
171#endif174#endif
172 if (data->flags & MMC_DATA_STREAM)175 if (data->flags & MMC_DATA_STREAM)
173 nob = 0xffff;176 nob = 0xffff;
@@ -183,7 +186,7 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) · 9 unmodified lines
183 for_each_sg(data->sg, sg, data->sg_len, i) {186 for_each_sg(data->sg, sg, data->sg_len, i) {
184 if (sg->offset & 3 || sg->length & 3) {187 if (sg->offset & 3 || sg->length & 3) {
185 host->do_dma = 0;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 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,195 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
193 data->sg_len, host->dma_dir);196 data->sg_len, host->dma_dir);
194 197
195 imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,198 ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
196 host->res->start + MMC_REG_BUFFER_ACCESS,199 datasize,
197 DMA_MODE_READ);200 host->res->start + MMC_REG_BUFFER_ACCESS,
201 DMA_MODE_READ);
198 } else {202 } else {
199 host->dma_dir = DMA_TO_DEVICE;203 host->dma_dir = DMA_TO_DEVICE;
200 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,204 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
201 data->sg_len, host->dma_dir);205 data->sg_len, host->dma_dir);
202 206
203 imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,207 ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
204 host->res->start + MMC_REG_BUFFER_ACCESS,208 datasize,
205 DMA_MODE_WRITE);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 wmb();217 wmb();
209 218
210 imx_dma_enable(host->dma);219 imx_dma_enable(host->dma);
211#endif /* HAS_DMA */220#endif /* HAS_DMA */
221 return 0;
212}222}
213 223
214static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,224static 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 stat = readl(host->base + MMC_REG_STATUS);355 stat = readl(host->base + MMC_REG_STATUS);
346 if (stat & STATUS_ERR_MASK)356 if (stat & STATUS_ERR_MASK)
347 return stat;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 return STATUS_TIME_OUT_READ;361 return STATUS_TIME_OUT_READ;
362 }
350 if (stat & mask)363 if (stat & mask)
351 return 0;364 return 0;
352 cpu_relax();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 struct mxcmci_host *host = mmc_priv(mmc);545 struct mxcmci_host *host = mmc_priv(mmc);
533 unsigned int cmdat = host->cmdat;546 unsigned int cmdat = host->cmdat;
547 int error;
534 548
535 WARN_ON(host->req != NULL);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 host->do_dma = 1;554 host->do_dma = 1;
541#endif555#endif
542 if (req->data) {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 cmdat |= CMD_DAT_CONT_DATA_ENABLE;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 cmdat |= CMD_DAT_CONT_WRITE;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);
571out:
572 if (error)
552 mxcmci_finish_request(host, req);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 goto out_clk_put;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 mmc->f_max = clk_get_rate(host->clk) >> 1;751 mmc->f_max = clk_get_rate(host->clk) >> 1;
729 752
730 /* recommended in data sheet */753 /* recommended in data sheet */
drivers/mmc/host/omap.c+1−1
@@ -822,7 +822,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) · 821 unmodified lines
822 del_timer(&host->cmd_abort_timer);822 del_timer(&host->cmd_abort_timer);
823 host->abort = 1;823 host->abort = 1;
824 OMAP_MMC_WRITE(host, IE, 0);824 OMAP_MMC_WRITE(host, IE, 0);
825 disable_irq(host->irq);825 disable_irq_nosync(host->irq);
826 schedule_work(&host->cmd_abort_work);826 schedule_work(&host->cmd_abort_work);
827 return IRQ_HANDLED;827 return IRQ_HANDLED;
828 }828 }
drivers/mmc/host/omap_hsmmc.c+1−1
@@ -680,7 +680,7 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) · 679 unmodified lines
680 host->dma_ch = -1;680 host->dma_ch = -1;
681 /*681 /*
682 * DMA Callback: run in interrupt context.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 up(&host->sem);685 up(&host->sem);
686}686}
drivers/mmc/host/sdhci-of.c+8−1
@@ -55,7 +55,13 @@ static u32 esdhc_readl(struct sdhci_host *host, int reg) · 54 unmodified lines
55 55
56static u16 esdhc_readw(struct sdhci_host *host, int reg)56static 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
61static u8 esdhc_readb(struct sdhci_host *host, int reg)67static 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
277static const struct of_device_id sdhci_of_match[] = {283static const struct of_device_id sdhci_of_match[] = {
278 { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },284 { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
279 { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },285 { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
286 { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, },
280 { .compatible = "generic-sdhci", },287 { .compatible = "generic-sdhci", },
281 {},288 {},
282};289};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t