summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-15 15:57:25 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-15 15:57:25 -0800
commitce51c2b7ceb23a23eb0dc523c80879d8f35e4f38 (patch)
tree9088f11b41470e02bbf020027682454d33a1871d /drivers/mmc/host
parent9d0d886799e49e0f6d51e70c823416919544fdb7 (diff)
parent72b248cfbf3fd308807afe7cc30d05fefeff7fb1 (diff)
Merge tag 'mmc-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson: "MMC core: - Initial support for SD express card/host MMC host: - mxc: Convert the driver to DT-only - mtk-sd: Add HS400 enhanced strobe support - mtk-sd: Add support for the MT8192 SoC variant - sdhci-acpi: Allow changing HS200/HS400 driver strength for AMDI0040 - sdhci-esdhc-imx: Convert the driver to DT-only - sdhci-pci-gli: Improve performance for HS400 mode for GL9763E - sdhci-pci-gli: Reduce power consumption for GL9755 - sdhci-xenon: Introduce ACPI support - tmio: Fix command error processing - tmio: Inform the core about the max_busy_timeout - tmio/renesas_sdhi: Support custom calculation of busy-wait time - renesas_sdhi: Reset SCC only when available - rtsx_pci: Add SD Express mode support for RTS5261 - rtsx_pci: Various fixes and improvements for RTS5261 MEMSTICK: - Minor fixes/improvements" * tag 'mmc-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (72 commits) dt-bindings: mmc: eliminate yamllint warnings mmc: sdhci-xenon: introduce ACPI support mmc: sdhci-xenon: use clk only with DT mmc: sdhci-xenon: switch to device_* API mmc: sdhci-xenon: use match data for controllers variants dt-bindings: mmc: Fix xlnx,mio-bank property values for arasan driver mmc: renesas_sdhi: populate hook for longer busy_wait mmc: tmio: add hook for custom busy_wait calculation mmc: tmio: set max_busy_timeout dt-bindings: mmc: imx: fix the wrongly dropped imx8qm compatible string mmc: sdhci-pci-gli: Disable slow mode in HS400 mode for GL9763E mmc: sdhci: Use more concise device_property_read_u64 memstick: r592: Fix error return in r592_probe() mmc: mxc: Convert the driver to DT-only mmc: mxs: Remove the unused .id_table mmc: sdhci-of-arasan: Fix fall-through warnings for Clang mmc: sdhci-pci-gli: Reduce power consumption for GL9755 mmc: mediatek: depend on COMMON_CLK to fix compile tests mmc: pxamci: Fix error return code in pxamci_probe mmc: sdhci: Update firmware interface API ...
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/Kconfig7
-rw-r--r--drivers/mmc/host/davinci_mmc.c2
-rw-r--r--drivers/mmc/host/dw_mmc.c17
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c2
-rw-r--r--drivers/mmc/host/meson-mx-sdio.c5
-rw-r--r--drivers/mmc/host/moxart-mmc.c5
-rw-r--r--drivers/mmc/host/mtk-sd.c125
-rw-r--r--drivers/mmc/host/mxcmmc.c33
-rw-r--r--drivers/mmc/host/mxs-mmc.c18
-rw-r--r--drivers/mmc/host/owl-mmc.c9
-rw-r--r--drivers/mmc/host/pxamci.c1
-rw-r--r--drivers/mmc/host/renesas_sdhi_core.c119
-rw-r--r--drivers/mmc/host/rtsx_pci_sdmmc.c71
-rw-r--r--drivers/mmc/host/s3cmci.c2
-rw-r--r--drivers/mmc/host/sdhci-acpi.c38
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c91
-rw-r--r--drivers/mmc/host/sdhci-msm.c13
-rw-r--r--drivers/mmc/host/sdhci-of-arasan.c4
-rw-r--r--drivers/mmc/host/sdhci-pci-gli.c27
-rw-r--r--drivers/mmc/host/sdhci-pic32.c11
-rw-r--r--drivers/mmc/host/sdhci-sprd.c2
-rw-r--r--drivers/mmc/host/sdhci-st.c2
-rw-r--r--drivers/mmc/host/sdhci-tegra.c2
-rw-r--r--drivers/mmc/host/sdhci-xenon-phy.c40
-rw-r--r--drivers/mmc/host/sdhci-xenon.c91
-rw-r--r--drivers/mmc/host/sdhci-xenon.h12
-rw-r--r--drivers/mmc/host/sdhci.c8
-rw-r--r--drivers/mmc/host/sunxi-mmc.c3
-rw-r--r--drivers/mmc/host/tmio_mmc.c3
-rw-r--r--drivers/mmc/host/tmio_mmc.h6
-rw-r--r--drivers/mmc/host/tmio_mmc_core.c26
-rw-r--r--drivers/mmc/host/uniphier-sd.c1
32 files changed, 478 insertions, 318 deletions
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 31481c9fcc2e..596f32637315 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -631,8 +631,8 @@ config MMC_SPI
config MMC_S3C
tristate "Samsung S3C SD/MMC Card Interface support"
- depends on ARCH_S3C24XX
- depends on S3C24XX_DMAC
+ depends on ARCH_S3C24XX || COMPILE_TEST
+ depends on S3C24XX_DMAC || COMPILE_TEST
help
This selects a driver for the MCI interface found in
Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs.
@@ -664,7 +664,7 @@ config MMC_S3C_PIO
config MMC_S3C_DMA
bool "Use DMA transfers only"
help
- Use DMA to transfer data between memory and the hardare.
+ Use DMA to transfer data between memory and the hardware.
Currently, the DMA support in this driver seems to not be
working properly and needs to be debugged before this
@@ -1023,6 +1023,7 @@ config MMC_BCM2835
config MMC_MTK
tristate "MediaTek SD/MMC Card Interface support"
depends on HAS_DMA
+ depends on COMMON_CLK
select REGULATOR
select MMC_CQHCI
help
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 90cd179625fc..2a757c88f9d2 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -290,7 +290,7 @@ static void mmc_davinci_start_command(struct mmc_davinci_host *host,
default:
s = ", (R? response)";
break;
- }; s; }));
+ } s; }));
host->cmd = cmd;
switch (mmc_resp_type(cmd)) {
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 43c5795691fb..a5244435556b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2617,7 +2617,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
struct dw_mci *host = dev_id;
u32 pending;
struct dw_mci_slot *slot = host->slot;
- unsigned long irqflags;
pending = mci_readl(host, MINTSTS); /* read-only mask reg */
@@ -2632,15 +2631,15 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
* Hold the lock; we know cmd11_timer can't be kicked
* off after the lock is released, so safe to delete.
*/
- spin_lock_irqsave(&host->irq_lock, irqflags);
+ spin_lock(&host->irq_lock);
dw_mci_cmd_interrupt(host, pending);
- spin_unlock_irqrestore(&host->irq_lock, irqflags);
+ spin_unlock(&host->irq_lock);
del_timer(&host->cmd11_timer);
}
if (pending & DW_MCI_CMD_ERROR_FLAGS) {
- spin_lock_irqsave(&host->irq_lock, irqflags);
+ spin_lock(&host->irq_lock);
del_timer(&host->cto_timer);
mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS);
@@ -2648,7 +2647,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
smp_wmb(); /* drain writebuffer */
set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
- spin_unlock_irqrestore(&host->irq_lock, irqflags);
+ spin_unlock(&host->irq_lock);
}
if (pending & DW_MCI_DATA_ERROR_FLAGS) {
@@ -2661,7 +2660,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
}
if (pending & SDMMC_INT_DATA_OVER) {
- spin_lock_irqsave(&host->irq_lock, irqflags);
+ spin_lock(&host->irq_lock);
del_timer(&host->dto_timer);
@@ -2676,7 +2675,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
tasklet_schedule(&host->tasklet);
- spin_unlock_irqrestore(&host->irq_lock, irqflags);
+ spin_unlock(&host->irq_lock);
}
if (pending & SDMMC_INT_RXDR) {
@@ -2692,12 +2691,12 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
}
if (pending & SDMMC_INT_CMD_DONE) {
- spin_lock_irqsave(&host->irq_lock, irqflags);
+ spin_lock(&host->irq_lock);
mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE);
dw_mci_cmd_interrupt(host, pending);
- spin_unlock_irqrestore(&host->irq_lock, irqflags);
+ spin_unlock(&host->irq_lock);
}
if (pending & SDMMC_INT_CD) {
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 4ec41579940a..13f6a2c0ed04 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -1265,7 +1265,7 @@ static struct platform_driver meson_mmc_driver = {
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
- .of_match_table = of_match_ptr(meson_mmc_of_match),
+ .of_match_table = meson_mmc_of_match,
},
};
diff --git a/drivers/mmc/host/meson-mx-sdio.c b/drivers/mmc/host/meson-mx-sdio.c
index 1c5299cd0cbe..d4a48916bfb6 100644
--- a/drivers/mmc/host/meson-mx-sdio.c
+++ b/drivers/mmc/host/meson-mx-sdio.c
@@ -418,10 +418,9 @@ static irqreturn_t meson_mx_mmc_irq(int irq, void *data)
{
struct meson_mx_mmc_host *host = (void *) data;
u32 irqs, send;
- unsigned long irqflags;
irqreturn_t ret;
- spin_lock_irqsave(&host->irq_lock, irqflags);
+ spin_lock(&host->irq_lock);
irqs = readl(host->base + MESON_MX_SDIO_IRQS);
send = readl(host->base + MESON_MX_SDIO_SEND);
@@ -434,7 +433,7 @@ static irqreturn_t meson_mx_mmc_irq(int irq, void *data)
/* finally ACK all pending interrupts */
writel(irqs, host->base + MESON_MX_SDIO_IRQS);
- spin_unlock_irqrestore(&host->irq_lock, irqflags);
+ spin_unlock(&host->irq_lock);
return ret;
}
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
index f25079ba3bca..89bff4e8ec10 100644
--- a/drivers/mmc/host/moxart-mmc.c
+++ b/drivers/mmc/host/moxart-mmc.c
@@ -465,9 +465,8 @@ static irqreturn_t moxart_irq(int irq, void *devid)
{
struct moxart_host *host = (struct moxart_host *)devid;
u32 status;
- unsigned long flags;
- spin_lock_irqsave(&host->lock, flags);
+ spin_lock(&host->lock);
status = readl(host->base + REG_STATUS);
if (status & CARD_CHANGE) {
@@ -484,7 +483,7 @@ static irqreturn_t moxart_irq(int irq, void *devid)
if (status & (FIFO_ORUN | FIFO_URUN) && host->mrq)
moxart_transfer_pio(host);
- spin_unlock_irqrestore(&host->lock, flags);
+ spin_unlock(&host->lock);
return IRQ_HANDLED;
}
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 004fbfc23672..de09c6347524 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -35,6 +35,7 @@
#include "cqhci.h"
#define MAX_BD_NUM 1024
+#define MSDC_NR_CLOCKS 3
/*--------------------------------------------------------------------------*/
/* Common Definition */
@@ -77,9 +78,12 @@
#define MSDC_PAD_TUNE0 0xf0
#define PAD_DS_TUNE 0x188
#define PAD_CMD_TUNE 0x18c
+#define EMMC51_CFG0 0x204
#define EMMC50_CFG0 0x208
+#define EMMC50_CFG1 0x20c
#define EMMC50_CFG3 0x220
#define SDC_FIFO_CFG 0x228
+#define CQHCI_SETTING 0x7fc
/*--------------------------------------------------------------------------*/
/* Top Pad Register Offset */
@@ -260,15 +264,26 @@
#define PAD_CMD_TUNE_RX_DLY3 (0x1f << 1) /* RW */
+/* EMMC51_CFG0 mask */
+#define CMDQ_RDAT_CNT (0x3ff << 12) /* RW */
+
#define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0) /* RW */
#define EMMC50_CFG_CRCSTS_EDGE (0x1 << 3) /* RW */
#define EMMC50_CFG_CFCSTS_SEL (0x1 << 4) /* RW */
+#define EMMC50_CFG_CMD_RESP_SEL (0x1 << 9) /* RW */
+
+/* EMMC50_CFG1 mask */
+#define EMMC50_CFG1_DS_CFG (0x1 << 28) /* RW */
#define EMMC50_CFG3_OUTS_WR (0x1f << 0) /* RW */
#define SDC_FIFO_CFG_WRVALIDSEL (0x1 << 24) /* RW */
#define SDC_FIFO_CFG_RDVALIDSEL (0x1 << 25) /* RW */
+/* CQHCI_SETTING */
+#define CQHCI_RD_CMD_WND_SEL (0x1 << 14) /* RW */
+#define CQHCI_WR_CMD_WND_SEL (0x1 << 15) /* RW */
+
/* EMMC_TOP_CONTROL mask */
#define PAD_RXDLY_SEL (0x1 << 0) /* RW */
#define DELAY_EN (0x1 << 1) /* RW */
@@ -425,6 +440,8 @@ struct msdc_host {
struct clk *h_clk; /* msdc h_clk */
struct clk *bus_clk; /* bus clock which used to access register */
struct clk *src_clk_cg; /* msdc source clock control gate */
+ struct clk *sys_clk_cg; /* msdc subsys clock control gate */
+ struct clk_bulk_data bulk_clks[MSDC_NR_CLOCKS];
u32 mclk; /* mmc subsystem clock frequency */
u32 src_clk_freq; /* source clock frequency */
unsigned char timing;
@@ -785,6 +802,7 @@ static void msdc_set_busy_timeout(struct msdc_host *host, u64 ns, u64 clks)
static void msdc_gate_clock(struct msdc_host *host)
{
+ clk_bulk_disable_unprepare(MSDC_NR_CLOCKS, host->bulk_clks);
clk_disable_unprepare(host->src_clk_cg);
clk_disable_unprepare(host->src_clk);
clk_disable_unprepare(host->bus_clk);
@@ -793,10 +811,18 @@ static void msdc_gate_clock(struct msdc_host *host)
static void msdc_ungate_clock(struct msdc_host *host)
{
+ int ret;
+
clk_prepare_enable(host->h_clk);
clk_prepare_enable(host->bus_clk);
clk_prepare_enable(host->src_clk);
clk_prepare_enable(host->src_clk_cg);
+ ret = clk_bulk_prepare_enable(MSDC_NR_CLOCKS, host->bulk_clks);
+ if (ret) {
+ dev_err(host->dev, "Cannot enable pclk/axi/ahb clock gates\n");
+ return;
+ }
+
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
}
@@ -1537,13 +1563,12 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
struct mmc_host *mmc = mmc_from_priv(host);
while (true) {
- unsigned long flags;
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
u32 events, event_mask;
- spin_lock_irqsave(&host->lock, flags);
+ spin_lock(&host->lock);
events = readl(host->base + MSDC_INT);
event_mask = readl(host->base + MSDC_INTEN);
if ((events & event_mask) & MSDC_INT_SDIOIRQ)
@@ -1554,7 +1579,7 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
mrq = host->mrq;
cmd = host->cmd;
data = host->data;
- spin_unlock_irqrestore(&host->lock, flags);
+ spin_unlock(&host->lock);
if ((events & event_mask) & MSDC_INT_SDIOIRQ)
sdio_signal_irq(mmc);
@@ -2266,6 +2291,31 @@ static int msdc_get_cd(struct mmc_host *mmc)
return !val;
}
+static void msdc_hs400_enhanced_strobe(struct mmc_host *mmc,
+ struct mmc_ios *ios)
+{
+ struct msdc_host *host = mmc_priv(mmc);
+
+ if (ios->enhanced_strobe) {
+ msdc_prepare_hs400_tuning(mmc, ios);
+ sdr_set_field(host->base + EMMC50_CFG0, EMMC50_CFG_PADCMD_LATCHCK, 1);
+ sdr_set_field(host->base + EMMC50_CFG0, EMMC50_CFG_CMD_RESP_SEL, 1);
+ sdr_set_field(host->base + EMMC50_CFG1, EMMC50_CFG1_DS_CFG, 1);
+
+ sdr_clr_bits(host->base + CQHCI_SETTING, CQHCI_RD_CMD_WND_SEL);
+ sdr_clr_bits(host->base + CQHCI_SETTING, CQHCI_WR_CMD_WND_SEL);
+ sdr_clr_bits(host->base + EMMC51_CFG0, CMDQ_RDAT_CNT);
+ } else {
+ sdr_set_field(host->base + EMMC50_CFG0, EMMC50_CFG_PADCMD_LATCHCK, 0);
+ sdr_set_field(host->base + EMMC50_CFG0, EMMC50_CFG_CMD_RESP_SEL, 0);
+ sdr_set_field(host->base + EMMC50_CFG1, EMMC50_CFG1_DS_CFG, 0);
+
+ sdr_set_bits(host->base + CQHCI_SETTING, CQHCI_RD_CMD_WND_SEL);
+ sdr_set_bits(host->base + CQHCI_SETTING, CQHCI_WR_CMD_WND_SEL);
+ sdr_set_field(host->base + EMMC51_CFG0, CMDQ_RDAT_CNT, 0xb4);
+ }
+}
+
static void msdc_cqe_enable(struct mmc_host *mmc)
{
struct msdc_host *host = mmc_priv(mmc);
@@ -2323,6 +2373,7 @@ static const struct mmc_host_ops mt_msdc_ops = {
.set_ios = msdc_ops_set_ios,
.get_ro = mmc_gpio_get_ro,
.get_cd = msdc_get_cd,
+ .hs400_enhanced_strobe = msdc_hs400_enhanced_strobe,
.enable_sdio_irq = msdc_enable_sdio_irq,
.ack_sdio_irq = msdc_ack_sdio_irq,
.start_signal_voltage_switch = msdc_ops_switch_volt,
@@ -2367,6 +2418,48 @@ static void msdc_of_property_parse(struct platform_device *pdev,
host->cqhci = false;
}
+static int msdc_of_clock_parse(struct platform_device *pdev,
+ struct msdc_host *host)
+{
+ int ret;
+
+ host->src_clk = devm_clk_get(&pdev->dev, "source");
+ if (IS_ERR(host->src_clk))
+ return PTR_ERR(host->src_clk);
+
+ host->h_clk = devm_clk_get(&pdev->dev, "hclk");
+ if (IS_ERR(host->h_clk))
+ return PTR_ERR(host->h_clk);
+
+ host->bus_clk = devm_clk_get_optional(&pdev->dev, "bus_clk");
+ if (IS_ERR(host->bus_clk))
+ host->bus_clk = NULL;
+
+ /*source clock control gate is optional clock*/
+ host->src_clk_cg = devm_clk_get_optional(&pdev->dev, "source_cg");
+ if (IS_ERR(host->src_clk_cg))
+ host->src_clk_cg = NULL;
+
+ host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg");
+ if (IS_ERR(host->sys_clk_cg))
+ host->sys_clk_cg = NULL;
+
+ /* If present, always enable for this clock gate */
+ clk_prepare_enable(host->sys_clk_cg);
+
+ host->bulk_clks[0].id = "pclk_cg";
+ host->bulk_clks[1].id = "axi_cg";
+ host->bulk_clks[2].id = "ahb_cg";
+ ret = devm_clk_bulk_get_optional(&pdev->dev, MSDC_NR_CLOCKS,
+ host->bulk_clks);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot get pclk/axi/ahb clock gates\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int msdc_drv_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
@@ -2406,30 +2499,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
if (ret)
goto host_free;
- host->src_clk = devm_clk_get(&pdev->dev, "source");
- if (IS_ERR(host->src_clk)) {
- ret = PTR_ERR(host->src_clk);
- goto host_free;
- }
-
- host->h_clk = devm_clk_get(&pdev->dev, "hclk");
- if (IS_ERR(host->h_clk)) {
- ret = PTR_ERR(host->h_clk);
+ ret = msdc_of_clock_parse(pdev, host);
+ if (ret)
goto host_free;
- }
-
- host->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");
- if (IS_ERR(host->bus_clk))
- host->bus_clk = NULL;
- /*source clock control gate is optional clock*/
- host->src_clk_cg = devm_clk_get(&pdev->dev, "source_cg");
- if (IS_ERR(host->src_clk_cg))
- host->src_clk_cg = NULL;
host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,
"hrst");
- if (IS_ERR(host->reset))
- return PTR_ERR(host->reset);
+ if (IS_ERR(host->reset)) {
+ ret = PTR_ERR(host->reset);
+ goto host_free;
+ }
host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0) {
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 12ee07285980..2fe6fcdbb1b3 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -157,32 +157,16 @@ struct mxcmci_host {
enum mxcmci_type devtype;
};
-static const struct platform_device_id mxcmci_devtype[] = {
- {
- .name = "imx21-mmc",
- .driver_data = IMX21_MMC,
- }, {
- .name = "imx31-mmc",
- .driver_data = IMX31_MMC,
- }, {
- .name = "mpc512x-sdhc",
- .driver_data = MPC512X_MMC,
- }, {
- /* sentinel */
- }
-};
-MODULE_DEVICE_TABLE(platform, mxcmci_devtype);
-
static const struct of_device_id mxcmci_of_match[] = {
{
.compatible = "fsl,imx21-mmc",
- .data = &mxcmci_devtype[IMX21_MMC],
+ .data = (void *) IMX21_MMC,
}, {
.compatible = "fsl,imx31-mmc",
- .data = &mxcmci_devtype[IMX31_MMC],
+ .data = (void *) IMX31_MMC,
}, {
.compatible = "fsl,mpc5121-sdhc",
- .data = &mxcmci_devtype[MPC512X_MMC],
+ .data = (void *) MPC512X_MMC,
}, {
/* sentinel */
}
@@ -1001,13 +985,10 @@ static int mxcmci_probe(struct platform_device *pdev)
int ret = 0, irq;
bool dat3_card_detect = false;
dma_cap_mask_t mask;
- const struct of_device_id *of_id;
struct imxmmc_platform_data *pdata = pdev->dev.platform_data;
pr_info("i.MX/MPC512x SDHC driver\n");
- of_id = of_match_device(mxcmci_of_match, &pdev->dev);
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
@@ -1044,12 +1025,7 @@ static int mxcmci_probe(struct platform_device *pdev)
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
mmc->max_seg_size = mmc->max_req_size;
- if (of_id) {
- const struct platform_device_id *id_entry = of_id->data;
- host->devtype = id_entry->driver_data;
- } else {
- host->devtype = pdev->id_entry->driver_data;
- }
+ host->devtype = (enum mxcmci_type)of_device_get_match_data(&pdev->dev);
/* adjust max_segs after devtype detection */
if (!is_mpc512x_mmc(host))
@@ -1241,7 +1217,6 @@ static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume);
static struct platform_driver mxcmci_driver = {
.probe = mxcmci_probe,
.remove = mxcmci_remove,
- .id_table = mxcmci_devtype,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 75007f61df97..56bbc6cd9c84 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -545,19 +545,6 @@ static const struct mmc_host_ops mxs_mmc_ops = {
.enable_sdio_irq = mxs_mmc_enable_sdio_irq,
};
-static const struct platform_device_id mxs_ssp_ids[] = {
- {
- .name = "imx23-mmc",
- .driver_data = IMX23_SSP,
- }, {
- .name = "imx28-mmc",
- .driver_data = IMX28_SSP,
- }, {
- /* sentinel */
- }
-};
-MODULE_DEVICE_TABLE(platform, mxs_ssp_ids);
-
static const struct of_device_id mxs_mmc_dt_ids[] = {
{ .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_SSP, },
{ .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_SSP, },
@@ -567,8 +554,6 @@ MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
static int mxs_mmc_probe(struct platform_device *pdev)
{
- const struct of_device_id *of_id =
- of_match_device(mxs_mmc_dt_ids, &pdev->dev);
struct device_node *np = pdev->dev.of_node;
struct mxs_mmc_host *host;
struct mmc_host *mmc;
@@ -593,7 +578,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
goto out_mmc_free;
}
- ssp->devid = (enum mxs_ssp_id) of_id->data;
+ ssp->devid = (enum mxs_ssp_id)of_device_get_match_data(&pdev->dev);
host->mmc = mmc;
host->sdio_irq_en = 0;
@@ -723,7 +708,6 @@ static SIMPLE_DEV_PM_OPS(mxs_mmc_pm_ops, mxs_mmc_suspend, mxs_mmc_resume);
static struct platform_driver mxs_mmc_driver = {
.probe = mxs_mmc_probe,
.remove = mxs_mmc_remove,
- .id_table = mxs_ssp_ids,
.driver = {
.name = DRIVER_NAME,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
diff --git a/drivers/mmc/host/owl-mmc.c b/drivers/mmc/host/owl-mmc.c
index ccf214a89eda..53b81582f1af 100644
--- a/drivers/mmc/host/owl-mmc.c
+++ b/drivers/mmc/host/owl-mmc.c
@@ -134,10 +134,9 @@ static void owl_mmc_update_reg(void __iomem *reg, unsigned int val, bool state)
static irqreturn_t owl_irq_handler(int irq, void *devid)
{
struct owl_mmc_host *owl_host = devid;
- unsigned long flags;
u32 state;
- spin_lock_irqsave(&owl_host->lock, flags);
+ spin_lock(&owl_host->lock);
state = readl(owl_host->base + OWL_REG_SD_STATE);
if (state & OWL_SD_STATE_TEI) {
@@ -147,7 +146,7 @@ static irqreturn_t owl_irq_handler(int irq, void *devid)
complete(&owl_host->sdc_complete);
}
- spin_unlock_irqrestore(&owl_host->lock, flags);
+ spin_unlock(&owl_host->lock);
return IRQ_HANDLED;
}
@@ -522,11 +521,11 @@ static void owl_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
/* Enable DDR mode if requested */
if (ios->timing == MMC_TIMING_UHS_DDR50) {
- owl_host->ddr_50 = 1;
+ owl_host->ddr_50 = true;
owl_mmc_update_reg(owl_host->base + OWL_REG_SD_EN,
OWL_SD_EN_DDREN, true);
} else {
- owl_host->ddr_50 = 0;
+ owl_host->ddr_50 = false;
}
}
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 29f6180a0036..316393c694d7 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -731,6 +731,7 @@ static int pxamci_probe(struct platform_device *pdev)
host->power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
if (IS_ERR(host->power)) {
+ ret = PTR_ERR(host->power);
dev_err(dev, "Failed requesting gpio_power\n");
goto out;
}
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index acb9c81a4e45..38f028e70633 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -18,28 +18,39 @@
*
*/
-#include <linux/kernel.h>
#include <linux/clk.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_domain.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/slot-gpio.h>
-#include <linux/mfd/tmio.h>
-#include <linux/sh_dma.h>
-#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinctrl-state.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
#include <linux/regulator/consumer.h>
+#include <linux/sh_dma.h>
+#include <linux/slab.h>
#include <linux/sys_soc.h>
#include "renesas_sdhi.h"
#include "tmio_mmc.h"
-#define HOST_MODE 0xe4
+#define CTL_HOST_MODE 0xe4
+#define HOST_MODE_GEN2_SDR50_WMODE BIT(0)
+#define HOST_MODE_GEN2_SDR104_WMODE BIT(0)
+#define HOST_MODE_GEN3_WMODE BIT(0)
+#define HOST_MODE_GEN3_BUSWIDTH BIT(8)
+
+#define HOST_MODE_GEN3_16BIT HOST_MODE_GEN3_WMODE
+#define HOST_MODE_GEN3_32BIT (HOST_MODE_GEN3_WMODE | HOST_MODE_GEN3_BUSWIDTH)
+#define HOST_MODE_GEN3_64BIT 0
+
+#define CTL_SDIF_MODE 0xe6
+#define SDIF_MODE_HS400 BIT(0)
#define SDHI_VER_GEN2_SDR50 0x490c
#define SDHI_VER_RZ_A1 0x820b
@@ -60,26 +71,26 @@ static void renesas_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
*/
switch (sd_ctrl_read16(host, CTL_VERSION)) {
case SDHI_VER_GEN2_SDR50:
- val = (width == 32) ? 0x0001 : 0x0000;
+ val = (width == 32) ? HOST_MODE_GEN2_SDR50_WMODE : 0;
break;
case SDHI_VER_GEN2_SDR104:
- val = (width == 32) ? 0x0000 : 0x0001;
+ val = (width == 32) ? 0 : HOST_MODE_GEN2_SDR104_WMODE;
break;
case SDHI_VER_GEN3_SD:
case SDHI_VER_GEN3_SDMMC:
if (width == 64)
- val = 0x0000;
+ val = HOST_MODE_GEN3_64BIT;
else if (width == 32)
- val = 0x0101;
+ val = HOST_MODE_GEN3_32BIT;
else
- val = 0x0001;
+ val = HOST_MODE_GEN3_16BIT;
break;
default:
/* nothing to do */
return;
}
- sd_ctrl_write16(host, HOST_MODE, val);
+ sd_ctrl_write16(host, CTL_HOST_MODE, val);
}
static int renesas_sdhi_clk_enable(struct tmio_mmc_host *host)
@@ -373,7 +384,7 @@ static void renesas_sdhi_hs400_complete(struct mmc_host *mmc)
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
/* Set HS400 mode */
- sd_ctrl_write16(host, CTL_SDIF_MODE, 0x0001 |
+ sd_ctrl_write16(host, CTL_SDIF_MODE, SDIF_MODE_HS400 |
sd_ctrl_read16(host, CTL_SDIF_MODE));
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DT2FF,
@@ -424,9 +435,11 @@ static void renesas_sdhi_hs400_complete(struct mmc_host *mmc)
priv->needs_adjust_hs400 = true;
}
-static void renesas_sdhi_reset_scc(struct tmio_mmc_host *host,
- struct renesas_sdhi *priv)
+static void renesas_sdhi_disable_scc(struct mmc_host *mmc)
{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct renesas_sdhi *priv = host_to_priv(host);
+
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
@@ -434,14 +447,6 @@ static void renesas_sdhi_reset_scc(struct tmio_mmc_host *host,
~SH_MOBILE_SDHI_SCC_CKSEL_DTSEL &
sd_scc_read32(host, priv,
SH_MOBILE_SDHI_SCC_CKSEL));
-}
-
-static void renesas_sdhi_disable_scc(struct mmc_host *mmc)
-{
- struct tmio_mmc_host *host = mmc_priv(mmc);
- struct renesas_sdhi *priv = host_to_priv(host);
-
- renesas_sdhi_reset_scc(host, priv);
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
~SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN &
@@ -527,7 +532,7 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
/* Reset HS400 mode */
- sd_ctrl_write16(host, CTL_SDIF_MODE, ~0x0001 &
+ sd_ctrl_write16(host, CTL_SDIF_MODE, ~SDIF_MODE_HS400 &
sd_ctrl_read16(host, CTL_SDIF_MODE));
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DT2FF, priv->scc_tappos);
@@ -552,24 +557,38 @@ static int renesas_sdhi_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_io
return 0;
}
+/* only populated for TMIO_MMC_MIN_RCAR2 */
static void renesas_sdhi_reset(struct tmio_mmc_host *host)
{
struct renesas_sdhi *priv = host_to_priv(host);
+ u16 val;
- renesas_sdhi_reset_scc(host, priv);
- renesas_sdhi_reset_hs400_mode(host, priv);
- priv->needs_adjust_hs400 = false;
+ if (priv->scc_ctl) {
+ renesas_sdhi_disable_scc(host->mmc);
+ renesas_sdhi_reset_hs400_mode(host, priv);
+ priv->needs_adjust_hs400 = false;
- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+ sd_scc_write32(host, priv, SH_MOBILE_SDHI