Re: [PATCH 2/3] eSDHC: Fix errors when booting kernel with fsl esdhc

2011-07-05 Thread S, Venkatraman
On Tue, Jul 5, 2011 at 9:49 AM, Roy Zang tie-fei.z...@freescale.com wrote:
 From: Xu lei b33...@freescale.com

 When esdhc module was enabled in p5020, there were following errors:

 mmc0: Timeout waiting for hardware interrupt.
 mmc0: error -110 whilst initialising SD card
 mmc0: Unexpected interrupt 0x0200.
 mmc0: Timeout waiting for hardware interrupt.
 mmc0: error -110 whilst initialising SD card
 mmc0: Unexpected interrupt 0x0200.

 It is because ESDHC controller has different bit setting for PROCTL
 register, when kernel sets Power Control Register by method for standard
 SD Host Specification, it would overwritten FSL ESDHC PROCTL[DMAS];
 when it set Host Control Registers[DMAS], it sets PROCTL[EMODE] and
 PROCTL[D3CD]. These operations will set bad bits for PROCTL Register
 on FSL ESDHC Controller and cause errors, so this patch will make esdhc
 driver access FSL PROCTL Register according to block guide instead of
 standard SD Host Specification.

 For some FSL chips, such as MPC8536/P2020, PROCTL[VOLT_SEL] and PROCTL[DMAS]
 bits are reserved and even if they are set to wrong bits there is no error.
 But considering that all FSL ESDHC Controller register map is not fully
 compliant to standard SD Host Specification, we put the patch to all of
 FSL ESDHC Controllers.

 Signed-off-by: Lei Xu b33...@freescale.com
 Signed-off-by: Roy Zang tie-fei.z...@freescale.com
 Signed-off-by: Kumar Gala ga...@kernel.crashing.org
 ---
  drivers/mmc/host/sdhci-of-core.c |    3 ++
  drivers/mmc/host/sdhci.c         |   62 ++---
  include/linux/mmc/sdhci.h        |    6 ++-
  3 files changed, 57 insertions(+), 14 deletions(-)

 diff --git a/drivers/mmc/host/sdhci-of-core.c 
 b/drivers/mmc/host/sdhci-of-core.c
 index 60e4186..fede43d 100644
 --- a/drivers/mmc/host/sdhci-of-core.c
 +++ b/drivers/mmc/host/sdhci-of-core.c
 @@ -179,6 +179,9 @@ static int __devinit sdhci_of_probe(struct 
 platform_device *ofdev)
        if (sdhci_of_wp_inverted(np))
                host-quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;

 +       if (of_device_is_compatible(np, fsl,esdhc))
 +               host-quirks |= SDHCI_QUIRK_QORIQ_PROCTL_WEIRD;
 +
        clk = of_get_property(np, clock-frequency, size);
        if (clk  size == sizeof(*clk)  *clk)
                of_host-clock = be32_to_cpup(clk);
 diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
 index 58d5436..77174e5 100644
 --- a/drivers/mmc/host/sdhci.c
 +++ b/drivers/mmc/host/sdhci.c
 @@ -674,7 +674,7 @@ static void sdhci_set_transfer_irqs(struct sdhci_host 
 *host)
  static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command 
 *cmd)
  {
        u8 count;
 -       u8 ctrl;
 +       u32 ctrl;
        struct mmc_data *data = cmd-data;
        int ret;

 @@ -807,14 +807,28 @@ static void sdhci_prepare_data(struct sdhci_host *host, 
 struct mmc_command *cmd)
         * is ADMA.
         */
        if (host-version = SDHCI_SPEC_200) {
 -               ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 -               ctrl = ~SDHCI_CTRL_DMA_MASK;
 -               if ((host-flags  SDHCI_REQ_USE_DMA) 
 -                       (host-flags  SDHCI_USE_ADMA))
 -                       ctrl |= SDHCI_CTRL_ADMA32;
 -               else
 -                       ctrl |= SDHCI_CTRL_SDMA;
 -               sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 +               if (host-quirks  SDHCI_QUIRK_QORIQ_PROCTL_WEIRD) {
 +#define ESDHCI_PROCTL_DMAS_MASK                0x0300
 +#define ESDHCI_PROCTL_ADMA32           0x0200
 +#define ESDHCI_PROCTL_SDMA             0x

Breaks the code flow / readability. Can be moved to top of the file ?

 +                       ctrl = sdhci_readl(host, SDHCI_HOST_CONTROL);
 +                       ctrl = ~ESDHCI_PROCTL_DMAS_MASK;
 +                       if ((host-flags  SDHCI_REQ_USE_DMA) 
 +                               (host-flags  SDHCI_USE_ADMA))
 +                               ctrl |= ESDHCI_PROCTL_ADMA32;
 +                       else
 +                               ctrl |= ESDHCI_PROCTL_SDMA;
 +                       sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL);
 +               } else {
 +                       ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 +                       ctrl = ~SDHCI_CTRL_DMA_MASK;
 +                       if ((host-flags  SDHCI_REQ_USE_DMA) 
 +                               (host-flags  SDHCI_USE_ADMA))
 +                               ctrl |= SDHCI_CTRL_ADMA32;
 +                       else
 +                               ctrl |= SDHCI_CTRL_SDMA;
 +                       sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 +               }
        }

        if (!(host-flags  SDHCI_REQ_USE_DMA)) {
 @@ -1138,19 +1152,32 @@ out:
  static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
  {
        u8 pwr = 0;
 +       u8 volt = 0;

        if (power != (unsigned short)-1) {
                switch (1  power) {
 +#define        

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

2011-07-05 Thread Eric Miao
On Fri, Apr 29, 2011 at 4:45 AM, Philip Rakity prak...@marvell.com wrote:

 Support multiple sd/eMMC interfaces. enable mmc1, 2, and 3.
 mmc2 is used eMMC and slot is marked PERMANENT and 8 bit device.
 mmc1 is used for Wifi and slot is marked PERMANENT

 Note: eMMC (mmc2) is set to initialize first to workaround a problem
 where booting in logical order requires mmc create work queue
 to be multi-threaded otherwise boot process hangs.  BUG report
 send to linux-mmc and linux-kernel mailing list.

 Wifi (mmc1) requires we enable power on the device by toggling
 the gpio lines for power and reset.

 Signed-off-by: Philip Rakity prak...@marvell.com

Applied. Though the email client was fiddling the spaces/CR-LF a bit.

 ---
  arch/arm/mach-mmp/brownstone.c |   52 
 +++-
  1 files changed, 51 insertions(+), 1 deletions(-)

 diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
 index 7bb78fd..577e8de 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
 @@ -177,9 +178,56 @@ static struct i2c_board_info brownstone_twsi1_info[] = {
  };

  static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
 -       .max_speed      = 2500,
 +       .adjust_clocks  = 1,
 +       .clk_select     = 1,
 +       .clk_delay      = 31,
  };

 +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = {
 +       .adjust_clocks  = 1,
 +       .clk_select     = 1,
 +       .clk_delay      = 15,
 +       .flags          = PXA_FLAG_CARD_PERMANENT,
 +};
 +
 +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
 +       .adjust_clocks  = 1,
 +       .clk_select     = 1,
 +       .clk_delay      = 31,
 +       .flags          = PXA_FLAG_CARD_PERMANENT |
 +                               PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
 +};
 +
 +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, 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 */
 +}
 +
  static void __init brownstone_init(void)
  {
        mfp_config(ARRAY_AND_SIZE(brownstone_pin_config));
 @@ -188,7 +236,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(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] arm: mach-mmp: brownstone.c support multiple sd slots

2011-07-05 Thread zhangfei gao
On Tue, Jul 5, 2011 at 2:52 PM, Eric Miao eric.y.m...@gmail.com wrote:
 On Fri, Apr 29, 2011 at 4:45 AM, Philip Rakity prak...@marvell.com wrote:

 Support multiple sd/eMMC interfaces. enable mmc1, 2, and 3.
 mmc2 is used eMMC and slot is marked PERMANENT and 8 bit device.
 mmc1 is used for Wifi and slot is marked PERMANENT

 Note: eMMC (mmc2) is set to initialize first to workaround a problem
 where booting in logical order requires mmc create work queue
 to be multi-threaded otherwise boot process hangs.  BUG report
 send to linux-mmc and linux-kernel mailing list.

 Wifi (mmc1) requires we enable power on the device by toggling
 the gpio lines for power and reset.

 Signed-off-by: Philip Rakity prak...@marvell.com

 Applied. Though the email client was fiddling the spaces/CR-LF a bit.

 ---
  arch/arm/mach-mmp/brownstone.c |   52 
 +++-
  1 files changed, 51 insertions(+), 1 deletions(-)


Hi, Eric

arch/arm/mach-mmp/brownstone.c has already been modified from
mmc-next, here will have conflict.
Sorry for inconvenience.

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

2011-07-05 Thread Eric Miao
On Tue, Jul 5, 2011 at 3:05 PM, zhangfei gao zhangfei@gmail.com wrote:
 On Tue, Jul 5, 2011 at 2:52 PM, Eric Miao eric.y.m...@gmail.com wrote:
 On Fri, Apr 29, 2011 at 4:45 AM, Philip Rakity prak...@marvell.com wrote:

 Support multiple sd/eMMC interfaces. enable mmc1, 2, and 3.
 mmc2 is used eMMC and slot is marked PERMANENT and 8 bit device.
 mmc1 is used for Wifi and slot is marked PERMANENT

 Note: eMMC (mmc2) is set to initialize first to workaround a problem
 where booting in logical order requires mmc create work queue
 to be multi-threaded otherwise boot process hangs.  BUG report
 send to linux-mmc and linux-kernel mailing list.

 Wifi (mmc1) requires we enable power on the device by toggling
 the gpio lines for power and reset.

 Signed-off-by: Philip Rakity prak...@marvell.com

 Applied. Though the email client was fiddling the spaces/CR-LF a bit.

 ---
  arch/arm/mach-mmp/brownstone.c |   52 
 +++-
  1 files changed, 51 insertions(+), 1 deletions(-)


 Hi, Eric

 arch/arm/mach-mmp/brownstone.c has already been modified from
 mmc-next, here will have conflict.
 Sorry for inconvenience.

'K, I'll drop it then.


 Thanks

--
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: irq flood with mmc boot partitions on s3c2416 with 3.0rc1

2011-07-05 Thread Heiko Stübner
Hi again,

sorry for having taken so long, but university-work called :-)

Am Montag 20 Juni 2011, 21:34:53 schrieb Andrei Warkentin:
 On Sun, Jun 19, 2011 at 9:23 AM, Heiko Stübner he...@sntech.de wrote:
  Am Samstag 18 Juni 2011, 22:56:11 schrieb Daniel Mack:
 The log you sent out seems a bit short (it's covers  1s of boot time
 - usb0: no IPv6 routers present is the last line ). Can you send -
 1) A full log with errors without any of my patches.
 2) A full log with just the first patch.
 3) A full log with just the second patch.
I have attached a log with mmc-debugging enabled. 
The relevant parts start around line 2634 (waiting for /dev to be fully 
populated - the udev start). The culprit (Hynix-nand) is mmc1.

Switching the patches on and off will have to wait until the weekend. But I can 
say the error (irq message and register dump [and them looping endlessly]) has 
not not changed from before your patches.

I'm curious, is mmc_blk_resume (which is modified by your second patch) called 
at other times than when waking up from system suspend? [i.e. during system 
startup]

 I'm interested in knowing what the pattern of access to boot0 and
 boot1 is that causes these failures - does it only report I/O errors
 for for certain blocks (say, above some number) or for all of them.
it doesn't report io-errors at all. It send endless loops of CMD13 calls with 
the same argument and receives interrupts it does not expect :-)


Thanks again for your time
Heiko


dmesg-debug_20110629.txt.gz
Description: GNU Zip compressed data


Re: [PATCH 3/3] eSDHC: fix incorrect default value of the capabilities register on P4080

2011-07-05 Thread Anton Vorontsov
On Tue, Jul 05, 2011 at 12:19:03PM +0800, Roy Zang wrote:
 P4080 eSDHC errata 12 describes incorrect default value of the
 the host controller capabilities register.
 
 The default value of the VS18 and VS30 fields in the host controller
 capabilities register (HOSTCAPBLT) are incorrect. The default of these bits
 should be zero instead of one in the eSDHC logic.
 
 This patch adds the workaround for these errata.
 
 Signed-off-by: Roy Zang tie-fei.z...@freescale.com
 ---
  drivers/mmc/host/sdhci-of-core.c |3 +++
  drivers/mmc/host/sdhci.c |6 ++
  include/linux/mmc/sdhci.h|4 
  3 files changed, 13 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/mmc/host/sdhci-of-core.c 
 b/drivers/mmc/host/sdhci-of-core.c
 index fede43d..9bdd30d 100644
 --- a/drivers/mmc/host/sdhci-of-core.c
 +++ b/drivers/mmc/host/sdhci-of-core.c
 @@ -182,6 +182,9 @@ static int __devinit sdhci_of_probe(struct 
 platform_device *ofdev)
   if (of_device_is_compatible(np, fsl,esdhc))
   host-quirks |= SDHCI_QUIRK_QORIQ_PROCTL_WEIRD;
  
 + if (of_device_is_compatible(np, fsl,p4080-esdhc))
 + host-quirks |= SDHCI_QUIRK_QORIQ_HOSTCAPBLT_ONLY_VS33;

Should really use voltage-ranges, not quirks.

http://www.spinics.net/lists/linux-mmc/msg02785.html

Thanks,

-- 
Anton Vorontsov
Email: cbouatmai...@gmail.com
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2011-07-05 Thread Russell King - ARM Linux
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
--
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 2/4] mmci: adjust calculation of f_min

2011-07-05 Thread Russell King - ARM Linux
On Tue, Jun 28, 2011 at 09:57:33AM +0200, Linus Walleij wrote:
 From: Ulf Hansson ulf.hans...@stericsson.com
 
 For the st_clkdiv variant f_min is too low for practical cases,
 there is a heuristic calculation that appear to set the min
 frequency to mclk rounded up with 512, for our practical use
 cases dividing by 257 gives a reasonable floor value on the
 ST Micro version of the clock divider.

The only requirement with f_min is that the hardware is capable of
producing a clock at that rate.  Having it smaller than 'practical'
is not a problem, and may help some cards be detected.

The core tries clocks at 400kHz, 300, 200 and 100kHz during probe,
and that's the lowest frequency that will be attempted (provided
the card doesn't actualy say it wants something slower.)

So unless there is a reason not to (eg, divisors above 257 are invalid)
its better to leave it as is.
--
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 3/4] mmci: sync DATAEND irq with dma|pio transfer done

2011-07-05 Thread Russell King - ARM Linux
On Tue, Jun 28, 2011 at 09:57:40AM +0200, Linus Walleij wrote:
 From: Ulf Hansson ulf.hans...@stericsson.com
 
 The end of a dma|pio data transfer is synced with the
 DATAEND irq. This will prevent the mmci driver from ending
 the request before the dma|pio job is completely done.
 
 For dma we use DMA_PREP_INTERRUPT to register a callback
 function which is called when dma driver is done with job.
 
 To also make sure we prevent hanging forever, waiting for
 DATAEND irq or a dma|pio transfer to be done, we setup a timer
 when either a DATAEND or dma|pio job is done. Once both
 conditions have occured, the timer is cancelled and the data
 transfer is completed.
 
 If a timeout occurs, the data transfer is terminated in a
 controlled manner and EAGAIN is returned to the framework.
 A timeout value of 50 ms has been found to work well for
 our usecases.

What is the framework supposed to do with that error code?  Magic the
driver into disabling DMA by some non-existant callback?

Please, stop introducing magic new error codes which have no meaning to
the upper levels unless you're also going to add some handling of those
error conditions as well.
--
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] mmc: enable background operations for emmc4.41 with HPI support

2011-07-05 Thread Hanumath Prasad
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
+ *
+ * Send HPI command to interrupt ongoing background operations,
+ * to allow rapid servicing of foreground operations,e.g. read/
+ * writes. Wait until the card comes out of 

OMAP HS-MMC: convert to dev_pm_ops broke hibernation

2011-07-05 Thread Matthieu CASTET
Hi,

commit a791daa15305e7e549a418ef0ae6bc4b4580066e converted PM operations to use
dev_pm_ops. But this broke hibernation/suspend to disk :
- now there no state argument
- but there is one call back per state :
-- suspend/resume for s2ram
-- freeze/thaw poweroff/restore for s2disk

look like most of the mmc driver using dev_pm_ops got the same problem (only
jz4740_mmc define poweroff/restore)


Matthieu
--
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] mmc: documentation of mmc non-blocking request usage and design.

2011-07-05 Thread Per Forlin
Documentation about the background and the design of mmc non-blocking.
Host driver guide lines to minimize request preparation over head.

Signed-off-by: Per Forlin per.for...@linaro.org
---
 Documentation/mmc/00-INDEX  |2 +
 Documentation/mmc/mmc-async-req.txt |   85 +++
 2 files changed, 87 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..11bc2cf 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 request
diff --git a/Documentation/mmc/mmc-async-req.txt 
b/Documentation/mmc/mmc-async-req.txt
new file mode 100644
index 000..d139a51
--- /dev/null
+++ b/Documentation/mmc/mmc-async-req.txt
@@ -0,0 +1,85 @@
+Rationale
+=
+
+How significant is the cache maintenance over head?
+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 is done in parallel to 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 a mmc request ends and another mmc request begins.
+Using mmc_wait_for_req() the MMC controller is idle when dma_map_sg and
+dma_unmap_sg is processing. Using non-blocking mmc request makes it
+possible to prepare the caches for next job in parallel to 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 is 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 to the transfer performance wont 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()
+Is starts a new MMC command request for a host. The function isn't
+truely non-blocking. If there is on ongoing async request it waits
+for completion of that request and starts the new one and return. 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 to 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 over head:
+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_2st_chunk_for_dma(req)
+/*
+ * The second issue_pending should be called before MMC runs out
+ * of the first chunk. If the MMC runs out of the first data chunk before
+ * this call, the transfer is delayed.
+ */
+dma_issue_pending(req-dma_desc);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message 

[PATCH v2 0/3] Add device tree probe for sdhci-esdhc-imx

2011-07-05 Thread Shawn Guo
The first patch removes the uses of cpu_is_mx(), the second one makes
a dt related fix on sdhci-pltfm.c, and the third one adds device tree
probe for sdhci-esdhc-imx driver.

Changes since v1:
 * Address review comments given by Grant

Shawn Guo (3):
  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  |   40 ++
 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 |  144 ++--
 drivers/mmc/host/sdhci-pltfm.c |3 +-
 9 files changed, 202 insertions(+), 33 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/3] mmc: sdhci-esdhc-imx: get rid of the uses of cpu_is_mx()

2011-07-05 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
---
 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 a65838f..2955afa 100644
--- a/arch/arm/mach-imx/clock-imx25.c
+++ b/arch/arm/mach-imx/clock-imx25.c
@@ -300,8 +300,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 5a4cc1e..2f80f14 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 699b0d2..fd60e2c 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -1453,10 +1453,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)
@@ -1480,10 +1480,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, sdhci-esdhc-imx51.0),
+   REGULATOR_SUPPLY(vmmc, 

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

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

2011-07-05 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  |   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.
+
+Examples:
+
+esdhc@70004000 {
+   compatible = fsl,imx51-esdhc;
+   reg = 0x70004000 0x4000;
+   interrupts = 1;
+   fsl,cd-type = controller;
+   fsl,wp-type = controller;
+};
+
+esdhc@70008000 {
+   compatible = fsl,imx51-esdhc;
+   reg = 0x70008000 0x4000;
+   interrupts = 2;
+   fsl,cd-type = gpio;
+   fsl,wp-type = gpio;
+   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 1edda29..593d6b9 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
@@ -72,6 +75,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;
@@ -305,24 +316,96 @@ static irqreturn_t cd_irq(int irq, void *data)
return IRQ_HANDLED;
 };
 
+#ifdef CONFIG_OF
+static const char *cd_types[] = {
+   [ESDHC_CD_NONE] = none,
+   [ESDHC_CD_CONTROLLER]   = controller,
+   [ESDHC_CD_GPIO] = gpio,
+   [ESDHC_CD_PERMANENT]= permanent,
+};
+
+static const char *wp_types[] = {
+   [ESDHC_WP_NONE] = none,
+   [ESDHC_WP_CONTROLLER]   = controller,
+   [ESDHC_WP_GPIO] = gpio,
+};
+
+static int __devinit sdhci_esdhc_imx_probe_dt(struct platform_device *pdev)
+{
+   const struct of_device_id *of_id =
+   of_match_device(imx_esdhc_dt_ids, pdev-dev);
+   struct device_node *np = pdev-dev.of_node;
+   struct esdhc_platform_data *boarddata;
+   int err, i;
+   const char *cd, *wp;
+
+   if (!np)
+   return -ENODEV;
+
+   boarddata = kzalloc(sizeof(*boarddata), GFP_KERNEL);
+   if (!boarddata)
+   return -ENOMEM;
+   pdev-dev.platform_data = boarddata;
+
+   err = of_property_read_string(np, fsl,cd-type, cd);
+   if (err)
+   return err;
+   for (i = 0; i  ARRAY_SIZE(cd_types); i++)
+   if (!strcasecmp(cd, cd_types[i])) {
+   boarddata-cd_type = i;
+   break;
+   }
+
+   err = of_property_read_string(np, fsl,wp-type, wp);
+   if (err)
+   return err;
+   for (i = 0; i  ARRAY_SIZE(wp_types); i++)
+   if (!strcasecmp(wp, wp_types[i])) {
+   boarddata-wp_type = i;
+   break;
+   }
+
+   boarddata-cd_gpio = of_get_gpio(np, 0);
+   boarddata-wp_gpio = of_get_gpio(np, 1);

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

2011-07-05 Thread Chris Ball
Hi Per, minor proofreading,

On Tue, Jul 05 2011, Per Forlin wrote:
 Documentation about the background and the design of mmc non-blocking.
 Host driver guide lines to minimize request preparation over head.

guidelines, overhead


 Signed-off-by: Per Forlin per.for...@linaro.org
 ---
  Documentation/mmc/00-INDEX  |2 +
  Documentation/mmc/mmc-async-req.txt |   85 
 +++
  2 files changed, 87 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..11bc2cf 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 request
 diff --git a/Documentation/mmc/mmc-async-req.txt 
 b/Documentation/mmc/mmc-async-req.txt
 new file mode 100644
 index 000..d139a51
 --- /dev/null
 +++ b/Documentation/mmc/mmc-async-req.txt
 @@ -0,0 +1,85 @@
 +Rationale
 +=
 +
 +How significant is the cache maintenance over head?

overhead

 +It depends, fast eMMC and multiple cache levels with speculative cache 
 pre-fetch

This line is over 80 cols.  Please wrap at around 76 cols.

 +makes the cache overhead relatively significant. If the DMA preparations
 +for the next request is done in parallel to the current transfer

are done

 +the DMA preparation overhead would not affect the MMC performance.
 +The intention of non-blocking (asynchronous) mmc requests is to minimize the
 +time between a mmc request ends and another mmc request begins.

between when an

 +Using mmc_wait_for_req() the MMC controller is idle when dma_map_sg and

s/when/while/

 +dma_unmap_sg is processing. Using non-blocking mmc request makes it

requests

 +possible to prepare the caches for next job in parallel to 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 is 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 to the transfer performance wont 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()
 +Is starts a new MMC command request for a host. The function isn't

s/Is/It/

 +truely non-blocking. If there is on ongoing async request it waits

truly

 +for completion of that request and starts the new one and return. It

start

 +Doesn't wait for the new request to complete. If there is no ongoing

s/Doesn't/doesn't/

 +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 to 
 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 over head:

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);
 +
 +

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

2011-07-05 Thread Shawn Guo
On Mon, Jul 04, 2011 at 12:25:48AM -0600, Grant Likely wrote:
 On Sun, Jul 03, 2011 at 04:30:51PM +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
  ---
   .../devicetree/bindings/mmc/fsl-imx-esdhc.txt  |   40 
   drivers/mmc/host/sdhci-esdhc-imx.c |   99 
  +++-
   2 files changed, 134 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..e182e7c
  --- /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:
 
 Similar to previous comments, use the fsl, prefix to this property name.
 
I did not know even property name could be written like this.  I tried
it and found it works :)

  +none : No CD
  +controller : Uses eSDHC controller internal CD signal
  +gpio : Uses GPIO pin for CD
 
 I would say the presence of a cd-gpios property would implicitly
 mean gpio is to be used for the CD pin.
 
Yes, you are right.  But I would say this is a direct translation of
the existing platform_data.  After all, we are sharing most of code
path between platform and dt.

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

2011-07-05 Thread Grant Likely
On Tue, Jul 5, 2011 at 9:35 AM, Shawn Guo shawn@freescale.com wrote:
 On Mon, Jul 04, 2011 at 12:25:48AM -0600, Grant Likely wrote:
  +    none : No CD
  +    controller : Uses eSDHC controller internal CD signal
  +    gpio : Uses GPIO pin for CD

 I would say the presence of a cd-gpios property would implicitly
 mean gpio is to be used for the CD pin.

 Yes, you are right.  But I would say this is a direct translation of
 the existing platform_data.  After all, we are sharing most of code
 path between platform and dt.

Meh, that's just implementation detail and the DT bindings should
*not* be focused on what Linux happens to currently do.  Define a
binding that makes sense first and foremost, and then make the driver
use it.

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


Re: [PATCHv4 0/3] OMAP: HSMMC: cleanup and runtime pm

2011-07-05 Thread Kevin Hilman
S, Venkatraman svenk...@ti.com writes:

 From: Kevin Hilman khil...@ti.com
 Date: Fri, Jul 1, 2011 at 11:24 PM
 Subject: Re: [PATCHv4 0/3] OMAP: HSMMC: cleanup and runtime pm
 To: c...@laptop.org
 Cc: Balaji T K balaj...@ti.com, linux-o...@vger.kernel.org,
 linux-mmc@vger.kernel.org, t...@atomide.com, madhu...@ti.com,
 b-cous...@ti.com, p...@pwsan.com, kishore.kadiy...@ti.com


 Chris,

 Balaji T K balaj...@ti.com writes:

 Removing the custom state machine - lazy disable framework in
 omap_hsmmc to make way for runtime pm to handle host controller power
 states.

 This allows mmc_host_enable/mmc_host_disable to be replaced
 by runtime get_sync and put_sync at host controller driver.

 Enable runtime PM in omap_hsmmc

 Rebased to MMC tree : mmc-next branch
 Tested on OMAP4430SDP, OMAP3430SDP, OMAP2430SDP

 Reviewed-by: Kevin Hilman khil...@ti.com
 Tested-by: Kevin Hilman khil...@ti.com

 Could you queue this series for the v3.1 merge window?  Or, with your
 ack, we are happy to take this through the OMAP tree along with the
 other dependecies mentioned below.

 I've also tested this on OMAP4430/Blaze, OMAP3630/Zoom3 and
 OMAP3430/n900.

 We have OMAP PM core code changes queued for v3.1 which require the MMC
 driver to correctly use runtime PM or we can get hangs if MMC is used
 during boot.

 Kevin

 Kevin,
   Another series from Per Forlin [1] is also modifying the same file,
 and might result in merge conflict if this series is queued under OMAP
 and the other is queued by Chris.

OK, then Chris should take this series through his tree.

Thanks,

Kevin

 Chris,
   If you intend to queue [1] into mmc-next, Balaji / myself can repost
 this series on
 top of it or you'd like to practice some git merge ? Let me know if
 there is anything that I can do to help.

 [1] https://lkml.org/lkml/2011/7/1/303


 MMC runtime patch has dependency on
 [PATCH 0/6] OMAP2+: hwmod framework fixes [1]
 for MMC1/MMC2 clock to get ungated after idle in OMAP4.

 Without [1] patches, MMC1/MMC2 fails to get detected on OMAP4.

 [1] http://www.mail-archive.com/linux-omap@vger.kernel.org/msg51457.html

 Balaji T K (3):
   MMC: OMAP: HSMMC: Remove lazy_disable
   MMC: OMAP: HSMMC: add runtime pm support
   MMC: OMAP: HSMMC: Remove unused iclk

  drivers/mmc/host/omap_hsmmc.c |  365 
 +++--
  1 files changed, 57 insertions(+), 308 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


Re: [PATCH v2 1/3] mmc: sdhci-esdhc-imx: get rid of the uses of cpu_is_mx()

2011-07-05 Thread Grant Likely
On Tue, Jul 5, 2011 at 9:26 AM, Shawn Guo shawn@linaro.org wrote:
 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 a65838f..2955afa 100644
 --- a/arch/arm/mach-imx/clock-imx25.c
 +++ b/arch/arm/mach-imx/clock-imx25.c
 @@ -300,8 +300,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 5a4cc1e..2f80f14 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 699b0d2..fd60e2c 100644
 --- a/arch/arm/mach-mx5/clock-mx51-mx53.c
 +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
 @@ -1453,10 +1453,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)
 @@ -1480,10 +1480,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[] = {
 - 

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

2011-07-05 Thread Grant Likely
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?)  :-)

 +
 +Examples:
 +
 +esdhc@70004000 {
 +       compatible = fsl,imx51-esdhc;
 +       reg = 0x70004000 0x4000;
 +       interrupts = 1;
 +       fsl,cd-type = controller;
 +       fsl,wp-type = controller;
 +};
 +
 +esdhc@70008000 {
 +       compatible = fsl,imx51-esdhc;
 +       reg = 0x70008000 0x4000;
 +       interrupts = 2;
 +       fsl,cd-type = gpio;
 +       fsl,wp-type = gpio;
 +       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 1edda29..593d6b9 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
 @@ -72,6 +75,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;
 @@ -305,24 +316,96 @@ static irqreturn_t cd_irq(int irq, void *data)
        return IRQ_HANDLED;
  };

 +#ifdef CONFIG_OF
 +static const char *cd_types[] = {
 +       [ESDHC_CD_NONE]         = none,
 +       [ESDHC_CD_CONTROLLER]   = controller,
 +       [ESDHC_CD_GPIO]         = gpio,
 +       [ESDHC_CD_PERMANENT]    = permanent,
 +};
 +
 +static const char *wp_types[] = {
 +       [ESDHC_WP_NONE]         = none,
 +       [ESDHC_WP_CONTROLLER]   = controller,
 +       [ESDHC_WP_GPIO]         = gpio,
 +};
 +
 +static int __devinit sdhci_esdhc_imx_probe_dt(struct platform_device *pdev)
 +{
 +       const struct of_device_id *of_id =
 +                       of_match_device(imx_esdhc_dt_ids, pdev-dev);
 +       struct device_node *np = pdev-dev.of_node;
 +       struct esdhc_platform_data *boarddata;
 +       int err, i;
 +       const char *cd, *wp;
 +
 +       if (!np)
 +               return -ENODEV;
 +
 +       boarddata = kzalloc(sizeof(*boarddata), GFP_KERNEL);
 +       if (!boarddata)
 +               return -ENOMEM;
 +       pdev-dev.platform_data = boarddata;

This is illegal.  As far as device drivers are concerned,
pdev-dev.platform_data is immutable 

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

2011-07-05 Thread Per Forlin
On 5 July 2011 17:24, Chris Ball c...@laptop.org wrote:
 Hi Per, minor proofreading,

Hi Chris,

Thanks for all your comments. I'll update and send out a v2.

Thanks,
Per
--
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] documentation of mmc non-blocking request

2011-07-05 Thread Per Forlin
changes since v1:
 * Minor updates after proofreading comments from Chris

Per Forlin (1):
  mmc: documentation of mmc non-blocking request usage and design.

 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

-- 
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 v2] mmc: documentation of mmc non-blocking request usage and design.

2011-07-05 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
---
 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..11bc2cf 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 request
diff --git a/Documentation/mmc/mmc-async-req.txt 
b/Documentation/mmc/mmc-async-req.txt
new file mode 100644
index 000..ff1e66f
--- /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 to 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 is processing. Using non-blocking mmc requests makes it
+possible to prepare the caches for next job in parallel to 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 is 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 to the transfer performance wont 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 start the new one and return. 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 to
+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 before MMC runs out
+ * of the first chunk. If the MMC runs out of the first data chunk
+ * before this call, the transfer is delayed.
+ */
+dma_issue_pending(req-dma_desc);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a 

[PATCH v3] documentation of mmc non-blocking request

2011-07-05 Thread Per Forlin
changes since v2:
 * Minor updates after more comments from Chris

Per Forlin (1):
  mmc: documentation of mmc non-blocking request usage and design.

 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

-- 
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] mmc: documentation of mmc non-blocking request usage and design.

2011-07-05 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
---
 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..11bc2cf 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 request
diff --git a/Documentation/mmc/mmc-async-req.txt 
b/Documentation/mmc/mmc-async-req.txt
new file mode 100644
index 000..d7e7698
--- /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 to 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 is processing. Using non-blocking mmc requests makes it
+possible to prepare the caches for next job in parallel to 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 is 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 to the transfer performance wont 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 to
+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 before MMC runs out
+ * of the first chunk. If the MMC runs out of the first data chunk
+ * before this call, the transfer is delayed.
+ */
+dma_issue_pending(req-dma_desc)
-- 
1.7.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a 

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

2011-07-05 Thread Philip Rakity
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 */
+}
+
 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


On Jul 5, 2011, at 12:20 AM, Eric Miao wrote:

 On Tue, Jul 5, 2011 at 3:05 PM, zhangfei gao zhangfei@gmail.com wrote:
 On Tue, Jul 5, 2011 at 2:52 PM, Eric Miao eric.y.m...@gmail.com wrote:
 On Fri, Apr 29, 2011 at 4:45 AM, Philip Rakity prak...@marvell.com wrote:
 
 Support multiple sd/eMMC interfaces. enable mmc1, 2, and 3.
 mmc2 is used eMMC and slot is marked PERMANENT and 8 bit device.
 mmc1 is used for Wifi and slot is marked PERMANENT
 
 Note: eMMC (mmc2) is set to initialize first to workaround a problem
 where booting in logical order requires mmc create work queue
 to be multi-threaded otherwise boot process hangs.  BUG report
 send to linux-mmc and linux-kernel mailing list.
 
 Wifi (mmc1) requires we enable power on the device by toggling
 the gpio lines for power and reset.
 
 Signed-off-by: Philip Rakity prak...@marvell.com
 
 Applied. Though the email client was fiddling the spaces/CR-LF a bit.
 
 ---
  arch/arm/mach-mmp/brownstone.c |   52 
 +++-
  1 files changed, 51 insertions(+), 1 deletions(-)
 
 
 Hi, Eric
 
 arch/arm/mach-mmp/brownstone.c has already been modified from
 mmc-next, here will have conflict.
 Sorry for inconvenience.
 
 'K, I'll drop it then.
 
 
 Thanks
 

--
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] mmc: documentation of mmc non-blocking request usage and design.

2011-07-05 Thread Randy Dunlap
On Tue,  5 Jul 2011 21:43:28 +0200 Per Forlin wrote:

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

It would be better to omit the introductory email and put all of its comments
in this one [PATCH] email.


  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..11bc2cf 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 request

  requests


 diff --git a/Documentation/mmc/mmc-async-req.txt 
 b/Documentation/mmc/mmc-async-req.txt
 new file mode 100644
 index 000..d7e7698
 --- /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

   It depends:
or
   It depends. Fast

 +pre-fetch makes the cache overhead relatively significant. If the DMA
 +preparations for the next request are done in parallel to the current

  with the current

 +transfer the DMA preparation overhead would not affect the MMC performance.

   transfer,

 +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

 mmc_wait_for_req(),

 +dma_unmap_sg is processing. Using non-blocking mmc requests makes it

are processing.

 +possible to prepare the caches for next job in parallel to an active

   with an active

 +mmc request.
 +
 +MMC block driver
 +
 +
 +The issue_rw_rq() in the mmc block driver is made non-blocking.

preferably: MMC
throughout the file (when not a function or data name, etc.)

 +The increase in throughput is proportional to the time it takes to
 +prepare (major part of preparations is dma_map_sg and dma_unmap_sg)

   are

 +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 to the transfer performance wont be affected.

   withwon't

 +
 +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()

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

  hooks -- pre_req() and post_req() -- that

 +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

DMA

 +the dma_unmap_sg.
 +
 +Optimize for the first request
 +==
 +
 +The first request in a series of requests can't be prepared in parallel to

   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 

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

2011-07-05 Thread Per Forlin
On 5 July 2011 22:27, Randy Dunlap rdun...@xenotime.net wrote:
 On Tue,  5 Jul 2011 21:43:28 +0200 Per Forlin wrote:

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

 It would be better to omit the introductory email and put all of its comments
 in this one [PATCH] email.

I agree. I'll put the changelog after -- to exclude it from the
commit message.
All of your comments will be updated in v4.

Thanks for your comments,
Per
--
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: documentation of mmc non-blocking request usage and design.

2011-07-05 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
---
ChangeLog:
 v2: - Minor updates after proofreading comments from Chris
 v3: - Minor updates after more comments from Chris
 v4: - Minor updates after comments 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..4877f29
--- /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 wont 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 before MMC runs out
+ * of the first chunk. If the MMC runs out of the first data chunk
+ * 

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

2011-07-05 Thread Randy Dunlap
On Tue,  5 Jul 2011 23:35:32 +0200 Per Forlin wrote:

 +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 wont be affected.

 won't

Acked-by: Randy Dunlap rdun...@xenotime.net


thanks.
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
--
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] mmc: sd.c Set Non Default Drive Strength via platform

2011-07-05 Thread Philip Rakity

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 to 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.
There is not mechanism (like ethernet duplex or speed pulses)
to determine what should be done.

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

Signed-off-by: Philip Rakity prak...@marvell.com
---
 drivers/mmc/core/sd.c |   68 -
 1 files changed, 39 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;
 }
-- 
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-05 Thread Kyungmin Park
Hi Hanumath,

First thank you for working this tasks,
HPI  BKOPS is required for eMMC performance and latency.

But before implement these features. we should define what's addressed
by these features.
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.
BKOPS is a feature to give a chance to optimize the internal for next operation.

Current implementation is HPI is used for BKOPS but I think HPI is
used for Write operation to reduce the latency.
There are some reasons.
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.
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.
Related with this, you can find a HPI background and one of possible
solutions in the mmc Spec.
3. real use scenario, realtime class read request has too much latency
since previous write request, (when merge operation is happened eMMC
internally)

With these reason, I hope implement the write HPI first and continue
to work BKOPS support.

Thank you,
Kyungmin Park

On Tue, Jul 5, 2011 at 9:27 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 

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

2011-07-05 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.
 
Sorry. I fixed the example below.  But this one got missed.

 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?)  :-)
 
Ok, I'm getting to know you.

  +
  +Examples:
  +
  +esdhc@70004000 {
  +       compatible = fsl,imx51-esdhc;
  +       reg = 0x70004000 0x4000;
  +       interrupts = 1;
  +       fsl,cd-type = controller;
  +       fsl,wp-type = controller;
  +};
  +
  +esdhc@70008000 {
  +       compatible = fsl,imx51-esdhc;
  +       reg = 0x70008000 0x4000;
  +       interrupts = 2;
  +       fsl,cd-type = gpio;
  +       fsl,wp-type = gpio;
  +       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 1edda29..593d6b9 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
  @@ -72,6 +75,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;
  @@ -305,24 +316,96 @@ static irqreturn_t cd_irq(int irq, void *data)
         return IRQ_HANDLED;
   };
 
  +#ifdef CONFIG_OF
  +static const char *cd_types[] = {
  +       [ESDHC_CD_NONE]         = none,
  +       [ESDHC_CD_CONTROLLER]   = controller,
  +       [ESDHC_CD_GPIO]         = gpio,
  +       [ESDHC_CD_PERMANENT]    = permanent,
  +};
  +
  +static const char *wp_types[] = {
  +       [ESDHC_WP_NONE]         = none,
  +       [ESDHC_WP_CONTROLLER]   = controller,
  +       [ESDHC_WP_GPIO]         = gpio,
  +};
  +
  +static int __devinit sdhci_esdhc_imx_probe_dt(struct platform_device *pdev)
  +{
  +       const struct of_device_id *of_id =
  +                       of_match_device(imx_esdhc_dt_ids, pdev-dev);
  +       struct device_node *np = pdev-dev.of_node;
  +       struct esdhc_platform_data *boarddata;
  +       int err, i;
  +       const char *cd, *wp;
  +
  +       if (!np)
  +