Commit 5952cc77 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v4.5-rc2' of git://git.linaro.org/people/ulf.hansson/mmc

Pull MMC fixes from Ulf Hansson:
 "Here are some mmc fixes intended for v4.5 rc4.

  MMC core:
   - Fix an sysfs ABI regression
   - Return an error in a specific error path dealing with mmc ioctls

  MMC host:
   - sdhci-pci|acpi: Fix card detect race for Intel BXT/APL
   - sh_mmcif: Correct TX DMA channel allocation
   - mmc_spi: Fix error handling for dma mapping errors
   - sdhci-of-at91: Fix an unbalance issue for the runtime PM usage count
   - pxamci: Fix the device-tree probe deferral path
   - pxamci: Fix read-only GPIO polarity"

* tag 'mmc-v4.5-rc2' of git://git.linaro.org/people/ulf.hansson/mmc:
  Revert "mmc: block: don't use parameter prefix if built as module"
  mmc: sdhci-acpi: Fix card detect race for Intel BXT/APL
  mmc: sdhci-pci: Fix card detect race for Intel BXT/APL
  mmc: sdhci: Allow override of get_cd() called from sdhci_request()
  mmc: sdhci: Allow override of mmc host operations
  mmc: sh_mmcif: Correct TX DMA channel allocation
  mmc: block: return error on failed mmc_blk_get()
  mmc: pxamci: fix the device-tree probe deferral path
  mmc: mmc_spi: add checks for dma mapping error
  mmc: sdhci-of-at91: fix pm runtime unbalanced issue in error path
  mmc: pxamci: fix again read-only gpio detection polarity
parents 0df34ad9 a5ebb87d
...@@ -47,13 +47,10 @@ ...@@ -47,13 +47,10 @@
#include "queue.h" #include "queue.h"
MODULE_ALIAS("mmc:block"); MODULE_ALIAS("mmc:block");
#ifdef KERNEL
#ifdef MODULE_PARAM_PREFIX #ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX #undef MODULE_PARAM_PREFIX
#endif #endif
#define MODULE_PARAM_PREFIX "mmcblk." #define MODULE_PARAM_PREFIX "mmcblk."
#endif
#define INAND_CMD38_ARG_EXT_CSD 113 #define INAND_CMD38_ARG_EXT_CSD 113
#define INAND_CMD38_ARG_ERASE 0x00 #define INAND_CMD38_ARG_ERASE 0x00
...@@ -655,8 +652,10 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, ...@@ -655,8 +652,10 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev,
} }
md = mmc_blk_get(bdev->bd_disk); md = mmc_blk_get(bdev->bd_disk);
if (!md) if (!md) {
err = -EINVAL;
goto cmd_err; goto cmd_err;
}
card = md->queue.card; card = md->queue.card;
if (IS_ERR(card)) { if (IS_ERR(card)) {
......
...@@ -925,6 +925,10 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, ...@@ -925,6 +925,10 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
dma_addr = dma_map_page(dma_dev, sg_page(sg), 0, dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
PAGE_SIZE, dir); PAGE_SIZE, dir);
if (dma_mapping_error(dma_dev, dma_addr)) {
data->error = -EFAULT;
break;
}
if (direction == DMA_TO_DEVICE) if (direction == DMA_TO_DEVICE)
t->tx_dma = dma_addr + sg->offset; t->tx_dma = dma_addr + sg->offset;
else else
...@@ -1393,10 +1397,12 @@ static int mmc_spi_probe(struct spi_device *spi) ...@@ -1393,10 +1397,12 @@ static int mmc_spi_probe(struct spi_device *spi)
host->dma_dev = dev; host->dma_dev = dev;
host->ones_dma = dma_map_single(dev, ones, host->ones_dma = dma_map_single(dev, ones,
MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE); MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
if (dma_mapping_error(dev, host->ones_dma))
goto fail_ones_dma;
host->data_dma = dma_map_single(dev, host->data, host->data_dma = dma_map_single(dev, host->data,
sizeof(*host->data), DMA_BIDIRECTIONAL); sizeof(*host->data), DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, host->data_dma))
/* REVISIT in theory those map operations can fail... */ goto fail_data_dma;
dma_sync_single_for_cpu(host->dma_dev, dma_sync_single_for_cpu(host->dma_dev,
host->data_dma, sizeof(*host->data), host->data_dma, sizeof(*host->data),
...@@ -1462,6 +1468,11 @@ static int mmc_spi_probe(struct spi_device *spi) ...@@ -1462,6 +1468,11 @@ static int mmc_spi_probe(struct spi_device *spi)
if (host->dma_dev) if (host->dma_dev)
dma_unmap_single(host->dma_dev, host->data_dma, dma_unmap_single(host->dma_dev, host->data_dma,
sizeof(*host->data), DMA_BIDIRECTIONAL); sizeof(*host->data), DMA_BIDIRECTIONAL);
fail_data_dma:
if (host->dma_dev)
dma_unmap_single(host->dma_dev, host->ones_dma,
MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
fail_ones_dma:
kfree(host->data); kfree(host->data);
fail_nobuf1: fail_nobuf1:
......
...@@ -86,7 +86,7 @@ struct pxamci_host { ...@@ -86,7 +86,7 @@ struct pxamci_host {
static inline void pxamci_init_ocr(struct pxamci_host *host) static inline void pxamci_init_ocr(struct pxamci_host *host)
{ {
#ifdef CONFIG_REGULATOR #ifdef CONFIG_REGULATOR
host->vcc = regulator_get_optional(mmc_dev(host->mmc), "vmmc"); host->vcc = devm_regulator_get_optional(mmc_dev(host->mmc), "vmmc");
if (IS_ERR(host->vcc)) if (IS_ERR(host->vcc))
host->vcc = NULL; host->vcc = NULL;
...@@ -654,12 +654,8 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -654,12 +654,8 @@ static int pxamci_probe(struct platform_device *pdev)
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (!r || irq < 0) if (irq < 0)
return -ENXIO; return irq;
r = request_mem_region(r->start, SZ_4K, DRIVER_NAME);
if (!r)
return -EBUSY;
mmc = mmc_alloc_host(sizeof(struct pxamci_host), &pdev->dev); mmc = mmc_alloc_host(sizeof(struct pxamci_host), &pdev->dev);
if (!mmc) { if (!mmc) {
...@@ -695,7 +691,7 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -695,7 +691,7 @@ static int pxamci_probe(struct platform_device *pdev)
host->pdata = pdev->dev.platform_data; host->pdata = pdev->dev.platform_data;
host->clkrt = CLKRT_OFF; host->clkrt = CLKRT_OFF;
host->clk = clk_get(&pdev->dev, NULL); host->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(host->clk)) { if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk); ret = PTR_ERR(host->clk);
host->clk = NULL; host->clk = NULL;
...@@ -727,9 +723,9 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -727,9 +723,9 @@ static int pxamci_probe(struct platform_device *pdev)
host->irq = irq; host->irq = irq;
host->imask = MMC_I_MASK_ALL; host->imask = MMC_I_MASK_ALL;
host->base = ioremap(r->start, SZ_4K); host->base = devm_ioremap_resource(&pdev->dev, r);
if (!host->base) { if (IS_ERR(host->base)) {
ret = -ENOMEM; ret = PTR_ERR(host->base);
goto out; goto out;
} }
...@@ -742,7 +738,8 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -742,7 +738,8 @@ static int pxamci_probe(struct platform_device *pdev)
writel(64, host->base + MMC_RESTO); writel(64, host->base + MMC_RESTO);
writel(host->imask, host->base + MMC_I_MASK); writel(host->imask, host->base + MMC_I_MASK);
ret = request_irq(host->irq, pxamci_irq, 0, DRIVER_NAME, host); ret = devm_request_irq(&pdev->dev, host->irq, pxamci_irq, 0,
DRIVER_NAME, host);
if (ret) if (ret)
goto out; goto out;
...@@ -804,7 +801,7 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -804,7 +801,7 @@ static int pxamci_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro); dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro);
goto out; goto out;
} else { } else {
mmc->caps |= host->pdata->gpio_card_ro_invert ? mmc->caps2 |= host->pdata->gpio_card_ro_invert ?
0 : MMC_CAP2_RO_ACTIVE_HIGH; 0 : MMC_CAP2_RO_ACTIVE_HIGH;
} }
...@@ -833,14 +830,9 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -833,14 +830,9 @@ static int pxamci_probe(struct platform_device *pdev)
dma_release_channel(host->dma_chan_rx); dma_release_channel(host->dma_chan_rx);
if (host->dma_chan_tx) if (host->dma_chan_tx)
dma_release_channel(host->dma_chan_tx); dma_release_channel(host->dma_chan_tx);
if (host->base)
iounmap(host->base);
if (host->clk)
clk_put(host->clk);
} }
if (mmc) if (mmc)
mmc_free_host(mmc); mmc_free_host(mmc);
release_resource(r);
return ret; return ret;
} }
...@@ -859,9 +851,6 @@ static int pxamci_remove(struct platform_device *pdev) ...@@ -859,9 +851,6 @@ static int pxamci_remove(struct platform_device *pdev)
gpio_ro = host->pdata->gpio_card_ro; gpio_ro = host->pdata->gpio_card_ro;
gpio_power = host->pdata->gpio_power; gpio_power = host->pdata->gpio_power;
} }
if (host->vcc)
regulator_put(host->vcc);
if (host->pdata && host->pdata->exit) if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc); host->pdata->exit(&pdev->dev, mmc);
...@@ -870,16 +859,10 @@ static int pxamci_remove(struct platform_device *pdev) ...@@ -870,16 +859,10 @@ static int pxamci_remove(struct platform_device *pdev)
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
host->base + MMC_I_MASK); host->base + MMC_I_MASK);
free_irq(host->irq, host);
dmaengine_terminate_all(host->dma_chan_rx); dmaengine_terminate_all(host->dma_chan_rx);
dmaengine_terminate_all(host->dma_chan_tx); dmaengine_terminate_all(host->dma_chan_tx);
dma_release_channel(host->dma_chan_rx); dma_release_channel(host->dma_chan_rx);
dma_release_channel(host->dma_chan_tx); dma_release_channel(host->dma_chan_tx);
iounmap(host->base);
clk_put(host->clk);
release_resource(host->res);
mmc_free_host(mmc); mmc_free_host(mmc);
} }
......
...@@ -146,6 +146,33 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { ...@@ -146,6 +146,33 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = {
.ops = &sdhci_acpi_ops_int, .ops = &sdhci_acpi_ops_int,
}; };
static int bxt_get_cd(struct mmc_host *mmc)
{
int gpio_cd = mmc_gpio_get_cd(mmc);
struct sdhci_host *host = mmc_priv(mmc);
unsigned long flags;
int ret = 0;
if (!gpio_cd)
return 0;
pm_runtime_get_sync(mmc->parent);
spin_lock_irqsave(&host->lock, flags);
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
ret = !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
out:
spin_unlock_irqrestore(&host->lock, flags);
pm_runtime_mark_last_busy(mmc->parent);
pm_runtime_put_autosuspend(mmc->parent);
return ret;
}
static int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev, static int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev,
const char *hid, const char *uid) const char *hid, const char *uid)
{ {
...@@ -196,6 +223,9 @@ static int sdhci_acpi_sd_probe_slot(struct platform_device *pdev, ...@@ -196,6 +223,9 @@ static int sdhci_acpi_sd_probe_slot(struct platform_device *pdev,
/* Platform specific code during sd probe slot goes here */ /* Platform specific code during sd probe slot goes here */
if (hid && !strcmp(hid, "80865ACA"))
host->mmc_host_ops.get_cd = bxt_get_cd;
return 0; return 0;
} }
......
...@@ -217,6 +217,7 @@ static int sdhci_at91_probe(struct platform_device *pdev) ...@@ -217,6 +217,7 @@ static int sdhci_at91_probe(struct platform_device *pdev)
pm_runtime_disable: pm_runtime_disable:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev); pm_runtime_set_suspended(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
clocks_disable_unprepare: clocks_disable_unprepare:
clk_disable_unprepare(priv->gck); clk_disable_unprepare(priv->gck);
clk_disable_unprepare(priv->mainck); clk_disable_unprepare(priv->mainck);
......
...@@ -330,6 +330,33 @@ static void spt_read_drive_strength(struct sdhci_host *host) ...@@ -330,6 +330,33 @@ static void spt_read_drive_strength(struct sdhci_host *host)
sdhci_pci_spt_drive_strength = 0x10 | ((val >> 12) & 0xf); sdhci_pci_spt_drive_strength = 0x10 | ((val >> 12) & 0xf);
} }
static int bxt_get_cd(struct mmc_host *mmc)
{
int gpio_cd = mmc_gpio_get_cd(mmc);
struct sdhci_host *host = mmc_priv(mmc);
unsigned long flags;
int ret = 0;
if (!gpio_cd)
return 0;
pm_runtime_get_sync(mmc->parent);
spin_lock_irqsave(&host->lock, flags);
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
ret = !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
out:
spin_unlock_irqrestore(&host->lock, flags);
pm_runtime_mark_last_busy(mmc->parent);
pm_runtime_put_autosuspend(mmc->parent);
return ret;
}
static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
{ {
slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
...@@ -362,6 +389,10 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) ...@@ -362,6 +389,10 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
slot->cd_con_id = NULL; slot->cd_con_id = NULL;
slot->cd_idx = 0; slot->cd_idx = 0;
slot->cd_override_level = true; slot->cd_override_level = true;
if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXT_SD ||
slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_APL_SD)
slot->host->mmc_host_ops.get_cd = bxt_get_cd;
return 0; return 0;
} }
......
...@@ -1360,7 +1360,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) ...@@ -1360,7 +1360,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
sdhci_runtime_pm_get(host); sdhci_runtime_pm_get(host);
/* Firstly check card presence */ /* Firstly check card presence */
present = sdhci_do_get_cd(host); present = mmc->ops->get_cd(mmc);
spin_lock_irqsave(&host->lock, flags); spin_lock_irqsave(&host->lock, flags);
...@@ -2849,6 +2849,8 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, ...@@ -2849,6 +2849,8 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
host = mmc_priv(mmc); host = mmc_priv(mmc);
host->mmc = mmc; host->mmc = mmc;
host->mmc_host_ops = sdhci_ops;
mmc->ops = &host->mmc_host_ops;
return host; return host;
} }
...@@ -3037,7 +3039,6 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -3037,7 +3039,6 @@ int sdhci_add_host(struct sdhci_host *host)
/* /*
* Set host parameters. * Set host parameters.
*/ */
mmc->ops = &sdhci_ops;
max_clk = host->max_clk; max_clk = host->max_clk;
if (host->ops->get_min_clock) if (host->ops->get_min_clock)
......
...@@ -430,6 +430,7 @@ struct sdhci_host { ...@@ -430,6 +430,7 @@ struct sdhci_host {
/* Internal data */ /* Internal data */
struct mmc_host *mmc; /* MMC structure */ struct mmc_host *mmc; /* MMC structure */
struct mmc_host_ops mmc_host_ops; /* MMC host ops */
u64 dma_mask; /* custom DMA mask */ u64 dma_mask; /* custom DMA mask */
#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
......
...@@ -445,7 +445,7 @@ static void sh_mmcif_request_dma(struct sh_mmcif_host *host) ...@@ -445,7 +445,7 @@ static void sh_mmcif_request_dma(struct sh_mmcif_host *host)
pdata->slave_id_rx); pdata->slave_id_rx);
} else { } else {
host->chan_tx = dma_request_slave_channel(dev, "tx"); host->chan_tx = dma_request_slave_channel(dev, "tx");
host->chan_tx = dma_request_slave_channel(dev, "rx"); host->chan_rx = dma_request_slave_channel(dev, "rx");
} }
dev_dbg(dev, "%s: got channel TX %p RX %p\n", __func__, host->chan_tx, dev_dbg(dev, "%s: got channel TX %p RX %p\n", __func__, host->chan_tx,
host->chan_rx); host->chan_rx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment