[RFC PATCH 1/2] MMC: DTS: Add binding for Wondermedia WM8505 SDHC

2012-10-15 Thread Tony Prisk
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

2012-10-15 Thread Tony Prisk
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

2012-10-15 Thread Tony Prisk
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

2012-10-15 Thread Russell King - ARM Linux
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

2012-10-15 Thread Russell King - ARM Linux
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

2012-10-15 Thread Russell King - ARM Linux
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

2012-10-15 Thread Johan Rudholm
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

2012-10-15 Thread Girish K S
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

2012-10-15 Thread Lee Jones
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

2012-10-15 Thread Lee Jones
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

2012-10-15 Thread Arnd Bergmann
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

2012-10-15 Thread Russell King - ARM Linux
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

2012-10-15 Thread Konstantin Dorfman
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

2012-10-15 Thread Venkatraman S
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

2012-10-15 Thread Venkatraman S
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

2012-10-15 Thread Venkatraman S
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

2012-10-15 Thread Venkatraman S
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

2012-10-15 Thread Lee Jones
 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

2012-10-15 Thread Tony Prisk
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

2012-10-15 Thread Jean-Christophe PLAGNIOL-VILLARD
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

2012-10-15 Thread Tony Lindgren
* 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