aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/bfin_sdh.c2
-rw-r--r--drivers/mmc/host/jz4740_mmc.c5
-rw-r--r--drivers/mmc/host/mmci.c109
-rw-r--r--drivers/mmc/host/mmci.h5
-rw-r--r--drivers/mmc/host/sdhci-s3c.c36
-rw-r--r--drivers/mmc/host/ushc.c1
6 files changed, 67 insertions, 91 deletions
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index bac7d62866b7..0371bf502249 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -462,7 +462,7 @@ static int __devinit sdh_probe(struct platform_device *pdev)
462 goto out; 462 goto out;
463 } 463 }
464 464
465 mmc = mmc_alloc_host(sizeof(*mmc), &pdev->dev); 465 mmc = mmc_alloc_host(sizeof(struct sdh_host), &pdev->dev);
466 if (!mmc) { 466 if (!mmc) {
467 ret = -ENOMEM; 467 ret = -ENOMEM;
468 goto out; 468 goto out;
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index b3a0ab0e4c2b..74218ad677e4 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/mmc/host.h> 16#include <linux/mmc/host.h>
17#include <linux/err.h>
17#include <linux/io.h> 18#include <linux/io.h>
18#include <linux/irq.h> 19#include <linux/irq.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
@@ -827,8 +828,8 @@ static int __devinit jz4740_mmc_probe(struct platform_device* pdev)
827 } 828 }
828 829
829 host->clk = clk_get(&pdev->dev, "mmc"); 830 host->clk = clk_get(&pdev->dev, "mmc");
830 if (!host->clk) { 831 if (IS_ERR(host->clk)) {
831 ret = -ENOENT; 832 ret = PTR_ERR(host->clk);
832 dev_err(&pdev->dev, "Failed to get mmc clock\n"); 833 dev_err(&pdev->dev, "Failed to get mmc clock\n");
833 goto err_free_host; 834 goto err_free_host;
834 } 835 }
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 563022825667..2d6de3e03e2d 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -14,6 +14,7 @@
14#include <linux/ioport.h> 14#include <linux/ioport.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/kernel.h>
17#include <linux/delay.h> 18#include <linux/delay.h>
18#include <linux/err.h> 19#include <linux/err.h>
19#include <linux/highmem.h> 20#include <linux/highmem.h>
@@ -46,10 +47,6 @@ static unsigned int fmax = 515633;
46 * is asserted (likewise for RX) 47 * is asserted (likewise for RX)
47 * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY 48 * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
48 * is asserted (likewise for RX) 49 * is asserted (likewise for RX)
49 * @broken_blockend: the MCI_DATABLOCKEND is broken on the hardware
50 * and will not work at all.
51 * @broken_blockend_dma: the MCI_DATABLOCKEND is broken on the hardware when
52 * using DMA.
53 * @sdio: variant supports SDIO 50 * @sdio: variant supports SDIO
54 * @st_clkdiv: true if using a ST-specific clock divider algorithm 51 * @st_clkdiv: true if using a ST-specific clock divider algorithm
55 */ 52 */
@@ -59,8 +56,6 @@ struct variant_data {
59 unsigned int datalength_bits; 56 unsigned int datalength_bits;
60 unsigned int fifosize; 57 unsigned int fifosize;
61 unsigned int fifohalfsize; 58 unsigned int fifohalfsize;
62 bool broken_blockend;
63 bool broken_blockend_dma;
64 bool sdio; 59 bool sdio;
65 bool st_clkdiv; 60 bool st_clkdiv;
66}; 61};
@@ -76,7 +71,6 @@ static struct variant_data variant_u300 = {
76 .fifohalfsize = 8 * 4, 71 .fifohalfsize = 8 * 4,
77 .clkreg_enable = 1 << 13, /* HWFCEN */ 72 .clkreg_enable = 1 << 13, /* HWFCEN */
78 .datalength_bits = 16, 73 .datalength_bits = 16,
79 .broken_blockend_dma = true,
80 .sdio = true, 74 .sdio = true,
81}; 75};
82 76
@@ -86,7 +80,6 @@ static struct variant_data variant_ux500 = {
86 .clkreg = MCI_CLK_ENABLE, 80 .clkreg = MCI_CLK_ENABLE,
87 .clkreg_enable = 1 << 14, /* HWFCEN */ 81 .clkreg_enable = 1 << 14, /* HWFCEN */
88 .datalength_bits = 24, 82 .datalength_bits = 24,
89 .broken_blockend = true,
90 .sdio = true, 83 .sdio = true,
91 .st_clkdiv = true, 84 .st_clkdiv = true,
92}; 85};
@@ -210,8 +203,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
210 host->data = data; 203 host->data = data;
211 host->size = data->blksz * data->blocks; 204 host->size = data->blksz * data->blocks;
212 host->data_xfered = 0; 205 host->data_xfered = 0;
213 host->blockend = false;
214 host->dataend = false;
215 206
216 mmci_init_sg(host, data); 207 mmci_init_sg(host, data);
217 208
@@ -288,21 +279,26 @@ static void
288mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 279mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
289 unsigned int status) 280 unsigned int status)
290{ 281{
291 struct variant_data *variant = host->variant;
292
293 /* First check for errors */ 282 /* First check for errors */
294 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { 283 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
284 u32 remain, success;
285
286 /* Calculate how far we are into the transfer */
287 remain = readl(host->base + MMCIDATACNT);
288 success = data->blksz * data->blocks - remain;
289
295 dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); 290 dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
296 if (status & MCI_DATACRCFAIL) 291 if (status & MCI_DATACRCFAIL) {
292 /* Last block was not successful */
293 host->data_xfered = round_down(success - 1, data->blksz);
297 data->error = -EILSEQ; 294 data->error = -EILSEQ;
298 else if (status & MCI_DATATIMEOUT) 295 } else if (status & MCI_DATATIMEOUT) {
296 host->data_xfered = round_down(success, data->blksz);
299 data->error = -ETIMEDOUT; 297 data->error = -ETIMEDOUT;
300 else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) 298 } else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
299 host->data_xfered = round_down(success, data->blksz);
301 data->error = -EIO; 300 data->error = -EIO;
302 301 }
303 /* Force-complete the transaction */
304 host->blockend = true;
305 host->dataend = true;
306 302
307 /* 303 /*
308 * We hit an error condition. Ensure that any data 304 * We hit an error condition. Ensure that any data
@@ -321,61 +317,14 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
321 } 317 }
322 } 318 }
323 319
324 /* 320 if (status & MCI_DATABLOCKEND)
325 * On ARM variants in PIO mode, MCI_DATABLOCKEND 321 dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n");
326 * is always sent first, and we increase the
327 * transfered number of bytes for that IRQ. Then
328 * MCI_DATAEND follows and we conclude the transaction.
329 *
330 * On the Ux500 single-IRQ variant MCI_DATABLOCKEND
331 * doesn't seem to immediately clear from the status,
332 * so we can't use it keep count when only one irq is
333 * used because the irq will hit for other reasons, and
334 * then the flag is still up. So we use the MCI_DATAEND
335 * IRQ at the end of the entire transfer because
336 * MCI_DATABLOCKEND is broken.
337 *
338 * In the U300, the IRQs can arrive out-of-order,
339 * e.g. MCI_DATABLOCKEND sometimes arrives after MCI_DATAEND,
340 * so for this case we use the flags "blockend" and
341 * "dataend" to make sure both IRQs have arrived before
342 * concluding the transaction. (This does not apply
343 * to the Ux500 which doesn't fire MCI_DATABLOCKEND
344 * at all.) In DMA mode it suffers from the same problem
345 * as the Ux500.
346 */
347 if (status & MCI_DATABLOCKEND) {
348 /*
349 * Just being a little over-cautious, we do not
350 * use this progressive update if the hardware blockend
351 * flag is unreliable: since it can stay high between
352 * IRQs it will corrupt the transfer counter.
353 */
354 if (!variant->broken_blockend)
355 host->data_xfered += data->blksz;
356 host->blockend = true;
357 }
358
359 if (status & MCI_DATAEND)
360 host->dataend = true;
361 322
362 /* 323 if (status & MCI_DATAEND || data->error) {
363 * On variants with broken blockend we shall only wait for dataend,
364 * on others we must sync with the blockend signal since they can
365 * appear out-of-order.
366 */
367 if (host->dataend && (host->blockend || variant->broken_blockend)) {
368 mmci_stop_data(host); 324 mmci_stop_data(host);
369 325
370 /* Reset these flags */ 326 if (!data->error)
371 host->blockend = false; 327 /* The error clause is handled above, success! */
372 host->dataend = false;
373
374 /*
375 * Variants with broken blockend flags need to handle the
376 * end of the entire transfer here.
377 */
378 if (variant->broken_blockend && !data->error)
379 host->data_xfered += data->blksz * data->blocks; 328 host->data_xfered += data->blksz * data->blocks;
380 329
381 if (!data->stop) { 330 if (!data->stop) {
@@ -394,15 +343,15 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
394 343
395 host->cmd = NULL; 344 host->cmd = NULL;
396 345
397 cmd->resp[0] = readl(base + MMCIRESPONSE0);
398 cmd->resp[1] = readl(base + MMCIRESPONSE1);
399 cmd->resp[2] = readl(base + MMCIRESPONSE2);
400 cmd->resp[3] = readl(base + MMCIRESPONSE3);
401
402 if (status & MCI_CMDTIMEOUT) { 346 if (status & MCI_CMDTIMEOUT) {
403 cmd->error = -ETIMEDOUT; 347 cmd->error = -ETIMEDOUT;
404 } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { 348 } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
405 cmd->error = -EILSEQ; 349 cmd->error = -EILSEQ;
350 } else {
351 cmd->resp[0] = readl(base + MMCIRESPONSE0);
352 cmd->resp[1] = readl(base + MMCIRESPONSE1);
353 cmd->resp[2] = readl(base + MMCIRESPONSE2);
354 cmd->resp[3] = readl(base + MMCIRESPONSE3);
406 } 355 }
407 356
408 if (!cmd->data || cmd->error) { 357 if (!cmd->data || cmd->error) {
@@ -770,7 +719,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
770 struct variant_data *variant = id->data; 719 struct variant_data *variant = id->data;
771 struct mmci_host *host; 720 struct mmci_host *host;
772 struct mmc_host *mmc; 721 struct mmc_host *mmc;
773 unsigned int mask;
774 int ret; 722 int ret;
775 723
776 /* must have platform data */ 724 /* must have platform data */
@@ -951,12 +899,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
951 goto irq0_free; 899 goto irq0_free;
952 } 900 }
953 901
954 mask = MCI_IRQENABLE; 902 writel(MCI_IRQENABLE, host->base + MMCIMASK0);
955 /* Don't use the datablockend flag if it's broken */
956 if (variant->broken_blockend)
957 mask &= ~MCI_DATABLOCKEND;
958
959 writel(mask, host->base + MMCIMASK0);
960 903
961 amba_set_drvdata(dev, mmc); 904 amba_set_drvdata(dev, mmc);
962 905
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index df06f01aac89..c1df7b82d36c 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -137,7 +137,7 @@
137#define MCI_IRQENABLE \ 137#define MCI_IRQENABLE \
138 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ 138 (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
139 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ 139 MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
140 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK) 140 MCI_CMDRESPENDMASK|MCI_CMDSENTMASK)
141 141
142/* These interrupts are directed to IRQ1 when two IRQ lines are available */ 142/* These interrupts are directed to IRQ1 when two IRQ lines are available */
143#define MCI_IRQ1MASK \ 143#define MCI_IRQ1MASK \
@@ -177,9 +177,6 @@ struct mmci_host {
177 struct timer_list timer; 177 struct timer_list timer;
178 unsigned int oldstat; 178 unsigned int oldstat;
179 179
180 bool blockend;
181 bool dataend;
182
183 /* pio stuff */ 180 /* pio stuff */
184 struct sg_mapping_iter sg_miter; 181 struct sg_mapping_iter sg_miter;
185 unsigned int size; 182 unsigned int size;
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 17203586305c..5309ab95aada 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -277,10 +277,43 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
277 host->clock = clock; 277 host->clock = clock;
278} 278}
279 279
280/**
281 * sdhci_s3c_platform_8bit_width - support 8bit buswidth
282 * @host: The SDHCI host being queried
283 * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
284 *
285 * We have 8-bit width support but is not a v3 controller.
286 * So we add platform_8bit_width() and support 8bit width.
287 */
288static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width)
289{
290 u8 ctrl;
291
292 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
293
294 switch (width) {
295 case MMC_BUS_WIDTH_8:
296 ctrl |= SDHCI_CTRL_8BITBUS;
297 ctrl &= ~SDHCI_CTRL_4BITBUS;
298 break;
299 case MMC_BUS_WIDTH_4:
300 ctrl |= SDHCI_CTRL_4BITBUS;
301 ctrl &= ~SDHCI_CTRL_8BITBUS;
302 break;
303 default:
304 break;
305 }
306
307 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
308
309 return 0;
310}
311
280static struct sdhci_ops sdhci_s3c_ops = { 312static struct sdhci_ops sdhci_s3c_ops = {
281 .get_max_clock = sdhci_s3c_get_max_clk, 313 .get_max_clock = sdhci_s3c_get_max_clk,
282 .set_clock = sdhci_s3c_set_clock, 314 .set_clock = sdhci_s3c_set_clock,
283 .get_min_clock = sdhci_s3c_get_min_clock, 315 .get_min_clock = sdhci_s3c_get_min_clock,
316 .platform_8bit_width = sdhci_s3c_platform_8bit_width,
284}; 317};
285 318
286static void sdhci_s3c_notify_change(struct platform_device *dev, int state) 319static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
@@ -473,6 +506,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
473 if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT) 506 if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
474 host->mmc->caps = MMC_CAP_NONREMOVABLE; 507 host->mmc->caps = MMC_CAP_NONREMOVABLE;
475 508
509 if (pdata->host_caps)
510 host->mmc->caps |= pdata->host_caps;
511
476 host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR | 512 host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR |
477 SDHCI_QUIRK_32BIT_DMA_SIZE); 513 SDHCI_QUIRK_32BIT_DMA_SIZE);
478 514
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c
index f8f65df9b017..f08f944ac53c 100644
--- a/drivers/mmc/host/ushc.c
+++ b/drivers/mmc/host/ushc.c
@@ -19,7 +19,6 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/usb.h> 20#include <linux/usb.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/usb.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
24#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
25#include <linux/mmc/host.h> 24#include <linux/mmc/host.h>