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
6464 unsigned int tmout;
6565 int tmout_index;
6666
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+
6792 /* If timeout=0 then maximum timeout index is used. */
6893 tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);
6994 tmout += data->timeout_clks;
@@ -620,9 +645,18 @@ static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 550 unmodified lines
620645 if (ios->bus_width == MMC_BUS_WIDTH_4)
621646 ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS;
622647
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
623656 if (ios->timing == MMC_TIMING_MMC_HS ||
624657 ios->timing == MMC_TIMING_SD_HS)
625658 ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN;
659+#endif
626660
627661 host->ctrl = ctrl_reg;
628662 mvsd_write(MVSD_HOST_CTRL, ctrl_reg);
@@ -882,3 +916,4 @@ module_param(nodma, int, 0); · 253 unmodified lines
882916 MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre");
883917 MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver");
884918 MODULE_LICENSE("GPL");
919+MODULE_ALIAS("platform:mvsdio");
drivers/mmc/host/mxcmmc.c+35−12
@@ -140,6 +140,8 @@ struct mxcmci_host { · 139 unmodified lines
140140 struct work_struct datawork;
141141 };
142142
143+static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
144+
143145 static inline int mxcmci_use_dma(struct mxcmci_host *host)
144146 {
145147 return host->do_dma;
@@ -160,7 +162,7 @@ static void mxcmci_softreset(struct mxcmci_host *host) · 14 unmodified lines
160162 writew(0xff, host->base + MMC_REG_RES_TO);
161163 }
162164
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)
164166 {
165167 unsigned int nob = data->blocks;
166168 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
168170 #ifdef HAS_DMA
169171 struct scatterlist *sg;
170172 int i;
173+ int ret;
171174 #endif
172175 if (data->flags & MMC_DATA_STREAM)
173176 nob = 0xffff;
@@ -183,7 +186,7 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) · 9 unmodified lines
183186 for_each_sg(data->sg, sg, data->sg_len, i) {
184187 if (sg->offset & 3 || sg->length & 3) {
185188 host->do_dma = 0;
186− return;
189+ return 0;
187190 }
188191 }
189192
@@ -192,23 +195,30 @@ static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) · 2 unmodified lines
192195 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
193196 data->sg_len, host->dma_dir);
194197
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);
198202 } else {
199203 host->dma_dir = DMA_TO_DEVICE;
200204 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
201205 data->sg_len, host->dma_dir);
202206
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);
206211 }
207212
213+ if (ret) {
214+ dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret);
215+ return ret;
216+ }
208217 wmb();
209218
210219 imx_dma_enable(host->dma);
211220 #endif /* HAS_DMA */
221+ return 0;
212222 }
213223
214224 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
345355 stat = readl(host->base + MMC_REG_STATUS);
346356 if (stat & STATUS_ERR_MASK)
347357 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);
349361 return STATUS_TIME_OUT_READ;
362+ }
350363 if (stat & mask)
351364 return 0;
352365 cpu_relax();
@@ -531,6 +544,7 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) · 178 unmodified lines
531544 {
532545 struct mxcmci_host *host = mmc_priv(mmc);
533546 unsigned int cmdat = host->cmdat;
547+ int error;
534548
535549 WARN_ON(host->req != NULL);
536550
@@ -540,7 +554,12 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) · 3 unmodified lines
540554 host->do_dma = 1;
541555 #endif
542556 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+
544563
545564 cmdat |= CMD_DAT_CONT_DATA_ENABLE;
546565
@@ -548,7 +567,9 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) · 1 unmodified line
548567 cmdat |= CMD_DAT_CONT_WRITE;
549568 }
550569
551− if (mxcmci_start_cmd(host, req->cmd, cmdat))
570+ error = mxcmci_start_cmd(host, req->cmd, cmdat);
571+out:
572+ if (error)
552573 mxcmci_finish_request(host, req);
553574 }
554575
@@ -724,7 +745,9 @@ static int mxcmci_probe(struct platform_device *pdev) · 169 unmodified lines
724745 goto out_clk_put;
725746 }
726747
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;
728751 mmc->f_max = clk_get_rate(host->clk) >> 1;
729752
730753 /* 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
822822 del_timer(&host->cmd_abort_timer);
823823 host->abort = 1;
824824 OMAP_MMC_WRITE(host, IE, 0);
825− disable_irq(host->irq);
825+ disable_irq_nosync(host->irq);
826826 schedule_work(&host->cmd_abort_work);
827827 return IRQ_HANDLED;
828828 }
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
680680 host->dma_ch = -1;
681681 /*
682682 * 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.
684684 */
685685 up(&host->sem);
686686 }
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
5555
5656 static u16 esdhc_readw(struct sdhci_host *host, int reg)
5757 {
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;
5965 }
6066
6167 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
277283 static const struct of_device_id sdhci_of_match[] = {
278284 { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
279285 { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
286+ { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, },
280287 { .compatible = "generic-sdhci", },
281288 {},
282289 };

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