[RFC PATCH 1/2] MMC: DTS: Add binding for Wondermedia WM8505 SDHC
Binding documentation for WMT SD/MMC Host Controller found on Wondermedia 8xxx series SoCs. Based on mmc.txt binding with additional properties. Signed-off-by: Tony Prisk li...@prisktech.co.nz --- .../devicetree/bindings/mmc/vt8500-sdmmc.txt | 24 1 file changed, 24 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt diff --git a/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt b/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt new file mode 100644 index 000..69a817e --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt @@ -0,0 +1,24 @@ +* Wondermedia WM8505/WM8650 SD/MMC Host Controller + +Required properties: +- compatible: Should be wm,wm8505-sdhc. +- reg: Memory for sdhc controller. +- interrupts: Two interrupts are required - regular irq and dma irq. +- clocks: pHandle to clock for controller. +- bus-width: 1,4 or 8 data lines connected + +Optional properties: +- sdon-inverted: SD_ON bit is inverted on the controller +- cd-inverted: CD bit is inverted on the controller + +Examples: + +sdhc@d800a000 { + compatible = wm,wm8505-sdhc; + reg = 0xd800a000 0x1000; + interrupts = 20 21; + clocks = sdhc; + bus-width = 4; + sdon-inverted; +}; + -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 0/2] MMC: Add support for Wondermedia SoC SDHC
This patchset adds support for the Wondermedia 8xxx-series SD Host Controller currently found under arm/arch-vt8500. Tony Prisk (2): MMC: DTS: Add binding for Wondermedia WM8505 SDHC MMC: SD/MMC Host Controller for Wondermedia WM8505/WM8650 .../devicetree/bindings/mmc/vt8500-sdmmc.txt | 24 + drivers/mmc/host/Kconfig | 12 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/wmt-sdmmc.c | 983 4 files changed, 1020 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/vt8500-sdmmc.txt create mode 100644 drivers/mmc/host/wmt-sdmmc.c -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 2/2] MMC: SD/MMC Host Controller for Wondermedia WM8505/WM8650
This patch adds support for the SD/MMC host controller found on Wondermedia 8xxx series SoCs, currently supported under arm/arch-vt8500. Signed-off-by: Tony Prisk li...@prisktech.co.nz --- drivers/mmc/host/Kconfig | 12 + drivers/mmc/host/Makefile|1 + drivers/mmc/host/wmt-sdmmc.c | 983 ++ 3 files changed, 996 insertions(+) create mode 100644 drivers/mmc/host/wmt-sdmmc.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 9bf10e7..7f4377b 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -621,3 +621,15 @@ config MMC_USHC Note: These controllers only support SDIO cards and do not support MMC or SD memory cards. + +config MMC_WMT + tristate Wondermedia SD/MMC Host Controller support + depends on ARCH_VT8500 + default y + help + This selects support for the SD/MMC Host Controller on + Wondermedia WM8505/WM8650 based SoCs. + + To compile this driver as a module, choose M here: the + module will be called wmt-sdmmc. + diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 17ad0a7..9c91f1f 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_MMC_SH_MMCIF)+= sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o obj-$(CONFIG_MMC_VUB300) += vub300.o obj-$(CONFIG_MMC_USHC) += ushc.o +obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_CNS3XXX)+= sdhci-cns3xxx.o diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c new file mode 100644 index 000..def1ec9 --- /dev/null +++ b/drivers/mmc/host/wmt-sdmmc.c @@ -0,0 +1,983 @@ +/* + * WM8505/WM8650 SD/MMC Host Controller + * + * Copyright (C) 2010 Tony Prisk + * Copyright (C) 2008 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation + */ + +#include linux/init.h +#include linux/module.h +#include linux/platform_device.h +#include linux/ioport.h +#include linux/errno.h +#include linux/dma-mapping.h +#include linux/delay.h +#include linux/io.h +#include linux/irq.h +#include linux/clk.h +#include linux/gpio.h + +#include linux/of.h +#include linux/of_address.h +#include linux/of_irq.h + +#include linux/mmc/host.h +#include linux/mmc/mmc.h +#include linux/mmc/sd.h + +#include asm/byteorder.h + + +#define DRIVER_NAME wmt-sdhc + + +/* MMC/SD controller registers */ +#define SDMMC_CTLR 0x00 +#define SDMMC_CMD 0x01 +#define SDMMC_RSPTYPE 0x02 +#define SDMMC_ARG 0x04 +#define SDMMC_BUSMODE 0x08 +#define SDMMC_BLKLEN 0x0C +#define SDMMC_BLKCNT 0x0E +#define SDMMC_RSP 0x10 +#define SDMMC_CBCR 0x20 +#define SDMMC_INTMASK0 0x24 +#define SDMMC_INTMASK1 0x25 +#define SDMMC_STS0 0x28 +#define SDMMC_STS1 0x29 +#define SDMMC_STS2 0x2A +#define SDMMC_STS3 0x2B +#define SDMMC_RSPTIMEOUT 0x2C +#define SDMMC_CLK 0x30/* VT8500 only */ +#define SDMMC_EXTCTRL 0x34 +#define SDMMC_SBLKLEN 0x38 +#define SDMMC_DMATIMEOUT 0x3C + + +/* SDMMC_CTLR bit fields */ +#define CTLR_CMD_START 0x01 +#define CTLR_CMD_WRITE 0x04 +#define CTLR_FIFO_RESET0x08 + +/* SDMMC_BUSMODE bit fields */ +#define BM_SPI_MODE0x01 +#define BM_FOURBIT_MODE0x02 +#define BM_EIGHTBIT_MODE 0x04 +#define BM_SD_OFF 0x10 +#define BM_SPI_CS 0x20 +#define BM_SD_POWER0x40 +#define BM_SOFT_RESET 0x80 +#define BM_ONEBIT_MASK 0xFD + +/* SDMMC_BLKLEN bit fields */ +#define BLKL_CRCERR_ABORT 0x0800 +#define BLKL_CD_POL_HIGH 0x1000 +#define BLKL_GPI_CD0x2000 +#define BLKL_DATA3_CD 0x4000 +#define BLKL_INT_ENABLE0x8000 + +/* SDMMC_INTMASK0 bit fields */ +#define INT0_MBLK_TRAN_DONE_INT_EN 0x10 +#define INT0_BLK_TRAN_DONE_INT_EN 0x20 +#define INT0_CD_INT_EN 0x40 +#define INT0_DI_INT_EN 0x80 + +/* SDMMC_INTMASK1 bit fields */ +#define INT1_CMD_RES_TRAN_DONE_INT_EN 0x02 +#define INT1_CMD_RES_TOUT_INT_EN 0x04 +#define INT1_MBLK_AUTO_STOP_INT_EN 0x08 +#define INT1_DATA_TOUT_INT_EN 0x10 +#define INT1_RESCRC_ERR_INT_EN 0x20 +#define INT1_RCRC_ERR_INT_EN 0x40 +#define
[PATCH] MMC: fix sdhci-dove removal
1. Unregister the device _BEFORE_ taking away any resources it may be using. 2. Don't check clks against NULL. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk --- I noticed this while merging v3.6 into Rabeeh's cubox kernel. drivers/mmc/host/sdhci-dove.c | 13 ++--- 1 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index 90140eb..c11db64 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c @@ -117,14 +117,13 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_dove_priv *priv = pltfm_host-priv; - if (priv-clk) { - if (!IS_ERR(priv-clk)) { - clk_disable_unprepare(priv-clk); - clk_put(priv-clk); - } - devm_kfree(pdev-dev, priv-clk); + sdhci_pltfm_unregister(pdev); + + if (!IS_ERR(priv-clk)) { + clk_disable_unprepare(priv-clk); + clk_put(priv-clk); } - return sdhci_pltfm_unregister(pdev); + return 0; } static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] MMC: fix sdhci-dove removal
On Mon, Oct 15, 2012 at 10:43:48AM +0100, Russell King - ARM Linux wrote: 1. Unregister the device _BEFORE_ taking away any resources it may be using. 2. Don't check clks against NULL. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk Looking at this driver some more, who the hell came up with the sdhci registration interface? It violates one of the most fundamental principles of kernel driver programming. You do _NOT_ publish your driver interfaces _UNTIL_ you have finished setting your device up. Otherwise, in a preemptible or SMP kernel, your driver can be used before the initialization has completed. As this driver calls sdhci_pltfm_register() before it has obtained the clock for the interface, and this function does: sdhci_pltfm_init sdhci_add_host mmc_add_host mmc_start_host mmc_power_up mmc_set_ios sdhci_set_ios See, we're trying to power up and clock the card _before_ the dove sdhci driver has even claimed the clock let alone enabled it. This is total bollocks. The sdhci platform interface is total crap for creating this broken design in the first place. This is why MMC has the init + add interfaces, they're there to allow drivers to do stuff the Right(tm) way and avoid shit like the above. This should have been picked up at review time before the driver went into mainline. In any case, it needs to be fixed. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] MMC: fix sdhci-dove removal
On Mon, Oct 15, 2012 at 11:37:25AM +0100, Russell King - ARM Linux wrote: On Mon, Oct 15, 2012 at 10:43:48AM +0100, Russell King - ARM Linux wrote: 1. Unregister the device _BEFORE_ taking away any resources it may be using. 2. Don't check clks against NULL. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk Looking at this driver some more, who the hell came up with the sdhci registration interface? It violates one of the most fundamental principles of kernel driver programming. You do _NOT_ publish your driver interfaces _UNTIL_ you have finished setting your device up. Otherwise, in a preemptible or SMP kernel, your driver can be used before the initialization has completed. As this driver calls sdhci_pltfm_register() before it has obtained the clock for the interface, and this function does: sdhci_pltfm_init sdhci_add_host mmc_add_host mmc_start_host mmc_power_up mmc_set_ios sdhci_set_ios See, we're trying to power up and clock the card _before_ the dove sdhci driver has even claimed the clock let alone enabled it. This is total bollocks. The sdhci platform interface is total crap for creating this broken design in the first place. This is why MMC has the init + add interfaces, they're there to allow drivers to do stuff the Right(tm) way and avoid shit like the above. This should have been picked up at review time before the driver went into mainline. In any case, it needs to be fixed. Here's an updated patch which just about fixes the sdhci-dove driver. I would not be surprised given the idiotic sdhci-pltfm API if many other drivers suffered the same bug. 8 From: Russell King rmk+ker...@arm.linux.org.uk Subject: [PATCH] MMC: fix sdhci-dove probe/removal 1. Never ever publish a device in the system before it has been setup to a usable state. 2. Unregister the device _BEFORE_ taking away any resources it may be using. 3. Don't check clks against NULL. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk --- drivers/mmc/host/sdhci-dove.c | 36 ++-- 1 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index a6e53a1..7d3a4e4 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c @@ -83,30 +83,31 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) struct sdhci_dove_priv *priv; int ret; - ret = sdhci_pltfm_register(pdev, sdhci_dove_pdata); - if (ret) - goto sdhci_dove_register_fail; - priv = devm_kzalloc(pdev-dev, sizeof(struct sdhci_dove_priv), GFP_KERNEL); if (!priv) { dev_err(pdev-dev, unable to allocate private data); - ret = -ENOMEM; - goto sdhci_dove_allocate_fail; + return -ENOMEM; } + priv-clk = clk_get(pdev-dev, NULL); + if (!IS_ERR(priv-clk)) + clk_prepare_enable(priv-clk); + + ret = sdhci_pltfm_register(pdev, sdhci_dove_pdata); + if (ret) + goto sdhci_dove_register_fail; + host = platform_get_drvdata(pdev); pltfm_host = sdhci_priv(host); pltfm_host-priv = priv; - priv-clk = clk_get(pdev-dev, NULL); - if (!IS_ERR(priv-clk)) - clk_prepare_enable(priv-clk); return 0; -sdhci_dove_allocate_fail: - sdhci_pltfm_unregister(pdev); sdhci_dove_register_fail: + clk_unprepare_disable(priv-clk); + clk_put(priv-clk); +sdhci_dove_allocate_fail: return ret; } @@ -116,14 +117,13 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_dove_priv *priv = pltfm_host-priv; - if (priv-clk) { - if (!IS_ERR(priv-clk)) { - clk_disable_unprepare(priv-clk); - clk_put(priv-clk); - } - devm_kfree(pdev-dev, priv-clk); + sdhci_pltfm_unregister(pdev); + + if (!IS_ERR(priv-clk)) { + clk_disable_unprepare(priv-clk); + clk_put(priv-clk); } - return sdhci_pltfm_unregister(pdev); + return 0; } static struct platform_driver sdhci_dove_driver = { -- 1.7.4.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH v2] mmc: core: Fixup signal voltage switch
When switching SD and SDIO cards from 3.3V to 1.8V signal levels, the clock should be gated for 5 ms during the step. After enabling the clock, the host should wait for at least 1 ms before checking for failure. Failure by the card to switch is indicated by dat[0:3] being pulled low. The host should check for this condition and power-cycle the card if failure is indicated. Add a retry mechanism for the SDIO case. If the voltage switch fails repeatedly, give up and continue the initialization using the original voltage. Signed-off-by: Johan Rudholm johan.rudh...@stericsson.com --- This rfc/patch is based on the following two patches: [PATCH v2 1/2] mmc: core: Proper signal voltage switch [PATCH v2 2/2] mmc: core: Power cycle card on voltage switch fail This patch has been tested with a couple of UHS micro-SD cards, one of which sometimes requires up to five power cycles before it accepts the signal voltage switch. The patch has also been tested with various other micro-SD cards, as well as one SDIO WLAN chip (cw1200) to check for regressions. The patch has been tested with CONFIG_MMC_CLKGATE. I'd be very grateful if someone could help me test this patch with a SDIO card that supports 1.8V and perhaps also a combo card (which does seem to be rare these days?)? Changelog: v1 - v2 - Removed reset of signal voltage in mmc_sd_get_cid, since mmc: core: reset signal voltage on power up previous two patches - v1: - Keep calls to mmc_host_clk_hold / mmc_host_clk_release - Add retry-loop / power cycle in sdio.c - Fall back to 3.3 V if the switch repeatedly fails - Add an extra argument to the card_busy host_ops function, which can be used to signal polling use of the function --- drivers/mmc/core/core.c | 31 ++- drivers/mmc/core/core.h |1 + drivers/mmc/core/sd.c| 29 - drivers/mmc/core/sdio.c | 28 ++-- include/linux/mmc/host.h |6 ++ 5 files changed, 87 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 06c42cf..160760c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1243,8 +1243,37 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 host-ios.signal_voltage = signal_voltage; if (host-ops-start_signal_voltage_switch) { + u32 clock; + mmc_host_clk_hold(host); + clock = host-ios.clock; + if (cmd11) { + host-ios.clock = 0; + mmc_set_ios(host); + } + err = host-ops-start_signal_voltage_switch(host, host-ios); + + if (err cmd11) { + host-ios.clock = clock; + mmc_set_ios(host); + } else if (cmd11) { + /* Stop clock for at least 5 ms according to spec */ + mmc_delay(5); + host-ios.clock = clock; + mmc_set_ios(host); + + /* Wait for at least 1 ms according to spec */ + mmc_delay(1); + + /* +* Failure to switch is indicated by the card holding +* dat[0:3] low +*/ + if (host-ops-card_busy + host-ops-card_busy(host, 0)) + err = -EAGAIN; + } mmc_host_clk_release(host); } @@ -1284,7 +1313,7 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) * If a host does all the power sequencing itself, ignore the * initial MMC_POWER_UP stage. */ -static void mmc_power_up(struct mmc_host *host) +void mmc_power_up(struct mmc_host *host) { int bit; diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 3bdafbc..5a5170d 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -45,6 +45,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, void mmc_set_timing(struct mmc_host *host, unsigned int timing); void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); void mmc_power_off(struct mmc_host *host); +void mmc_power_up(struct mmc_host *host); static inline void mmc_delay(unsigned int ms) { diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 74972c2..0b456de 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -713,6 +713,14 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) { int err; u32 max_current; + int retries = 10; + +try_again: + if (!retries) { + ocr = ~SD_OCR_S18R; + pr_warning(%s: Skipping voltage switch\n, + mmc_hostname(host)); +
Re: [RFC PATCH 2/2] MMC: SD/MMC Host Controller for Wondermedia WM8505/WM8650
On 15 October 2012 17:24, Tony Prisk li...@prisktech.co.nz wrote: This patch adds support for the SD/MMC host controller found on Wondermedia 8xxx series SoCs, currently supported under arm/arch-vt8500. Signed-off-by: Tony Prisk li...@prisktech.co.nz --- drivers/mmc/host/Kconfig | 12 + drivers/mmc/host/Makefile|1 + drivers/mmc/host/wmt-sdmmc.c | 983 ++ 3 files changed, 996 insertions(+) create mode 100644 drivers/mmc/host/wmt-sdmmc.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 9bf10e7..7f4377b 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -621,3 +621,15 @@ config MMC_USHC Note: These controllers only support SDIO cards and do not support MMC or SD memory cards. + +config MMC_WMT + tristate Wondermedia SD/MMC Host Controller support + depends on ARCH_VT8500 + default y + help + This selects support for the SD/MMC Host Controller on + Wondermedia WM8505/WM8650 based SoCs. + + To compile this driver as a module, choose M here: the + module will be called wmt-sdmmc. + diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 17ad0a7..9c91f1f 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_MMC_SH_MMCIF)+= sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o obj-$(CONFIG_MMC_VUB300) += vub300.o obj-$(CONFIG_MMC_USHC) += ushc.o +obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_CNS3XXX)+= sdhci-cns3xxx.o diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c new file mode 100644 index 000..def1ec9 --- /dev/null +++ b/drivers/mmc/host/wmt-sdmmc.c @@ -0,0 +1,983 @@ +/* + * WM8505/WM8650 SD/MMC Host Controller + * + * Copyright (C) 2010 Tony Prisk + * Copyright (C) 2008 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation + */ + +#include linux/init.h +#include linux/module.h +#include linux/platform_device.h +#include linux/ioport.h +#include linux/errno.h +#include linux/dma-mapping.h +#include linux/delay.h +#include linux/io.h +#include linux/irq.h +#include linux/clk.h +#include linux/gpio.h + +#include linux/of.h +#include linux/of_address.h +#include linux/of_irq.h + +#include linux/mmc/host.h +#include linux/mmc/mmc.h +#include linux/mmc/sd.h + +#include asm/byteorder.h + + +#define DRIVER_NAME wmt-sdhc + + +/* MMC/SD controller registers */ +#define SDMMC_CTLR 0x00 +#define SDMMC_CMD 0x01 +#define SDMMC_RSPTYPE 0x02 +#define SDMMC_ARG 0x04 +#define SDMMC_BUSMODE 0x08 +#define SDMMC_BLKLEN 0x0C +#define SDMMC_BLKCNT 0x0E +#define SDMMC_RSP 0x10 +#define SDMMC_CBCR 0x20 +#define SDMMC_INTMASK0 0x24 +#define SDMMC_INTMASK1 0x25 +#define SDMMC_STS0 0x28 +#define SDMMC_STS1 0x29 +#define SDMMC_STS2 0x2A +#define SDMMC_STS3 0x2B +#define SDMMC_RSPTIMEOUT 0x2C +#define SDMMC_CLK 0x30/* VT8500 only */ +#define SDMMC_EXTCTRL 0x34 +#define SDMMC_SBLKLEN 0x38 +#define SDMMC_DMATIMEOUT 0x3C + + +/* SDMMC_CTLR bit fields */ +#define CTLR_CMD_START 0x01 +#define CTLR_CMD_WRITE 0x04 +#define CTLR_FIFO_RESET0x08 + +/* SDMMC_BUSMODE bit fields */ +#define BM_SPI_MODE0x01 +#define BM_FOURBIT_MODE0x02 +#define BM_EIGHTBIT_MODE 0x04 +#define BM_SD_OFF 0x10 +#define BM_SPI_CS 0x20 +#define BM_SD_POWER0x40 +#define BM_SOFT_RESET 0x80 +#define BM_ONEBIT_MASK 0xFD + +/* SDMMC_BLKLEN bit fields */ +#define BLKL_CRCERR_ABORT 0x0800 +#define BLKL_CD_POL_HIGH 0x1000 +#define BLKL_GPI_CD0x2000 +#define BLKL_DATA3_CD 0x4000 +#define BLKL_INT_ENABLE0x8000 + +/* SDMMC_INTMASK0 bit fields */ +#define INT0_MBLK_TRAN_DONE_INT_EN 0x10 +#define INT0_BLK_TRAN_DONE_INT_EN 0x20 +#define INT0_CD_INT_EN 0x40 +#define INT0_DI_INT_EN 0x80 + +/* SDMMC_INTMASK1 bit fields */ +#define INT1_CMD_RES_TRAN_DONE_INT_EN 0x02 +#define
[PATCH 1/2] mmc: core: Support all MMC capabilities when booting from Device Tree
Capabilities are an important part of the MMC subsystem. Much supported functionality would be lost if we didn't provide the same level of support when booting Device Tree as we currently do when the subsystem is passed capabilities via platform data. This patch supplies this support with one simple call to a DT parsing function. Cc: Chris Ball c...@laptop.org Cc: Russell King li...@arm.linux.org.uk Cc: linux-mmc@vger.kernel.org Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Ulf Hansson ulf.hans...@linaro.org Signed-off-by: Lee Jones lee.jo...@linaro.org --- drivers/mmc/core/host.c | 93 ++ include/linux/mmc/host.h |3 +- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index ee2e16b..61a02db 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -20,6 +20,7 @@ #include linux/leds.h #include linux/slab.h #include linux/suspend.h +#include linux/of.h #include linux/mmc/host.h #include linux/mmc/card.h @@ -436,3 +437,95 @@ void mmc_free_host(struct mmc_host *host) } EXPORT_SYMBOL(mmc_free_host); + +/** + * mmc_of_populate_caps - support all MMC capabilities from Device Tree + * @np: MMC OF device node + * @caps: Host capabilities - as per linux/mmc/host.h + * @caps2: More host cabibilies - as per linux/mmc/host.h + * + * Read capability string from the device node provided and populate + * the capability container accordingly. + */ +void mmc_of_populate_caps(struct device_node *np, + unsigned long *caps, + unsigned int *caps2) +{ + if(of_property_read_bool(np, mmc-cap-4-bit-data)) + *caps |= MMC_CAP_4_BIT_DATA; + if(of_property_read_bool(np, mmc-cap-mmc-highspeed)) + *caps |= MMC_CAP_MMC_HIGHSPEED; + if(of_property_read_bool(np, mmc-cap-sd-highspeed)) + *caps |= MMC_CAP_SD_HIGHSPEED; + if(of_property_read_bool(np, mmc-cap-sdio-irq)) + *caps |= MMC_CAP_SDIO_IRQ; + if(of_property_read_bool(np, mmc-cap-spi)) + *caps |= MMC_CAP_SPI; + if(of_property_read_bool(np, mmc-cap-needs-poll)) + *caps |= MMC_CAP_NEEDS_POLL; + if(of_property_read_bool(np, mmc-cap-8-bit-data)) + *caps |= MMC_CAP_8_BIT_DATA; + if(of_property_read_bool(np, mmc-cap-nonremovable)) + *caps |= MMC_CAP_NONREMOVABLE; + if(of_property_read_bool(np, mmc-cap-wait-while-busy)) + *caps |= MMC_CAP_WAIT_WHILE_BUSY; + if(of_property_read_bool(np, mmc-cap-erase)) + *caps |= MMC_CAP_ERASE; + if(of_property_read_bool(np, mmc-cap-1-8v-ddr)) + *caps |= MMC_CAP_1_8V_DDR; + if(of_property_read_bool(np, mmc-cap-1-2v-ddr)) + *caps |= MMC_CAP_1_2V_DDR; + if(of_property_read_bool(np, mmc-cap-power-off-card)) + *caps |= MMC_CAP_POWER_OFF_CARD; + if(of_property_read_bool(np, mmc-cap-bus-width-test)) + *caps |= MMC_CAP_BUS_WIDTH_TEST; + if(of_property_read_bool(np, mmc-cap-uhs-sdr12)) + *caps |= MMC_CAP_UHS_SDR12; + if(of_property_read_bool(np, mmc-cap-uhs-sdr25)) + *caps |= MMC_CAP_UHS_SDR25; + if(of_property_read_bool(np, mmc-cap-uhs-sdr50)) + *caps |= MMC_CAP_UHS_SDR50; + if(of_property_read_bool(np, mmc-cap-uhs-sdr104)) + *caps |= MMC_CAP_UHS_SDR104; + if(of_property_read_bool(np, mmc-cap-uhs-ddr50)) + *caps |= MMC_CAP_UHS_DDR50; + if(of_property_read_bool(np, mmc-cap-driver-type-a)) + *caps |= MMC_CAP_DRIVER_TYPE_A; + if(of_property_read_bool(np, mmc-cap-driver-type-c)) + *caps |= MMC_CAP_DRIVER_TYPE_C; + if(of_property_read_bool(np, mmc-cap-driver-type-d)) + *caps |= MMC_CAP_DRIVER_TYPE_D; + if(of_property_read_bool(np, mmc-cap-cmd23)) + *caps |= MMC_CAP_CMD23; + if(of_property_read_bool(np, mmc-cap-hw-reset)) + *caps |= MMC_CAP_HW_RESET; + + if(of_property_read_bool(np, mmc-cap2-bootpart-noacc)) + *caps2 |= MMC_CAP2_BOOTPART_NOACC; + if(of_property_read_bool(np, mmc-cap2-cache-ctrl)) + *caps2 |= MMC_CAP2_CACHE_CTRL; + if(of_property_read_bool(np, mmc-cap2-poweroff-notify)) + *caps2 |= MMC_CAP2_POWEROFF_NOTIFY; + if(of_property_read_bool(np, mmc-cap2-no-multi-read)) + *caps2 |= MMC_CAP2_NO_MULTI_READ; + if(of_property_read_bool(np, mmc-cap2-no-sleep-cmd)) + *caps2 |= MMC_CAP2_NO_SLEEP_CMD; + if(of_property_read_bool(np, mmc-cap2-hs200-1-8v-sdr)) + *caps2 |= MMC_CAP2_HS200_1_8V_SDR; + if(of_property_read_bool(np, mmc-cap2-hs200-1-2v-sdr)) + *caps2 |= MMC_CAP2_HS200_1_2V_SDR; + if(of_property_read_bool(np, mmc-cap2-hs200)) +
[PATCH 2/2] mmc: mmci: Make use of new DT capability parsing function
Instead of rolling our own parsers for each new capability we wish to support, we can make use of a call-once function which parses all known capability strings and populates the necessary properties for us. All we have to do is remove our own cruft and invoke the call. Cc: Chris Ball c...@laptop.org Cc: Russell King li...@arm.linux.org.uk Cc: linux-mmc@vger.kernel.org Acked-by: Linus Walleij linus.wall...@linaro.org Acked-by: Ulf Hansson ulf.hans...@linaro.org Signed-off-by: Lee Jones lee.jo...@linaro.org --- drivers/mmc/host/mmci.c | 20 +--- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index edc3e9b..bc02f05 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1227,25 +1227,7 @@ static void mmci_dt_populate_generic_pdata(struct device_node *np, if (!pdata-f_max) pr_warn(%s has no 'max-frequency' property\n, np-full_name); - if (of_get_property(np, mmc-cap-mmc-highspeed, NULL)) - pdata-capabilities |= MMC_CAP_MMC_HIGHSPEED; - if (of_get_property(np, mmc-cap-sd-highspeed, NULL)) - pdata-capabilities |= MMC_CAP_SD_HIGHSPEED; - - of_property_read_u32(np, bus-width, bus_width); - switch (bus_width) { - case 0 : - /* No bus-width supplied. */ - break; - case 4 : - pdata-capabilities |= MMC_CAP_4_BIT_DATA; - break; - case 8 : - pdata-capabilities |= MMC_CAP_8_BIT_DATA; - break; - default : - pr_warn(%s: Unsupported bus width\n, np-full_name); - } + mmc_of_populate_caps(np, pdata-capabilities, pdata-capabilities2); } #else static void mmci_dt_populate_generic_pdata(struct device_node *np, -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mmc: core: Support all MMC capabilities when booting from Device Tree
On Monday 15 October 2012, Lee Jones wrote: Capabilities are an important part of the MMC subsystem. Much supported functionality would be lost if we didn't provide the same level of support when booting Device Tree as we currently do when the subsystem is passed capabilities via platform data. This patch supplies this support with one simple call to a DT parsing function. We already document all the commonly used properties in Documentation/devicetree/bindings/mmc/mmc.txt Please don't add any duplicates or those that are not used so far. + if(of_property_read_bool(np, mmc-cap-4-bit-data)) + *caps |= MMC_CAP_4_BIT_DATA; see bus-width property. + if(of_property_read_bool(np, mmc-cap-mmc-highspeed)) + *caps |= MMC_CAP_MMC_HIGHSPEED; + if(of_property_read_bool(np, mmc-cap-sd-highspeed)) + *caps |= MMC_CAP_SD_HIGHSPEED; implied by max-frequency property. + if(of_property_read_bool(np, mmc-cap-sdio-irq)) + *caps |= MMC_CAP_SDIO_IRQ; implied by presence of SDIO irq property. + if(of_property_read_bool(np, mmc-cap-spi)) + *caps |= MMC_CAP_SPI; Only used by the mmc_spi driver, can be hardcoded there. + if(of_property_read_bool(np, mmc-cap-needs-poll)) + *caps |= MMC_CAP_NEEDS_POLL; implied by absence of irqs property. + if(of_property_read_bool(np, mmc-cap-8-bit-data)) + *caps |= MMC_CAP_8_BIT_DATA; see bus-width property. + if(of_property_read_bool(np, mmc-cap-nonremovable)) + *caps |= MMC_CAP_NONREMOVABLE; see non-removable property. + if(of_property_read_bool(np, mmc-cap-wait-while-busy)) + *caps |= MMC_CAP_WAIT_WHILE_BUSY; This seems to be a linux device driver specific quirk that doesn't belong into a hardware description. + if(of_property_read_bool(np, mmc-cap-erase)) + *caps |= MMC_CAP_ERASE; driver specific. ... and so on. What are you actually missing in the properties that are already there? Arnd -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] MMC: fix sdhci-dove removal
On Mon, Oct 15, 2012 at 04:58:55PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote: On 11:44 Mon 15 Oct , Russell King - ARM Linux wrote: On Mon, Oct 15, 2012 at 11:37:25AM +0100, Russell King - ARM Linux wrote: On Mon, Oct 15, 2012 at 10:43:48AM +0100, Russell King - ARM Linux wrote: 1. Unregister the device _BEFORE_ taking away any resources it may be using. 2. Don't check clks against NULL. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk Looking at this driver some more, who the hell came up with the sdhci registration interface? It violates one of the most fundamental principles of kernel driver programming. You do _NOT_ publish your driver interfaces _UNTIL_ you have finished setting your device up. Otherwise, in a preemptible or SMP kernel, your driver can be used before the initialization has completed. As this driver calls sdhci_pltfm_register() before it has obtained the clock for the interface, and this function does: sdhci_pltfm_init sdhci_add_host mmc_add_host mmc_start_host mmc_power_up mmc_set_ios sdhci_set_ios See, we're trying to power up and clock the card _before_ the dove sdhci driver has even claimed the clock let alone enabled it. This is total bollocks. The sdhci platform interface is total crap for creating this broken design in the first place. This is why MMC has the init + add interfaces, they're there to allow drivers to do stuff the Right(tm) way and avoid shit like the above. This should have been picked up at review time before the driver went into mainline. In any case, it needs to be fixed. Here's an updated patch which just about fixes the sdhci-dove driver. I would not be surprised given the idiotic sdhci-pltfm API if many other drivers suffered the same bug. 8 From: Russell King rmk+ker...@arm.linux.org.uk Subject: [PATCH] MMC: fix sdhci-dove probe/removal 1. Never ever publish a device in the system before it has been setup to a usable state. 2. Unregister the device _BEFORE_ taking away any resources it may be using. 3. Don't check clks against NULL. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk --- drivers/mmc/host/sdhci-dove.c | 36 ++-- 1 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index a6e53a1..7d3a4e4 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c @@ -83,30 +83,31 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) struct sdhci_dove_priv *priv; int ret; - ret = sdhci_pltfm_register(pdev, sdhci_dove_pdata); - if (ret) - goto sdhci_dove_register_fail; - priv = devm_kzalloc(pdev-dev, sizeof(struct sdhci_dove_priv), GFP_KERNEL); if (!priv) { dev_err(pdev-dev, unable to allocate private data); - ret = -ENOMEM; - goto sdhci_dove_allocate_fail; + return -ENOMEM; } + priv-clk = clk_get(pdev-dev, NULL); you have devm_clk_get too maybe you could use it here too This isn't a cleanup patch, this is a patch just to fix some stupid bugs in this code. If someone wants to convert that afterwards, it should be an entirely separate patch. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1] mmc: fix async request mechanism for sequential read scenarios
The main assumption of the async request design is that the file system adds block requests to the block device queue asynchronously without waiting for completion (see the Rationale section of https://wiki.linaro.org/WorkingGroups/Kernel/Specs /StoragePerfMMC-async-req). We found out that in case of sequential read operations this is not the case, due to the read ahead mechanism. When mmcqt reports on completion of a request there should be a context switch to allow the insertion of the next read ahead BIOs to the block layer. Since the mmcqd tries to fetch another request immediately after the completion of the previous request it gets NULL and starts waiting for the completion of the previous request. This wait on completion gives the FS the opportunity to insert the next request but the MMC layer is already blocked on the previous request completion and is not aware of the new request waiting to be fetched. This patch fixes the above behavior and allows the async request mechanism to work in case of sequential read scenarios. The main idea is to replace the blocking wait for a completion with an event driven mechanism and add a new event of new_request. When the block layer notifies the MMC layer on a new request, we check for the above case where MMC layer is waiting on a previous request completion and the current request is NULL. In such a case the new_request event will be triggered to wakeup the waiting thread. MMC layer will then fetch the new request and after its preparation will go back to waiting on the completion. Our tests showed that this fix improves the read sequential throughput by 16%. Signed-off-by: Konstantin Dorfman kdorf...@codeaurora.org diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 172a768..4d6431b 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -112,17 +112,6 @@ struct mmc_blk_data { static DEFINE_MUTEX(open_lock); -enum mmc_blk_status { - MMC_BLK_SUCCESS = 0, - MMC_BLK_PARTIAL, - MMC_BLK_CMD_ERR, - MMC_BLK_RETRY, - MMC_BLK_ABORT, - MMC_BLK_DATA_ERR, - MMC_BLK_ECC_ERR, - MMC_BLK_NOMEDIUM, -}; - module_param(perdev_minors, int, 0444); MODULE_PARM_DESC(perdev_minors, Minors numbers to allocate per device); @@ -1224,6 +1213,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, } mqrq-mmc_active.mrq = brq-mrq; + mqrq-mmc_active.mrq-sync_data = mq-sync_data; mqrq-mmc_active.err_check = mmc_blk_err_check; mmc_queue_bounce_pre(mqrq); @@ -1284,9 +1274,12 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) areq = mq-mqrq_cur-mmc_active; } else areq = NULL; - areq = mmc_start_req(card-host, areq, (int *) status); - if (!areq) + areq = mmc_start_data_req(card-host, areq, (int *)status); + if (!areq) { + if (status == MMC_BLK_NEW_REQUEST) + return status; return 0; + } mq_rq = container_of(areq, struct mmc_queue_req, mmc_active); brq = mq_rq-brq; @@ -1295,6 +1288,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) mmc_queue_bounce_post(mq_rq); switch (status) { + case MMC_BLK_NEW_REQUEST: + BUG_ON(1); /* should never get here */ case MMC_BLK_SUCCESS: case MMC_BLK_PARTIAL: /* @@ -1367,7 +1362,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) * prepare it again and resend. */ mmc_blk_rw_rq_prep(mq_rq, card, disable_multi, mq); - mmc_start_req(card-host, mq_rq-mmc_active, NULL); + mmc_start_data_req(card-host, mq_rq-mmc_active, + (int *)status); } } while (ret); @@ -1382,7 +1378,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) start_new_req: if (rqc) { mmc_blk_rw_rq_prep(mq-mqrq_cur, card, 0, mq); - mmc_start_req(card-host, mq-mqrq_cur-mmc_active, NULL); + mmc_start_data_req(card-host, mq-mqrq_cur-mmc_active, NULL); } return 0; @@ -1426,9 +1422,10 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) } out: - if (!req) + if (!req (ret != MMC_BLK_NEW_REQUEST)) /* release host only when there are no more requests */ mmc_release_host(card-host); + return ret; } diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index e360a97..65cecf2 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -67,7 +67,8 @@
[PATCH 1/4] MMC: omap_hsmmc: claim pinctrl at probe time
From: Daniel Mack zon...@gmail.com This allows DT-driven board to set up the pin mux only when the driver is in use. Signed-off-by: Daniel Mack zon...@gmail.com Cc: Venkatraman S svenk...@ti.com Cc: Chris Ball c...@laptop.org Cc: Grant Likely grant.lik...@secretlab.ca Cc: Rob Herring rob.herr...@calxeda.com Cc: Linus Walleij linus.wall...@linaro.org Cc: linux-o...@vger.kernel.org Acked-by: Linus Walleij linus.wall...@linaro.org Signed-off-by: Venkatraman S svenk...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 54bfd0c..01eeeae 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -37,6 +37,7 @@ #include linux/io.h #include linux/gpio.h #include linux/regulator/consumer.h +#include linux/pinctrl/consumer.h #include linux/pm_runtime.h #include mach/hardware.h #include plat/mmc.h @@ -1720,6 +1721,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) const struct of_device_id *match; dma_cap_mask_t mask; unsigned tx_req, rx_req; + struct pinctrl *pinctrl; match = of_match_device(of_match_ptr(omap_mmc_of_match), pdev-dev); if (match) { @@ -1923,6 +1925,11 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) omap_hsmmc_disable_irq(host); + pinctrl = devm_pinctrl_get_select_default(pdev-dev); + if (IS_ERR(pinctrl)) + dev_warn(pdev-dev, + pins are not configured from the driver\n); + omap_hsmmc_protect_card(host); mmc_add_host(mmc); -- 1.7.11.1.25.g0e18bef -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] MMC: omap_hsmmc: add DT property for max bus frequency
From: Daniel Mack zon...@gmail.com Maximum bus frequency can be limited by external circuitry like level shifters etc. Allow passing this value from DT. Signed-off-by: Daniel Mack zon...@gmail.com Cc: Venkatraman S svenk...@ti.com Cc: Chris Ball c...@laptop.org Cc: Grant Likely grant.lik...@secretlab.ca Cc: Rob Herring rob.herr...@calxeda.com Cc: linux-o...@vger.kernel.org Signed-off-by: Venkatraman S svenk...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 01eeeae..a33ab74 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1674,7 +1674,7 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) { struct omap_mmc_platform_data *pdata; struct device_node *np = dev-of_node; - u32 bus_width; + u32 bus_width, max_freq; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -1701,6 +1701,9 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) if (of_find_property(np, ti,needs-special-reset, NULL)) pdata-slots[0].features |= HSMMC_HAS_UPDATED_RESET; + if (!of_property_read_u32(np, max-frequency, max_freq)) + pdata-max_freq = max_freq; + return pdata; } #else -- 1.7.11.1.25.g0e18bef -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] mmc: omap_hsmmc: Fix NULL pointer dereference for dt boot
From: Balaji T K balaj...@ti.com dev-platform_data is NULL in case of device tree boot, instead use the saved version in struct omap_hsmmc_host. Signed-off-by: Balaji T K balaj...@ti.com Signed-off-by: Venkatraman S svenk...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 17 +++-- 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index a3929b7..0b5e7ab 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -179,7 +179,8 @@ struct omap_hsmmc_host { static int omap_hsmmc_card_detect(struct device *dev, int slot) { - struct omap_mmc_platform_data *mmc = dev-platform_data; + struct omap_hsmmc_host *host = dev_get_drvdata(dev); + struct omap_mmc_platform_data *mmc = host-pdata; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value_cansleep(mmc-slots[0].switch_pin); @@ -187,7 +188,8 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot) static int omap_hsmmc_get_wp(struct device *dev, int slot) { - struct omap_mmc_platform_data *mmc = dev-platform_data; + struct omap_hsmmc_host *host = dev_get_drvdata(dev); + struct omap_mmc_platform_data *mmc = host-pdata; /* NOTE: assumes write protect signal is active-high */ return gpio_get_value_cansleep(mmc-slots[0].gpio_wp); @@ -195,7 +197,8 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot) static int omap_hsmmc_get_cover_state(struct device *dev, int slot) { - struct omap_mmc_platform_data *mmc = dev-platform_data; + struct omap_hsmmc_host *host = dev_get_drvdata(dev); + struct omap_mmc_platform_data *mmc = host-pdata; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value_cansleep(mmc-slots[0].switch_pin); @@ -205,7 +208,8 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot) static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) { - struct omap_mmc_platform_data *mmc = dev-platform_data; + struct omap_hsmmc_host *host = dev_get_drvdata(dev); + struct omap_mmc_platform_data *mmc = host-pdata; disable_irq(mmc-slots[0].card_detect_irq); return 0; @@ -213,7 +217,8 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) { - struct omap_mmc_platform_data *mmc = dev-platform_data; + struct omap_hsmmc_host *host = dev_get_drvdata(dev); + struct omap_mmc_platform_data *mmc = host-pdata; enable_irq(mmc-slots[0].card_detect_irq); return 0; @@ -2019,9 +2024,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) clk_put(host-dbclk); } + omap_hsmmc_gpio_free(host-pdata); iounmap(host-base); mmc_free_host(host-mmc); - omap_hsmmc_gpio_free(pdev-dev.platform_data); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) -- 1.7.11.1.25.g0e18bef -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/4] MMC: some omap_hsmmc fixes
Daniel, On Sat, Oct 13, 2012 at 2:31 PM, Daniel Mack zon...@gmail.com wrote: On 12.10.2012 12:58, Daniel Mack wrote: Here are some assorted patches for the omap_hsmmc driver that I need on top Linus' current development branch to make it work on a AM33xx board. 1/4 and 2/4 qualify as bug fixes and I'm puzzled that these didn't hit anyone else yet. Daniel Mack (4): MMC: omap_hsmmc: set platform data after probe from DT node MMC: omap_hsmmc: fix DMA config block MMC: omap_hsmmc: claim pinctrl at probe time MMC: omap_hsmmc: add DT property for max bus frequency Ok, so 1/4 and 2/4 will be solved differently upstream, so they can be dropped. The other two remain, and 3/4 got an Acked-by Linus W. Thanks. I've just clubbed your two patches with Balaji's fixes and sent to Chris. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mmc: core: Support all MMC capabilities when booting from Device Tree
On Monday 15 October 2012, Lee Jones wrote: Capabilities are an important part of the MMC subsystem. Much supported functionality would be lost if we didn't provide the same level of support when booting Device Tree as we currently do when the subsystem is passed capabilities via platform data. This patch supplies this support with one simple call to a DT parsing function. We already document all the commonly used properties in Documentation/devicetree/bindings/mmc/mmc.txt snip and so on. What are you actually missing in the properties that are already there? MMC_CAP_ERASE MMC_CAP_UHS_SDR12 MMC_CAP_UHS_SDR25 MMC_CAP_UHS_DDR50 MMC_CAP_1_8V_DDR MMC_CAP2_DETECT_ON_ERR MMC_CAP2_NO_SLEEP_CMD -- Lee Jones Linaro ST-Ericsson Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/2] MMC: SD/MMC Host Controller for Wondermedia WM8505/WM8650
On Mon, 2012-10-15 at 21:32 +0900, Girish K S wrote: On 15 October 2012 17:24, Tony Prisk li...@prisktech.co.nz wrote: This patch adds support for the SD/MMC host controller found on Wondermedia 8xxx series SoCs, currently supported under arm/arch-vt8500. Signed-off-by: Tony Prisk li...@prisktech.co.nz --- drivers/mmc/host/Kconfig | 12 + drivers/mmc/host/Makefile|1 + drivers/mmc/host/wmt-sdmmc.c | 983 ++ 3 files changed, 996 insertions(+) create mode 100644 drivers/mmc/host/wmt-sdmmc.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 9bf10e7..7f4377b 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -621,3 +621,15 @@ config MMC_USHC Note: These controllers only support SDIO cards and do not support MMC or SD memory cards. + +config MMC_WMT + tristate Wondermedia SD/MMC Host Controller support + depends on ARCH_VT8500 + default y + help + This selects support for the SD/MMC Host Controller on + Wondermedia WM8505/WM8650 based SoCs. + + To compile this driver as a module, choose M here: the + module will be called wmt-sdmmc. + diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 17ad0a7..9c91f1f 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_MMC_SH_MMCIF)+= sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o obj-$(CONFIG_MMC_VUB300) += vub300.o obj-$(CONFIG_MMC_USHC) += ushc.o +obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_CNS3XXX)+= sdhci-cns3xxx.o diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c new file mode 100644 index 000..def1ec9 --- /dev/null +++ b/drivers/mmc/host/wmt-sdmmc.c @@ -0,0 +1,983 @@ +/* + * WM8505/WM8650 SD/MMC Host Controller + * + * Copyright (C) 2010 Tony Prisk + * Copyright (C) 2008 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation + */ + +#include linux/init.h +#include linux/module.h +#include linux/platform_device.h +#include linux/ioport.h +#include linux/errno.h +#include linux/dma-mapping.h +#include linux/delay.h +#include linux/io.h +#include linux/irq.h +#include linux/clk.h +#include linux/gpio.h + +#include linux/of.h +#include linux/of_address.h +#include linux/of_irq.h + +#include linux/mmc/host.h +#include linux/mmc/mmc.h +#include linux/mmc/sd.h + +#include asm/byteorder.h + + +#define DRIVER_NAME wmt-sdhc + + +/* MMC/SD controller registers */ +#define SDMMC_CTLR 0x00 +#define SDMMC_CMD 0x01 +#define SDMMC_RSPTYPE 0x02 +#define SDMMC_ARG 0x04 +#define SDMMC_BUSMODE 0x08 +#define SDMMC_BLKLEN 0x0C +#define SDMMC_BLKCNT 0x0E +#define SDMMC_RSP 0x10 +#define SDMMC_CBCR 0x20 +#define SDMMC_INTMASK0 0x24 +#define SDMMC_INTMASK1 0x25 +#define SDMMC_STS0 0x28 +#define SDMMC_STS1 0x29 +#define SDMMC_STS2 0x2A +#define SDMMC_STS3 0x2B +#define SDMMC_RSPTIMEOUT 0x2C +#define SDMMC_CLK 0x30/* VT8500 only */ +#define SDMMC_EXTCTRL 0x34 +#define SDMMC_SBLKLEN 0x38 +#define SDMMC_DMATIMEOUT 0x3C + + +/* SDMMC_CTLR bit fields */ +#define CTLR_CMD_START 0x01 +#define CTLR_CMD_WRITE 0x04 +#define CTLR_FIFO_RESET0x08 + +/* SDMMC_BUSMODE bit fields */ +#define BM_SPI_MODE0x01 +#define BM_FOURBIT_MODE0x02 +#define BM_EIGHTBIT_MODE 0x04 +#define BM_SD_OFF 0x10 +#define BM_SPI_CS 0x20 +#define BM_SD_POWER0x40 +#define BM_SOFT_RESET 0x80 +#define BM_ONEBIT_MASK 0xFD + +/* SDMMC_BLKLEN bit fields */ +#define BLKL_CRCERR_ABORT 0x0800 +#define BLKL_CD_POL_HIGH 0x1000 +#define BLKL_GPI_CD0x2000 +#define BLKL_DATA3_CD 0x4000 +#define BLKL_INT_ENABLE0x8000 + +/* SDMMC_INTMASK0 bit fields */ +#define INT0_MBLK_TRAN_DONE_INT_EN 0x10 +#define INT0_BLK_TRAN_DONE_INT_EN 0x20 +#define
Re: [PATCH] MMC: fix sdhci-dove removal
On 11:44 Mon 15 Oct , Russell King - ARM Linux wrote: On Mon, Oct 15, 2012 at 11:37:25AM +0100, Russell King - ARM Linux wrote: On Mon, Oct 15, 2012 at 10:43:48AM +0100, Russell King - ARM Linux wrote: 1. Unregister the device _BEFORE_ taking away any resources it may be using. 2. Don't check clks against NULL. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk Looking at this driver some more, who the hell came up with the sdhci registration interface? It violates one of the most fundamental principles of kernel driver programming. You do _NOT_ publish your driver interfaces _UNTIL_ you have finished setting your device up. Otherwise, in a preemptible or SMP kernel, your driver can be used before the initialization has completed. As this driver calls sdhci_pltfm_register() before it has obtained the clock for the interface, and this function does: sdhci_pltfm_init sdhci_add_host mmc_add_host mmc_start_host mmc_power_up mmc_set_ios sdhci_set_ios See, we're trying to power up and clock the card _before_ the dove sdhci driver has even claimed the clock let alone enabled it. This is total bollocks. The sdhci platform interface is total crap for creating this broken design in the first place. This is why MMC has the init + add interfaces, they're there to allow drivers to do stuff the Right(tm) way and avoid shit like the above. This should have been picked up at review time before the driver went into mainline. In any case, it needs to be fixed. Here's an updated patch which just about fixes the sdhci-dove driver. I would not be surprised given the idiotic sdhci-pltfm API if many other drivers suffered the same bug. 8 From: Russell King rmk+ker...@arm.linux.org.uk Subject: [PATCH] MMC: fix sdhci-dove probe/removal 1. Never ever publish a device in the system before it has been setup to a usable state. 2. Unregister the device _BEFORE_ taking away any resources it may be using. 3. Don't check clks against NULL. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk --- drivers/mmc/host/sdhci-dove.c | 36 ++-- 1 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index a6e53a1..7d3a4e4 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c @@ -83,30 +83,31 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) struct sdhci_dove_priv *priv; int ret; - ret = sdhci_pltfm_register(pdev, sdhci_dove_pdata); - if (ret) - goto sdhci_dove_register_fail; - priv = devm_kzalloc(pdev-dev, sizeof(struct sdhci_dove_priv), GFP_KERNEL); if (!priv) { dev_err(pdev-dev, unable to allocate private data); - ret = -ENOMEM; - goto sdhci_dove_allocate_fail; + return -ENOMEM; } + priv-clk = clk_get(pdev-dev, NULL); you have devm_clk_get too maybe you could use it here too Best Regards, J. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] ARM: OMAP: Trivial driver changes to remove include plat/cpu.h
* Tony Lindgren t...@atomide.com [121009 17:21]: * Péter Ujfalusi peter.ujfal...@ti.com [121009 02:03]: On 10/08/2012 07:35 PM, Tony Lindgren wrote: - omap-dma.c and omap-pcm.c can test the arch locally as omap1 and omap2 cannot be compiled together because of conflicting compiler flags sound/soc/omap/omap-pcm.c |9 +++-- Tony: is this going to be included in 3.7? Hmm I guess we could try to get this out of the way to cut down the dependencies. Let's if maintainers of the other affected drivers this is OK for the -rc series. It seems that nobody needs these until for v3.8, so I'll be applying this into omap-for-v3.8/cleanup-headers-prepare branch soon. Anybody else care to ack? Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html