summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt3
-rw-r--r--Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt29
-rw-r--r--Documentation/devicetree/bindings/mmc/jz4740.txt38
-rw-r--r--Documentation/devicetree/bindings/mmc/mmc.txt6
-rw-r--r--Documentation/devicetree/bindings/mmc/sdhci-omap.txt7
-rw-r--r--Documentation/devicetree/bindings/mmc/tmio_mmc.txt2
-rw-r--r--arch/mips/boot/dts/ingenic/ci20.dts34
-rw-r--r--arch/mips/boot/dts/ingenic/jz4780.dtsi52
-rw-r--r--arch/mips/configs/ci20_defconfig4
-rw-r--r--drivers/mmc/core/block.c11
-rw-r--r--drivers/mmc/core/card.h6
-rw-r--r--drivers/mmc/core/core.c67
-rw-r--r--drivers/mmc/core/core.h4
-rw-r--r--drivers/mmc/core/host.c16
-rw-r--r--drivers/mmc/core/mmc.c16
-rw-r--r--drivers/mmc/core/pwrseq_simple.c14
-rw-r--r--drivers/mmc/core/quirks.h3
-rw-r--r--drivers/mmc/core/sd.c12
-rw-r--r--drivers/mmc/core/sdio.c70
-rw-r--r--drivers/mmc/core/slot-gpio.c22
-rw-r--r--drivers/mmc/host/Kconfig32
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/android-goldfish.c8
-rw-r--r--drivers/mmc/host/atmel-mci.c21
-rw-r--r--drivers/mmc/host/au1xmmc.c12
-rw-r--r--drivers/mmc/host/davinci_mmc.c6
-rw-r--r--drivers/mmc/host/dw_mmc-bluefield.c81
-rw-r--r--drivers/mmc/host/dw_mmc-rockchip.c5
-rw-r--r--drivers/mmc/host/dw_mmc.c4
-rw-r--r--drivers/mmc/host/jz4740_mmc.c203
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c72
-rw-r--r--drivers/mmc/host/mmci.c5
-rw-r--r--drivers/mmc/host/mtk-sd.c63
-rw-r--r--drivers/mmc/host/mvsdio.c6
-rw-r--r--drivers/mmc/host/mxcmmc.c22
-rw-r--r--drivers/mmc/host/renesas_sdhi_core.c5
-rw-r--r--drivers/mmc/host/renesas_sdhi_internal_dmac.c32
-rw-r--r--drivers/mmc/host/renesas_sdhi_sys_dmac.c3
-rw-r--r--drivers/mmc/host/rtsx_usb_sdmmc.c19
-rw-r--r--drivers/mmc/host/sdhci-bcm-kona.c4
-rw-r--r--drivers/mmc/host/sdhci-cadence.c22
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c22
-rw-r--r--drivers/mmc/host/sdhci-msm.c85
-rw-r--r--drivers/mmc/host/sdhci-of-arasan.c9
-rw-r--r--drivers/mmc/host/sdhci-omap.c92
-rw-r--r--drivers/mmc/host/sdhci-pci-core.c38
-rw-r--r--drivers/mmc/host/sdhci-pci.h1
-rw-r--r--drivers/mmc/host/sdhci-pic32.c4
-rw-r--r--drivers/mmc/host/sdhci-pxav2.c4
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c4
-rw-r--r--drivers/mmc/host/sdhci-s3c.c4
-rw-r--r--drivers/mmc/host/sdhci-spear.c4
-rw-r--r--drivers/mmc/host/sdhci-st.c4
-rw-r--r--drivers/mmc/host/sdhci-tegra.c2
-rw-r--r--drivers/mmc/host/sdhci-xenon-phy.c11
-rw-r--r--drivers/mmc/host/sdhci.c148
-rw-r--r--drivers/mmc/host/sdhci.h15
-rw-r--r--drivers/mmc/host/sunxi-mmc.c187
-rw-r--r--drivers/mmc/host/ushc.c4
-rw-r--r--drivers/mmc/host/wbsd.c68
-rw-r--r--drivers/mmc/host/wmt-sdmmc.c6
-rw-r--r--include/dt-bindings/dma/jz4780-dma.h49
-rw-r--r--include/linux/mmc/card.h2
-rw-r--r--include/linux/mmc/core.h1
-rw-r--r--include/linux/mmc/host.h6
-rw-r--r--include/linux/mmc/sdio_ids.h1
66 files changed, 1382 insertions, 431 deletions
diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt
index 50bf611a4d2c..13e70409e8ac 100644
--- a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt
+++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt
@@ -12,6 +12,7 @@ Required properties:
- "amlogic,meson-gxbb-mmc"
- "amlogic,meson-gxl-mmc"
- "amlogic,meson-gxm-mmc"
+ - "amlogic,meson-axg-mmc"
- clocks : A list of phandle + clock-specifier pairs for the clocks listed in clock-names.
- clock-names: Should contain the following:
"core" - Main peripheral bus clock
@@ -19,6 +20,7 @@ Required properties:
"clkin1" - Other parent clock of internal mux
The driver has an internal mux clock which switches between clkin0 and clkin1 depending on the
clock rate requested by the MMC core.
+- resets : phandle of the internal reset line
Example:
@@ -29,4 +31,5 @@ Example:
clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, <&clkc CLKID_FCLK_DIV2>;
clock-names = "core", "clkin0", "clkin1";
pinctrl-0 = <&emmc_pins>;
+ resets = <&reset RESET_SD_EMMC_A>;
};
diff --git a/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt
new file mode 100644
index 000000000000..b0f0999ea1a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt
@@ -0,0 +1,29 @@
+* Mellanox Bluefield SoC specific extensions to the Synopsys Designware
+ Mobile Storage Host Controller
+
+Read synopsys-dw-mshc.txt for more details
+
+The Synopsys designware mobile storage host controller is used to interface
+a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
+differences between the core Synopsys dw mshc controller properties described
+by synopsys-dw-mshc.txt and the properties used by the Mellanox Bluefield SoC
+specific extensions to the Synopsys Designware Mobile Storage Host Controller.
+
+Required Properties:
+
+* compatible: should be one of the following.
+ - "mellanox,bluefield-dw-mshc": for controllers with Mellanox Bluefield SoC
+ specific extensions.
+
+Example:
+
+ /* Mellanox Bluefield SoC MMC */
+ mmc@6008000 {
+ compatible = "mellanox,bluefield-dw-mshc";
+ reg = <0x6008000 0x400>;
+ interrupts = <32>;
+ fifo-depth = <0x100>;
+ clock-frequency = <24000000>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ };
diff --git a/Documentation/devicetree/bindings/mmc/jz4740.txt b/Documentation/devicetree/bindings/mmc/jz4740.txt
new file mode 100644
index 000000000000..7cd8c432d7c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/jz4740.txt
@@ -0,0 +1,38 @@
+* Ingenic JZ47xx MMC controllers
+
+This file documents the device tree properties used for the MMC controller in
+Ingenic JZ4740/JZ4780 SoCs. These are in addition to the core MMC properties
+described in mmc.txt.
+
+Required properties:
+- compatible: Should be one of the following:
+ - "ingenic,jz4740-mmc" for the JZ4740
+ - "ingenic,jz4780-mmc" for the JZ4780
+- reg: Should contain the MMC controller registers location and length.
+- interrupts: Should contain the interrupt specifier of the MMC controller.
+- clocks: Clock for the MMC controller.
+
+Optional properties:
+- dmas: List of DMA specifiers with the controller specific format
+ as described in the generic DMA client binding. A tx and rx
+ specifier is required.
+- dma-names: RX and TX DMA request names.
+ Should be "rx" and "tx", in that order.
+
+For additional details on DMA client bindings see ../dma/dma.txt.
+
+Example:
+
+mmc0: mmc@13450000 {
+ compatible = "ingenic,jz4780-mmc";
+ reg = <0x13450000 0x1000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <37>;
+
+ clocks = <&cgu JZ4780_CLK_MSC0>;
+ clock-names = "mmc";
+
+ dmas = <&dma JZ4780_DMA_MSC0_RX 0xffffffff>, <&dma JZ4780_DMA_MSC0_TX 0xffffffff>;
+ dma-names = "rx", "tx";
+};
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index 467cd7b147ce..f5a0923b34ca 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -19,6 +19,8 @@ Optional properties:
- wp-gpios: Specify GPIOs for write protection, see gpio binding
- cd-inverted: when present, polarity on the CD line is inverted. See the note
below for the case, when a GPIO is used for the CD line
+- cd-debounce-delay-ms: Set delay time before detecting card after card insert interrupt.
+ It's only valid when cd-gpios is present.
- wp-inverted: when present, polarity on the WP line is inverted. See the note
below for the case, when a GPIO is used for the WP line
- disable-wp: When set no physical WP line is present. This property should
@@ -56,6 +58,10 @@ Optional properties:
- fixed-emmc-driver-type: for non-removable eMMC, enforce this driver type.
The value <n> is the driver type as specified in the eMMC specification
(table 206 in spec version 5.1).
+- post-power-on-delay-ms : It was invented for MMC pwrseq-simple which could
+ be referred to mmc-pwrseq-simple.txt. But now it's reused as a tunable delay
+ waiting for I/O signalling and card power supply to be stable, regardless of
+ whether pwrseq-simple is used. Default to 10ms if no available.
*NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
polarity properties, we have to fix the meaning of the "normal" and "inverted"
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
index 51775a372c06..393848c2138e 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
+++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
@@ -4,7 +4,14 @@ Refer to mmc.txt for standard MMC bindings.
Required properties:
- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
+ Should be "ti,k2g-sdhci" for K2G
- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
+ (Not required for K2G).
+- pinctrl-names: Should be subset of "default", "hs", "sdr12", "sdr25", "sdr50",
+ "ddr50-rev11", "sdr104-rev11", "ddr50", "sdr104",
+ "ddr_1_8v-rev11", "ddr_1_8v" or "ddr_3_3v", "hs200_1_8v-rev11",
+ "hs200_1_8v",
+- pinctrl-<n> : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt
Example:
mmc1: mmc@4809c000 {
diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
index 2d5287eeed95..ee978c95189d 100644
--- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
@@ -26,6 +26,8 @@ Required properties:
"renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC
"renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC
"renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC
+ "renesas,sdhi-r8a77965" - SDHI IP on R8A77965 SoC
+ "renesas,sdhi-r8a77980" - SDHI IP on R8A77980 SoC
"renesas,sdhi-r8a77995" - SDHI IP on R8A77995 SoC
"renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller
"renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index 38078594cf97..50cff3cbcc6d 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -36,6 +36,28 @@
clock-frequency = <48000000>;
};
+&mmc0 {
+ status = "okay";
+
+ bus-width = <4>;
+ max-frequency = <50000000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_mmc0>;
+
+ cd-gpios = <&gpf 20 GPIO_ACTIVE_LOW>;
+};
+
+&mmc1 {
+ status = "okay";
+
+ bus-width = <4>;
+ max-frequency = <50000000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_mmc1>;
+};
+
&uart0 {
status = "okay";
@@ -203,4 +225,16 @@
groups = "nemc-cs6";
bias-disable;
};
+
+ pins_mmc0: mmc0 {
+ function = "mmc0";
+ groups = "mmc0-1bit-e", "mmc0-4bit-e";
+ bias-disable;
+ };
+
+ pins_mmc1: mmc1 {
+ function = "mmc1";
+ groups = "mmc1-1bit-d", "mmc1-4bit-d";
+ bias-disable;
+ };
};
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi
index 9b5794667aee..b72e53bb7292 100644
--- a/arch/mips/boot/dts/ingenic/jz4780.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/clock/jz4780-cgu.h>
+#include <dt-bindings/dma/jz4780-dma.h>
/ {
#address-cells = <1>;
@@ -241,6 +242,57 @@
status = "disabled";
};
+ dma: dma@13420000 {
+ compatible = "ingenic,jz4780-dma";
+ reg = <0x13420000 0x10000>;
+ #dma-cells = <2>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <10>;
+
+ clocks = <&cgu JZ4780_CLK_PDMA>;
+ };
+
+ mmc0: mmc@13450000 {
+ compatible = "ingenic,jz4780-mmc";
+ reg = <0x13450000 0x1000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <37>;
+
+ clocks = <&cgu JZ4780_CLK_MSC0>;
+ clock-names = "mmc";
+
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ cap-sdio-irq;
+ dmas = <&dma JZ4780_DMA_MSC0_RX 0xffffffff>,
+ <&dma JZ4780_DMA_MSC0_TX 0xffffffff>;
+ dma-names = "rx", "tx";
+
+ status = "disabled";
+ };
+
+ mmc1: mmc@13460000 {
+ compatible = "ingenic,jz4780-mmc";
+ reg = <0x13460000 0x1000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <36>;
+
+ clocks = <&cgu JZ4780_CLK_MSC1>;
+ clock-names = "mmc";
+
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ cap-sdio-irq;
+ dmas = <&dma JZ4780_DMA_MSC1_RX 0xffffffff>,
+ <&dma JZ4780_DMA_MSC1_TX 0xffffffff>;
+ dma-names = "rx", "tx";
+
+ status = "disabled";
+ };
+
bch: bch@134d0000 {
compatible = "ingenic,jz4780-bch";
reg = <0x134d0000 0x10000>;
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
index b5f4ad8f2c45..be23fd25eeaa 100644
--- a/arch/mips/configs/ci20_defconfig
+++ b/arch/mips/configs/ci20_defconfig
@@ -104,10 +104,14 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
+CONFIG_MMC_JZ4740=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_JZ4740=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_JZ4780=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_MEMORY=y
+CONFIG_EXT4_FS=y
# CONFIG_DNOTIFY is not set
CONFIG_PROC_KCORE=y
# CONFIG_PROC_PAGE_MONITOR is not set
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index d89e17829527..a0b9102c4c6e 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -2351,7 +2351,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
set_disk_ro(md->disk, md->read_only || default_ro);
md->disk->flags = GENHD_FL_EXT_DEVT;
if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT))
- md->disk->flags |= GENHD_FL_NO_PART_SCAN;
+ md->disk->flags |= GENHD_FL_NO_PART_SCAN
+ | GENHD_FL_SUPPRESS_PARTITION_INFO;
/*
* As discussed on lkml, GENHD_FL_REMOVABLE should:
@@ -2965,9 +2966,11 @@ static void mmc_blk_remove(struct mmc_card *card)
mmc_blk_remove_debugfs(card, md);
mmc_blk_remove_parts(card, md);
pm_runtime_get_sync(&card->dev);
- mmc_claim_host(card->host);
- mmc_blk_part_switch(card, md->part_type);
- mmc_release_host(card->host);
+ if (md->part_curr != md->part_type) {
+ mmc_claim_host(card->host);
+ mmc_blk_part_switch(card, md->part_type);
+ mmc_release_host(card->host);
+ }
if (card->type != MMC_TYPE_SD_COMBO)
pm_runtime_disable(&card->dev);
pm_runtime_put_noidle(&card->dev);
diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h
index 9c821eedd156..1170feb8f969 100644
--- a/drivers/mmc/core/card.h
+++ b/drivers/mmc/core/card.h
@@ -149,6 +149,12 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
card->quirks &= ~data;
}
+static inline void __maybe_unused add_limit_rate_quirk(struct mmc_card *card,
+ int data)
+{
+ card->quirk_max_rate = data;
+}
+
/*
* Quirk add/remove for MMC products.
*/
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 121ce50b6d5e..281826d1fcca 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -50,9 +50,6 @@
#include "sd_ops.h"
#include "sdio_ops.h"
-/* If the device is not responding */
-#define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
-
/* The max erase timeout, used when host->max_busy_timeout isn't specified */
#define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */
@@ -1484,6 +1481,17 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
}
+void mmc_set_initial_signal_voltage(struct mmc_host *host)
+{
+ /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */
+ if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330))
+ dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n");
+ else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180))
+ dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n");
+ else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120))
+ dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n");
+}
+
int mmc_host_set_uhs_voltage(struct mmc_host *host)
{
u32 clock;
@@ -1646,19 +1654,13 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
/* Set initial state and call mmc_set_ios */
mmc_set_initial_state(host);
- /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */
- if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330))
- dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n");
- else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180))
- dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n");
- else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120))
- dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n");
+ mmc_set_initial_signal_voltage(host);
/*
* This delay should be sufficient to allow the power supply
* to reach the minimum voltage.
*/
- mmc_delay(10);
+ mmc_delay(host->ios.power_delay_ms);
mmc_pwrseq_post_power_on(host);
@@ -1671,7 +1673,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
* This delay must be at least 74 clock sizes, or 1 ms, or the
* time required to reach a stable voltage.
*/
- mmc_delay(10);
+ mmc_delay(host->ios.power_delay_ms);
}
void mmc_power_off(struct mmc_host *host)
@@ -1967,6 +1969,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
unsigned int qty = 0, busy_timeout = 0;
bool use_r1b_resp = false;
unsigned long timeout;
+ int loop_udelay=64, udelay_max=32768;
int err;
mmc_retune_hold(card->host);
@@ -2091,9 +2094,15 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
err = -EIO;
goto out;
}
+ if ((cmd.resp[0] & R1_READY_FOR_DATA) &&
+ R1_CURRENT_STATE(cmd.resp[0]) != R1_STATE_PRG)
+ break;
+
+ usleep_range(loop_udelay, loop_udelay*2);
+ if (loop_udelay < udelay_max)
+ loop_udelay *= 2;
+ } while (1);
- } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
- (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
out:
mmc_retune_release(card->host);
return err;
@@ -2435,22 +2444,46 @@ int mmc_hw_reset(struct mmc_host *host)
return -EINVAL;
mmc_bus_get(host);
- if (!host->bus_ops || host->bus_dead || !host->bus_ops->reset) {
+ if (!host->bus_ops || host->bus_dead || !host->bus_ops->hw_reset) {
mmc_bus_put(host);
return -EOPNOTSUPP;
}
- ret = host->bus_ops->reset(host);
+ ret = host->bus_ops->hw_reset(host);
mmc_bus_put(host);
if (ret)
- pr_warn("%s: tried to reset card, got error %d\n",
+ pr_warn("%s: tried to HW reset card, got error %d\n",
mmc_hostname(host), ret);
return ret;
}
EXPORT_SYMBOL(mmc_hw_reset);
+int mmc_sw_reset(struct mmc_host *host)
+{
+ int ret;
+
+ if (!host->card)
+ return -EINVAL;
+
+ mmc_bus_get(host);
+ if (!host->bus_ops || host->bus_dead || !host->bus_ops->sw_reset) {
+ mmc_bus_put(host);
+ return -EOPNOTSUPP;
+ }
+
+ ret = host->bus_ops->sw_reset(host);
+ mmc_bus_put(host);
+
+ if (ret)
+ pr_warn("%s: tried to SW reset card, got error %d\n",
+ mmc_hostname(host), ret);
+
+ return ret;
+}
+EXPORT_SYMBOL(mmc_sw_reset);
+
static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
{
host->f_init = freq;
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index d6303d69071b..9d8f09ac0821 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -32,7 +32,8 @@ struct mmc_bus_ops {
int (*power_restore)(struct mmc_host *);
int (*alive)(struct mmc_host *);
int (*shutdown)(struct mmc_host *);
- int (*reset)(struct mmc_host *);
+ int (*hw_reset)(struct mmc_host *);
+ int (*sw_reset)(struct mmc_host *);
};
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
@@ -51,6 +52,7 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr);
int mmc_host_set_uhs_voltage(struct mmc_host *host);
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
+void mmc_set_initial_signal_voltage(struct mmc_host *host);
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 64b03d6eaf18..abf9e884386c 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -143,9 +143,6 @@ int mmc_retune(struct mmc_host *host)
goto out;
return_to_hs400 = true;
-
- if (host->ops->prepare_hs400_tuning)
- host->ops->prepare_hs400_tuning(host, &host->ios);
}
err = mmc_execute_tuning(host->card);
@@ -179,7 +176,7 @@ static void mmc_retune_timer(struct timer_list *t)
int mmc_of_parse(struct mmc_host *host)
{
struct device *dev = host->parent;
- u32 bus_width, drv_type;
+ u32 bus_width, drv_type, cd_debounce_delay_ms;
int ret;
bool cd_cap_invert, cd_gpio_invert = false;
bool ro_cap_invert, ro_gpio_invert = false;
@@ -230,11 +227,16 @@ int mmc_of_parse(struct mmc_host *host)
} else {
cd_cap_invert = device_property_read_bool(dev, "cd-inverted");
+ if (device_property_read_u32(dev, "cd-debounce-delay-ms",
+ &cd_debounce_delay_ms))
+ cd_debounce_delay_ms = 200;
+
if (device_property_read_bool(dev, "broken-cd"))
host->caps |= MMC_CAP_NEEDS_POLL;
ret = mmc_gpiod_request_cd(host, "cd", 0, true,
- 0, &cd_gpio_invert);
+ cd_debounce_delay_ms,
+ &cd_gpio_invert);
if (!ret)
dev_info(host->parent, "Got CD GPIO\n");
else if (ret != -ENOENT && ret != -ENOSYS)
@@ -338,6 +340,9 @@ int mmc_of_parse(struct mmc_host *host)
host->dsr_req = 0;
}
+ device_property_read_u32(dev, "post-power-on-delay-ms",
+ &host->ios.power_delay_ms);
+