diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/core/quirks.h | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/alcor.c | 60 | ||||
| -rw-r--r-- | drivers/mmc/host/davinci_mmc.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/mxcmmc.c | 16 | ||||
| -rw-r--r-- | drivers/mmc/host/pxamci.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/renesas_sdhi_core.c | 8 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-omap.c | 41 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci.c | 13 | ||||
| -rw-r--r-- | drivers/mmc/host/tifm_sd.c | 3 | ||||
| -rw-r--r-- | drivers/mmc/host/via-sdmmc.c | 10 |
10 files changed, 87 insertions, 70 deletions
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index dd2f73af8f2c..2d2d9ea8be4f 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -159,7 +159,7 @@ static inline void mmc_fixup_device(struct mmc_card *card, (f->ext_csd_rev == EXT_CSD_REV_ANY || f->ext_csd_rev == card->ext_csd.rev) && rev >= f->rev_start && rev <= f->rev_end) { - dev_dbg(&card->dev, "calling %pf\n", f->vendor_fixup); + dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup); f->vendor_fixup(card, f->data); } } diff --git a/drivers/mmc/host/alcor.c b/drivers/mmc/host/alcor.c index c712b7deb3a9..6e6b7ade4b60 100644 --- a/drivers/mmc/host/alcor.c +++ b/drivers/mmc/host/alcor.c @@ -48,7 +48,6 @@ struct alcor_sdmmc_host { struct mmc_command *cmd; struct mmc_data *data; unsigned int dma_on:1; - unsigned int early_data:1; struct mutex cmd_mutex; @@ -144,8 +143,7 @@ static void alcor_data_set_dma(struct alcor_sdmmc_host *host) host->sg_count--; } -static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host, - bool early) +static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host) { struct alcor_pci_priv *priv = host->alcor_pci; struct mmc_data *data = host->data; @@ -155,13 +153,6 @@ static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host, ctrl |= AU6601_DATA_WRITE; if (data->host_cookie == COOKIE_MAPPED) { - if (host->early_data) { - host->early_data = false; - return; - } - - host->early_data = early; - alcor_data_set_dma(host); ctrl |= AU6601_DATA_DMA_MODE; host->dma_on = 1; @@ -231,6 +222,7 @@ static void alcor_prepare_sg_miter(struct alcor_sdmmc_host *host) static void alcor_prepare_data(struct alcor_sdmmc_host *host, struct mmc_command *cmd) { + struct alcor_pci_priv *priv = host->alcor_pci; struct mmc_data *data = cmd->data; if (!data) @@ -248,7 +240,7 @@ static void alcor_prepare_data(struct alcor_sdmmc_host *host, if (data->host_cookie != COOKIE_MAPPED) alcor_prepare_sg_miter(host); - alcor_trigger_data_transfer(host, true); + alcor_write8(priv, 0, AU6601_DATA_XFER_CTRL); } static void alcor_send_cmd(struct alcor_sdmmc_host *host, @@ -435,7 +427,7 @@ static int alcor_cmd_irq_done(struct alcor_sdmmc_host *host, u32 intmask) if (!host->data) return false; - alcor_trigger_data_transfer(host, false); + alcor_trigger_data_transfer(host); host->cmd = NULL; return true; } @@ -456,7 +448,7 @@ static void alcor_cmd_irq_thread(struct alcor_sdmmc_host *host, u32 intmask) if (!host->data) alcor_request_complete(host, 1); else - alcor_trigger_data_transfer(host, false); + alcor_trigger_data_transfer(host); host->cmd = NULL; } @@ -487,15 +479,9 @@ static int alcor_data_irq_done(struct alcor_sdmmc_host *host, u32 intmask) break; case AU6601_INT_READ_BUF_RDY: alcor_trf_block_pio(host, true); - if (!host->blocks) - break; - alcor_trigger_data_transfer(host, false); return 1; case AU6601_INT_WRITE_BUF_RDY: alcor_trf_block_pio(host, false); - if (!host->blocks) - break; - alcor_trigger_data_transfer(host, false); return 1; case AU6601_INT_DMA_END: if (!host->sg_count) @@ -508,8 +494,14 @@ static int alcor_data_irq_done(struct alcor_sdmmc_host *host, u32 intmask) break; } - if (intmask & AU6601_INT_DATA_END) - return 0; + if (intmask & AU6601_INT_DATA_END) { + if (!host->dma_on && host->blocks) { + alcor_trigger_data_transfer(host); + return 1; + } else { + return 0; + } + } return 1; } @@ -967,7 +959,6 @@ static void alcor_timeout_timer(struct work_struct *work) alcor_request_complete(host, 0); } - mmiowb(); mutex_unlock(&host->cmd_mutex); } @@ -1044,14 +1035,27 @@ static void alcor_init_mmc(struct alcor_sdmmc_host *host) mmc->caps2 = MMC_CAP2_NO_SDIO; mmc->ops = &alcor_sdc_ops; - /* Hardware cannot do scatter lists */ + /* The hardware does DMA data transfer of 4096 bytes to/from a single + * buffer address. Scatterlists are not supported, but upon DMA + * completion (signalled via IRQ), the original vendor driver does + * then immediately set up another DMA transfer of the next 4096 + * bytes. + * + * This means that we need to handle the I/O in 4096 byte chunks. + * Lacking a way to limit the sglist entries to 4096 bytes, we instead + * impose that only one segment is provided, with maximum size 4096, + * which also happens to be the minimum size. This means that the + * single-entry sglist handled by this driver can be handed directly + * to the hardware, nice and simple. + * + * Unfortunately though, that means we only do 4096 bytes I/O per + * MMC command. A future improvement would be to make the driver + * accept sg lists and entries of any size, and simply iterate + * through them 4096 bytes at a time. + */ mmc->max_segs = AU6601_MAX_DMA_SEGMENTS; mmc->max_seg_size = AU6601_MAX_DMA_BLOCK_SIZE; - - mmc->max_blk_size = mmc->max_seg_size; - mmc->max_blk_count = mmc->max_segs; - - mmc->max_req_size = mmc->max_seg_size * mmc->max_segs; + mmc->max_req_size = mmc->max_seg_size; } static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev) diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 49e0daf2ef5e..f37003df1e01 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -1117,7 +1117,7 @@ static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host) { } #endif -static void __init init_mmcsd_host(struct mmc_davinci_host *host) +static void init_mmcsd_host(struct mmc_davinci_host *host) { mmc_davinci_reset_ctrl(host, 1); diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index d54612257b06..45f7b9b53d48 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -290,11 +290,8 @@ static void mxcmci_swap_buffers(struct mmc_data *data) struct scatterlist *sg; int i; - for_each_sg(data->sg, sg, data->sg_len, i) { - void *buf = kmap_atomic(sg_page(sg) + sg->offset); - buffer_swap32(buf, sg->length); - kunmap_atomic(buf); - } + for_each_sg(data->sg, sg, data->sg_len, i) + buffer_swap32(sg_virt(sg), sg->length); } #else static inline void mxcmci_swap_buffers(struct mmc_data *data) {} @@ -611,7 +608,6 @@ static int mxcmci_transfer_data(struct mxcmci_host *host) { struct mmc_data *data = host->req->data; struct scatterlist *sg; - void *buf; int stat, i; host->data = data; @@ -619,18 +615,14 @@ static int mxcmci_transfer_data(struct mxcmci_host *host) if (data->flags & MMC_DATA_READ) { for_each_sg(data->sg, sg, data->sg_len, i) { - buf = kmap_atomic(sg_page(sg) + sg->offset); - stat = mxcmci_pull(host, buf, sg->length); - kunmap(buf); + stat = mxcmci_pull(host, sg_virt(sg), sg->length); if (stat) return stat; host->datasize += sg->length; } } else { for_each_sg(data->sg, sg, data->sg_len, i) { - buf = kmap_atomic(sg_page(sg) + sg->offset); - stat = mxcmci_push(host, buf, sg->length); - kunmap(buf); + stat = mxcmci_push(host, sg_virt(sg), sg->length); if (stat) return stat; host->datasize += sg->length; diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index c907bf502a12..c1d3f0e38921 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -162,7 +162,7 @@ static void pxamci_dma_irq(void *param); static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) { struct dma_async_tx_descriptor *tx; - enum dma_data_direction direction; + enum dma_transfer_direction direction; struct dma_slave_config config; struct dma_chan *chan; unsigned int nob = data->blocks; diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 71e13844df6c..8742e27e4e8b 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -641,6 +641,7 @@ int renesas_sdhi_probe(struct platform_device *pdev, struct renesas_sdhi *priv; struct resource *res; int irq, ret, i; + u16 ver; of_data = of_device_get_match_data(&pdev->dev); @@ -773,12 +774,17 @@ int renesas_sdhi_probe(struct platform_device *pdev, if (ret) goto efree; + ver = sd_ctrl_read16(host, CTL_VERSION); + /* GEN2_SDR104 is first known SDHI to use 32bit block count */ + if (ver < SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count > U16_MAX) + mmc_data->max_blk_count = U16_MAX; + ret = tmio_mmc_host_probe(host); if (ret < 0) goto edisclk; /* One Gen2 SDHI incarnation does NOT have a CBSY bit */ - if (sd_ctrl_read16(host, CTL_VERSION) == SDHI_VER_GEN2_SDR50) + if (ver == SDHI_VER_GEN2_SDR50) mmc_data->flags &= ~TMIO_MMC_HAVE_CBSY; /* Enable tuning iff we have an SCC and a supported mode */ diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index b1a66ca3821a..9f20fff9781b 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c @@ -797,6 +797,43 @@ void sdhci_omap_reset(struct sdhci_host *host, u8 mask) sdhci_reset(host, mask); } +#define CMD_ERR_MASK (SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX |\ + SDHCI_INT_TIMEOUT) +#define CMD_MASK (CMD_ERR_MASK | SDHCI_INT_RESPONSE) + +static u32 sdhci_omap_irq(struct sdhci_host *host, u32 intmask) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); + + if (omap_host->is_tuning && host->cmd && !host->data_early && + (intmask & CMD_ERR_MASK)) { + + /* + * Since we are not resetting data lines during tuning + * operation, data error or data complete interrupts + * might still arrive. Mark this request as a failure + * but still wait for the data interrupt + */ + if (intmask & SDHCI_INT_TIMEOUT) + host->cmd->error = -ETIMEDOUT; + else + host->cmd->error = -EILSEQ; + + host->cmd = NULL; + + /* + * Sometimes command error interrupts and command complete + * interrupt will arrive together. Clear all command related + * interrupts here. + */ + sdhci_writel(host, intmask & CMD_MASK, SDHCI_INT_STATUS); + intmask &= ~CMD_MASK; + } + + return intmask; +} + static struct sdhci_ops sdhci_omap_ops = { .set_clock = sdhci_omap_set_clock, .set_power = sdhci_omap_set_power, @@ -807,6 +844,7 @@ static struct sdhci_ops sdhci_omap_ops = { .platform_send_init_74_clocks = sdhci_omap_init_74_clocks, .reset = sdhci_omap_reset, .set_uhs_signaling = sdhci_omap_set_uhs_signaling, + .irq = sdhci_omap_irq, }; static int sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host) @@ -1056,6 +1094,9 @@ static int sdhci_omap_probe(struct platform_device *pdev) mmc->f_max = 48000000; } + if (!mmc_can_gpio_ro(mmc)) + mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT; + pltfm_host->clk = devm_clk_get(dev, "fck"); if (IS_ERR(pltfm_host->clk)) { ret = PTR_ERR(pltfm_host->clk); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a8141ff9be03..42e1bad024f4 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1807,7 +1807,6 @@ void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) sdhci_send_command(host, mrq->cmd); } - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } EXPORT_SYMBOL_GPL(sdhci_request); @@ -2010,8 +2009,6 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) */ if (host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); - - mmiowb(); } EXPORT_SYMBOL_GPL(sdhci_set_ios); @@ -2105,7 +2102,6 @@ static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable) sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); - mmiowb(); } } @@ -2353,7 +2349,6 @@ void sdhci_send_tuning(struct sdhci_host *host, u32 opcode) host->tuning_done = 0; - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); /* Wait for Buffer Read Ready interrupt */ @@ -2705,7 +2700,6 @@ static bool sdhci_request_done(struct sdhci_host *host) host->mrqs_done[i] = NULL; - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); mmc_request_done(host->mmc, mrq); @@ -2739,7 +2733,6 @@ static void sdhci_timeout_timer(struct timer_list *t) sdhci_finish_mrq(host, host->cmd->mrq); } - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } @@ -2770,7 +2763,6 @@ static void sdhci_timeout_data_timer(struct timer_list *t) } } - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } @@ -3251,7 +3243,6 @@ int sdhci_resume_host(struct sdhci_host *host) mmc->ops->set_ios(mmc, &mmc->ios); } else { sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER)); - mmiowb(); } if (host->irq_wake_enabled) { @@ -3391,7 +3382,6 @@ void sdhci_cqe_enable(struct mmc_host *mmc) mmc_hostname(mmc), host->ier, sdhci_readl(host, SDHCI_INT_STATUS)); - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } EXPORT_SYMBOL_GPL(sdhci_cqe_enable); @@ -3416,7 +3406,6 @@ void sdhci_cqe_disable(struct mmc_host *mmc, bool recovery) mmc_hostname(mmc), host->ier, sdhci_readl(host, SDHCI_INT_STATUS)); - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } EXPORT_SYMBOL_GPL(sdhci_cqe_disable); @@ -4255,8 +4244,6 @@ int __sdhci_add_host(struct sdhci_host *host) goto unirq; } - mmiowb(); - ret = mmc_add_host(mmc); if (ret) goto unled; diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index b6644ce296b2..35dd34b82a4d 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c @@ -889,7 +889,6 @@ static int tifm_sd_initialize_host(struct tifm_sd *host) struct tifm_dev *sock = host->dev; writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); - mmiowb(); host->clk_div = 61; host->clk_freq = 20000000; writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); @@ -940,7 +939,6 @@ static int tifm_sd_initialize_host(struct tifm_sd *host) writel(TIFM_MMCSD_CERR | TIFM_MMCSD_BRS | TIFM_MMCSD_EOC | TIFM_MMCSD_ERRMASK, sock->addr + SOCK_MMCSD_INT_ENABLE); - mmiowb(); return 0; } @@ -1005,7 +1003,6 @@ static void tifm_sd_remove(struct tifm_dev *sock) spin_lock_irqsave(&sock->lock, flags); host->eject = 1; writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); - mmiowb(); spin_unlock_irqrestore(&sock->lock, flags); tasklet_kill(&host->finish_tasklet); diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c index 32c4211506fc..412395ac2935 100644 --- a/drivers/mmc/host/via-sdmmc.c +++ b/drivers/mmc/host/via-sdmmc.c @@ -686,7 +686,6 @@ static void via_sdc_request(struct mmc_host *mmc, struct mmc_request *mrq) via_sdc_send_command(host, mrq->cmd); } - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } @@ -711,7 +710,6 @@ static void via_sdc_set_power(struct via_crdr_mmc_host *host, gatt &= ~VIA_CRDR_PCICLKGATT_PAD_PWRON; writeb(gatt, host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT); - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); via_pwron_sleep(host); @@ -770,7 +768,6 @@ static void via_sdc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (readb(addrbase + VIA_CRDR_PCISDCCLK) != clock) writeb(clock, addrbase + VIA_CRDR_PCISDCCLK); - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); if (ios->power_mode != MMC_POWER_OFF) @@ -830,7 +827,6 @@ static void via_reset_pcictrl(struct via_crdr_mmc_host *host) via_restore_pcictrlreg(host); via_restore_sdcreg(host); - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } @@ -925,7 +921,6 @@ static irqreturn_t via_sdc_isr(int irq, void *dev_id) result = IRQ_HANDLED; - mmiowb(); out: spin_unlock(&sdhost->lock); @@ -960,7 +955,6 @@ static void via_sdc_timeout(struct timer_list *t) } } - mmiowb(); spin_unlock_irqrestore(&sdhost->lock, flags); } @@ -1012,7 +1006,6 @@ static void via_sdc_card_detect(struct work_struct *work) tasklet_schedule(&host->finish_tasklet); } - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); via_reset_pcictrl(host); @@ -1020,7 +1013,6 @@ static void via_sdc_card_detect(struct work_struct *work) spin_lock_irqsave(&host->lock, flags); } - mmiowb(); spin_unlock_irqrestore(&host->lock, flags); via_print_pcictrl(host); @@ -1188,7 +1180,6 @@ static void via_sd_remove(struct pci_dev *pcidev) /* Disable generating further interrupts */ writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL); - mmiowb(); if (sdhost->mrq) { pr_err("%s: Controller removed during " @@ -1197,7 +1188,6 @@ static void via_sd_remove(struct pci_dev *pcidev) /* make sure all DMA is stopped */ writel(VIA_CRDR_DMACTRL_SFTRST, sdhost->ddma_mmiobase + VIA_CRDR_DMACTRL); - mmiowb(); sdhost->mrq->cmd->error = -ENOMEDIUM; if (sdhost->mrq->stop) sdhost->mrq->stop->error = -ENOMEDIUM; |

