Commit f1454959 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v4.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - Fixup devname in /proc/interrupts for card detect GPIO

  MMC host:
   - sdhci-esdhc-imx: Allow 1.8V speed-modes without 100/200MHz pinctrls
   - sunxi: Disable IRQ in low power state to prevent IRQ storm
   - dw_mmc: Fix card threshold control configuration
   - renesas_sdhi_internal_dmac: Fixup DMA error paths"

* tag 'mmc-v4.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci-esdhc-imx: allow 1.8V modes without 100/200MHz pinctrl states
  mmc: sunxi: Disable irq during pm_suspend
  mmc: dw_mmc: fix card threshold control configuration
  mmc: core: cd_label must be last entry of mmc_gpio struct
  mmc: renesas_sdhi_internal_dmac: Cannot clear the RX_IN_USE in abort
  mmc: renesas_sdhi_internal_dmac: Fix missing unmap in error patch
parents 5d580932 92748bea
...@@ -27,8 +27,8 @@ struct mmc_gpio { ...@@ -27,8 +27,8 @@ struct mmc_gpio {
bool override_cd_active_level; bool override_cd_active_level;
irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id);
char *ro_label; char *ro_label;
char cd_label[0];
u32 cd_debounce_delay_ms; u32 cd_debounce_delay_ms;
char cd_label[];
}; };
static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
......
...@@ -1065,8 +1065,8 @@ static void dw_mci_ctrl_thld(struct dw_mci *host, struct mmc_data *data) ...@@ -1065,8 +1065,8 @@ static void dw_mci_ctrl_thld(struct dw_mci *host, struct mmc_data *data)
* It's used when HS400 mode is enabled. * It's used when HS400 mode is enabled.
*/ */
if (data->flags & MMC_DATA_WRITE && if (data->flags & MMC_DATA_WRITE &&
!(host->timing != MMC_TIMING_MMC_HS400)) host->timing != MMC_TIMING_MMC_HS400)
return; goto disable;
if (data->flags & MMC_DATA_WRITE) if (data->flags & MMC_DATA_WRITE)
enable = SDMMC_CARD_WR_THR_EN; enable = SDMMC_CARD_WR_THR_EN;
...@@ -1074,7 +1074,8 @@ static void dw_mci_ctrl_thld(struct dw_mci *host, struct mmc_data *data) ...@@ -1074,7 +1074,8 @@ static void dw_mci_ctrl_thld(struct dw_mci *host, struct mmc_data *data)
enable = SDMMC_CARD_RD_THR_EN; enable = SDMMC_CARD_RD_THR_EN;
if (host->timing != MMC_TIMING_MMC_HS200 && if (host->timing != MMC_TIMING_MMC_HS200 &&
host->timing != MMC_TIMING_UHS_SDR104) host->timing != MMC_TIMING_UHS_SDR104 &&
host->timing != MMC_TIMING_MMC_HS400)
goto disable; goto disable;
blksz_depth = blksz / (1 << host->data_shift); blksz_depth = blksz / (1 << host->data_shift);
......
...@@ -139,8 +139,7 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) { ...@@ -139,8 +139,7 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) {
renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST, renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST,
RST_RESERVED_BITS | val); RST_RESERVED_BITS | val);
if (host->data && host->data->flags & MMC_DATA_READ) clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
renesas_sdhi_internal_dmac_enable_dma(host, true); renesas_sdhi_internal_dmac_enable_dma(host, true);
} }
...@@ -164,17 +163,14 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, ...@@ -164,17 +163,14 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
goto force_pio; goto force_pio;
/* This DMAC cannot handle if buffer is not 8-bytes alignment */ /* This DMAC cannot handle if buffer is not 8-bytes alignment */
if (!IS_ALIGNED(sg_dma_address(sg), 8)) { if (!IS_ALIGNED(sg_dma_address(sg), 8))
dma_unmap_sg(&host->pdev->dev, sg, host->sg_len, goto force_pio_with_unmap;
mmc_get_dma_dir(data));
goto force_pio;
}
if (data->flags & MMC_DATA_READ) { if (data->flags & MMC_DATA_READ) {
dtran_mode |= DTRAN_MODE_CH_NUM_CH1; dtran_mode |= DTRAN_MODE_CH_NUM_CH1;
if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) && if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) &&
test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags)) test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags))
goto force_pio; goto force_pio_with_unmap;
} else { } else {
dtran_mode |= DTRAN_MODE_CH_NUM_CH0; dtran_mode |= DTRAN_MODE_CH_NUM_CH0;
} }
...@@ -189,6 +185,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, ...@@ -189,6 +185,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
return; return;
force_pio_with_unmap:
dma_unmap_sg(&host->pdev->dev, sg, host->sg_len, mmc_get_dma_dir(data));
force_pio: force_pio:
host->force_pio = true; host->force_pio = true;
renesas_sdhi_internal_dmac_enable_dma(host, false); renesas_sdhi_internal_dmac_enable_dma(host, false);
......
...@@ -312,6 +312,15 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) ...@@ -312,6 +312,15 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
if (imx_data->socdata->flags & ESDHC_FLAG_HS400) if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
val |= SDHCI_SUPPORT_HS400; val |= SDHCI_SUPPORT_HS400;
/*
* Do not advertise faster UHS modes if there are no
* pinctrl states for 100MHz/200MHz.
*/
if (IS_ERR_OR_NULL(imx_data->pins_100mhz) ||
IS_ERR_OR_NULL(imx_data->pins_200mhz))
val &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50
| SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_HS400);
} }
} }
...@@ -1158,18 +1167,6 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, ...@@ -1158,18 +1167,6 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
ESDHC_PINCTRL_STATE_100MHZ); ESDHC_PINCTRL_STATE_100MHZ);
imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,
ESDHC_PINCTRL_STATE_200MHZ); ESDHC_PINCTRL_STATE_200MHZ);
if (IS_ERR(imx_data->pins_100mhz) ||
IS_ERR(imx_data->pins_200mhz)) {
dev_warn(mmc_dev(host->mmc),
"could not get ultra high speed state, work on normal mode\n");
/*
* fall back to not supporting uhs by specifying no
* 1.8v quirk
*/
host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
}
} else {
host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
} }
/* call to generic mmc_of_parse to support additional capabilities */ /* call to generic mmc_of_parse to support additional capabilities */
......
...@@ -1446,6 +1446,7 @@ static int sunxi_mmc_runtime_resume(struct device *dev) ...@@ -1446,6 +1446,7 @@ static int sunxi_mmc_runtime_resume(struct device *dev)
sunxi_mmc_init_host(host); sunxi_mmc_init_host(host);
sunxi_mmc_set_bus_width(host, mmc->ios.bus_width); sunxi_mmc_set_bus_width(host, mmc->ios.bus_width);
sunxi_mmc_set_clk(host, &mmc->ios); sunxi_mmc_set_clk(host, &mmc->ios);
enable_irq(host->irq);
return 0; return 0;
} }
...@@ -1455,6 +1456,12 @@ static int sunxi_mmc_runtime_suspend(struct device *dev) ...@@ -1455,6 +1456,12 @@ static int sunxi_mmc_runtime_suspend(struct device *dev)
struct mmc_host *mmc = dev_get_drvdata(dev); struct mmc_host *mmc = dev_get_drvdata(dev);
struct sunxi_mmc_host *host = mmc_priv(mmc); struct sunxi_mmc_host *host = mmc_priv(mmc);
/*
* When clocks are off, it's possible receiving
* fake interrupts, which will stall the system.
* Disabling the irq will prevent this.
*/
disable_irq(host->irq);
sunxi_mmc_reset_host(host); sunxi_mmc_reset_host(host);
sunxi_mmc_disable(host); sunxi_mmc_disable(host);
......
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