summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-29 12:09:30 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-29 12:09:30 -0700
commit6b2a4f7a5b777ea8fcf3bb38a0a33e68a920a9dc (patch)
treefcf7d9bddc31974ad046aecd51cc856c68e14cdd
parenteefbab599531240adaffa1d23900afbc8b0342bd (diff)
parent022b483596fabb5d1320aa4b76f43a754063f37e (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (26 commits) mmc: SDHI should depend on SUPERH || ARCH_SHMOBILE mmc: tmio_mmc: Move some defines into a shared header mmc: tmio: support aggressive clock gating mmc: tmio: fix power-mode interpretation mmc: tmio: remove work-around for unmasked SDIO interrupts sh: fix SDHI IO address-range ARM: mach-shmobile: fix SDHI IO address-range mmc: tmio: only access registers above 0xff, if available mfd: remove now redundant sh_mobile_sdhi.h header sh: convert boards to use linux/mmc/sh_mobile_sdhi.h ARM: mach-shmobile: convert boards to use linux/mmc/sh_mobile_sdhi.h mmc: tmio: convert the SDHI MMC driver from MFD to a platform driver sh: ecovec: use the CONFIG_MMC_TMIO symbols instead of MFD mmc: tmio: split core functionality, DMA and MFD glue mmc: tmio: use PIO for short transfers mmc: tmio-mmc: Improve DMA stability on sh-mobile mmc: fix mmc_app_send_scr() for dma transfer mmc: sdhci-esdhc: enable esdhc on imx53 mmc: sdhci-esdhc: use writel/readl as general APIs mmc: sdhci: add the abort CMDTYPE bits definition ...
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c6
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c6
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c8
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c6
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c12
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c4
-rw-r--r--arch/sh/boards/mach-migor/setup.c4
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c6
-rw-r--r--drivers/mfd/Kconfig14
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mmc/card/mmc_test.c3
-rw-r--r--drivers/mmc/core/sd_ops.c14
-rw-r--r--drivers/mmc/host/Kconfig14
-rw-r--r--drivers/mmc/host/Makefile8
-rw-r--r--drivers/mmc/host/dw_mmc.c4
-rw-r--r--drivers/mmc/host/mmci.c13
-rw-r--r--drivers/mmc/host/of_mmc_spi.c2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c86
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h3
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c3
-rw-r--r--drivers/mmc/host/sdhci-pci.c6
-rw-r--r--drivers/mmc/host/sdhci-pltfm.h2
-rw-r--r--drivers/mmc/host/sdhci.h1
-rw-r--r--drivers/mmc/host/sh_mobile_sdhi.c (renamed from drivers/mfd/sh_mobile_sdhi.c)95
-rw-r--r--drivers/mmc/host/tmio_mmc.c1285
-rw-r--r--drivers/mmc/host/tmio_mmc.h123
-rw-r--r--drivers/mmc/host/tmio_mmc_dma.c317
-rw-r--r--drivers/mmc/host/tmio_mmc_pio.c897
-rw-r--r--drivers/mmc/host/via-sdmmc.c5
-rw-r--r--include/linux/mmc/sh_mobile_sdhi.h (renamed from include/linux/mfd/sh_mobile_sdhi.h)0
-rw-r--r--include/linux/mmc/tmio.h63
31 files changed, 1615 insertions, 1396 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 08cc45137bdc..783b66fa95fb 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -24,9 +24,9 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
@@ -312,7 +312,7 @@ static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0xe6850000,
- .end = 0xe68501ff,
+ .end = 0xe68500ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -345,7 +345,7 @@ static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0xe6860000,
- .end = 0xe68601ff,
+ .end = 0xe68600ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index dee3e9231fb9..c87a7b7c5832 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -31,7 +31,7 @@
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
#include <linux/mmc/host.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/gpio.h>
#include <mach/sh7377.h>
#include <mach/common.h>
@@ -205,7 +205,7 @@ static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0xe6d50000,
- .end = 0xe6d501ff,
+ .end = 0xe6d50nff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -232,7 +232,7 @@ static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0xe6d60000,
- .end = 0xe6d601ff,
+ .end = 0xe6d600ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index f0d0af14ae06..8184d4d4f234 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -32,10 +32,10 @@
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/leds.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
@@ -690,7 +690,7 @@ static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0xe6850000,
- .end = 0xe68501ff,
+ .end = 0xe68500ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -725,7 +725,7 @@ static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0xe6860000,
- .end = 0xe68601ff,
+ .end = 0xe68600ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -768,7 +768,7 @@ static struct resource sdhi2_resources[] = {
[0] = {
.name = "SDHI2",
.start = 0xe6870000,
- .end = 0xe68701ff,
+ .end = 0xe68700ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 3e5fc3bbf3ed..636d8318a72a 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -14,8 +14,8 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/sh_flctl.h>
#include <linux/delay.h>
@@ -423,7 +423,7 @@ static struct resource sdhi0_cn3_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -453,7 +453,7 @@ static struct resource sdhi1_cn7_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0x04cf0000,
- .end = 0x04cf01ff,
+ .end = 0x04cf00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 3fbae0d0b6c8..fd4ff25f23b2 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -11,9 +11,9 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
@@ -464,7 +464,7 @@ static struct i2c_board_info ts_i2c_clients = {
.irq = IRQ0,
};
-#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
/* SDHI0 */
static void sdhi0_set_pwr(struct platform_device *pdev, int state)
{
@@ -482,7 +482,7 @@ static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -522,7 +522,7 @@ static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0x04cf0000,
- .end = 0x04cf01ff,
+ .end = 0x04cf00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -880,7 +880,7 @@ static struct platform_device *ecovec_devices[] __initdata = {
&ceu0_device,
&ceu1_device,
&keysc_device,
-#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
&sdhi0_device,
#if !defined(CONFIG_MMC_SH_MMCIF)
&sdhi1_device,
@@ -1162,7 +1162,7 @@ static int __init arch_setup(void)
gpio_direction_input(GPIO_PTR5);
gpio_direction_input(GPIO_PTR6);
-#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
/* enable SDHI0 on CN11 (needs DS2.4 set to ON) */
gpio_request(GPIO_FN_SDHI0CD, NULL);
gpio_request(GPIO_FN_SDHI0WP, NULL);
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 7504daaa85da..8b4abbbd1477 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -10,8 +10,8 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/onenand.h>
@@ -354,7 +354,7 @@ static struct resource kfr2r09_sh_sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 03a7ffe729d5..184fde169132 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -12,8 +12,8 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
#include <linux/i2c.h>
@@ -399,7 +399,7 @@ static struct resource sdhi_cn9_resources[] = {
[0] = {
.name = "SDHI",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index c8bcf6a19b55..12357671023e 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -14,8 +14,8 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/delay.h>
#include <linux/smc91x.h>
@@ -456,7 +456,7 @@ static struct resource sdhi0_cn7_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -488,7 +488,7 @@ static struct resource sdhi1_cn8_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0x04cf0000,
- .end = 0x04cf01ff,
+ .end = 0x04cf00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 9a46d64996a9..e2fea580585a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -60,15 +60,6 @@ config MFD_ASIC3
This driver supports the ASIC3 multifunction chip found on many
PDAs (mainly iPAQ and HTC based ones)
-config MFD_SH_MOBILE_SDHI
- bool "Support for SuperH Mobile SDHI"
- depends on SUPERH || ARCH_SHMOBILE
- select MFD_CORE
- select TMIO_MMC_DMA
- ---help---
- This driver supports the SDHI hardware block found in many
- SuperH Mobile SoCs.
-
config MFD_DAVINCI_VOICECODEC
tristate
select MFD_CORE
@@ -266,11 +257,6 @@ config MFD_TMIO
bool
default n
-config TMIO_MMC_DMA
- bool
- select DMA_ENGINE
- select DMADEVICES
-
config MFD_T7L66XB
bool "Support Toshiba T7L66XB"
depends on ARM && HAVE_CLK
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index ef489f253402..419caa9d7dcf 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -6,7 +6,6 @@
obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
-obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 5ec8eddfcf6e..f5cedeccad42 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -1875,7 +1875,7 @@ static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
unsigned int tot_sz, int max_scatter)
{
unsigned int dev_addr, i, cnt, sz, ssz;
- struct timespec ts1, ts2, ts;
+ struct timespec ts1, ts2;
int ret;
sz = test->area.max_tfr;
@@ -1912,7 +1912,6 @@ static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
}
getnstimeofday(&ts2);
- ts = timespec_sub(ts2, ts1);
mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
return 0;
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 797cdb5887fd..76af349c14b4 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -9,6 +9,7 @@
* your option) any later version.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/scatterlist.h>
@@ -252,6 +253,7 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
struct mmc_command cmd;
struct mmc_data data;
struct scatterlist sg;
+ void *data_buf;
BUG_ON(!card);
BUG_ON(!card->host);
@@ -263,6 +265,13 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
if (err)
return err;
+ /* dma onto stack is unsafe/nonportable, but callers to this
+ * routine normally provide temporary on-stack buffers ...
+ */
+ data_buf = kmalloc(sizeof(card->raw_scr), GFP_KERNEL);
+ if (data_buf == NULL)
+ return -ENOMEM;
+
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
@@ -280,12 +289,15 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
data.sg = &sg;
data.sg_len = 1;
- sg_init_one(&sg, scr, 8);
+ sg_init_one(&sg, data_buf, 8);
mmc_set_data_timeout(&data, card);
mmc_wait_for_req(card->host, &mrq);
+ memcpy(scr, data_buf, sizeof(card->raw_scr));
+ kfree(data_buf);
+
if (cmd.error)
return cmd.error;
if (data.error)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 1a21c6427a19..94df40531c38 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -439,13 +439,25 @@ config MMC_SDRICOH_CS
To compile this driver as a module, choose M here: the
module will be called sdricoh_cs.
+config MMC_TMIO_CORE
+ tristate
+
config MMC_TMIO
tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
- depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI
+ depends on MFD_TMIO || MFD_ASIC3
+ select MMC_TMIO_CORE
help
This provides support for the SD/MMC cell found in TC6393XB,
T7L66XB and also HTC ASIC3
+config MMC_SDHI
+ tristate "SH-Mobile SDHI SD/SDIO controller support"
+ depends on SUPERH || ARCH_SHMOBILE
+ select MMC_TMIO_CORE
+ help
+ This provides support for the SDHI SD/SDIO controller found in
+ SuperH and ARM SH-Mobile SoCs
+
config MMC_CB710
tristate "ENE CB710 MMC/SD Interface support"
depends on PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 30aa6867745f..4f1df0aae574 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -29,7 +29,13 @@ endif
obj-$(CONFIG_MMC_S3C) += s3cmci.o
obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o
obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o
-obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
+obj-$(CONFIG_MMC_TMIO_CORE) += tmio_mmc_core.o
+tmio_mmc_core-y := tmio_mmc_pio.o
+ifneq ($(CONFIG_MMC_SDHI),n)
+tmio_mmc_core-y += tmio_mmc_dma.o
+endif
+obj-$(CONFIG_MMC_SDHI) += sh_mobile_sdhi.o
+obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
obj-$(CONFIG_MMC_DW) += dw_mmc.o
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 5a614069cb00..87e1f57ec9ba 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -316,7 +316,7 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
/* Stop the IDMAC running */
temp = mci_readl(host, BMOD);
- temp &= ~SDMMC_IDMAC_ENABLE;
+ temp &= ~(SDMMC_IDMAC_ENABLE | SDMMC_IDMAC_FB);
mci_writel(host, BMOD, temp);
}
@@ -385,7 +385,7 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
/* Enable the IDMAC */
temp = mci_readl(host, BMOD);
- temp |= SDMMC_IDMAC_ENABLE;
+ temp |= SDMMC_IDMAC_ENABLE | SDMMC_IDMAC_FB;
mci_writel(host, BMOD, temp);
/* Start it running */
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 5bbb87d10251..b4a7e4fba90f 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -68,6 +68,12 @@ static struct variant_data variant_arm = {
.datalength_bits = 16,
};
+static struct variant_data variant_arm_extended_fifo = {
+ .fifosize = 128 * 4,
+ .fifohalfsize = 64 * 4,
+ .datalength_bits = 16,
+};
+
static struct variant_data variant_u300 = {
.fifosize = 16 * 4,
.fifohalfsize = 8 * 4,
@@ -1277,10 +1283,15 @@ static int mmci_resume(struct amba_device *dev)
static struct amba_id mmci_ids[] = {
{
.id = 0x00041180,
- .mask = 0x000fffff,
+ .mask = 0xff0fffff,
.data = &variant_arm,
},
{
+ .id = 0x01041180,
+ .mask = 0xff0fffff,
+ .data = &variant_arm_extended_fifo,
+ },
+ {
.id = 0x00041181,
.mask = 0x000fffff,
.data = &variant_arm,
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index 5530def54e5b..e2aecb7f1d5c 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -15,9 +15,11 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
+#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
#include <linux/spi/spi.h>
#include <linux/spi/mmc_spi.h>
#include <linux/mmc/core.h>
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 3b5248567973..a19967d0bfc4 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -16,14 +16,40 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdhci-pltfm.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
#include <mach/hardware.h>
#include <mach/esdhc.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
+/* VENDOR SPEC register */
+#define SDHCI_VENDOR_SPEC 0xC0
+#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
+
+#define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0)
+/*
+ * The CMDTYPE of the CMD register (offset 0xE) should be set to
+ * "11" when the STOP CMD12 is issued on imx53 to abort one
+ * open ended multi-blk IO. Otherwise the TC INT wouldn't
+ * be generated.
+ * In exact block transfer, the controller doesn't complete the
+ * operations automatically as required at the end of the
+ * transfer and remains on hold if the abort command is not sent.
+ * As a result, the TC flag is not asserted and SW received timeout
+ * exeception. Bit1 of Vendor Spec registor is used to fix it.
+ */
+#define ESDHC_FLAG_MULTIBLK_NO_INT (1 << 1)
+
+struct pltfm_imx_data {
+ int flags;
+ u32 scratchpad;
+};
+
static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
{
void __iomem *base = host->ioaddr + (reg & ~0x3);
@@ -34,10 +60,14 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i
static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
/* fake CARD_PRESENT flag on mx25/35 */
u32 val = readl(host->ioaddr + reg);
- if (unlikely(reg == SDHCI_PRESENT_STATE)) {
+ if (unlikely((reg == SDHCI_PRESENT_STATE)
+ && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) {
struct esdhc_platform_data *boarddata =
host->mmc->parent->platform_data;
@@ -55,13 +85,26 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
{
- if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE))
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
+ if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
+ && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP)))
/*
* these interrupts won't work with a custom card_detect gpio
* (only applied to mx25/35)
*/
val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
+ if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
+ && (reg == SDHCI_INT_STATUS)
+ && (val & SDHCI_INT_DATA_END))) {
+ u32 v;
+ v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ v &= ~SDHCI_VENDOR_SPEC_SDIO_QUIRK;
+ writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+ }
+
writel(val, host->ioaddr + reg);
}
@@ -76,6 +119,7 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
switch (reg) {
case SDHCI_TRANSFER_MODE:
@@ -83,10 +127,22 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
* Postpone this write, we must do it together with a
* command write that is down below.
*/
- pltfm_host->scratchpad = val;
+ if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
+ && (host->cmd->opcode == SD_IO_RW_EXTENDED)
+ && (host->cmd->data->blocks > 1)
+ && (host->cmd->data->flags & MMC_DATA_READ)) {
+ u32 v;
+ v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ v |= SDHCI_VENDOR_SPEC_SDIO_QUIRK;
+ writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+ }
+ imx_data->scratchpad = val;
return;
case SDHCI_COMMAND:
- writel(val << 16 | pltfm_host->scratchpad,
+ if ((host->cmd->opcode == MMC_STOP_TRANSMISSION)
+ && (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+ val |= SDHCI_CMD_ABORTCMD;
+ writel(val << 16 | imx_data->scratchpad,
host->ioaddr + SDHCI_TRANSFER_MODE);
return;
case SDHCI_BLOCK_SIZE:
@@ -146,7 +202,9 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
}
static struct sdhci_ops sdhci_esdhc_ops = {
+ .read_l = esdhc_readl_le,
.read_w = esdhc_readw_le,
+ .write_l = esdhc_writel_le,
.write_w = esdhc_writew_le,
.write_b = esdhc_writeb_le,
.set_clock = esdhc_set_clock,
@@ -168,6 +226,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
struct clk *clk;
int err;
+ struct pltfm_imx_data *imx_data;
clk = clk_get(mmc_dev(host->mmc), NULL);
if (IS_ERR(clk)) {
@@ -177,7 +236,15 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
clk_enable(clk);
pltfm_host->clk = clk;
- if (cpu_is_mx35() || cpu_is_mx51())
+ imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
+ if (!imx_data) {
+ clk_disable(pltfm_host->clk);
+ clk_put(pltfm_host->clk);
+ return -ENOMEM;
+ }
+ pltfm_host->priv = imx_data;
+
+ if (!cpu_is_mx25())
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
if (cpu_is_mx25() || cpu_is_mx35()) {
@@ -187,6 +254,9 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
}
+ if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
+ imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
+
if (boarddata) {
err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
if (err) {
@@ -214,8 +284,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
goto no_card_detect_irq;
}
- sdhci_esdhc_ops.write_l = esdhc_writel_le;
- sdhci_esdhc_ops.read_l = esdhc_readl_le;
+ imx_data->flags |= ESDHC_FLAG_GPIO_FOR_CD_WP;
/* Now we have a working card_detect again */
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
@@ -227,6 +296,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
no_card_detect_pin:
boarddata->cd_gpio = err;
not_supported:
+ kfree(imx_data);
return 0;
}
@@ -234,6 +304,7 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
if (boarddata && gpio_is_valid(boarddata->wp_gpio))
gpio_free(boarddata->wp_gpio);
@@ -247,6 +318,7 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
clk_disable(pltfm_host->clk);
clk_put(pltfm_host->clk);
+ kfree(imx_data);
}
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index c55aae828aac..c3b08f111942 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -23,8 +23,7 @@
SDHCI_QUIRK_NONSTANDARD_CLOCK | \
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
SDHCI_QUIRK_PIO_NEEDS_DELAY | \
- SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | \
- SDHCI_QUIRK_NO_CARD_NO_RESET)
+ SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
#define ESDHC_SYSTEM_CONTROL 0x2c
#define ESDHC_CLOCK_MASK 0x0000fff0
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 08161f690ae8..ba40d6d035c7 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -74,7 +74,8 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
struct sdhci_of_data sdhci_esdhc = {
/* card detection could be handled via GPIO */
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
+ | SDHCI_QUIRK_NO_CARD_NO_RESET,
.ops = {
.read_l = sdhci_be32bs_readl,
.read_w = esdhc_readw,
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 2f8d46854acd..a136be706347 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -1016,16 +1016,14 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
struct sdhci_pci_chip *chip;
struct sdhci_pci_slot *slot;
- u8 slots, rev, first_bar;
+ u8 slots, first_bar;
int ret, i;
BUG_ON(pdev == NULL);
BUG_ON(ent == NULL);
- pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
-
dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n",
- (int)pdev->vendor, (int)pdev->device, (int)rev);
+ (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots);
if (ret)
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index ea2e44d9be5e..2b37016ad0ac 100644
--- a/