diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-11 13:00:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-11 13:00:22 -0400 |
commit | f1454959ad89f9fe2b6862fa3c41070feaffeab9 (patch) | |
tree | f6e2cac708ce6adc8f3505570bea8821d3ffbe62 | |
parent | 5d58093285d00ddf5f7e9b438c8e769cae2b24ee (diff) | |
parent | 92748beac07c471d995fbec642b63572dc01b3dc (diff) |
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
-rw-r--r-- | drivers/mmc/core/slot-gpio.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 7 | ||||
-rw-r--r-- | drivers/mmc/host/renesas_sdhi_internal_dmac.c | 15 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 21 | ||||
-rw-r--r-- | drivers/mmc/host/sunxi-mmc.c | 7 |
5 files changed, 28 insertions, 24 deletions
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index ef05e0039378..2a833686784b 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c | |||
@@ -27,8 +27,8 @@ struct mmc_gpio { | |||
27 | bool override_cd_active_level; | 27 | bool override_cd_active_level; |
28 | irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); | 28 | irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); |
29 | char *ro_label; | 29 | char *ro_label; |
30 | char cd_label[0]; | ||
31 | u32 cd_debounce_delay_ms; | 30 | u32 cd_debounce_delay_ms; |
31 | char cd_label[]; | ||
32 | }; | 32 | }; |
33 | 33 | ||
34 | static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) | 34 | static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 623f4d27fa01..80dc2fd6576c 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -1065,8 +1065,8 @@ static void dw_mci_ctrl_thld(struct dw_mci *host, struct mmc_data *data) | |||
1065 | * It's used when HS400 mode is enabled. | 1065 | * It's used when HS400 mode is enabled. |
1066 | */ | 1066 | */ |
1067 | if (data->flags & MMC_DATA_WRITE && | 1067 | if (data->flags & MMC_DATA_WRITE && |
1068 | !(host->timing != MMC_TIMING_MMC_HS400)) | 1068 | host->timing != MMC_TIMING_MMC_HS400) |
1069 | return; | 1069 | goto disable; |
1070 | 1070 | ||
1071 | if (data->flags & MMC_DATA_WRITE) | 1071 | if (data->flags & MMC_DATA_WRITE) |
1072 | enable = SDMMC_CARD_WR_THR_EN; | 1072 | 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 | enable = SDMMC_CARD_RD_THR_EN; | 1074 | enable = SDMMC_CARD_RD_THR_EN; |
1075 | 1075 | ||
1076 | if (host->timing != MMC_TIMING_MMC_HS200 && | 1076 | if (host->timing != MMC_TIMING_MMC_HS200 && |
1077 | host->timing != MMC_TIMING_UHS_SDR104) | 1077 | host->timing != MMC_TIMING_UHS_SDR104 && |
1078 | host->timing != MMC_TIMING_MMC_HS400) | ||
1078 | goto disable; | 1079 | goto disable; |
1079 | 1080 | ||
1080 | blksz_depth = blksz / (1 << host->data_shift); | 1081 | blksz_depth = blksz / (1 << host->data_shift); |
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index f7f9773d161f..d032bd63444d 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c | |||
@@ -139,8 +139,7 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) { | |||
139 | renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST, | 139 | renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST, |
140 | RST_RESERVED_BITS | val); | 140 | RST_RESERVED_BITS | val); |
141 | 141 | ||
142 | if (host->data && host->data->flags & MMC_DATA_READ) | 142 | clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags); |
143 | clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags); | ||
144 | 143 | ||
145 | renesas_sdhi_internal_dmac_enable_dma(host, true); | 144 | renesas_sdhi_internal_dmac_enable_dma(host, true); |
146 | } | 145 | } |
@@ -164,17 +163,14 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, | |||
164 | goto force_pio; | 163 | goto force_pio; |
165 | 164 | ||
166 | /* This DMAC cannot handle if buffer is not 8-bytes alignment */ | 165 | /* This DMAC cannot handle if buffer is not 8-bytes alignment */ |
167 | if (!IS_ALIGNED(sg_dma_address(sg), 8)) { | 166 | if (!IS_ALIGNED(sg_dma_address(sg), 8)) |
168 | dma_unmap_sg(&host->pdev->dev, sg, host->sg_len, | 167 | goto force_pio_with_unmap; |
169 | mmc_get_dma_dir(data)); | ||
170 | goto force_pio; | ||
171 | } | ||
172 | 168 | ||
173 | if (data->flags & MMC_DATA_READ) { | 169 | if (data->flags & MMC_DATA_READ) { |
174 | dtran_mode |= DTRAN_MODE_CH_NUM_CH1; | 170 | dtran_mode |= DTRAN_MODE_CH_NUM_CH1; |
175 | if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) && | 171 | if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) && |
176 | test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags)) | 172 | test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags)) |
177 | goto force_pio; | 173 | goto force_pio_with_unmap; |
178 | } else { | 174 | } else { |
179 | dtran_mode |= DTRAN_MODE_CH_NUM_CH0; | 175 | dtran_mode |= DTRAN_MODE_CH_NUM_CH0; |
180 | } | 176 | } |
@@ -189,6 +185,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, | |||
189 | 185 | ||
190 | return; | 186 | return; |
191 | 187 | ||
188 | force_pio_with_unmap: | ||
189 | dma_unmap_sg(&host->pdev->dev, sg, host->sg_len, mmc_get_dma_dir(data)); | ||
190 | |||
192 | force_pio: | 191 | force_pio: |
193 | host->force_pio = true; | 192 | host->force_pio = true; |
194 | renesas_sdhi_internal_dmac_enable_dma(host, false); | 193 | renesas_sdhi_internal_dmac_enable_dma(host, false); |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index d6aef70d34fa..4eb3d29ecde1 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -312,6 +312,15 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) | |||
312 | 312 | ||
313 | if (imx_data->socdata->flags & ESDHC_FLAG_HS400) | 313 | if (imx_data->socdata->flags & ESDHC_FLAG_HS400) |
314 | val |= SDHCI_SUPPORT_HS400; | 314 | val |= SDHCI_SUPPORT_HS400; |
315 | |||
316 | /* | ||
317 | * Do not advertise faster UHS modes if there are no | ||
318 | * pinctrl states for 100MHz/200MHz. | ||
319 | */ | ||
320 | if (IS_ERR_OR_NULL(imx_data->pins_100mhz) || | ||
321 | IS_ERR_OR_NULL(imx_data->pins_200mhz)) | ||
322 | val &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50 | ||
323 | | SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_HS400); | ||
315 | } | 324 | } |
316 | } | 325 | } |
317 | 326 | ||
@@ -1158,18 +1167,6 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, | |||
1158 | ESDHC_PINCTRL_STATE_100MHZ); | 1167 | ESDHC_PINCTRL_STATE_100MHZ); |
1159 | imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, | 1168 | imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, |
1160 | ESDHC_PINCTRL_STATE_200MHZ); | 1169 | ESDHC_PINCTRL_STATE_200MHZ); |
1161 | if (IS_ERR(imx_data->pins_100mhz) || | ||
1162 | IS_ERR(imx_data->pins_200mhz)) { | ||
1163 | dev_warn(mmc_dev(host->mmc), | ||
1164 | "could not get ultra high speed state, work on normal mode\n"); | ||
1165 | /* | ||
1166 | * fall back to not supporting uhs by specifying no | ||
1167 | * 1.8v quirk | ||
1168 | */ | ||
1169 | host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; | ||
1170 | } | ||
1171 | } else { | ||
1172 | host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; | ||
1173 | } | 1170 | } |
1174 | 1171 | ||
1175 | /* call to generic mmc_of_parse to support additional capabilities */ | 1172 | /* call to generic mmc_of_parse to support additional capabilities */ |
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index e7472590f2ed..8e7f3e35ee3d 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c | |||
@@ -1446,6 +1446,7 @@ static int sunxi_mmc_runtime_resume(struct device *dev) | |||
1446 | sunxi_mmc_init_host(host); | 1446 | sunxi_mmc_init_host(host); |
1447 | sunxi_mmc_set_bus_width(host, mmc->ios.bus_width); | 1447 | sunxi_mmc_set_bus_width(host, mmc->ios.bus_width); |
1448 | sunxi_mmc_set_clk(host, &mmc->ios); | 1448 | sunxi_mmc_set_clk(host, &mmc->ios); |
1449 | enable_irq(host->irq); | ||
1449 | 1450 | ||
1450 | return 0; | 1451 | return 0; |
1451 | } | 1452 | } |
@@ -1455,6 +1456,12 @@ static int sunxi_mmc_runtime_suspend(struct device *dev) | |||
1455 | struct mmc_host *mmc = dev_get_drvdata(dev); | 1456 | struct mmc_host *mmc = dev_get_drvdata(dev); |
1456 | struct sunxi_mmc_host *host = mmc_priv(mmc); | 1457 | struct sunxi_mmc_host *host = mmc_priv(mmc); |
1457 | 1458 | ||
1459 | /* | ||
1460 | * When clocks are off, it's possible receiving | ||
1461 | * fake interrupts, which will stall the system. | ||
1462 | * Disabling the irq will prevent this. | ||
1463 | */ | ||
1464 | disable_irq(host->irq); | ||
1458 | sunxi_mmc_reset_host(host); | 1465 | sunxi_mmc_reset_host(host); |
1459 | sunxi_mmc_disable(host); | 1466 | sunxi_mmc_disable(host); |
1460 | 1467 | ||