[PATCH v5] mmc: documentation of mmc non-blocking request usage and design.

2011-07-06 Thread Per Forlin
Documentation about the background and the design of mmc non-blocking.
Host driver guidelines to minimize request preparation overhead.

Signed-off-by: Per Forlin per.for...@linaro.org
Acked-by: Randy Dunlap rdun...@xenotime.net
---
ChangeLog:
 v2: - Minor updates after proofreading comments from Chris
 v3: - Minor updates after more comments from Chris
 v4: - Minor updates after comments from Randy
 v5: - Fixed one more comment and Acked-by from Randy

 Documentation/mmc/00-INDEX  |2 +
 Documentation/mmc/mmc-async-req.txt |   86 +++
 2 files changed, 88 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/mmc/mmc-async-req.txt

diff --git a/Documentation/mmc/00-INDEX b/Documentation/mmc/00-INDEX
index 93dd7a7..a9ba672 100644
--- a/Documentation/mmc/00-INDEX
+++ b/Documentation/mmc/00-INDEX
@@ -4,3 +4,5 @@ mmc-dev-attrs.txt
 - info on SD and MMC device attributes
 mmc-dev-parts.txt
 - info on SD and MMC device partitions
+mmc-async-req.txt
+- info on mmc asynchronous requests
diff --git a/Documentation/mmc/mmc-async-req.txt 
b/Documentation/mmc/mmc-async-req.txt
new file mode 100644
index 000..b7a52ea
--- /dev/null
+++ b/Documentation/mmc/mmc-async-req.txt
@@ -0,0 +1,86 @@
+Rationale
+=
+
+How significant is the cache maintenance overhead?
+It depends. Fast eMMC and multiple cache levels with speculative cache
+pre-fetch makes the cache overhead relatively significant. If the DMA
+preparations for the next request are done in parallel with the current
+transfer, the DMA preparation overhead would not affect the MMC performance.
+The intention of non-blocking (asynchronous) MMC requests is to minimize the
+time between when an MMC request ends and another MMC request begins.
+Using mmc_wait_for_req(), the MMC controller is idle while dma_map_sg and
+dma_unmap_sg are processing. Using non-blocking MMC requests makes it
+possible to prepare the caches for next job in parallel with an active
+MMC request.
+
+MMC block driver
+
+
+The issue_rw_rq() in the MMC block driver is made non-blocking.
+The increase in throughput is proportional to the time it takes to
+prepare (major part of preparations are dma_map_sg and dma_unmap_sg)
+a request and how fast the memory is. The faster the MMC/SD is
+the more significant the prepare request time becomes. Roughly the expected
+performance gain is 5% for large writes and 10% on large reads on a L2 cache
+platform. In power save mode, when clocks run on a lower frequency, the DMA
+preparation may cost even more. As long as these slower preparations are run
+in parallel with the transfer performance won't be affected.
+
+Details on measurements from IOZone and mmc_test
+
+
+https://wiki.linaro.org/WorkingGroups/Kernel/Specs/StoragePerfMMC-async-req
+
+MMC core API extension
+==
+
+There is one new public function mmc_start_req().
+It starts a new MMC command request for a host. The function isn't
+truly non-blocking. If there is on ongoing async request it waits
+for completion of that request and starts the new one and returns. It
+doesn't wait for the new request to complete. If there is no ongoing
+request it starts the new request and returns immediately.
+
+MMC host extensions
+===
+
+There are two optional hooks -- pre_req() and post_req() -- that the host
+driver may implement in order to move work to before and after the actual
+mmc_request function is called. In the DMA case pre_req() may do
+dma_map_sg() and prepare the DMA descriptor, and post_req runs
+the dma_unmap_sg.
+
+Optimize for the first request
+==
+
+The first request in a series of requests can't be prepared in parallel with
+the previous transfer, since there is no previous request.
+The argument is_first_req in pre_req() indicates that there is no previous
+request. The host driver may optimize for this scenario to minimize
+the performance loss. A way to optimize for this is to split the current
+request in two chunks, prepare the first chunk and start the request,
+and finally prepare the second chunk and start the transfer.
+
+Pseudocode to handle is_first_req scenario with minimal prepare overhead:
+if (is_first_req  req-size  threshold)
+   /* start MMC transfer for the complete transfer size */
+   mmc_start_command(MMC_CMD_TRANSFER_FULL_SIZE);
+
+   /*
+* Begin to prepare DMA while cmd is being processed by MMC.
+* The first chunk of the request should take the same time
+* to prepare as the MMC process command time.
+* If prepare time exceeds MMC cmd time
+* the transfer is delayed, guesstimate max 4k as first chunk size.
+*/
+prepare_1st_chunk_for_dma(req);
+/* flush pending desc to the DMAC (dmaengine.h) */
+dma_issue_pending(req-dma_desc);
+
+prepare_2nd_chunk_for_dma(req);
+/*
+ * The second issue_pending should be called 

Re: [PATCH v3] arm: mach-mmp: brownstone.c support multiple sd slots

2011-07-06 Thread zhangfei gao
On Wed, Jul 6, 2011 at 4:20 AM, Philip Rakity prak...@marvell.com wrote:
 Subject: [PATCH V3] arm: mach-mmp: brownstone.c support multiple sd slots

 V3
 ==
 Change since V2 -- delete mmc3 since it was committed
 to linux next.

 enable mmc1 used for wifi (8688) and marked PERMANENT.
 Wifi requires enabling of power on the device by
 toggling the gpio lines for power and reset.  Enable eMMC first to work
 around problem in booting order due to workqueue bug.

 Signed-off-by: Philip Rakity prak...@marvell.com
 ---
  arch/arm/mach-mmp/brownstone.c |   41 
 +++-
  1 files changed, 40 insertions(+), 1 deletions(-)

 diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
 index c79162a..940982c 100644
 --- a/arch/arm/mach-mmp/brownstone.c
 +++ b/arch/arm/mach-mmp/brownstone.c
 @@ -19,6 +19,7 @@
  #include linux/regulator/max8649.h
  #include linux/regulator/fixed.h
  #include linux/mfd/max8925.h
 +#include linux/delay.h

  #include asm/mach-types.h
  #include asm/mach/arch.h
 @@ -180,6 +181,11 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 
 = {
        .clk_delay_cycles = 0x1f,
  };

 +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = {
 +       .clk_delay_cycles = 0x1f,
 +       .flags          = PXA_FLAG_CARD_PERMANENT,
 +};
 +
  static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
        .clk_delay_cycles = 0x1f,
        .flags = PXA_FLAG_CARD_PERMANENT
 @@ -187,6 +193,38 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 
 = {
  };


 +static void __init mmc_sdio_wifi(void)
 +{
 +       int poweron;
 +       int reset;
 +
 +       poweron = mfp_to_gpio(GPIO57_GPIO);
 +       reset = mfp_to_gpio(GPIO58_GPIO);
 +
 +       if (gpio_request(reset, sd8xxx reset)) {
 +               printk(KERN_INFO gpio %d request failed\n, reset);
 +               return;
 +       }
 +
 +       if (gpio_request(poweron, sd8xxx PDn)) {
 +               gpio_free(reset);
 +               printk(KERN_INFO gpio %d request failed\n, poweron);
 +               return;
 +       }
 +
 +       gpio_direction_output(poweron, 0);
 +       msleep(1);
 +       gpio_direction_output(poweron, 1);
 +       msleep(1);
 +       gpio_direction_output(reset, 0);
 +       msleep(1);
 +       gpio_direction_output(reset, 1);
 +       gpio_free(reset);
 +       gpio_free(poweron);
 +
 +       mmp2_add_sdhost(1, mmp2_sdh_platdata_mmc1); /* Wifi */
 +}
 +

The method keeps power on wifi chip, without dynamically
enable/disable wifi power, which is not final solution.
How about pushing later with dynamically control power, which is in
debugging here.

  static void __init brownstone_init(void)
  {
        mfp_config(ARRAY_AND_SIZE(brownstone_pin_config));
 @@ -195,8 +233,9 @@ static void __init brownstone_init(void)
        mmp2_add_uart(1);
        mmp2_add_uart(3);
        mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
 -       mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */
        mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */
 +       mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */
 +       mmc_sdio_wifi();

        /* enable 5v regulator */
        platform_device_register(brownstone_v_5vp_device);
 --
 1.7.0.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


[PATCH V4] MMC: PM: add suspend/resume in atmel-mci

2011-07-06 Thread Nicolas Ferre
Take care of slots while going to suspend state.

Signed-off-by: Nicolas Ferre nicolas.fe...@atmel.com
---
V4: make CONFIG_PM logic work even if not selected
V3: take care of each slot SUSPENDED state
(adding a status bit in the slot flags)
V2: move to pm_ops


 drivers/mmc/host/atmel-mci.c |   63 ++
 1 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index aa8039f..fa8cae1 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -203,6 +203,7 @@ struct atmel_mci_slot {
 #define ATMCI_CARD_PRESENT 0
 #define ATMCI_CARD_NEED_INIT   1
 #define ATMCI_SHUTDOWN 2
+#define ATMCI_SUSPENDED3
 
int detect_pin;
int wp_pin;
@@ -1878,10 +1879,72 @@ static int __exit atmci_remove(struct platform_device 
*pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
+static int atmci_suspend(struct device *dev)
+{
+   struct atmel_mci *host = dev_get_drvdata(dev);
+   int i;
+
+for (i = 0; i  ATMEL_MCI_MAX_NR_SLOTS; i++) {
+   struct atmel_mci_slot *slot = host-slot[i];
+   int ret;
+
+   if (!slot)
+   continue;
+   ret = mmc_suspend_host(slot-mmc);
+   if (ret  0) {
+   while (--i = 0) {
+   slot = host-slot[i];
+   if (slot
+test_bit(ATMCI_SUSPENDED, slot-flags)) {
+   mmc_resume_host(host-slot[i]-mmc);
+   clear_bit(ATMCI_SUSPENDED, 
slot-flags);
+   }
+   }
+   return ret;
+   } else {
+   set_bit(ATMCI_SUSPENDED, slot-flags);
+   }
+   }
+
+   return 0;
+}
+
+static int atmci_resume(struct device *dev)
+{
+   struct atmel_mci *host = dev_get_drvdata(dev);
+   int i;
+   int ret = 0;
+
+   for (i = 0; i  ATMEL_MCI_MAX_NR_SLOTS; i++) {
+   struct atmel_mci_slot *slot = host-slot[i];
+   int err;
+
+   slot = host-slot[i];
+   if (!slot)
+   continue;
+   if (!test_bit(ATMCI_SUSPENDED, slot-flags))
+   continue;
+   err = mmc_resume_host(slot-mmc);
+   if (err  0)
+   ret = err;
+   else
+   clear_bit(ATMCI_SUSPENDED, slot-flags);
+   }
+
+   return ret;
+}
+static SIMPLE_DEV_PM_OPS(atmci_pm, atmci_suspend, atmci_resume);
+#define ATMCI_PM_OPS   (atmci_pm)
+#else
+#define ATMCI_PM_OPS   NULL
+#endif
+
 static struct platform_driver atmci_driver = {
.remove = __exit_p(atmci_remove),
.driver = {
.name   = atmel_mci,
+   .pm = ATMCI_PM_OPS,
},
 };
 
-- 
1.7.3

--
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 V4] MMC: PM: add suspend/resume in atmel-mci

2011-07-06 Thread Felipe Balbi
Hi,

On Wed, Jul 06, 2011 at 11:31:36AM +0200, Nicolas Ferre wrote:
 Take care of slots while going to suspend state.
 
 Signed-off-by: Nicolas Ferre nicolas.fe...@atmel.com

FWIW:

Reviewed-by: Felipe Balbi ba...@ti.com

 @@ -1878,10 +1879,72 @@ static int __exit atmci_remove(struct platform_device 
 *pdev)
   return 0;
  }
  
 +#ifdef CONFIG_PM
 +static int atmci_suspend(struct device *dev)
 +{
 + struct atmel_mci *host = dev_get_drvdata(dev);
 + int i;
 +
 +  for (i = 0; i  ATMEL_MCI_MAX_NR_SLOTS; i++) {
 + struct atmel_mci_slot *slot = host-slot[i];
 + int ret;
 +
 + if (!slot)
 + continue;
 + ret = mmc_suspend_host(slot-mmc);
 + if (ret  0) {
 + while (--i = 0) {
 + slot = host-slot[i];
 + if (slot
 +  test_bit(ATMCI_SUSPENDED, slot-flags)) {
 + mmc_resume_host(host-slot[i]-mmc);
 + clear_bit(ATMCI_SUSPENDED, 
 slot-flags);
 + }
 + }
 + return ret;
 + } else {
 + set_bit(ATMCI_SUSPENDED, slot-flags);
 + }

just one small nitpicking which you can ignore if you like, but you
don't really need the else branch here. If you fall into if (ret  0)
you will return early anyway, so you can save two lines and an
indentation level :-p

-- 
balbi


signature.asc
Description: Digital signature


[PATCH] ARM i.MX dma: Fix burstsize settings

2011-07-06 Thread Sascha Hauer
dmaengine expects the maxburst parameter in words, not bytes.
The imxdma driver and its users do this wrong. Fix this.

As a side note the imx-pcm-dma-mx2 driver was 'fixed' to work
with imx-dma. This broke the driver with imx-sdma support which
correctly takes the maxburst parameter in words. This patch
puts the sdma based sound back to work.

Signed-off-by: Sascha Hauer s.ha...@pengutronix.de
---

I made this as a cross subsystem patch to maintain bisectability. I
suggest to push it either via my tree or the dmaengine tree.

 drivers/dma/imx-dma.c   |3 ++-
 drivers/mmc/host/mxcmmc.c   |8 
 sound/soc/imx/imx-pcm-dma-mx2.c |4 ++--
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index e18eaab..d99f71c 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -135,7 +135,8 @@ static int imxdma_control(struct dma_chan *chan, enum 
dma_ctrl_cmd cmd,
if (ret)
return ret;
 
-   imx_dma_config_burstlen(imxdmac-imxdma_channel, 
imxdmac-watermark_level);
+   imx_dma_config_burstlen(imxdmac-imxdma_channel,
+   imxdmac-watermark_level * imxdmac-word_size);
 
return 0;
default:
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index cc20e02..14aa213 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -715,13 +715,13 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
int burstlen, ret;
 
/*
-* use burstlen of 64 in 4 bit mode (-- reg value  0)
-* use burstlen of 16 in 1 bit mode (-- reg value 16)
+* use burstlen of 64 (16 words) in 4 bit mode (-- reg value  0)
+* use burstlen of 16 (4 words) in 1 bit mode (-- reg value 16)
 */
if (ios-bus_width == MMC_BUS_WIDTH_4)
-   burstlen = 64;
-   else
burstlen = 16;
+   else
+   burstlen = 4;
 
if (mxcmci_use_dma(host)  burstlen != host-burstlen) {
host-burstlen = burstlen;
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 4173b3d..43fdc24f 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -110,12 +110,12 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream 
*substream,
slave_config.direction = DMA_TO_DEVICE;
slave_config.dst_addr = dma_params-dma_addr;
slave_config.dst_addr_width = buswidth;
-   slave_config.dst_maxburst = dma_params-burstsize * buswidth;
+   slave_config.dst_maxburst = dma_params-burstsize;
} else {
slave_config.direction = DMA_FROM_DEVICE;
slave_config.src_addr = dma_params-dma_addr;
slave_config.src_addr_width = buswidth;
-   slave_config.src_maxburst = dma_params-burstsize * buswidth;
+   slave_config.src_maxburst = dma_params-burstsize;
}
 
ret = dmaengine_slave_config(iprtd-dma_chan, slave_config);
-- 
1.7.5.3

-- 
Pengutronix e.K.   | |
Industrial Linux Solutions | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
--
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] mxs-mmc: fix clock rate setting

2011-07-06 Thread Wolfram Sang
  About the patch itself: I didn't verify the formulas, but it does solve one
  special problem here. Thanks a lot! So:
 
 Does it solve any other special problem except for the wrong clock rate 
 setting?

Nope, but that it does :)

-- 
Pengutronix e.K.   | Wolfram Sang|
Industrial Linux Solutions | http://www.pengutronix.de/  |


signature.asc
Description: Digital signature


[PATCH v2 0/4] mmc: dw_mmc: mmc_test related fixes

2011-07-06 Thread James Hogan
No changes since v1 except acked-by and tested-by

More improvements and fixes for the Synopsys DesignWare MCI driver so
that it passes the mmc_test suite:

[PATCH 1/4] mmc: dw_mmc: fix stop when fallen back to PIO
Fixes a hang after an error/timeout in PIO mode.
[PATCH 2/4] mmc: dw_mmc: remove unnecessary error messages
Removes some dev_err's since an errno is sufficient.
[PATCH 3/4] mmc: dw_mmc: handle no CRC status error
Fixes Correct xfer_size at write tests.
[PATCH 4/4] mmc: dw_mmc: reset FIFO after an error
Fixes modified Correct xfer_size at write tests (3 blocks
instead of 2).

 drivers/mmc/host/dw_mmc.c  |   41 +++--
 include/linux/mmc/dw_mmc.h |2 ++
 2 files changed, 33 insertions(+), 10 deletions(-)

--
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 v2 1/4] mmc: dw_mmc: fix stop when fallen back to PIO

2011-07-06 Thread James Hogan
There are several situations when dw_mci_submit_data_dma() decides to
fall back to PIO mode instead of using DMA, due to a short (to avoid
overhead) or complex (e.g. with unaligned buffers) transaction, even
though host-use_dma is set. However dw_mci_stop_dma() decides whether
to stop DMA or set the EVENT_XFER_COMPLETE event based on host-use_dma.
When falling back to PIO mode this results in data timeout errors
getting missed and the driver locking up.

Therefore add host-using_dma to indicate whether the current
transaction is using dma or not, and adjust dw_mci_stop_dma() to use
that instead.

Signed-off-by: James Hogan james.ho...@imgtec.com
Acked-by: Will Newton will.new...@imgtec.com
Tested-by: Jaehoon Chung jh80.ch...@samsung.com
---
 drivers/mmc/host/dw_mmc.c  |6 +-
 include/linux/mmc/dw_mmc.h |2 ++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 10b6979..fcff3c0 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -287,7 +287,7 @@ static void send_stop_cmd(struct dw_mci *host, struct 
mmc_data *data)
 /* DMA interface functions */
 static void dw_mci_stop_dma(struct dw_mci *host)
 {
-   if (host-use_dma) {
+   if (host-using_dma) {
host-dma_ops-stop(host);
host-dma_ops-cleanup(host);
} else {
@@ -435,6 +435,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, 
struct mmc_data *data)
unsigned int i, direction, sg_len;
u32 temp;
 
+   host-using_dma = 0;
+
/* If we don't have a channel, we can't do DMA */
if (!host-use_dma)
return -ENODEV;
@@ -454,6 +456,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, 
struct mmc_data *data)
return -EINVAL;
}
 
+   host-using_dma = 1;
+
if (data-flags  MMC_DATA_READ)
direction = DMA_FROM_DEVICE;
else
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index f3f68ee..6b46819 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -48,6 +48,7 @@ struct mmc_data;
  * @data: The data currently being transferred, or NULL if no data
  * transfer is in progress.
  * @use_dma: Whether DMA channel is initialized or not.
+ * @using_dma: Whether DMA is in use for the current transfer.
  * @sg_dma: Bus address of DMA buffer.
  * @sg_cpu: Virtual address of DMA buffer.
  * @dma_ops: Pointer to platform-specific DMA callbacks.
@@ -121,6 +122,7 @@ struct dw_mci {
 
/* DMA interface members*/
int use_dma;
+   int using_dma;
 
dma_addr_t  sg_dma;
void*sg_cpu;
-- 
1.7.2.3


--
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: dw_mmc: remove unnecessary error messages

2011-07-06 Thread James Hogan
Remove error messages for timeout and CRC failure, since the error code
already indicates the problem.

Signed-off-by: James Hogan james.ho...@imgtec.com
Acked-by: Will Newton will.new...@imgtec.com
Tested-by: Jaehoon Chung jh80.ch...@samsung.com
---
 drivers/mmc/host/dw_mmc.c |4 
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index fcff3c0..bf2157a 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -908,12 +908,8 @@ static void dw_mci_tasklet_func(unsigned long priv)
 
if (status  DW_MCI_DATA_ERROR_FLAGS) {
if (status  SDMMC_INT_DTO) {
-   dev_err(host-pdev-dev,
-   data timeout error\n);
data-error = -ETIMEDOUT;
} else if (status  SDMMC_INT_DCRC) {
-   dev_err(host-pdev-dev,
-   data CRC error\n);
data-error = -EILSEQ;
} else {
dev_err(host-pdev-dev,
-- 
1.7.2.3

--
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] mxs-mmc: fix clock rate setting

2011-07-06 Thread Wolfram Sang
On Mon, Jul 04, 2011 at 12:59:29PM +0200, Koen Beel wrote:
 On Mon, Jul 4, 2011 at 12:34 PM, Wolfram Sang w.s...@pengutronix.de wrote:
 
 Well, maybe not. My colleague complained and I think he is right 
 that we are
 mapping div2 from the range 0 to 256 (inclusive!) to an 8-bit range. 
 This must
 be wrong for one value per se.

If you look at the context of the patch, you will find it's 'div2 - 1'
than 'div2' gets written into register.
  
   Exactly. The '- 1' is why Koen changed the upper limit from  256 to = 
   256.
   The lower limit fix is currently 'if (div2 == 0) div2 == 1', which is a 
   2:1
   mapping. Not good, or?
  
  So you are saying the patch is a right fix but not the most optimal
  one?  In that case, it does not concern me.  I acked it as an valid
  fix.
 
  The patches fixes a few things, but for div2, it is curing the symptoms,
  not the cause, I think. If you look at the formula in the datasheet:
 
  rate = ssp / (clock_divide * (1 + clock_rate));
 
  In the code, the calculation of div2 is equal to '1 + clock_rate' (the 1
  gets subtracted when the value is written to the register which is a bit
  unfortunate; doing it earlier would reduce confusion IMO). So that can
  never be 0, it is a divisor. We should really use DIV_ROUND_UP here.
  Even when not dealing with 0, this seems needed. Assume:
 
  ssp = 5760, wanted_rate = 2500, div1 = 2
 
  will give
 
  div2 = int(1.152) = 1 (meaning 0 + 1, because div2 - 1 will be written)
 
  The rate will thus be:
 
  actual_rate = 5760 / 2 * (0 + 1)
             = 2880
 
  - too fast!
 
  Or did I get something wrong?
 
  Regards,
 
    Wolfram
 
 Well, right now the clock freq. is set to the minimum clock value
 reaching the requested rate. 

Sorry, it gets a bit confusing: what do you mean with right now?

 In current implementation, the rate will
 be higher in lot's of cases (all cases where the requested clock freq.
 cannot exactly be made).

Yes.

 But the thing is, the driver now enters dev_err, and returns without
 changing anything when the clock cannot be made as low as requested.
 In that case you will almost certainly end up with a clock being even
 higher then the lowest possible. So that not good I think.
 I might be better to set the clock as low as possible not matter what
 you to after that.

Yes, might be a bit academic (who would want 4kHz ;)), but still
correct. Shawn, do you agree?

 About the rounding. I don't think rounding is good. I think it would

We do rounding already (int conversion). Just in the wrong direction.

 be better to choose between having at least the requested rate (as it
 is now; will result is somewhat higher clock then requested in many
 cases)

You want a rate faster than what the card could do?

, or having at maximum the requested clock rate. Both have there
 problems.

If I understood you correctly, this is my DIV_ROUND_UP suggestion. Which
problems does it have?

Regards,

   Wolfram


signature.asc
Description: Digital signature


[PATCH v2 3/4] mmc: dw_mmc: handle no CRC status error

2011-07-06 Thread James Hogan
When a data write isn't acknowledged by the card (so no CRC status token
is detected after the data), the error -EIO is returned instead of the
-ETIMEDOUT expected by mmc_test 15 - Correct xfer_size at write (start
failure) and 17 Correct xfer_size at write (midway failure). In PIO
mode the reported number of bytes transferred is also exaggerated since
the last block actually failed.

Handle the Write no CRC error specially, setting the error to
-ETIMEDOUT and setting the bytes_xferred to 0.

Signed-off-by: James Hogan james.ho...@imgtec.com
Acked-by: Will Newton will.new...@imgtec.com
Tested-by: Jaehoon Chung jh80.ch...@samsung.com
---
 drivers/mmc/host/dw_mmc.c |   19 +++
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index bf2157a..0dac397 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -496,15 +496,16 @@ static void dw_mci_submit_data(struct dw_mci *host, 
struct mmc_data *data)
host-sg = NULL;
host-data = data;
 
+   if (data-flags  MMC_DATA_READ)
+   host-dir_status = DW_MCI_RECV_STATUS;
+   else
+   host-dir_status = DW_MCI_SEND_STATUS;
+
if (dw_mci_submit_data_dma(host, data)) {
host-sg = data-sg;
host-pio_offset = 0;
host-part_buf_start = 0;
host-part_buf_count = 0;
-   if (data-flags  MMC_DATA_READ)
-   host-dir_status = DW_MCI_RECV_STATUS;
-   else
-   host-dir_status = DW_MCI_SEND_STATUS;
 
mci_writel(host, RINTSTS, SDMMC_INT_TXDR | SDMMC_INT_RXDR);
temp = mci_readl(host, INTMASK);
@@ -911,6 +912,16 @@ static void dw_mci_tasklet_func(unsigned long priv)
data-error = -ETIMEDOUT;
} else if (status  SDMMC_INT_DCRC) {
data-error = -EILSEQ;
+   } else if (status  SDMMC_INT_EBE 
+  host-dir_status ==
+   DW_MCI_SEND_STATUS) {
+   /*
+* No data CRC status was returned.
+* The number of bytes transferred will
+* be exaggerated in PIO mode.
+*/
+   data-bytes_xfered = 0;
+   data-error = -ETIMEDOUT;
} else {
dev_err(host-pdev-dev,
data FIFO error 
-- 
1.7.2.3

--
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 v2 4/4] mmc: dw_mmc: reset FIFO after an error

2011-07-06 Thread James Hogan
If an error occurs mid way through a transaction (such as a missing CRC
status response after the 2nd block written out of 3), then the FIFO may
still contain data which will interfere with the next transaction.
Therefore after an error has been detected, reset the fifo using the
CTRL register.

Signed-off-by: James Hogan james.ho...@imgtec.com
Acked-by: Will Newton will.new...@imgtec.com
Tested-by: Jaehoon Chung jh80.ch...@samsung.com
---
 drivers/mmc/host/dw_mmc.c |   12 +++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0dac397..0c839d3 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -849,7 +849,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
struct mmc_command *cmd;
enum dw_mci_state state;
enum dw_mci_state prev_state;
-   u32 status;
+   u32 status, ctrl;
 
spin_lock(host-lock);
 
@@ -929,6 +929,16 @@ static void dw_mci_tasklet_func(unsigned long priv)
status);
data-error = -EIO;
}
+   /*
+* After an error, there may be data lingering
+* in the FIFO, so reset it - doing so
+* generates a block interrupt, hence setting
+* the scatter-gather pointer to NULL.
+*/
+   host-sg = NULL;
+   ctrl = mci_readl(host, CTRL);
+   ctrl |= SDMMC_CTRL_FIFO_RESET;
+   mci_writel(host, CTRL, ctrl);
} else {
data-bytes_xfered = data-blocks * data-blksz;
data-error = 0;
-- 
1.7.2.3


--
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] mxs-mmc: fix clock rate setting

2011-07-06 Thread Koen Beel
On Wed, Jul 6, 2011 at 11:38 AM, Wolfram Sang w.s...@pengutronix.de wrote:
 On Mon, Jul 04, 2011 at 12:59:29PM +0200, Koen Beel wrote:
 On Mon, Jul 4, 2011 at 12:34 PM, Wolfram Sang w.s...@pengutronix.de wrote:
 
 Well, maybe not. My colleague complained and I think he is right 
 that we are
 mapping div2 from the range 0 to 256 (inclusive!) to an 8-bit 
 range. This must
 be wrong for one value per se.

If you look at the context of the patch, you will find it's 'div2 - 1'
than 'div2' gets written into register.
  
   Exactly. The '- 1' is why Koen changed the upper limit from  256 to = 
   256.
   The lower limit fix is currently 'if (div2 == 0) div2 == 1', which is a 
   2:1
   mapping. Not good, or?
  
  So you are saying the patch is a right fix but not the most optimal
  one?  In that case, it does not concern me.  I acked it as an valid
  fix.
 
  The patches fixes a few things, but for div2, it is curing the symptoms,
  not the cause, I think. If you look at the formula in the datasheet:
 
  rate = ssp / (clock_divide * (1 + clock_rate));
 
  In the code, the calculation of div2 is equal to '1 + clock_rate' (the 1
  gets subtracted when the value is written to the register which is a bit
  unfortunate; doing it earlier would reduce confusion IMO). So that can
  never be 0, it is a divisor. We should really use DIV_ROUND_UP here.
  Even when not dealing with 0, this seems needed. Assume:
 
  ssp = 5760, wanted_rate = 2500, div1 = 2
 
  will give
 
  div2 = int(1.152) = 1 (meaning 0 + 1, because div2 - 1 will be written)
 
  The rate will thus be:
 
  actual_rate = 5760 / 2 * (0 + 1)
             = 2880
 
  - too fast!
 
  Or did I get something wrong?
 
  Regards,
 
    Wolfram

 Well, right now the clock freq. is set to the minimum clock value
 reaching the requested rate.

 Sorry, it gets a bit confusing: what do you mean with right now?

I mean: in current mainline the actual clock is set to be at least the
requested clock rate.


 In current implementation, the rate will
 be higher in lot's of cases (all cases where the requested clock freq.
 cannot exactly be made).

 Yes.

This is just the consequence of the fact that the actual clock is set
to be at least the requested clock rate.


 But the thing is, the driver now enters dev_err, and returns without
 changing anything when the clock cannot be made as low as requested.
 In that case you will almost certainly end up with a clock being even
 higher then the lowest possible. So that not good I think.
 I might be better to set the clock as low as possible not matter what
 you to after that.

 Yes, might be a bit academic (who would want 4kHz ;)), but still
 correct. Shawn, do you agree?

 About the rounding. I don't think rounding is good. I think it would

 We do rounding already (int conversion). Just in the wrong direction.

 be better to choose between having at least the requested rate (as it
 is now; will result is somewhat higher clock then requested in many
 cases)

 You want a rate faster than what the card could do?

Correct, you don't want the clock to be faster then the requested clock.
So the rounding is indeed in the wrong direction now.


, or having at maximum the requested clock rate. Both have there
 problems.

 If I understood you correctly, this is my DIV_ROUND_UP suggestion. Which
 problems does it have?

I think I misunderstood this suggestion previously. Using DIV_ROUND_UP
would do the rounding in the correct direction.
This should result in: the actual clock is as high as possible
without being higher then the requested clock.


 Regards,

   Wolfram

 -BEGIN PGP SIGNATURE-
 Version: GnuPG v1.4.10 (GNU/Linux)

 iEYEARECAAYFAk4ULSgACgkQD27XaX1/VRsorQCfVRVm9Vpv4YSsfiMqIFctTKG9
 7qkAnicSrjSzwObzBjyISDnXz6+Sze2s
 =5LIq
 -END PGP SIGNATURE-


--
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] mxs-mmc: fix clock rate setting

2011-07-06 Thread Wolfram Sang

 I think I misunderstood this suggestion previously. Using DIV_ROUND_UP
 would do the rounding in the correct direction.
 This should result in: the actual clock is as high as possible
 without being higher then the requested clock.

Yes, that should be done in V2. And if you could also put the '- 1' to
the line calculating div2, that would be an extra plus. I think it is a
lot more readable to have the whole formula in one place, and not split
up.

Regards,

   Wolfram

-- 
Pengutronix e.K.   | Wolfram Sang|
Industrial Linux Solutions | http://www.pengutronix.de/  |


signature.asc
Description: Digital signature


Lavagna luminosa a LED con telecomando e lampada per ombrelloni

2011-07-06 Thread Led Technology Srl
Led Technology srl vi presenta questo fantastico prodotto per presentare il 
vostro Menù in un modo più tecnologico,
oppure la lampada a led per illuminare i vostri tavoli sotto gli ombrelloni.

Vedi la brochure della lavagna cliccando su questo link: 
http://www.led-technology.it/files/lavagna_luminosa.jpg
Vedi la brochure della lampada per ombrelloni clickando su questo link:  
http://www.led-shop.it/luci_per_ombrelloni.jpg

oppure visitate il nostro negozio online per visionare tutti i nostri prodotti 
a LED per illuminazione stradale,
illuminazione architetturale, illuminazione per campi sportivi, illuminazione 
industriale etc.

www.led-shop.it

Per acquistare la lavagna luminosa online clicca su questo link: 
http://www.led-shop.it/negozio/cat066.php?n=1#1
Per acquistare la lampada per ombrelloni clicca su questo link: 
http://www.led-shop.it/negozio/cat061.php?n=1#1

Contatto commerciale diretto:
PIAZZALUNGA ROBERTO
CELL. 345 2412480

Se non vi è gradita questa mail scrivete a unsubscr...@led-shop.it , non sarete 
più disturbati.

Grazie.
--
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: enable background operations for emmc4.41 with HPI support

2011-07-06 Thread Sebastian RASMUSSEN
Hi!

 HPI is a feature to handle a higher or urgent request then pre-ongoing
 request and it's only possible when some conditions are met.

Agreed, as I read the spec this would writes, erases and BKOPS
(eMMC spec 4.41 7.6.20 (table 20) and the 3rd paragraph in 7.6.19).

 BKOPS is a feature to give a chance to optimize the internal 
 for next operation.

Yes, I believe the main reasons would be when blocks are 
either replaced or a ERASE or TRIM operation has been issued.
The BKOPS feature would allow the eMMC device to clean up its
internal state and pre-erase any internal flash devices so
that the next write operation would have better performance.
I believe this to be the intent at least.

 Current implementation is HPI is used for BKOPS but I think 
 HPI is used for Write operation to reduce the latency.

True, the focus of HPI is for Write operations, however in
eMMC spec 4.41 chapter 7.6.19 on background operations it
does state that a host may interrupt any ongoing background
operations by using HPI. So to me it seems as if the intent
from Jedec has been that it may be used in case of BKOPS
taking too long and so may be blocking pending requests..?

 1. I wonder BKOPS is really required to perform frequently? 
 Yes I know it's helpful to use but no need to call it frequently.

According to the spec it is advised to start bkops whenever 
the eMMC device itself indicates an urgent need for it. In 
what way do you think the proposed patch issues bkops too often?
I believe that the patch properly checks for R1_URGENT_BKOPS,
which seems correct..?

 2. Previous time only one request is handled at mmc block. so it can't
 implement the HPI for user request. but as Per Forlin implement the
 double buffering concept. it can possible to implement the HPI,
 interrupt the current write operation and do urgent read request.

Yes, absolutely. Interrupting ongoing write or erase/trim operations
would be the other use for BKOPS. How do you feel that the addition
of BKOPS (and thus HPI) interferes with this? Is it just a matter
of in what order these two features are integrated into the kernel?

 Related with this, you can find a HPI background and one of possible
 solutions in the mmc Spec.

What part of the spec are you referring to?

 3. real use scenario, realtime class read request has too much 
 latency since previous write request, (when merge operation is 
 happened eMMC internally)

I'm not sure what you are explaining here. Would you care to 
describe it further/differently?

 / Sebastian

PS. Sorry for possibly breaking the mail-thread but I was not 
subscribed when the original reply was posted.
N�r��yb�X��ǧv�^�)޺{.n�+{��g��^n�r���z���h����G���h�(�階�ݢj���m��z�ޖ���f���h���~�m�

Re: [PATCH] ARM i.MX dma: Fix burstsize settings

2011-07-06 Thread Mark Brown
On Wed, Jul 06, 2011 at 11:18:33AM +0200, Sascha Hauer wrote:
 dmaengine expects the maxburst parameter in words, not bytes.
 The imxdma driver and its users do this wrong. Fix this.
 
 As a side note the imx-pcm-dma-mx2 driver was 'fixed' to work
 with imx-dma. This broke the driver with imx-sdma support which
 correctly takes the maxburst parameter in words. This patch
 puts the sdma based sound back to work.

Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com

Probably makes sense to send via the ARM tree unless there's merge
issues?
--
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: enable background operations for emmc4.41 with HPI support

2011-07-06 Thread Kyungmin Park
On Wed, Jul 6, 2011 at 11:40 PM, Sebastian RASMUSSEN
sebastian.rasmus...@stericsson.com wrote:
 Hi!

 HPI is a feature to handle a higher or urgent request then pre-ongoing
 request and it's only possible when some conditions are met.

 Agreed, as I read the spec this would writes, erases and BKOPS
 (eMMC spec 4.41 7.6.20 (table 20) and the 3rd paragraph in 7.6.19).

 BKOPS is a feature to give a chance to optimize the internal
 for next operation.

 Yes, I believe the main reasons would be when blocks are
 either replaced or a ERASE or TRIM operation has been issued.
 The BKOPS feature would allow the eMMC device to clean up its
 internal state and pre-erase any internal flash devices so
 that the next write operation would have better performance.
 I believe this to be the intent at least.

 Current implementation is HPI is used for BKOPS but I think
 HPI is used for Write operation to reduce the latency.

 True, the focus of HPI is for Write operations, however in
 eMMC spec 4.41 chapter 7.6.19 on background operations it
 does state that a host may interrupt any ongoing background
 operations by using HPI. So to me it seems as if the intent
 from Jedec has been that it may be used in case of BKOPS
 taking too long and so may be blocking pending requests..?

Yes right, there are some operations which doesn't have timeout. BKOPS
is one of them.
it have to be interrupted when user request. in that case it should use the HPI.


 1. I wonder BKOPS is really required to perform frequently?
 Yes I know it's helpful to use but no need to call it frequently.

 According to the spec it is advised to start bkops whenever
 the eMMC device itself indicates an urgent need for it. In
 what way do you think the proposed patch issues bkops too often?
 I believe that the patch properly checks for R1_URGENT_BKOPS,
 which seems correct..?

Right, it checks the R1_URGENT_BKOPS, I mean it called every user
request is finished.

 2. Previous time only one request is handled at mmc block. so it can't
 implement the HPI for user request. but as Per Forlin implement the
 double buffering concept. it can possible to implement the HPI,
 interrupt the current write operation and do urgent read request.

 Yes, absolutely. Interrupting ongoing write or erase/trim operations
 would be the other use for BKOPS. How do you feel that the addition
 of BKOPS (and thus HPI) interferes with this? Is it just a matter
 of in what order these two features are integrated into the kernel?

 Related with this, you can find a HPI background and one of possible
 solutions in the mmc Spec.

 What part of the spec are you referring to?
I refers the JDEDC v4.41 and v4.5 draft version.

 3. real use scenario, realtime class read request has too much
 latency since previous write request, (when merge operation is
 happened eMMC internally)

 I'm not sure what you are explaining here. Would you care to
 describe it further/differently?
Actually there's no big issue without HPI. but some case (as above)
has read latency problem esp. when play movie at foreground, but some
background heavy write case.

Thank you,
Kyungmin Park
--
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 v3] arm: mach-mmp: brownstone.c support multiple sd slots

2011-07-06 Thread Philip Rakity

On Jul 6, 2011, at 12:19 AM, zhangfei gao wrote:

 On Wed, Jul 6, 2011 at 4:20 AM, Philip Rakity prak...@marvell.com wrote:
 Subject: [PATCH V3] arm: mach-mmp: brownstone.c support multiple sd slots
 
 V3
 ==
 Change since V2 -- delete mmc3 since it was committed
 to linux next.
 
 enable mmc1 used for wifi (8688) and marked PERMANENT.
 Wifi requires enabling of power on the device by
 toggling the gpio lines for power and reset.  Enable eMMC first to work
 around problem in booting order due to workqueue bug.
 
 Signed-off-by: Philip Rakity prak...@marvell.com
 ---
  arch/arm/mach-mmp/brownstone.c |   41 
 +++-
  1 files changed, 40 insertions(+), 1 deletions(-)
 
 diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
 index c79162a..940982c 100644
 --- a/arch/arm/mach-mmp/brownstone.c
 +++ b/arch/arm/mach-mmp/brownstone.c
 @@ -19,6 +19,7 @@
  #include linux/regulator/max8649.h
  #include linux/regulator/fixed.h
  #include linux/mfd/max8925.h
 +#include linux/delay.h
 
  #include asm/mach-types.h
  #include asm/mach/arch.h
 @@ -180,6 +181,11 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 
 = {
.clk_delay_cycles = 0x1f,
  };
 
 +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = {
 +   .clk_delay_cycles = 0x1f,
 +   .flags  = PXA_FLAG_CARD_PERMANENT,
 +};
 +
  static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
.clk_delay_cycles = 0x1f,
.flags = PXA_FLAG_CARD_PERMANENT
 @@ -187,6 +193,38 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 
 = {
  };
 
 
 +static void __init mmc_sdio_wifi(void)
 +{
 +   int poweron;
 +   int reset;
 +
 +   poweron = mfp_to_gpio(GPIO57_GPIO);
 +   reset = mfp_to_gpio(GPIO58_GPIO);
 +
 +   if (gpio_request(reset, sd8xxx reset)) {
 +   printk(KERN_INFO gpio %d request failed\n, reset);
 +   return;
 +   }
 +
 +   if (gpio_request(poweron, sd8xxx PDn)) {
 +   gpio_free(reset);
 +   printk(KERN_INFO gpio %d request failed\n, poweron);
 +   return;
 +   }
 +
 +   gpio_direction_output(poweron, 0);
 +   msleep(1);
 +   gpio_direction_output(poweron, 1);
 +   msleep(1);
 +   gpio_direction_output(reset, 0);
 +   msleep(1);
 +   gpio_direction_output(reset, 1);
 +   gpio_free(reset);
 +   gpio_free(poweron);
 +
 +   mmp2_add_sdhost(1, mmp2_sdh_platdata_mmc1); /* Wifi */
 +}
 +
 
 The method keeps power on wifi chip, without dynamically
 enable/disable wifi power, which is not final solution.
 How about pushing later with dynamically control power, which is in
 debugging here.
 

Good Point -- Will do.  

What is the correct method to handle this ? 

  static void __init brownstone_init(void)
  {
mfp_config(ARRAY_AND_SIZE(brownstone_pin_config));
 @@ -195,8 +233,9 @@ static void __init brownstone_init(void)
mmp2_add_uart(1);
mmp2_add_uart(3);
mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
 -   mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */
mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */
 +   mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */
 +   mmc_sdio_wifi();
 
/* enable 5v regulator */
platform_device_register(brownstone_v_5vp_device);
 --
 1.7.0.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


Re: [PATCH v2 3/3] mmc: sdhci-esdhc-imx: add device tree probe support

2011-07-06 Thread Shawn Guo
On Tue, Jul 05, 2011 at 11:54:34AM -0600, Grant Likely wrote:
 On Tue, Jul 5, 2011 at 9:26 AM, Shawn Guo shawn@linaro.org wrote:
  The patch adds device tree probe support for sdhci-esdhc-imx driver.
 
  Signed-off-by: Shawn Guo shawn@linaro.org
  Cc: Wolfram Sang w.s...@pengutronix.de
  Cc: Chris Ball c...@laptop.org
  Cc: Grant Likely grant.lik...@secretlab.ca
  ---
   .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   40 
   drivers/mmc/host/sdhci-esdhc-imx.c                 |  102 
  +++-
   2 files changed, 137 insertions(+), 5 deletions(-)
   create mode 100644 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
 
  diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt 
  b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
  new file mode 100644
  index 000..351d239
  --- /dev/null
  +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
  @@ -0,0 +1,40 @@
  +* Freescale Enhanced Secure Digital Host Controller (eSDHC) for i.MX
  +
  +The Enhanced Secure Digital Host Controller on Freescale i.MX family
  +provides an interface for MMC, SD, and SDIO types of memory cards.
  +
  +Required properties:
  +- compatible : Should be fsl,chip-esdhc
  +- reg : Should contain eSDHC registers location and length
  +- interrupts : Should contain eSDHC interrupt
  +- cd-type : String, card detection (CD) method.  Supported values are:
  +    none : No CD
  +    controller : Uses eSDHC controller internal CD signal
  +    gpio : Uses GPIO pin for CD
  +    permanent : No CD because card is permanently wired to host
  +- wp-type : String, write protection (WP) method.  Supported values are:
  +    none : No WP
  +    controller : Uses eSDHC controller internal WP signal
  +    gpio : Uses GPIO pin for WP
  +- gpios : Should specify GPIOs in this order: CD GPIO, WP GPIO, if
  +  properties cd-type and wp-type are gpio.
 
 Again, be explicit in your gpios property names.  Create a different
 property for each gpio: cd-gpios and wp-gpios.
 
 As for wp-type and cd-type, I think you can drop them.  Default to
 internal controller CD and WP pins.  Use gpio if cd-gpios or wp-gpios
 is present, and define specific properties for the no-wp, no-cd and
 fixed-card cases.  (can you tell that I'm not a fan of the *-type
 binding for this driver?)  :-)
 
I would let default be no CD/WP, and define properties for
controller internal CD/WP and wired case, if you do not see a
problem with it.

-- 
Regards,
Shawn

--
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 v2 3/3] mmc: sdhci-esdhc-imx: add device tree probe support

2011-07-06 Thread Grant Likely
On Wed, Jul 06, 2011 at 11:43:15PM +0800, Shawn Guo wrote:
 On Tue, Jul 05, 2011 at 11:54:34AM -0600, Grant Likely wrote:
  On Tue, Jul 5, 2011 at 9:26 AM, Shawn Guo shawn@linaro.org wrote:
   The patch adds device tree probe support for sdhci-esdhc-imx driver.
  
   Signed-off-by: Shawn Guo shawn@linaro.org
   Cc: Wolfram Sang w.s...@pengutronix.de
   Cc: Chris Ball c...@laptop.org
   Cc: Grant Likely grant.lik...@secretlab.ca
   ---
    .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   40 
    drivers/mmc/host/sdhci-esdhc-imx.c                 |  102 
   +++-
    2 files changed, 137 insertions(+), 5 deletions(-)
    create mode 100644 
   Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
  
   diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt 
   b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
   new file mode 100644
   index 000..351d239
   --- /dev/null
   +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
   @@ -0,0 +1,40 @@
   +* Freescale Enhanced Secure Digital Host Controller (eSDHC) for i.MX
   +
   +The Enhanced Secure Digital Host Controller on Freescale i.MX family
   +provides an interface for MMC, SD, and SDIO types of memory cards.
   +
   +Required properties:
   +- compatible : Should be fsl,chip-esdhc
   +- reg : Should contain eSDHC registers location and length
   +- interrupts : Should contain eSDHC interrupt
   +- cd-type : String, card detection (CD) method.  Supported values are:
   +    none : No CD
   +    controller : Uses eSDHC controller internal CD signal
   +    gpio : Uses GPIO pin for CD
   +    permanent : No CD because card is permanently wired to host
   +- wp-type : String, write protection (WP) method.  Supported values are:
   +    none : No WP
   +    controller : Uses eSDHC controller internal WP signal
   +    gpio : Uses GPIO pin for WP
   +- gpios : Should specify GPIOs in this order: CD GPIO, WP GPIO, if
   +  properties cd-type and wp-type are gpio.
  
  Again, be explicit in your gpios property names.  Create a different
  property for each gpio: cd-gpios and wp-gpios.
  
  As for wp-type and cd-type, I think you can drop them.  Default to
  internal controller CD and WP pins.  Use gpio if cd-gpios or wp-gpios
  is present, and define specific properties for the no-wp, no-cd and
  fixed-card cases.  (can you tell that I'm not a fan of the *-type
  binding for this driver?)  :-)
  
 I would let default be no CD/WP, and define properties for
 controller internal CD/WP and wired case, if you do not see a
 problem with it.

Okay.

g.

--
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 V2] mmc: sd.c Set Non Default Drive Strength via platform

2011-07-06 Thread Philip Rakity

V2
--
Include host.h change for callback to select_drive_strength

V1
--
Non default Drive Strength cannot be set automatically.
It is a function of the board design and only if there
is a specific platform handler can it be set.  The platform
handler needs to take into account the board design.  Pass
to the platform code the necessary information.

For example:  The card and host controller may indicate
they support HIGH and LOW drive strength.  There is no way
to know what should be chosen without specific board knowledge.
Setting HIGH may lead to reflections and setting LOW may not
be sufficient.
There is no mechanism (like ethernet duplex or speed pulses)
to determine what should be done automatically.

If no platform handler is defined -- use the default value.

Signed-off-by: Philip Rakity prak...@marvell.com
---
 drivers/mmc/core/sd.c|   68 ++---
 include/linux/mmc/host.h |1 +
 2 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index ff27741..633975f 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -409,52 +409,62 @@ out:
 
 static int sd_select_driver_type(struct mmc_card *card, u8 *status)
 {
-   int host_drv_type = 0, card_drv_type = 0;
+   int host_drv_type = SD_DRIVER_TYPE_B;
+   int card_drv_type = SD_DRIVER_TYPE_B;
+   int drive_strength;
int err;
 
/*
 * If the host doesn't support any of the Driver Types A,C or D,
-* default Driver Type B is used.
+* or there is no board specific handler then default Driver
+* Type B is used.
 */
if (!(card-host-caps  (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C
| MMC_CAP_DRIVER_TYPE_D)))
return 0;
 
-   if (card-host-caps  MMC_CAP_DRIVER_TYPE_A) {
-   host_drv_type = MMC_SET_DRIVER_TYPE_A;
-   if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_A)
-   card_drv_type = MMC_SET_DRIVER_TYPE_A;
-   else if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_B)
-   card_drv_type = MMC_SET_DRIVER_TYPE_B;
-   else if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_C)
-   card_drv_type = MMC_SET_DRIVER_TYPE_C;
-   } else if (card-host-caps  MMC_CAP_DRIVER_TYPE_C) {
-   host_drv_type = MMC_SET_DRIVER_TYPE_C;
-   if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_C)
-   card_drv_type = MMC_SET_DRIVER_TYPE_C;
-   } else if (!(card-host-caps  MMC_CAP_DRIVER_TYPE_D)) {
-   /*
-* If we are here, that means only the default driver type
-* B is supported by the host.
-*/
-   host_drv_type = MMC_SET_DRIVER_TYPE_B;
-   if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_B)
-   card_drv_type = MMC_SET_DRIVER_TYPE_B;
-   else if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_C)
-   card_drv_type = MMC_SET_DRIVER_TYPE_C;
-   }
+   if (!card-host-ops-select_drive_strength)
+   return 0;
+
+   if (card-host-caps  MMC_CAP_DRIVER_TYPE_A)
+   host_drv_type |= SD_DRIVER_TYPE_A;
+
+   if (card-host-caps  MMC_CAP_DRIVER_TYPE_C)
+   host_drv_type |= SD_DRIVER_TYPE_C;
+
+   if (card-host-caps  MMC_CAP_DRIVER_TYPE_D)
+   host_drv_type |= SD_DRIVER_TYPE_D;
+
+   if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_A)
+   card_drv_type |= SD_DRIVER_TYPE_A;
+
+   if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_C)
+   card_drv_type |= SD_DRIVER_TYPE_C;
+
+   if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_D)
+   card_drv_type |= SD_DRIVER_TYPE_D;
+
+   /*
+* The drive strength that the hardware can support
+* depends on the board design.  Pass the appropriate
+* information and let the hardware specific code
+* return what is possible given the options
+*/
+   drive_strength = card-host-ops-select_drive_strength(
+   card-sw_caps.uhs_max_dtr,
+   host_drv_type, card_drv_type);
 
-   err = mmc_sd_switch(card, 1, 2, card_drv_type, status);
+   err = mmc_sd_switch(card, 1, 2, drive_strength, status);
if (err)
return err;
 
-   if ((status[15]  0xF) != card_drv_type) {
-   printk(KERN_WARNING %s: Problem setting driver strength!\n,
+   if ((status[15]  0xF) != drive_strength) {
+   printk(KERN_WARNING %s: Problem setting drive strength!\n,
mmc_hostname(card-host));
return 0;
}
 
-   mmc_set_driver_type(card-host, host_drv_type);
+   mmc_set_driver_type(card-host, drive_strength);
 
return 0;
 }
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index ac3fbac..4913f6c 100644
--- 

Re: -ENOSYS suspend-powerdown regression

2011-07-06 Thread Daniel Drake
On 28 June 2011 23:04, Ohad Ben-Cohen o...@wizery.com wrote:
 On Wed, Jun 29, 2011 at 12:54 AM, Daniel Drake d...@laptop.org wrote:
 Too many patches floating around, just trying to be sure of what I'm doing!

 Ok, let's start from fresh :)

 Let's take 3.0-rc5, it already includes our work:

 297c7f2 mmc: sdio: fix runtime PM path during driver removal
 c6e633a mmc: sdio: reset card during power_restore

 Then apply these hunks:

Thanks, done. Sorry for the delay in getting to this.

Unfortunately something is still weird, this is possibly a case that
we missed before.

Even if I just do the simplistic test of booting, and then suspending
(without loading the libertas driver), things go wrong:
http://dev.laptop.org/~dsd/20110706/dmesg.txt

I added printk's in mmc_power_save_host and mmc_power_restore_host.
The strange thing is that it tries to resume mmc1 even though it is
powered down and there is no available driver, and also that it then
tries to power it down again (but it is already off).

Daniel
--
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 v4] arm: mach-mmp: brownstone.c support multiple sd slots

2011-07-06 Thread Philip Rakity
Eric,

Not sure what to suggest.

If it makes more sense to take V3 which powers on the wifi card but does not do 
power handling per
new spec take that.  At least wifi card works and then wait for power code.  
New code could delete
power code as part of the mod.

If it makes more sense to wait for power code -- take V4.

Philip




V4
==
remove code to enable power for wifi.  Coming in separate patch
(by others) that conforms to new power architecture.

V3
==
Change since V2 -- delete mmc3 since it was committed
to linux next.

enable mmc1 used for wifi (8688) and marked PERMANENT.
Wifi requires enabling of power on the device by
toggling the gpio lines for power and reset.

Signed-off-by: Philip Rakity prak...@marvell.com
---
 arch/arm/mach-mmp/brownstone.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index c79162a..7634b2f 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -180,6 +180,11 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
.clk_delay_cycles = 0x1f,
 };
 
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = {
+   .clk_delay_cycles = 0x1f,
+   .flags  = PXA_FLAG_CARD_PERMANENT,
+};
+
 static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
.clk_delay_cycles = 0x1f,
.flags = PXA_FLAG_CARD_PERMANENT
@@ -195,8 +200,9 @@ static void __init brownstone_init(void)
mmp2_add_uart(1);
mmp2_add_uart(3);
mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
-   mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */
mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */
+   mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */
+   mmp2_add_sdhost(1, mmp2_sdh_platdata_mmc1); /* Wifi */
 
/* enable 5v regulator */
platform_device_register(brownstone_v_5vp_device);
-- 
1.7.0.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


Re: [PATCH v4] arm: mach-mmp: brownstone.c support multiple sd slots

2011-07-06 Thread Eric Miao
On Thu, Jul 7, 2011 at 12:08 AM, Philip Rakity prak...@marvell.com wrote:
 Eric,

 Not sure what to suggest.

 If it makes more sense to take V3 which powers on the wifi card but does not 
 do power handling per
 new spec take that.  At least wifi card works and then wait for power code.  
 New code could delete
 power code as part of the mod.

 If it makes more sense to wait for power code -- take V4.


No worries. I'll wait for v4.

 Philip




 V4
 ==
 remove code to enable power for wifi.  Coming in separate patch
 (by others) that conforms to new power architecture.

 V3
 ==
 Change since V2 -- delete mmc3 since it was committed
 to linux next.

 enable mmc1 used for wifi (8688) and marked PERMANENT.
 Wifi requires enabling of power on the device by
 toggling the gpio lines for power and reset.

 Signed-off-by: Philip Rakity prak...@marvell.com
 ---
  arch/arm/mach-mmp/brownstone.c |    8 +++-
  1 files changed, 7 insertions(+), 1 deletions(-)

 diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
 index c79162a..7634b2f 100644
 --- a/arch/arm/mach-mmp/brownstone.c
 +++ b/arch/arm/mach-mmp/brownstone.c
 @@ -180,6 +180,11 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 
 = {
        .clk_delay_cycles = 0x1f,
  };

 +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = {
 +       .clk_delay_cycles = 0x1f,
 +       .flags          = PXA_FLAG_CARD_PERMANENT,
 +};
 +
  static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
        .clk_delay_cycles = 0x1f,
        .flags = PXA_FLAG_CARD_PERMANENT
 @@ -195,8 +200,9 @@ static void __init brownstone_init(void)
        mmp2_add_uart(1);
        mmp2_add_uart(3);
        mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
 -       mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */
        mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */
 +       mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */
 +       mmp2_add_sdhost(1, mmp2_sdh_platdata_mmc1); /* Wifi */

        /* enable 5v regulator */
        platform_device_register(brownstone_v_5vp_device);
 --
 1.7.0.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


RE: [PATCH] mmc: enable background operations for emmc4.41 with HPI support

2011-07-06 Thread Sebastian RASMUSSEN
Hi!

   1. I wonder BKOPS is really required to perform frequently?
   Yes I know it's helpful to use but no need to call it frequently.
  I believe that the patch properly checks for R1_URGENT_BKOPS,
  which seems correct..?

 Right, it checks the R1_URGENT_BKOPS, I mean it called every user
 request is finished.

Aha, are you referring to the mmc_start_bkops() called from
mmc_queue_thread()? If so, I should point to the check for whether
BKOPS are _really_ needed, mmc_card_need_bkops(), at the beginning
of mmc_start_bkops(). That flag is only set if R1_URGET_BKOPS is 
asserted by the eMMC device. So even if mmc_start_bkops() is called
after every user request that function would just do an early return.

One could argue that the call to mmc_card_need_bkops() should be in
queue.c, before the call to mmc_start_bkops(). Maybe that is preferable
and would have improved readability..?

   Related with this, you can find a HPI background and one of possible
   solutions in the mmc Spec.
  What part of the spec are you referring to?

 I refers the JDEDC v4.41 and v4.5 draft version.

Ok, then I'm not sure I understand what you are getting at.
I tried to look through the chapters for BKOPS but I'm not
seeing any descriptive list of solutions concerning HPI 
BKOPS?

(BTW, it seems as if 4.5 draft is now final -- 
http://www.jedec.org/sites/default/files/docs/jesd84-B45.pdf)

 Actually there's no big issue without HPI. but some case (as above)
 has read latency problem esp. when play movie at foreground, but 
 some background heavy write case.

Ok, so what you are looking for is to have BKOPS and HPI in separate
patches along with measurements to backup that the HPI really _does_
improve request latency when HPI is used?

 / Sebastian


[PATCH v3 1/4] mmc: sdhci-esdhc-imx: do not reference platform data after probe

2011-07-06 Thread Shawn Guo
The patch copies platform data into pltfm_imx_data and reference
the data there than platform data after probe.

This work is inspired by Grant Likely and Troy Kisky.

Signed-off-by: Shawn Guo shawn@linaro.org
Cc: Troy Kisky troy.ki...@boundarydevices.com
Cc: Grant Likely grant.lik...@secretlab.ca
Cc: Wolfram Sang w.s...@pengutronix.de
Cc: Chris Ball c...@laptop.org
---
 drivers/mmc/host/sdhci-esdhc-imx.c |   22 +-
 1 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c 
b/drivers/mmc/host/sdhci-esdhc-imx.c
index 3cc6f61..0b0e62e 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -45,6 +45,7 @@
 struct pltfm_imx_data {
int flags;
u32 scratchpad;
+   struct esdhc_platform_data boarddata;
 };
 
 static unsigned int esdhc_pltfm_get_max_blk_size(struct sdhci_host *host)
@@ -69,8 +70,9 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, 
u32 mask, u32 val, i
 
 static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 {
-   struct esdhc_platform_data *boarddata =
-   host-mmc-parent-platform_data;
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct pltfm_imx_data *imx_data = pltfm_host-priv;
+   struct esdhc_platform_data *boarddata = imx_data-boarddata;
 
/* fake CARD_PRESENT flag */
u32 val = readl(host-ioaddr + reg);
@@ -92,8 +94,7 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, 
int reg)
 {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct pltfm_imx_data *imx_data = pltfm_host-priv;
-   struct esdhc_platform_data *boarddata =
-   host-mmc-parent-platform_data;
+   struct esdhc_platform_data *boarddata = imx_data-boarddata;
 
if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
 (boarddata-cd_type == ESDHC_CD_GPIO)))
@@ -210,8 +211,9 @@ static unsigned int esdhc_pltfm_get_min_clock(struct 
sdhci_host *host)
 
 static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
 {
-   struct esdhc_platform_data *boarddata =
-   host-mmc-parent-platform_data;
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct pltfm_imx_data *imx_data = pltfm_host-priv;
+   struct esdhc_platform_data *boarddata = imx_data-boarddata;
 
switch (boarddata-wp_type) {
case ESDHC_WP_GPIO:
@@ -291,12 +293,14 @@ static int __devinit sdhci_esdhc_imx_probe(struct 
platform_device *pdev)
if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
imx_data-flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
 
-   boarddata = host-mmc-parent-platform_data;
-   if (!boarddata) {
+   if (!host-mmc-parent-platform_data) {
dev_err(mmc_dev(host-mmc), no board data!\n);
err = -EINVAL;
goto no_board_data;
}
+   imx_data-boarddata = *((struct esdhc_platform_data *)
+   host-mmc-parent-platform_data);
+   boarddata = imx_data-boarddata;
 
/* write_protect */
if (boarddata-wp_type == ESDHC_WP_GPIO) {
@@ -373,8 +377,8 @@ static int __devexit sdhci_esdhc_imx_remove(struct 
platform_device *pdev)
 {
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-   struct esdhc_platform_data *boarddata = 
host-mmc-parent-platform_data;
struct pltfm_imx_data *imx_data = pltfm_host-priv;
+   struct esdhc_platform_data *boarddata = imx_data-boarddata;
int dead = (readl(host-ioaddr + SDHCI_INT_STATUS) == 0x);
 
sdhci_remove_host(host, dead);
-- 
1.7.4.1


--
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 v3 2/4] mmc: sdhci-esdhc-imx: get rid of the uses of cpu_is_mx()

2011-07-06 Thread Shawn Guo
The patch removes all the uses of cpu_is_mx().  Instead, it utilizes
platform_device_id to distinguish the esdhc differences among SoCs.

Signed-off-by: Shawn Guo shawn@linaro.org
Cc: Wolfram Sang w.s...@pengutronix.de
Cc: Chris Ball c...@laptop.org
Acked-by: Grant Likely grant.lik...@secretlab.ca
---
 arch/arm/mach-imx/clock-imx25.c|4 +-
 arch/arm/mach-imx/clock-imx35.c|6 +-
 arch/arm/mach-mx5/clock-mx51-mx53.c|   16 +++---
 arch/arm/mach-mx5/mx51_efika.c |4 +-
 .../plat-mxc/devices/platform-sdhci-esdhc-imx.c|   17 +++---
 arch/arm/plat-mxc/include/mach/devices-common.h|1 +
 drivers/mmc/host/sdhci-esdhc-imx.c |   60 ++-
 7 files changed, 81 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
index 42ef76a..9bb9062 100644
--- a/arch/arm/mach-imx/clock-imx25.c
+++ b/arch/arm/mach-imx/clock-imx25.c
@@ -301,8 +301,8 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(imx2-wdt.0, NULL, wdt_clk)
_REGISTER_CLOCK(imx-ssi.0, NULL, ssi1_clk)
_REGISTER_CLOCK(imx-ssi.1, NULL, ssi2_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.0, NULL, esdhc1_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.1, NULL, esdhc2_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx25.0, NULL, esdhc1_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx25.1, NULL, esdhc2_clk)
_REGISTER_CLOCK(mx2-camera.0, NULL, csi_clk)
_REGISTER_CLOCK(NULL, audmux, audmux_clk)
_REGISTER_CLOCK(flexcan.0, NULL, can1_clk)
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c
index b44cb06..2d0b4c8 100644
--- a/arch/arm/mach-imx/clock-imx35.c
+++ b/arch/arm/mach-imx/clock-imx35.c
@@ -458,9 +458,9 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(imx-epit.0, NULL, epit1_clk)
_REGISTER_CLOCK(imx-epit.1, NULL, epit2_clk)
_REGISTER_CLOCK(NULL, esai, esai_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.0, NULL, esdhc1_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.1, NULL, esdhc2_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.2, NULL, esdhc3_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx35.0, NULL, esdhc1_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx35.1, NULL, esdhc2_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx35.2, NULL, esdhc3_clk)
_REGISTER_CLOCK(fec.0, NULL, fec_clk)
_REGISTER_CLOCK(NULL, gpio, gpio1_clk)
_REGISTER_CLOCK(NULL, gpio, gpio2_clk)
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c 
b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 6634f6c..0e1aa03 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -1454,10 +1454,10 @@ static struct clk_lookup mx51_lookups[] = {
_REGISTER_CLOCK(imx51-ecspi.0, NULL, ecspi1_clk)
_REGISTER_CLOCK(imx51-ecspi.1, NULL, ecspi2_clk)
_REGISTER_CLOCK(imx51-cspi.0, NULL, cspi_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.0, NULL, esdhc1_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.1, NULL, esdhc2_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.2, NULL, esdhc3_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.3, NULL, esdhc4_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx51.0, NULL, esdhc1_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx51.1, NULL, esdhc2_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx51.2, NULL, esdhc3_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx51.3, NULL, esdhc4_clk)
_REGISTER_CLOCK(NULL, cpu_clk, cpu_clk)
_REGISTER_CLOCK(NULL, iim_clk, iim_clk)
_REGISTER_CLOCK(imx2-wdt.0, NULL, dummy_clk)
@@ -1482,10 +1482,10 @@ static struct clk_lookup mx53_lookups[] = {
_REGISTER_CLOCK(imx-i2c.0, NULL, i2c1_clk)
_REGISTER_CLOCK(imx-i2c.1, NULL, i2c2_clk)
_REGISTER_CLOCK(imx-i2c.2, NULL, i2c3_mx53_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.0, NULL, esdhc1_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.1, NULL, esdhc2_mx53_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.2, NULL, esdhc3_mx53_clk)
-   _REGISTER_CLOCK(sdhci-esdhc-imx.3, NULL, esdhc4_mx53_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx53.0, NULL, esdhc1_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx53.1, NULL, esdhc2_mx53_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx53.2, NULL, esdhc3_mx53_clk)
+   _REGISTER_CLOCK(sdhci-esdhc-imx53.3, NULL, esdhc4_mx53_clk)
_REGISTER_CLOCK(imx53-ecspi.0, NULL, ecspi1_clk)
_REGISTER_CLOCK(imx53-ecspi.1, NULL, ecspi2_clk)
_REGISTER_CLOCK(imx53-cspi.0, NULL, cspi_clk)
diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-mx5/mx51_efika.c
index 56739c2..4435e03 100644
--- a/arch/arm/mach-mx5/mx51_efika.c
+++ b/arch/arm/mach-mx5/mx51_efika.c
@@ -260,8 +260,8 @@ static struct regulator_consumer_supply vvideo_consumers[] 
= {
 };
 
 static struct regulator_consumer_supply vsd_consumers[] = {
-   REGULATOR_SUPPLY(vmmc, sdhci-esdhc-imx.0),
-   REGULATOR_SUPPLY(vmmc, sdhci-esdhc-imx.1),
+   REGULATOR_SUPPLY(vmmc, 

[PATCH v3 3/4] mmc: sdhci-pltfm: dt device does not pass parent to sdhci_alloc_host

2011-07-06 Thread Shawn Guo
Neither platform based nor dt based device needs to pass the parent
to sdhci_alloc_host.  There is no difference between platform and dt
on this point.

The patch makes the change to pass device itself than its parent to
sdhci_alloc_host for dt case too.  Otherwise the probe function of
sdhci based drivers which is shared between platform and dt will
fail on dt case.

Signed-off-by: Shawn Guo shawn@linaro.org
Acked-by: Grant Likely grant.lik...@secretlab.ca
Cc: Chris Ball c...@laptop.org
---
 drivers/mmc/host/sdhci-pltfm.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 71c0ce1..6414efe 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -85,6 +85,7 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device 
*pdev,
 {
struct sdhci_host *host;
struct sdhci_pltfm_host *pltfm_host;
+   struct device_node *np = pdev-dev.of_node;
struct resource *iomem;
int ret;
 
@@ -98,7 +99,7 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device 
*pdev,
dev_err(pdev-dev, Invalid iomem size!\n);
 
/* Some PCI-based MFD need the parent here */
-   if (pdev-dev.parent != platform_bus)
+   if (pdev-dev.parent != platform_bus  !np)
host = sdhci_alloc_host(pdev-dev.parent, sizeof(*pltfm_host));
else
host = sdhci_alloc_host(pdev-dev, sizeof(*pltfm_host));
-- 
1.7.4.1


--
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 v3 0/4] Add device tree probe for sdhci-esdhc-imx

2011-07-06 Thread Shawn Guo
The first patch copies platform data into driver private data, and
do not reference platform data after probe.  The second one removes
the uses of cpu_is_mx().  The third one makes a dt related fix on
sdhci-pltfm.c, and the last one adds actual device tree probe for
sdhci-esdhc-imx driver.

Changes since v2:
 * Add patch #1
 * Do not use Linux details of cd-type and wp-type for binding

Changes since v1:
 * Address review comments given by Grant

Shawn Guo (4):
  mmc: sdhci-esdhc-imx: do not reference platform data after probe
  mmc: sdhci-esdhc-imx: get rid of the uses of cpu_is_mx()
  mmc: sdhci-pltfm: dt device does not pass parent to sdhci_alloc_host
  mmc: sdhci-esdhc-imx: add device tree probe support

 .../devicetree/bindings/mmc/fsl-imx-esdhc.txt  |   34 +
 arch/arm/mach-imx/clock-imx25.c|4 +-
 arch/arm/mach-imx/clock-imx35.c|6 +-
 arch/arm/mach-mx5/clock-mx51-mx53.c|   16 +-
 arch/arm/mach-mx5/mx51_efika.c |4 +-
 .../plat-mxc/devices/platform-sdhci-esdhc-imx.c|   17 ++-
 arch/arm/plat-mxc/include/mach/devices-common.h|1 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  151 +---
 drivers/mmc/host/sdhci-pltfm.c |3 +-
 9 files changed, 194 insertions(+), 42 deletions(-)

--
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 v3 4/4] mmc: sdhci-esdhc-imx: add device tree probe support

2011-07-06 Thread Shawn Guo
The patch adds device tree probe support for sdhci-esdhc-imx driver.

Signed-off-by: Shawn Guo shawn@linaro.org
Cc: Wolfram Sang w.s...@pengutronix.de
Cc: Chris Ball c...@laptop.org
Cc: Grant Likely grant.lik...@secretlab.ca
---
 .../devicetree/bindings/mmc/fsl-imx-esdhc.txt  |   34 +
 drivers/mmc/host/sdhci-esdhc-imx.c |   77 +---
 2 files changed, 102 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt 
b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
new file mode 100644
index 000..ab22fe6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
@@ -0,0 +1,34 @@
+* Freescale Enhanced Secure Digital Host Controller (eSDHC) for i.MX
+
+The Enhanced Secure Digital Host Controller on Freescale i.MX family
+provides an interface for MMC, SD, and SDIO types of memory cards.
+
+Required properties:
+- compatible : Should be fsl,chip-esdhc
+- reg : Should contain eSDHC registers location and length
+- interrupts : Should contain eSDHC interrupt
+
+Optional properties:
+- fsl,card-wired : Indicate the card is wired to host permanently
+- fsl,cd-internal : Indicate to use controller internal card detection
+- fsl,wp-internal : Indicate to use controller internal write protection
+- cd-gpios : Specify GPIOs for card detection
+- wp-gpios : Specify GPIOs for write protection
+
+Examples:
+
+esdhc@70004000 {
+   compatible = fsl,imx51-esdhc;
+   reg = 0x70004000 0x4000;
+   interrupts = 1;
+   fsl,cd-internal;
+   fsl,wp-internal;
+};
+
+esdhc@70008000 {
+   compatible = fsl,imx51-esdhc;
+   reg = 0x70008000 0x4000;
+   interrupts = 2;
+   cd-gpios = gpio0 6 0; /* GPIO1_6 */
+   wp-gpios = gpio0 5 0; /* GPIO1_5 */
+};
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c 
b/drivers/mmc/host/sdhci-esdhc-imx.c
index f3efb3b..cbdd91f 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -20,6 +20,9 @@
 #include linux/mmc/host.h
 #include linux/mmc/mmc.h
 #include linux/mmc/sdio.h
+#include linux/of.h
+#include linux/of_device.h
+#include linux/of_gpio.h
 #include mach/esdhc.h
 #include sdhci-pltfm.h
 #include sdhci-esdhc.h
@@ -73,6 +76,14 @@ static struct platform_device_id imx_esdhc_devtype[] = {
}
 };
 
+static const struct of_device_id imx_esdhc_dt_ids[] = {
+   { .compatible = fsl,imx25-esdhc, .data = 
imx_esdhc_devtype[IMX25_ESDHC], },
+   { .compatible = fsl,imx35-esdhc, .data = 
imx_esdhc_devtype[IMX35_ESDHC], },
+   { .compatible = fsl,imx51-esdhc, .data = 
imx_esdhc_devtype[IMX51_ESDHC], },
+   { .compatible = fsl,imx53-esdhc, .data = 
imx_esdhc_devtype[IMX53_ESDHC], },
+   { /* sentinel */ }
+};
+
 static inline int is_imx25_esdhc(struct pltfm_imx_data *data)
 {
return data-devtype == IMX25_ESDHC;
@@ -307,8 +318,48 @@ static irqreturn_t cd_irq(int irq, void *data)
return IRQ_HANDLED;
 };
 
+#ifdef CONFIG_OF
+static int __devinit
+sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
+struct esdhc_platform_data *boarddata)
+{
+   struct device_node *np = pdev-dev.of_node;
+
+   if (!np)
+   return -ENODEV;
+
+   if (of_get_property(np, fsl,card-wired, NULL))
+   boarddata-cd_type = ESDHC_CD_PERMANENT;
+
+   if (of_get_property(np, fsl,cd-controller, NULL))
+   boarddata-cd_type = ESDHC_CD_CONTROLLER;
+
+   if (of_get_property(np, fsl,wp-controller, NULL))
+   boarddata-wp_type = ESDHC_WP_CONTROLLER;
+
+   boarddata-cd_gpio = of_get_named_gpio(np, cd-gpios, 0);
+   if (gpio_is_valid(boarddata-cd_gpio))
+   boarddata-cd_type = ESDHC_CD_GPIO;
+
+   boarddata-wp_gpio = of_get_named_gpio(np, wp-gpios, 0);
+   if (gpio_is_valid(boarddata-wp_gpio))
+   boarddata-wp_type = ESDHC_WP_GPIO;
+
+   return 0;
+}
+#else
+static inline int
+sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
+struct esdhc_platform_data *boarddata)
+{
+   return -ENODEV;
+}
+#endif
+
 static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 {
+   const struct of_device_id *of_id =
+   of_match_device(imx_esdhc_dt_ids, pdev-dev);
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_host *host;
struct esdhc_platform_data *boarddata;
@@ -323,9 +374,13 @@ static int __devinit sdhci_esdhc_imx_probe(struct 
platform_device *pdev)
pltfm_host = sdhci_priv(host);
 
imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
-   if (!imx_data)
-   return -ENOMEM;
+   if (!imx_data) {
+   err = -ENOMEM;
+   goto err_imx_data;
+   }
 
+   if (of_id)
+   pdev-id_entry = of_id-data;
imx_data-devtype = pdev-id_entry-driver_data;

RE: [PATCH V2] mmc: sd.c Set Non Default Drive Strength via platform

2011-07-06 Thread Nath, Arindam
Hi Philip,


 -Original Message-
 From: Philip Rakity [mailto:prak...@marvell.com]
 Sent: Wednesday, July 06, 2011 9:22 PM
 To: linux-mmc@vger.kernel.org
 Cc: Nath, Arindam
 Subject: [PATCH V2] mmc: sd.c Set Non Default Drive Strength via
 platform
 
 
 V2
 --
 Include host.h change for callback to select_drive_strength
 
 V1
 --
 Non default Drive Strength cannot be set automatically.
 It is a function of the board design and only if there
 is a specific platform handler can it be set.  The platform
 handler needs to take into account the board design.  Pass
 to the platform code the necessary information.
 
 For example:  The card and host controller may indicate
 they support HIGH and LOW drive strength.  There is no way
 to know what should be chosen without specific board knowledge.
 Setting HIGH may lead to reflections and setting LOW may not
 be sufficient.
 There is no mechanism (like ethernet duplex or speed pulses)
 to determine what should be done automatically.
 
 If no platform handler is defined -- use the default value.
 
 Signed-off-by: Philip Rakity prak...@marvell.com
 ---
  drivers/mmc/core/sd.c|   68 ++
 ---
  include/linux/mmc/host.h |1 +
  2 files changed, 40 insertions(+), 29 deletions(-)
 
 diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
 index ff27741..633975f 100644
 --- a/drivers/mmc/core/sd.c
 +++ b/drivers/mmc/core/sd.c
 @@ -409,52 +409,62 @@ out:
 
  static int sd_select_driver_type(struct mmc_card *card, u8 *status)
  {
 - int host_drv_type = 0, card_drv_type = 0;
 + int host_drv_type = SD_DRIVER_TYPE_B;
 + int card_drv_type = SD_DRIVER_TYPE_B;
 + int drive_strength;
   int err;
 
   /*
* If the host doesn't support any of the Driver Types A,C or D,
 -  * default Driver Type B is used.
 +  * or there is no board specific handler then default Driver
 +  * Type B is used.
*/
   if (!(card-host-caps  (MMC_CAP_DRIVER_TYPE_A |
 MMC_CAP_DRIVER_TYPE_C
   | MMC_CAP_DRIVER_TYPE_D)))
   return 0;
 
 - if (card-host-caps  MMC_CAP_DRIVER_TYPE_A) {
 - host_drv_type = MMC_SET_DRIVER_TYPE_A;
 - if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_A)
 - card_drv_type = MMC_SET_DRIVER_TYPE_A;
 - else if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_B)
 - card_drv_type = MMC_SET_DRIVER_TYPE_B;
 - else if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_C)
 - card_drv_type = MMC_SET_DRIVER_TYPE_C;
 - } else if (card-host-caps  MMC_CAP_DRIVER_TYPE_C) {
 - host_drv_type = MMC_SET_DRIVER_TYPE_C;
 - if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_C)
 - card_drv_type = MMC_SET_DRIVER_TYPE_C;
 - } else if (!(card-host-caps  MMC_CAP_DRIVER_TYPE_D)) {
 - /*
 -  * If we are here, that means only the default driver type
 -  * B is supported by the host.
 -  */
 - host_drv_type = MMC_SET_DRIVER_TYPE_B;
 - if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_B)
 - card_drv_type = MMC_SET_DRIVER_TYPE_B;
 - else if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_C)
 - card_drv_type = MMC_SET_DRIVER_TYPE_C;
 - }
 + if (!card-host-ops-select_drive_strength)
 + return 0;
 +
 + if (card-host-caps  MMC_CAP_DRIVER_TYPE_A)
 + host_drv_type |= SD_DRIVER_TYPE_A;
 +
 + if (card-host-caps  MMC_CAP_DRIVER_TYPE_C)
 + host_drv_type |= SD_DRIVER_TYPE_C;
 +
 + if (card-host-caps  MMC_CAP_DRIVER_TYPE_D)
 + host_drv_type |= SD_DRIVER_TYPE_D;
 +
 + if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_A)
 + card_drv_type |= SD_DRIVER_TYPE_A;
 +
 + if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_C)
 + card_drv_type |= SD_DRIVER_TYPE_C;
 +
 + if (card-sw_caps.sd3_drv_type  SD_DRIVER_TYPE_D)
 + card_drv_type |= SD_DRIVER_TYPE_D;
 +
 + /*
 +  * The drive strength that the hardware can support
 +  * depends on the board design.  Pass the appropriate
 +  * information and let the hardware specific code
 +  * return what is possible given the options
 +  */
 + drive_strength = card-host-ops-select_drive_strength(
 + card-sw_caps.uhs_max_dtr,
 + host_drv_type, card_drv_type);
 
 - err = mmc_sd_switch(card, 1, 2, card_drv_type, status);
 + err = mmc_sd_switch(card, 1, 2, drive_strength, status);
   if (err)
   return err;
 
 - if ((status[15]  0xF) != card_drv_type) {
 - printk(KERN_WARNING %s: Problem setting driver
 strength!\n,
 + if ((status[15]  0xF) != drive_strength) {
 + printk(KERN_WARNING %s: Problem setting drive
 strength!\n,
   mmc_hostname(card-host));
   return 0;
   }
 
 - 

Re: [PATCH] mmc: enable background operations for emmc4.41 with HPI support

2011-07-06 Thread S, Venkatraman
On Tue, Jul 5, 2011 at 5:57 PM, Hanumath Prasad
hanumath.pra...@stericsson.com wrote:
 Background operations is an optional feature defined in eMMC4.41 spec.
 The need for BKOPS will be checked after servicing each user request
 in R1 response. If need for BKOPS flag is set, then start BKOPS when
 request queue is idle. Once bkops is started and meanwhile any
 user read/write request comes then the bkops will be interrupted by
 issuing HPI, otherwise bkops keep going  until it gets finished.
 This patch is based on the four patches submitted by Chuanxiao Dong
 to linux-mmc.

 Signed-off-by: Hanumath Prasad hanumath.pra...@stericsson.com
 ---
  drivers/mmc/card/block.c   |   14 +++-
  drivers/mmc/card/queue.c   |    1 +
  drivers/mmc/core/core.c    |   75 
 
  drivers/mmc/core/mmc.c     |   52 +-
  drivers/mmc/core/mmc_ops.c |   33 +++
  drivers/mmc/core/mmc_ops.h |    1 +
  include/linux/mmc/card.h   |   14 
  include/linux/mmc/core.h   |    3 +-
  include/linux/mmc/mmc.h    |    6 +++
  9 files changed, 195 insertions(+), 4 deletions(-)

 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
 index 71da564..26a87ca 100644
 --- a/drivers/mmc/card/block.c
 +++ b/drivers/mmc/card/block.c
 @@ -799,6 +799,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
 struct request *req)

                mmc_queue_bounce_pre(mq);

 +               if (mmc_card_doing_bkops(card)) {
 +                       if (mmc_interrupt_bkops(card))
 +                               goto cmd_err;
 +               }
 +
                mmc_wait_for_req(card-host, brq.mrq);

                mmc_queue_bounce_post(mq);
 @@ -897,10 +902,17 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
 struct request *req)
                        goto cmd_err;
                }

 +               spin_lock_irq(md-lock);
 +               /*
 +                * Check BKOPS urgency from each R1 response
 +                */
 +               if (mmc_card_mmc(card) 
 +                       (brq.cmd.resp[0]  R1_URGENT_BKOPS))
 +                       mmc_card_set_need_bkops(card);
 +
                /*
                 * A block was successfully transferred.
                 */
 -               spin_lock_irq(md-lock);
                ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
                spin_unlock_irq(md-lock);
        } while (ret);
 diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
 index c07322c..c491edd 100644
 --- a/drivers/mmc/card/queue.c
 +++ b/drivers/mmc/card/queue.c
 @@ -64,6 +64,7 @@ static int mmc_queue_thread(void *d)
                                set_current_state(TASK_RUNNING);
                                break;
                        }
 +                       mmc_start_bkops(mq-card);
                        up(mq-thread_sem);
                        schedule();
                        down(mq-thread_sem);
 diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
 index 68091dd..e5e1d7c 100644
 --- a/drivers/mmc/core/core.c
 +++ b/drivers/mmc/core/core.c
 @@ -196,6 +196,48 @@ mmc_start_request(struct mmc_host *host, struct 
 mmc_request *mrq)
        host-ops-request(host, mrq);
  }

 +/**
 + *     mmc_start_bkops - start BKOPS for supported cards
 + *     @card: MMC card to start BKOPS
 + *
 + *     Start background operations whenever requested.
 + *     when the urgent BKOPS bit is set in a R1 command response
 + *     then background operations should be started immediately.
 + */
 +void mmc_start_bkops(struct mmc_card *card)
 +{
 +       int err;
 +       unsigned long flags;
 +
 +       if (!card || !card-ext_csd.bkops_en)
 +               return;
 +       /*
 +        * If card is already doing bkops or need for
 +        * bkops flag is not set, then do nothing just
 +        * return
 +        */
 +       if (mmc_card_doing_bkops(card)
 +                       || !mmc_card_need_bkops(card))
 +               return;
 +
 +       mmc_claim_host(card-host);
 +       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 +                       EXT_CSD_BKOPS_START, 1, 0);
 +       if (err) {
 +               printk(KERN_ERR error %d starting bkops\n,
 +                               err);
 +               mmc_card_clr_need_bkops(card);
 +               goto out;
 +       }
 +       spin_lock_irqsave(card-host-lock, flags);
 +       mmc_card_clr_need_bkops(card);
 +       mmc_card_set_doing_bkops(card);
 +       spin_unlock_irqrestore(card-host-lock, flags);
 +out:
 +       mmc_release_host(card-host);
 +}
 +EXPORT_SYMBOL(mmc_start_bkops);
 +
  static void mmc_wait_done(struct mmc_request *mrq)
  {
        complete(mrq-done_data);
 @@ -254,6 +296,39 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct 
 mmc_command *cmd, int retries
  EXPORT_SYMBOL(mmc_wait_for_cmd);

  /**
 + *     mmc_interrupt_bkops - interrupt ongoing BKOPS
 + *     @card: MMC card to check BKOPS
 + *
 

Re: [PATCH 1/4] mmci: use StartBitErr to detect bad connections

2011-07-06 Thread Russell King - ARM Linux
On Tue, Jul 05, 2011 at 12:16:11PM +0100, Russell King - ARM Linux wrote:
 On Tue, Jun 28, 2011 at 09:57:25AM +0200, Linus Walleij wrote:
  Stresstesting insert/remove of SD-cards can trigger
  a StartBitErr. This made the driver to hang in forever
  waiting for a non ocurring data timeout.
  
  This bit and interrupt is documented in the original
  PL180 TRM, just never implemented until now.
  
  Signed-off-by: Ulf Hansson ulf.hans...@stericsson.com
  Reviewed-by: Linus Walleij linus.wall...@stericsson.com
  Reviewed-by: Jonas Aberg jonas.ab...@stericsson.com
  Signed-off-by: Linus Walleij linus.wall...@linaro.org
 
 Acked-by: Russell King rmk+ker...@arm.linux.org.uk

Ok, I've taken this into my fixes branch.
--
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 v3 1/4] mmc: sdhci-esdhc-imx: do not reference platform data after probe

2011-07-06 Thread Grant Likely
On Thu, Jul 07, 2011 at 12:47:47AM +0800, Shawn Guo wrote:
 The patch copies platform data into pltfm_imx_data and reference
 the data there than platform data after probe.
 
 This work is inspired by Grant Likely and Troy Kisky.
 
 Signed-off-by: Shawn Guo shawn@linaro.org
 Cc: Troy Kisky troy.ki...@boundarydevices.com
 Cc: Grant Likely grant.lik...@secretlab.ca
 Cc: Wolfram Sang w.s...@pengutronix.de
 Cc: Chris Ball c...@laptop.org

Acked-by: Grant Likely grant.lik...@secretlab.ca

 ---
  drivers/mmc/host/sdhci-esdhc-imx.c |   22 +-
  1 files changed, 13 insertions(+), 9 deletions(-)
 
 diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c 
 b/drivers/mmc/host/sdhci-esdhc-imx.c
 index 3cc6f61..0b0e62e 100644
 --- a/drivers/mmc/host/sdhci-esdhc-imx.c
 +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
 @@ -45,6 +45,7 @@
  struct pltfm_imx_data {
   int flags;
   u32 scratchpad;
 + struct esdhc_platform_data boarddata;
  };
  
  static unsigned int esdhc_pltfm_get_max_blk_size(struct sdhci_host *host)
 @@ -69,8 +70,9 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, 
 u32 mask, u32 val, i
  
  static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
  {
 - struct esdhc_platform_data *boarddata =
 - host-mmc-parent-platform_data;
 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 + struct pltfm_imx_data *imx_data = pltfm_host-priv;
 + struct esdhc_platform_data *boarddata = imx_data-boarddata;
  
   /* fake CARD_PRESENT flag */
   u32 val = readl(host-ioaddr + reg);
 @@ -92,8 +94,7 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 
 val, int reg)
  {
   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
   struct pltfm_imx_data *imx_data = pltfm_host-priv;
 - struct esdhc_platform_data *boarddata =
 - host-mmc-parent-platform_data;
 + struct esdhc_platform_data *boarddata = imx_data-boarddata;
  
   if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
(boarddata-cd_type == ESDHC_CD_GPIO)))
 @@ -210,8 +211,9 @@ static unsigned int esdhc_pltfm_get_min_clock(struct 
 sdhci_host *host)
  
  static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
  {
 - struct esdhc_platform_data *boarddata =
 - host-mmc-parent-platform_data;
 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 + struct pltfm_imx_data *imx_data = pltfm_host-priv;
 + struct esdhc_platform_data *boarddata = imx_data-boarddata;
  
   switch (boarddata-wp_type) {
   case ESDHC_WP_GPIO:
 @@ -291,12 +293,14 @@ static int __devinit sdhci_esdhc_imx_probe(struct 
 platform_device *pdev)
   if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
   imx_data-flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
  
 - boarddata = host-mmc-parent-platform_data;
 - if (!boarddata) {
 + if (!host-mmc-parent-platform_data) {
   dev_err(mmc_dev(host-mmc), no board data!\n);
   err = -EINVAL;
   goto no_board_data;
   }
 + imx_data-boarddata = *((struct esdhc_platform_data *)
 + host-mmc-parent-platform_data);
 + boarddata = imx_data-boarddata;
  
   /* write_protect */
   if (boarddata-wp_type == ESDHC_WP_GPIO) {
 @@ -373,8 +377,8 @@ static int __devexit sdhci_esdhc_imx_remove(struct 
 platform_device *pdev)
  {
   struct sdhci_host *host = platform_get_drvdata(pdev);
   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 - struct esdhc_platform_data *boarddata = 
 host-mmc-parent-platform_data;
   struct pltfm_imx_data *imx_data = pltfm_host-priv;
 + struct esdhc_platform_data *boarddata = imx_data-boarddata;
   int dead = (readl(host-ioaddr + SDHCI_INT_STATUS) == 0x);
  
   sdhci_remove_host(host, dead);
 -- 
 1.7.4.1
 
 
--
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 v3 4/4] mmc: sdhci-esdhc-imx: add device tree probe support

2011-07-06 Thread Grant Likely
On Thu, Jul 07, 2011 at 12:47:50AM +0800, Shawn Guo wrote:
 The patch adds device tree probe support for sdhci-esdhc-imx driver.
 
 Signed-off-by: Shawn Guo shawn@linaro.org
 Cc: Wolfram Sang w.s...@pengutronix.de
 Cc: Chris Ball c...@laptop.org
 Cc: Grant Likely grant.lik...@secretlab.ca

Acked-by: Grant Likely grant.lik...@secretlab.ca

 ---
  .../devicetree/bindings/mmc/fsl-imx-esdhc.txt  |   34 +
  drivers/mmc/host/sdhci-esdhc-imx.c |   77 
 +---
  2 files changed, 102 insertions(+), 9 deletions(-)
  create mode 100644 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
 
 diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt 
 b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
 new file mode 100644
 index 000..ab22fe6
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
 @@ -0,0 +1,34 @@
 +* Freescale Enhanced Secure Digital Host Controller (eSDHC) for i.MX
 +
 +The Enhanced Secure Digital Host Controller on Freescale i.MX family
 +provides an interface for MMC, SD, and SDIO types of memory cards.
 +
 +Required properties:
 +- compatible : Should be fsl,chip-esdhc
 +- reg : Should contain eSDHC registers location and length
 +- interrupts : Should contain eSDHC interrupt
 +
 +Optional properties:
 +- fsl,card-wired : Indicate the card is wired to host permanently
 +- fsl,cd-internal : Indicate to use controller internal card detection
 +- fsl,wp-internal : Indicate to use controller internal write protection
 +- cd-gpios : Specify GPIOs for card detection
 +- wp-gpios : Specify GPIOs for write protection
 +
 +Examples:
 +
 +esdhc@70004000 {
 + compatible = fsl,imx51-esdhc;
 + reg = 0x70004000 0x4000;
 + interrupts = 1;
 + fsl,cd-internal;
 + fsl,wp-internal;
 +};
 +
 +esdhc@70008000 {
 + compatible = fsl,imx51-esdhc;
 + reg = 0x70008000 0x4000;
 + interrupts = 2;
 + cd-gpios = gpio0 6 0; /* GPIO1_6 */
 + wp-gpios = gpio0 5 0; /* GPIO1_5 */
 +};
 diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c 
 b/drivers/mmc/host/sdhci-esdhc-imx.c
 index f3efb3b..cbdd91f 100644
 --- a/drivers/mmc/host/sdhci-esdhc-imx.c
 +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
 @@ -20,6 +20,9 @@
  #include linux/mmc/host.h
  #include linux/mmc/mmc.h
  #include linux/mmc/sdio.h
 +#include linux/of.h
 +#include linux/of_device.h
 +#include linux/of_gpio.h
  #include mach/esdhc.h
  #include sdhci-pltfm.h
  #include sdhci-esdhc.h
 @@ -73,6 +76,14 @@ static struct platform_device_id imx_esdhc_devtype[] = {
   }
  };
  
 +static const struct of_device_id imx_esdhc_dt_ids[] = {
 + { .compatible = fsl,imx25-esdhc, .data = 
 imx_esdhc_devtype[IMX25_ESDHC], },
 + { .compatible = fsl,imx35-esdhc, .data = 
 imx_esdhc_devtype[IMX35_ESDHC], },
 + { .compatible = fsl,imx51-esdhc, .data = 
 imx_esdhc_devtype[IMX51_ESDHC], },
 + { .compatible = fsl,imx53-esdhc, .data = 
 imx_esdhc_devtype[IMX53_ESDHC], },
 + { /* sentinel */ }
 +};
 +
  static inline int is_imx25_esdhc(struct pltfm_imx_data *data)
  {
   return data-devtype == IMX25_ESDHC;
 @@ -307,8 +318,48 @@ static irqreturn_t cd_irq(int irq, void *data)
   return IRQ_HANDLED;
  };
  
 +#ifdef CONFIG_OF
 +static int __devinit
 +sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
 +  struct esdhc_platform_data *boarddata)
 +{
 + struct device_node *np = pdev-dev.of_node;
 +
 + if (!np)
 + return -ENODEV;
 +
 + if (of_get_property(np, fsl,card-wired, NULL))
 + boarddata-cd_type = ESDHC_CD_PERMANENT;
 +
 + if (of_get_property(np, fsl,cd-controller, NULL))
 + boarddata-cd_type = ESDHC_CD_CONTROLLER;
 +
 + if (of_get_property(np, fsl,wp-controller, NULL))
 + boarddata-wp_type = ESDHC_WP_CONTROLLER;
 +
 + boarddata-cd_gpio = of_get_named_gpio(np, cd-gpios, 0);
 + if (gpio_is_valid(boarddata-cd_gpio))
 + boarddata-cd_type = ESDHC_CD_GPIO;
 +
 + boarddata-wp_gpio = of_get_named_gpio(np, wp-gpios, 0);
 + if (gpio_is_valid(boarddata-wp_gpio))
 + boarddata-wp_type = ESDHC_WP_GPIO;
 +
 + return 0;
 +}
 +#else
 +static inline int
 +sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
 +  struct esdhc_platform_data *boarddata)
 +{
 + return -ENODEV;
 +}
 +#endif
 +
  static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
  {
 + const struct of_device_id *of_id =
 + of_match_device(imx_esdhc_dt_ids, pdev-dev);
   struct sdhci_pltfm_host *pltfm_host;
   struct sdhci_host *host;
   struct esdhc_platform_data *boarddata;
 @@ -323,9 +374,13 @@ static int __devinit sdhci_esdhc_imx_probe(struct 
 platform_device *pdev)
   pltfm_host = sdhci_priv(host);
  
   imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
 - if (!imx_data)
 - return -ENOMEM;
 + if (!imx_data) {
 + err = -ENOMEM;
 + 

Re: [PATCH] ARM i.MX dma: Fix burstsize settings

2011-07-06 Thread Vinod Koul
On Wed, 2011-07-06 at 08:03 -0700, Mark Brown wrote:
 On Wed, Jul 06, 2011 at 11:18:33AM +0200, Sascha Hauer wrote:
  dmaengine expects the maxburst parameter in words, not bytes.
  The imxdma driver and its users do this wrong. Fix this.
  
  As a side note the imx-pcm-dma-mx2 driver was 'fixed' to work
  with imx-dma. This broke the driver with imx-sdma support which
  correctly takes the maxburst parameter in words. This patch
  puts the sdma based sound back to work.
 
 Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com
Acked-by: Vinod Koul vinod.k...@intel.com

 
 Probably makes sense to send via the ARM tree unless there's merge
 issues?
Sure, I dont have naything on this driver in my next and previous
updates for Sascha went thru imx tree, so would make sense for these to
go that way as well

~Vinod Koul
Intel Corp.


--
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