Re: [PATCH] mmc: mxs-mmc: add support for pre_req and post_req

2011-04-21 Thread Shawn Guo
On Wed, Apr 20, 2011 at 05:22:34PM +0200, Per Forlin wrote:
[...]
  Do you have omap_hsmmc and mmci mmc_test result data to share?
 
 I keep the here:
 https://wiki.linaro.org/WorkingGroups/Kernel/Specs/StoragePerfMMC-async-req
 
Actually, I have seen this page before.  I was wondering if you have
mmc_test raw data (test log of cases #37 ~ #40) to share.

-- 
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] mmc: mxs-mmc: add support for pre_req and post_req

2011-04-21 Thread Shawn Guo
On Wed, Apr 20, 2011 at 05:30:22PM +0200, Per Forlin wrote:
[...]
 Remove dma_map and dma_unmap from your host driver and run the tests
 (obviously nonblocking and blocking will have the same results). If
 there is still no performance gain the cache penalty is very small on
 your platform and therefore nonblocking doesn't improve things much.
 Please let me know the result.
 
Sorry, I could not understand.  What's the point to run the test when
the driver is even broken.  The removal of  dma_map_sg and
dma_unmap_sg makes mxs-mmc host driver broken.

-- 
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: CMD23 plumbing and support patchset.

2011-04-21 Thread Andrei Warkentin
Hi Chris,

On Wed, Apr 20, 2011 at 8:44 PM, Chris Ball c...@laptop.org wrote:
 Hi,

 On Sat, Apr 16 2011, Andrei Warkentin wrote:
 This is the third version of the CMD23 plumbing and host driver support
 patch set.

 Changes:
 1) CMD23 support (used for features such as reliable writes) is decoupled
    from general multiblock trans through use of a quirk for affected cards.
 2) Newer Sandisk MMC products are whitelisted along with some known good 
 ones. All other
    MMC products do not use CMD23 for general transfers (seems like safest 
 choice for now).
    SD products unaffected.

 Just gave this a try on SEM04G, which is in the whitelist, but didn't
 see a performance increase (or decrease).  What are you using for a
 testcase?  I'm a little wary of running mmc_test on it.  :)


Can you give me the manufacturing date? This is pretty interesting.

You can see an improvement even if you do something like time block
writes (O_DIRECT | O_SYNC, of course). But after all synthetic tests I
measured the time it took to do 4 SQLite insertions and saw
something like 30% improvement.

A
--
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: CMD23 plumbing and support patchset.

2011-04-21 Thread Andrei Warkentin
On Thu, Apr 21, 2011 at 1:29 AM, Andrei Warkentin andr...@motorola.com wrote:
 Hi Chris,

 On Wed, Apr 20, 2011 at 8:44 PM, Chris Ball c...@laptop.org wrote:
 Hi,

 On Sat, Apr 16 2011, Andrei Warkentin wrote:
 This is the third version of the CMD23 plumbing and host driver support
 patch set.

 Changes:
 1) CMD23 support (used for features such as reliable writes) is decoupled
    from general multiblock trans through use of a quirk for affected cards.
 2) Newer Sandisk MMC products are whitelisted along with some known good 
 ones. All other
    MMC products do not use CMD23 for general transfers (seems like safest 
 choice for now).
    SD products unaffected.

 Just gave this a try on SEM04G, which is in the whitelist, but didn't
 see a performance increase (or decrease).  What are you using for a
 testcase?  I'm a little wary of running mmc_test on it.  :)


 Can you give me the manufacturing date? This is pretty interesting.

 You can see an improvement even if you do something like time block
 writes (O_DIRECT | O_SYNC, of course). But after all synthetic tests I
 measured the time it took to do 4 SQLite insertions and saw
 something like 30% improvement.


And you're trying this on SDHCI I presume, right?

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


[PATCH 2/3 v3] MMC: add runtime and system power-management support to the MMCIF driver

2011-04-21 Thread Guennadi Liakhovetski
Adding support for runtime power-management to the MMCIF driver allows
it to save power as long as no card is present. System-wide power
management has been verified with experimental PM patches on AP4-
based systems.

Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
---
v3: A further improvement over v2, but in any case waiting for a result of 
the runtime PM vs. driver unbinding discussion:

http://thread.gmane.org/gmane.linux.kernel.mmc/7433/focus=7476

specific changes are:

(1) the patch to bus.c is dropped as wrong, instead, platform specific 
runtime PM prototype code has been fixed

(2) consolidated calls to

pm_runtime_put_noidle();
pm_runtime_suspend();

to one call to

pm_runtime_put_sync()

(3) fixed probe() error path.

v2: With this patch and with the patch to mmc/core/bus.c, that I've sent a 
couple of minutes ago

http://article.gmane.org/gmane.linux.kernel.mmc/7433

PM works correctly with all possible modprobe / rmmod, card-insert / 
eject, and STR scenarios, that I could come up with. The part in 
sh_mmcif_remove() is a bit rough though...

 drivers/mmc/host/sh_mmcif.c |   69 --
 1 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index d3871b6..1889d64 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -29,6 +29,7 @@
 #include linux/mmc/sh_mmcif.h
 #include linux/pagemap.h
 #include linux/platform_device.h
+#include linux/pm_runtime.h
 #include linux/spinlock.h
 
 #define DRIVER_NAMEsh_mmcif
@@ -173,6 +174,7 @@ struct sh_mmcif_host {
struct completion intr_wait;
enum mmcif_state state;
spinlock_t lock;
+   bool power;
 
/* DMA support */
struct dma_chan *chan_rx;
@@ -877,11 +879,21 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
if (ios-power_mode == MMC_POWER_UP) {
if (p-set_pwr)
p-set_pwr(host-pd, ios-power_mode);
+   if (!host-power) {
+   pm_runtime_get_sync(host-pd-dev);
+   host-power = true;
+   }
} else if (ios-power_mode == MMC_POWER_OFF || !ios-clock) {
/* clock stop */
sh_mmcif_clock_control(host, 0);
-   if (ios-power_mode == MMC_POWER_OFF  p-down_pwr)
-   p-down_pwr(host-pd);
+   if (ios-power_mode == MMC_POWER_OFF) {
+   if (host-power) {
+   pm_runtime_put(host-pd-dev);
+   host-power = false;
+   }
+   if (p-down_pwr)
+   p-down_pwr(host-pd);
+   }
host-state = STATE_IDLE;
return;
}
@@ -1053,6 +1065,12 @@ static int __devinit sh_mmcif_probe(struct 
platform_device *pdev)
sh_mmcif_sync_reset(host);
platform_set_drvdata(pdev, host);
 
+   pm_runtime_enable(pdev-dev);
+   host-power = false;
+   ret = pm_runtime_resume(pdev-dev);
+   if (ret  0)
+   goto clean_up2;
+
/* See if we also get DMA */
sh_mmcif_request_dma(host, pd);
 
@@ -1063,13 +1081,13 @@ static int __devinit sh_mmcif_probe(struct 
platform_device *pdev)
ret = request_irq(irq[0], sh_mmcif_intr, 0, sh_mmc:error, host);
if (ret) {
dev_err(pdev-dev, request_irq error (sh_mmc:error)\n);
-   goto clean_up2;
+   goto clean_up3;
}
ret = request_irq(irq[1], sh_mmcif_intr, 0, sh_mmc:int, host);
if (ret) {
free_irq(irq[0], host);
dev_err(pdev-dev, request_irq error (sh_mmc:int)\n);
-   goto clean_up2;
+   goto clean_up3;
}
 
sh_mmcif_detect(host-mmc);
@@ -1079,7 +1097,12 @@ static int __devinit sh_mmcif_probe(struct 
platform_device *pdev)
sh_mmcif_readl(host-addr, MMCIF_CE_VERSION)  0x);
return ret;
 
+clean_up3:
+   mmc_remove_host(mmc);
+   sh_mmcif_release_dma(host);
+   pm_runtime_suspend(pdev-dev);
 clean_up2:
+   pm_runtime_disable(pdev-dev);
clk_disable(host-hclk);
 clean_up1:
mmc_free_host(mmc);
@@ -1112,15 +1135,53 @@ static int __devexit sh_mmcif_remove(struct 
platform_device *pdev)
 
clk_disable(host-hclk);
mmc_free_host(host-mmc);
+   pm_runtime_put_sync(pdev-dev);
+   pm_runtime_disable(pdev-dev);
+   pm_runtime_get_noresume(pdev-dev);
 
return 0;
 }
 
+#ifdef CONFIG_PM
+static int sh_mmcif_suspend(struct device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev);
+   struct sh_mmcif_host *host = platform_get_drvdata(pdev);
+   int ret = mmc_suspend_host(host-mmc);
+
+   if (!ret) {
+   sh_mmcif_writel(host-addr, 

[PATCH] MMC: tmio: fix a recent regression: restore .set_ios(MMC_POWER_UP) handling

2011-04-21 Thread Guennadi Liakhovetski
The aggressive clock gating for TMIO MMC patch has broken switching
interface power on, using MFD or platform callbacks. Restore the
ios-power_mode == MMC_POWER_UP  ios-clock == 0 case handling.

Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
---

This one should go in 2.6.39

 drivers/mmc/host/tmio_mmc_pio.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 6e3271d..f4fac9f 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -772,15 +772,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
tmio_mmc_set_clock(host, ios-clock);
 
/* Power sequence - OFF - UP - ON */
-   if (ios-power_mode == MMC_POWER_OFF || !ios-clock) {
+   if (ios-power_mode == MMC_POWER_UP) {
+   /* power up SD bus */
+   if (host-set_pwr)
+   host-set_pwr(host-pdev, 1);
+   } else if (ios-power_mode == MMC_POWER_OFF || !ios-clock) {
/* power down SD bus */
if (ios-power_mode == MMC_POWER_OFF  host-set_pwr)
host-set_pwr(host-pdev, 0);
tmio_mmc_clk_stop(host);
-   } else if (ios-power_mode == MMC_POWER_UP) {
-   /* power up SD bus */
-   if (host-set_pwr)
-   host-set_pwr(host-pdev, 1);
} else {
/* start bus clock */
tmio_mmc_clk_start(host);
-- 
1.7.2.5

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


[PATCH 1/2] MMC: protect the tmio_mmc driver against a theoretical race

2011-04-21 Thread Guennadi Liakhovetski
The MMC subsystem does not guarantee, that host driver .request() and
.set_ios() callbacks are serialised. Such concurrent calls, however,
do not have to be meaningfully supported, drivers just have to make
sure to avoid any severe problems.

Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
---
 drivers/mmc/host/tmio_mmc.h |1 +
 drivers/mmc/host/tmio_mmc_pio.c |   62 +++
 2 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 099ed49..f353624 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -19,6 +19,7 @@
 #include linux/highmem.h
 #include linux/mmc/tmio.h
 #include linux/pagemap.h
+#include linux/spinlock.h
 
 /* Definitions for values the CTRL_SDIO_STATUS register can take. */
 #define TMIO_SDIO_STAT_IOIRQ   0x0001
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 62d37de..6e3271d 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -243,8 +243,12 @@ static void tmio_mmc_reset_work(struct work_struct *work)
spin_lock_irqsave(host-lock, flags);
mrq = host-mrq;
 
-   /* request already finished */
-   if (!mrq
+   /*
+* is request already finished? Since we use a non-blocking
+* cancel_delayed_work(), it can happen, that a .set_ios() call preempts
+* us, so, have to check for IS_ERR(host-mrq)
+*/
+   if (IS_ERR_OR_NULL(mrq)
|| time_is_after_jiffies(host-last_req_ts +
msecs_to_jiffies(2000))) {
spin_unlock_irqrestore(host-lock, flags);
@@ -264,16 +268,19 @@ static void tmio_mmc_reset_work(struct work_struct *work)
 
host-cmd = NULL;
host-data = NULL;
-   host-mrq = NULL;
host-force_pio = false;
 
spin_unlock_irqrestore(host-lock, flags);
 
tmio_mmc_reset(host);
 
+   /* Ready for new calls */
+   host-mrq = NULL;
+
mmc_request_done(host-mmc, mrq);
 }
 
+/* called with host-lock held, interrupts disabled */
 static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
 {
struct mmc_request *mrq = host-mrq;
@@ -281,13 +288,15 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host 
*host)
if (!mrq)
return;
 
-   host-mrq = NULL;
host-cmd = NULL;
host-data = NULL;
host-force_pio = false;
 
cancel_delayed_work(host-delayed_reset_work);
 
+   host-mrq = NULL;
+
+   /* FIXME: mmc_request_done() can schedule! */
mmc_request_done(host-mmc, mrq);
 }
 
@@ -685,15 +694,27 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
 static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
struct tmio_mmc_host *host = mmc_priv(mmc);
+   unsigned long flags;
int ret;
 
-   if (host-mrq)
+   spin_lock_irqsave(host-lock, flags);
+
+   if (host-mrq) {
pr_debug(request not null\n);
+   if (IS_ERR(host-mrq)) {
+   spin_unlock_irqrestore(host-lock, flags);
+   mrq-cmd-error = -EAGAIN;
+   mmc_request_done(mmc, mrq);
+   return;
+   }
+   }
 
host-last_req_ts = jiffies;
wmb();
host-mrq = mrq;
 
+   spin_unlock_irqrestore(host-lock, flags);
+
if (mrq-data) {
ret = tmio_mmc_start_data(host, mrq-data);
if (ret)
@@ -708,8 +729,8 @@ static void tmio_mmc_request(struct mmc_host *mmc, struct 
mmc_request *mrq)
}
 
 fail:
-   host-mrq = NULL;
host-force_pio = false;
+   host-mrq = NULL;
mrq-cmd-error = ret;
mmc_request_done(mmc, mrq);
 }
@@ -723,6 +744,29 @@ fail:
 static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
struct tmio_mmc_host *host = mmc_priv(mmc);
+   unsigned long flags;
+
+   spin_lock_irqsave(host-lock, flags);
+   if (host-mrq) {
+   if (IS_ERR(host-mrq)) {
+   dev_dbg(host-pdev-dev,
+   %s.%d: concurrent .set_ios(), clk %u, mode 
%u\n,
+   current-comm, task_pid_nr(current),
+   ios-clock, ios-power_mode);
+   host-mrq = ERR_PTR(-EINTR);
+   } else {
+   dev_dbg(host-pdev-dev,
+   %s.%d: CMD%u active since %lu, now %lu!\n,
+   current-comm, task_pid_nr(current),
+   host-mrq-cmd-opcode, host-last_req_ts, 
jiffies);
+   }
+   spin_unlock_irqrestore(host-lock, flags);
+   return;
+   }
+
+   host-mrq = ERR_PTR(-EBUSY);
+
+   spin_unlock_irqrestore(host-lock, flags);
 
if (ios-clock)

[PATCH 2/2] MMC: add runtime and system power-management support to the TMIO MMCI driver

2011-04-21 Thread Guennadi Liakhovetski
This patch adds a very crude runtime power-management to the TMIO MMC
driver. It only takes care to enable the hardware on probe() and keep
it enabled until remove(), at which time it disables it again. A
finer grained runtime PM would require implementing card detection
support on switched off interface.

System-wide power management has been verified with experimental PM
patches on AP4-based systems.

Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
---

This patch slightly changes driver's PM behaviour also on non-SDHI 
systems, namely, it adds a reset call to the resume path. If this is 
undesired, it can be easily moved to the SDHI-specific part. On SDHI it 
helps to faster recover the controller and avoid failing MMC requests due 
to timing out interrupts, and a repeated request retry from the core.

Runtime PM might change, if the core behaviour changes on driver unbind.

 drivers/mmc/host/sh_mobile_sdhi.c |6 
 drivers/mmc/host/tmio_mmc.c   |   11 ++
 drivers/mmc/host/tmio_mmc.h   |8 +
 drivers/mmc/host/tmio_mmc_pio.c   |   58 +++--
 4 files changed, 73 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c 
b/drivers/mmc/host/sh_mobile_sdhi.c
index cc70123..f60e954 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -143,10 +143,16 @@ static int sh_mobile_sdhi_remove(struct platform_device 
*pdev)
return 0;
 }
 
+static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
+   .suspend = tmio_mmc_host_suspend,
+   .resume = tmio_mmc_host_resume,
+};
+
 static struct platform_driver sh_mobile_sdhi_driver = {
.driver = {
.name   = sh_mobile_sdhi,
.owner  = THIS_MODULE,
+   .pm = tmio_mmc_dev_pm_ops,
},
.probe  = sh_mobile_sdhi_probe,
.remove = __devexit_p(sh_mobile_sdhi_remove),
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index 79c5684..be739f7 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -30,7 +30,7 @@ static int tmio_mmc_suspend(struct platform_device *dev, 
pm_message_t state)
struct mmc_host *mmc = platform_get_drvdata(dev);
int ret;
 
-   ret = mmc_suspend_host(mmc);
+   ret = tmio_mmc_host_suspend(dev-dev);
 
/* Tell MFD core it can disable us now.*/
if (!ret  cell-disable)
@@ -46,15 +46,12 @@ static int tmio_mmc_resume(struct platform_device *dev)
int ret = 0;
 
/* Tell the MFD core we are ready to be enabled */
-   if (cell-resume) {
+   if (cell-resume)
ret = cell-resume(dev);
-   if (ret)
-   goto out;
-   }
 
-   mmc_resume_host(mmc);
+   if (!ret)
+   ret = tmio_mmc_host_resume(dev-dev);
 
-out:
return ret;
 }
 #else
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index f353624..249c724 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -121,4 +121,12 @@ static inline void tmio_mmc_release_dma(struct 
tmio_mmc_host *host)
 }
 #endif
 
+#ifdef CONFIG_PM
+int tmio_mmc_host_suspend(struct device *dev);
+int tmio_mmc_host_resume(struct device *dev);
+#else
+#define tmio_mmc_host_suspend NULL
+#define tmio_mmc_host_resume NULL
+#endif
+
 #endif
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index f4fac9f..d1791ba 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -39,6 +39,7 @@
 #include linux/module.h
 #include linux/pagemap.h
 #include linux/platform_device.h
+#include linux/pm_runtime.h
 #include linux/scatterlist.h
 #include linux/workqueue.h
 #include linux/spinlock.h
@@ -884,12 +885,17 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host 
**host,
else
mmc-ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 
+   pm_runtime_enable(pdev-dev);
+   ret = pm_runtime_resume(pdev-dev);
+   if (ret  0)
+   goto pm_disable;
+
tmio_mmc_clk_stop(_host);
tmio_mmc_reset(_host);
 
ret = platform_get_irq(pdev, 0);
if (ret  0)
-   goto unmap_ctl;
+   goto pm_suspend;
 
_host-irq = ret;
 
@@ -900,7 +906,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host 
**host,
ret = request_irq(_host-irq, tmio_mmc_irq, IRQF_DISABLED |
IRQF_TRIGGER_FALLING, dev_name(pdev-dev), _host);
if (ret)
-   goto unmap_ctl;
+   goto pm_suspend;
 
spin_lock_init(_host-lock);
 
@@ -910,6 +916,9 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host 
**host,
/* See if we also get DMA */
tmio_mmc_request_dma(_host, pdata);
 
+   /* We have to keep the device powered for its card detection to work */
+   pm_runtime_get_noresume(pdev-dev);
+
mmc_add_host(mmc);
 
  

Re: [PATCH 0/5] consolidate sdhci pltfm OF drivers and get them self registered

2011-04-21 Thread Shawn Guo
Hi Wolfram,

Thanks for the review.

On Tue, Apr 19, 2011 at 12:20:31PM +0200, Wolfram Sang wrote:
[...]
 The approach seems sensible, so have a look at my (mostly minor)
 comments inside the patches. However, there is one bigger piece missing.
 You converted all the drivers which had a seperate source-file and
 hooked into sdhci-pltfm.c. However, those are only those users which
 need additional code to work around the quirks. There are also users
 which can take the plain pltfm-driver with a properly set
 platform_data (check the thread [PATCH] mmc: add SDHCI driver for STM
 platforms (V2) for an example). Those have to be converted, too.

Even those drivers need pltfm-something.c to accommodate the
platform_data, right?  I think sdhci-dove.c (sitting on mainline) is
also such an example.  So if I'm not mistaken, I did take care of the
drivers which can take the current plain pltfm-sdhci driver.

 Now the discussion could be if every of those users gets its own
 pltfm-something.c or if we create something similat to
 sdhci-pltfm-generic, which can also be setup with platform_data like the
 old driver (/me likes the latter a bit more. If we don't change the name
 of the driver (not talking about the sourcefile) and keep it
 sdhci-pltfm, then you wouldn't need to change all those users if you
 ensured it behaves the same.
 
Since there are already pltfm-something.c to hold platform_data for
those users anyway, it's not an argument here.

 Also, I think the next version of this series should have all makers of
 a sdhci-pltfm user CCed so we give them a chance to report breakage. Or
 donate acks or tested-by.
 
Ok, will do.

-- 
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 1/5] mmc: sdhci: make sdhci-pltfm device drivers self registered

2011-04-21 Thread Shawn Guo
On Tue, Apr 19, 2011 at 12:20:42PM +0200, Wolfram Sang wrote:
 
 On Fri, Mar 25, 2011 at 04:48:47PM +0800, Shawn Guo wrote:
  The patch turns the common stuff in sdhci-pltfm.c into functions, and
  add device drivers their own .probe and .remove which in turn call
  into the common functions, so that those sdhci-pltfm device drivers
  register itself and keep all device specific things away from common
  sdhci-pltfm file.
  
  Signed-off-by: Shawn Guo shawn@linaro.org
  ---
 
 I'll second the comments from Grant (with one slight exception which is
 noted below)
 
  +static int __devexit sdhci_dove_remove(struct platform_device *pdev)
  +{
  +   struct sdhci_host *host = platform_get_drvdata(pdev);
  +   int dead = 0;
  +   u32 scratch;
  +
  +   scratch = readl(host-ioaddr + SDHCI_INT_STATUS);
  +   if (scratch == (u32)-1)
  +   dead = 1;
 
 I'd prefer
 
   dead = (readl() == 0x);
 
 (or (u32)-1 if you prefer). But keeping a variable 'dead' is more
 descriptive than keeping 'scratch'.
 
Ok.

  +MODULE_LICENSE(GPL v2);
 
 Just to be sure: Did you double-check if the original licenses were v2
 or v2+?
 
It seems to me that sdhci-cns3xxx.c, sdhci-dove.c, sdhci-esdhc-imx.c
and sdhci-tegra.c all use v2.

Actually I do not even know how v2+ is stated.  Do you have an example
for me to refer?

  --- a/drivers/mmc/host/sdhci-pltfm.c
  +++ b/drivers/mmc/host/sdhci-pltfm.c
 
 [...]
 
  -err_add_host:
  -   if (pdata  pdata-exit)
  -   pdata-exit(host);
  -err_plat_init:
  -   iounmap(host-ioaddr);
   err_remap:
  release_mem_region(iomem-start, resource_size(iomem));
   err_request:
  sdhci_free_host(host);
   err:
  -   printk(KERN_ERRProbing of sdhci-pltfm failed: %d\n, ret);
  -   return ret;
  +   pr_err(%s failed %d\n, __func__, ret);
 
 dev_err?
 
Good catch.

  +   return NULL;
   }
   
 
 I didn't pay much attention to the OF version of the tegra driver, since
 it still is not upstream yet, right?
 
Do not worry about that.  You will not see that in the next version,
which will be based on mmc-next.  And tegra OF support should be in
another patch.

-- 
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 2/5] mmc: sdhci: eliminate sdhci_of_host and sdhci_of_data

2011-04-21 Thread Shawn Guo
On Tue, Apr 19, 2011 at 12:20:53PM +0200, Wolfram Sang wrote:
 On Fri, Mar 25, 2011 at 04:48:48PM +0800, Shawn Guo wrote:
  The patch is to migrate the use of sdhci_of_host and sdhci_of_data
  to sdhci_pltfm_host and sdhci_pltfm_data, so that the former pair can
  be eliminated.
  
  Signed-off-by: Shawn Guo shawn@linaro.org
  ---
 
 [...]
 
  diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
  index a3e4be0..12afe86 100644
  --- a/drivers/mmc/host/sdhci-pltfm.h
  +++ b/drivers/mmc/host/sdhci-pltfm.h
  @@ -19,6 +19,10 @@
   struct sdhci_pltfm_host {
  struct clk *clk;
  u32 scratchpad; /* to handle quirks across io-accessor calls */
  +
  +   /* migrate from sdhci_of_host */
  +   unsigned int clock;
  +   u16 xfer_mode_shadow;
 
 xfer_mode_shadow can be merged into scratchpad. They both fix the same
 issue.
 
Yeah.

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


[RFC] MMC: Block: Ensure hardware partitions don't mess with mmcblk device naming.

2011-04-21 Thread Andrei Warkentin
With the hardware partitions support (which represent additional logical devices
present on MMC), devidx does not correspond with index used to form
/dev/mmcblkX names. So use an additional allocated index for device names.

Signed-off-by: Andrei Warkentin andr...@motorola.com
---
 drivers/mmc/card/block.c |   24 +---
 1 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 9e30cf6..5572012 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -75,6 +75,7 @@ static int max_devices;
 
 /* 256 minors, so at most 256 separate devices */
 static DECLARE_BITMAP(dev_use, 256);
+static DECLARE_BITMAP(name_use, 256);
 
 /*
  * There is one mmc_blk_data per slot.
@@ -88,6 +89,7 @@ struct mmc_blk_data {
unsigned intusage;
unsigned intread_only;
unsigned intpart_type;
+   unsigned intname_idx;
 
/*
 * Only set in main mmc_blk_data associated
@@ -776,6 +778,18 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct 
mmc_card *card,
}
 
/*
+* !subname implies we are creating main mmc_blk_data that will be
+* associated with mmc_card with mmc_set_drvdata. Due to device 
partitions,
+* devidx will not coincide with a per-physical card index anymore
+* so we keep track of a name index.
+*/
+   if (!subname)
+   md-name_idx = find_first_zero_bit(name_use, max_devices);
+   else
+   md-name_idx = ((struct mmc_blk_data *)
+   dev_to_disk(parent)-private_data)-name_idx;
+
+   /*
 * Set the read-only status based on the supported commands
 * and the write protect switch.
 */
@@ -820,13 +834,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct 
mmc_card *card,
 * messages to tell when the card is present.
 */
 
-   if (subname)
-   snprintf(md-disk-disk_name, sizeof(md-disk-disk_name),
-mmcblk%d%s,
-mmc_get_devidx(dev_to_disk(parent)), subname);
-   else
-   snprintf(md-disk-disk_name, sizeof(md-disk-disk_name),
-mmcblk%d, devidx);
+   snprintf(md-disk-disk_name, sizeof(md-disk-disk_name),
+mmcblk%d%s, md-name_idx, subname ? subname : );
 
blk_queue_logical_block_size(md-queue.queue, 512);
set_capacity(md-disk, size);
@@ -953,6 +962,7 @@ static void mmc_blk_remove_parts(struct mmc_card *card,
struct list_head *pos, *q;
struct mmc_blk_data *part_md;
 
+   __clear_bit(md-name_idx, name_use);
list_for_each_safe(pos, q, md-part) {
part_md = list_entry(pos, struct mmc_blk_data, part);
list_del(pos);
-- 
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 3/5] mmc: sdhci: make sdhci-of device drivers self registered

2011-04-21 Thread Shawn Guo
On Tue, Apr 19, 2011 at 12:21:01PM +0200, Wolfram Sang wrote:
 
  +static int __devinit sdhci_esdhc_probe(struct platform_device *pdev)
  +{
  +   struct sdhci_host *host;
  +   int ret;
  +
  +   host = sdhci_pltfm_init(pdev, sdhci_esdhc_pdata);
  +   if (!host)
  +   return -ENOMEM;
 
 Just noticed: Since pltfm_init may fail due to various reasons, maybe
 ERRPTR might be a good idea?
 
Ok.

 [...]
 
  +static int __init sdhci_hlwd_init(void)
  +{
  +   return platform_driver_register(sdhci_hlwd_driver);
  +}
  +module_init(sdhci_hlwd_init);
  +
  +static void __exit sdhci_hlwd_exit(void)
  +{
  +   platform_driver_unregister(sdhci_hlwd_driver);
  +}
  +module_exit(sdhci_hlwd_exit);
  +
  +MODULE_DESCRIPTION(Secure Digital Host Controller Interface OF driver);
  +MODULE_AUTHOR(Xiaobo Xie x@freescale.com, 
  + Anton Vorontsov avoront...@ru.mvista.com);
  +MODULE_LICENSE(GPL v2);
 
 Please double check the authors. It is based on the fsl driver, but the
 copyright should go to
 
  * Copyright (C) 2009 The GameCube Linux Team
  * Copyright (C) 2009 Albert Herranz
 
 I think.
 
Sorry, I misread the current copyright in sdhci-of-hlwd.c.  You are
right.

-- 
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: [RFC] MMC: Block: Ensure hardware partitions don't mess with mmcblk device naming.

2011-04-21 Thread Andrei Warkentin
On Thu, Apr 21, 2011 at 1:07 AM, Andrei Warkentin andr...@motorola.com wrote:
 With the hardware partitions support (which represent additional logical 
 devices
 present on MMC), devidx does not correspond with index used to form
 /dev/mmcblkX names. So use an additional allocated index for device names.

 Signed-off-by: Andrei Warkentin andr...@motorola.com
 ---
  drivers/mmc/card/block.c |   24 +---
  1 files changed, 17 insertions(+), 7 deletions(-)

The alternative is to borrow from a previous suggestion by Stephen
Warren, but instead of using card-host-index in place of devidx, use
card-host-index in place of an additional name_index used to form
/dev/mmcblkX device names.

Using card-host-index for devidx doesn't work when you have multiple
logical devices per host (because MMC card contains HW partitions).

Chris, unfortunately I am working OOF for next couple of days(I am
happy I took my eMMC board with me), so I was not able to test second
card (laptop only has 1 slot). Tested on your mmc tree with SDHCI and
my MMC08G card. Would you mind testing above RFC change? Sorry again
for the regression, g.

A
--
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: mxs-mmc: add support for pre_req and post_req

2011-04-21 Thread Per Forlin
On 21 April 2011 08:29, Shawn Guo shawn@freescale.com wrote:
 On Wed, Apr 20, 2011 at 05:30:22PM +0200, Per Forlin wrote:
 [...]
 Remove dma_map and dma_unmap from your host driver and run the tests
 (obviously nonblocking and blocking will have the same results). If
 there is still no performance gain the cache penalty is very small on
 your platform and therefore nonblocking doesn't improve things much.
 Please let me know the result.

 Sorry, I could not understand.  What's the point to run the test when
 the driver is even broken.  The removal of  dma_map_sg and
 dma_unmap_sg makes mxs-mmc host driver broken.
The point is only to get a measurement of the cost of handling
dma_map_sg and dma_unmap_sg, this is the maximum time mmc nonblocking
can save.
The nonblocking mmc_test should save the total time of dma_map_sg and
dma_unmap_sg, if the pre_req and post_req hooks are implemented
correctly.
Running without dma_map_sg and dma_unmap_sg will confirm if the
pre_req and post_req hooks are implemented correctly.


 --
 Regards,
 Shawn


Regards,
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] sdhci: add quirk to support shared bus controller

2011-04-21 Thread Barry Song
From: Bin Shi bin@csr.com

some controllers share data bus or other pins between
multi-controllers and need to switch the functions of shared pins
runtime
this patch requested those shared pins before actual hardware access
and release them after access

Signed-off-by: Bin Shi bin@csr.com
Cc: Binghua Duan binghua.d...@csr.com
Signed-off-by: Barry Song 21cn...@gmail.com
---
 drivers/mmc/host/sdhci.c  |   13 +
 drivers/mmc/host/sdhci.h  |2 ++
 include/linux/mmc/sdhci.h |2 ++
 3 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index f31077d..7b07152 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1379,6 +1379,13 @@ static void sdhci_tasklet_finish(unsigned long param)
sdhci_reset(host, SDHCI_RESET_DATA);
}

+   /*
+* some controllers share data bus or other pins between 
multi-controller
+* and need to switch the function of pins runtime
+*/
+   if (host-quirks  SDHCI_QUIRK_SHARED_PINS)
+   host-ops-get_shared_pins(host);
+
host-mrq = NULL;
host-cmd = NULL;
host-data = NULL;
@@ -1391,6 +1398,12 @@ static void sdhci_tasklet_finish(unsigned long param)
spin_unlock_irqrestore(host-lock, flags);

mmc_request_done(host-mmc, mrq);
+
+   /*
+* release shared pins so that other controllers can use them
+*/
+   if (host-quirks  SDHCI_QUIRK_SHARED_PINS)
+   host-ops-get_shared_pins(host);
 }

 static void sdhci_timeout_timer(unsigned long data)
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 85750a9..9d918a5 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -229,6 +229,8 @@ struct sdhci_ops {
void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 u8 power_mode);
unsigned int(*get_ro)(struct sdhci_host *host);
+   unsigned int(*get_shared_pins)(struct sdhci_host *host);
+   unsigned int(*put_shared_pins)(struct sdhci_host *host);
 };

 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 83bd9f7..32ab422 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -85,6 +85,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK_NO_HISPD_BIT   (129)
 /* Controller treats ADMA descriptors with length h incorrectly */
 #define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC   (130)
+/* Controller shared data bus or other pins with other controllers */
+#define SDHCI_QUIRK_SHARED_PINS (131)

int irq;/* Device IRQ */
void __iomem *ioaddr;   /* Mapped address */
-- 
1.7.1
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mmc: mxs-mmc: add support for pre_req and post_req

2011-04-21 Thread Per Forlin
On 21 April 2011 08:25, Shawn Guo shawn@freescale.com wrote:
 On Wed, Apr 20, 2011 at 05:22:34PM +0200, Per Forlin wrote:
 [...]
  Do you have omap_hsmmc and mmci mmc_test result data to share?
 
 I keep the here:
 https://wiki.linaro.org/WorkingGroups/Kernel/Specs/StoragePerfMMC-async-req

 Actually, I have seen this page before.  I was wondering if you have
 mmc_test raw data (test log of cases #37 ~ #40) to share.
My test numbers are 39 - 42, same tests though.

PANDA - omap_hsmmc:
mmc0: Test case 39. Multiple write performance with sync req 4k to 4MB...
 mmc0: Transfer of 32768 x 8 sectors (32768 x 4 KiB) took 18.987487792
seconds (7068 kB/s, 6903 KiB/s)
 mmc0: Transfer of 16384 x 16 sectors (16384 x 8 KiB) took
11.947631837 seconds (11233 kB/s, 10970 KiB/s)
 mmc0: Transfer of 8192 x 32 sectors (8192 x 16 KiB) took 9.472808839
seconds (14168 kB/s, 13836 KiB/s)
 mmc0: Transfer of 4096 x 64 sectors (4096 x 32 KiB) took 8.260650636
seconds (16247 kB/s, 15867 KiB/s)
 mmc0: Transfer of 2048 x 128 sectors (2048 x 64 KiB) took 7.622741699
seconds (17607 kB/s, 17194 KiB/s)
 mmc0: Transfer of 1024 x 256 sectors (1024 x 128 KiB) took
7.323181152 seconds (18327 kB/s, 17898 KiB/s)
 mmc0: Transfer of 512 x 512 sectors (512 x 256 KiB) took 6.744140626
seconds (19901 kB/s, 19434 KiB/s)
 mmc0: Transfer of 256 x 1024 sectors (256 x 512 KiB) took 6.679138184
seconds (20095 kB/s, 19624 KiB/s)
 mmc0: Transfer of 128 x 2048 sectors (128 x 1024 KiB) took
6.625518800 seconds (20257 kB/s, 19782 KiB/s)
 mmc0: Transfer of 32 x 8192 sectors (32 x 4096 KiB) took 6.620574950
seconds (20272 kB/s, 19797 KiB/s)
 mmc0: Result: OK
 mmc0: Tests completed.
 mmc0: Starting tests of card mmc0:80ca...
 mmc0: Test case 40. Multiple write performance with async req 4k to 4MB...
 mmc0: Transfer of 32768 x 8 sectors (32768 x 4 KiB) took 18.647644043
seconds (7197 kB/s, 7028 KiB/s)
 mmc0: Transfer of 16384 x 16 sectors (16384 x 8 KiB) took
11.624816894 seconds (11545 kB/s, 11275 KiB/s)
 mmc0: Transfer of 8192 x 32 sectors (8192 x 16 KiB) took 9.170440675
seconds (14635 kB/s, 14292 KiB/s)
 mmc0: Transfer of 4096 x 64 sectors (4096 x 32 KiB) took 7.965667725
seconds (16849 kB/s, 16454 KiB/s)
 mmc0: Transfer of 2048 x 128 sectors (2048 x 64 KiB) took 7.318023681
seconds (18340 kB/s, 17910 KiB/s)
 mmc0: Transfer of 1024 x 256 sectors (1024 x 128 KiB) took
7.040740969 seconds (19063 kB/s, 18616 KiB/s)
 mmc0: Transfer of 512 x 512 sectors (512 x 256 KiB) took 6.444641113
seconds (20826 kB/s, 20338 KiB/s)
 mmc0: Transfer of 256 x 1024 sectors (256 x 512 KiB) took 6.380249023
seconds (21036 kB/s, 20543 KiB/s)
 mmc0: Transfer of 128 x 2048 sectors (128 x 1024 KiB) took
6.43506 seconds (21192 kB/s, 20695 KiB/s)
 mmc0: Transfer of 32 x 8192 sectors (32 x 4096 KiB) took 6.328002930
seconds (21210 kB/s, 20713 KiB/s)
 mmc0: Result: OK
 mmc0: Tests completed.
 mmc0: Starting tests of card mmc0:80ca...
 mmc0: Test case 41. Multiple read performance with sync req 4k to 4MB...
 mmc0: Transfer of 32768 x 8 sectors (32768 x 4 KiB) took 20.567749024
seconds (6525 kB/s, 6372 KiB/s)
 mmc0: Transfer of 16384 x 16 sectors (16384 x 8 KiB) took
12.770507813 seconds (10509 kB/s, 10263 KiB/s)
 mmc0: Transfer of 8192 x 32 sectors (8192 x 16 KiB) took 10.003143311
seconds (13417 kB/s, 13103 KiB/s)
 mmc0: Transfer of 4096 x 64 sectors (4096 x 32 KiB) took 7.775665284
seconds (17261 kB/s, 16856 KiB/s)
 mmc0: Transfer of 2048 x 128 sectors (2048 x 64 KiB) took 6.960906982
seconds (19281 kB/s, 18829 KiB/s)
 mmc0: Transfer of 1024 x 256 sectors (1024 x 128 KiB) took
6.661651612 seconds (20147 kB/s, 19675 KiB/s)
 mmc0: Transfer of 512 x 512 sectors (512 x 256 KiB) took 6.510711672
seconds (20614 kB/s, 20131 KiB/s)
 mmc0: Transfer of 256 x 1024 sectors (256 x 512 KiB) took 6.434722900
seconds (20858 kB/s, 20369 KiB/s)
 mmc0: Transfer of 128 x 2048 sectors (128 x 1024 KiB) took
6.396850587 seconds (20981 kB/s, 20490 KiB/s)
 mmc0: Transfer of 32 x 8192 sectors (32 x 4096 KiB) took 6.368560791
seconds (21075 kB/s, 20581 KiB/s)
 mmc0: Result: OK
 mmc0: Tests completed.
 mmc0: Starting tests of card mmc0:80ca...
 mmc0: Test case 42. Multiple read performance with async req 4k to 4MB...
 mmc0: Transfer of 32768 x 8 sectors (32768 x 4 KiB) took 20.650848389
seconds (6499 kB/s, 6347 KiB/s)
 mmc0: Transfer of 16384 x 16 sectors (16384 x 8 KiB) took
12.796203613 seconds (10488 kB/s, 10243 KiB/s)
 mmc0: Transfer of 8192 x 32 sectors (8192 x 16 KiB) took 10.019592286
seconds (13395 kB/s, 13081 KiB/s)
 mmc0: Transfer of 4096 x 64 sectors (4096 x 32 KiB) took 7.603942870
seconds (17651 kB/s, 17237 KiB/s)
 mmc0: Transfer of 2048 x 128 sectors (2048 x 64 KiB) took 6.751251223
seconds (19880 kB/s, 19414 KiB/s)
 mmc0: Transfer of 1024 x 256 sectors (1024 x 128 KiB) took
6.252929687 seconds (21464 kB/s, 20961 KiB/s)
 mmc0: Transfer of 512 x 512 sectors (512 x 256 KiB) took 5.956726076
seconds (22532 kB/s, 22004 KiB/s)
 mmc0: Transfer of 256 x 1024 sectors (256 x 512 KiB) took 5.863586425

Re: [PATCH] sdhci: add quirk to support shared bus controller

2011-04-21 Thread Andrei Warkentin
Hi,

On Thu, Apr 21, 2011 at 3:51 AM, Barry Song 21cn...@gmail.com wrote:
 From: Bin Shi bin@csr.com

 some controllers share data bus or other pins between
 multi-controllers and need to switch the functions of shared pins
 runtime
 this patch requested those shared pins before actual hardware access
 and release them after access

 Signed-off-by: Bin Shi bin@csr.com
 Cc: Binghua Duan binghua.d...@csr.com
 Signed-off-by: Barry Song 21cn...@gmail.com
 ---
  drivers/mmc/host/sdhci.c  |   13 +
  drivers/mmc/host/sdhci.h  |    2 ++
  include/linux/mmc/sdhci.h |    2 ++
  3 files changed, 17 insertions(+), 0 deletions(-)

 diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
 index f31077d..7b07152 100644
 --- a/drivers/mmc/host/sdhci.c
 +++ b/drivers/mmc/host/sdhci.c
 @@ -1379,6 +1379,13 @@ static void sdhci_tasklet_finish(unsigned long param)
                sdhci_reset(host, SDHCI_RESET_DATA);
        }

 +       /*
 +        * some controllers share data bus or other pins between 
 multi-controller
 +        * and need to switch the function of pins runtime
 +        */
 +       if (host-quirks  SDHCI_QUIRK_SHARED_PINS)
 +               host-ops-get_shared_pins(host);
 +

Why in tasklet_finish? Why not in sdhci_request?
No need to waste a quirk flag. Just invoke if method is not NULL.

Also, I would assume host-ops-get_shared_pins would need to
synchronize with other SDHCI instances
it shares the pins with. Since you do it after the host-lock (as you
should), what happens if get_shared_pins needs to wait?
Can you show the rest (sdhci driver implementing these hooks)?

        host-mrq = NULL;
        host-cmd = NULL;
        host-data = NULL;
 @@ -1391,6 +1398,12 @@ static void sdhci_tasklet_finish(unsigned long param)
        spin_unlock_irqrestore(host-lock, flags);

        mmc_request_done(host-mmc, mrq);
 +
 +       /*
 +        * release shared pins so that other controllers can use them
 +        */
 +       if (host-quirks  SDHCI_QUIRK_SHARED_PINS)
 +               host-ops-get_shared_pins(host);
  }

  static void sdhci_timeout_timer(unsigned long data)
 diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
 index 85750a9..9d918a5 100644
 --- a/drivers/mmc/host/sdhci.h
 +++ b/drivers/mmc/host/sdhci.h
 @@ -229,6 +229,8 @@ struct sdhci_ops {
        void (*platform_send_init_74_clocks)(struct sdhci_host *host,
                                             u8 power_mode);
        unsigned int    (*get_ro)(struct sdhci_host *host);
 +       unsigned int    (*get_shared_pins)(struct sdhci_host *host);
 +       unsigned int    (*put_shared_pins)(struct sdhci_host *host);
  };

  #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
 diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
 index 83bd9f7..32ab422 100644
 --- a/include/linux/mmc/sdhci.h
 +++ b/include/linux/mmc/sdhci.h
 @@ -85,6 +85,8 @@ struct sdhci_host {
  #define SDHCI_QUIRK_NO_HISPD_BIT                       (129)
  /* Controller treats ADMA descriptors with length h incorrectly */
  #define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC           (130)
 +/* Controller shared data bus or other pins with other controllers */
 +#define SDHCI_QUIRK_SHARED_PINS                         (131)

        int irq;                /* Device IRQ */
        void __iomem *ioaddr;   /* Mapped address */
 --
 1.7.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

--
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: mxs-mmc: add support for pre_req and post_req

2011-04-21 Thread Shawn Guo
On Thu, Apr 21, 2011 at 10:46:18AM +0200, Per Forlin wrote:
 On 21 April 2011 08:29, Shawn Guo shawn@freescale.com wrote:
  On Wed, Apr 20, 2011 at 05:30:22PM +0200, Per Forlin wrote:
  [...]
  Remove dma_map and dma_unmap from your host driver and run the tests
  (obviously nonblocking and blocking will have the same results). If
  there is still no performance gain the cache penalty is very small on
  your platform and therefore nonblocking doesn't improve things much.
  Please let me know the result.
 
  Sorry, I could not understand.  What's the point to run the test when
  the driver is even broken.  The removal of  dma_map_sg and
  dma_unmap_sg makes mxs-mmc host driver broken.
 The point is only to get a measurement of the cost of handling
 dma_map_sg and dma_unmap_sg, this is the maximum time mmc nonblocking
 can save.
 The nonblocking mmc_test should save the total time of dma_map_sg and
 dma_unmap_sg, if the pre_req and post_req hooks are implemented
 correctly.
 Running without dma_map_sg and dma_unmap_sg will confirm if the
 pre_req and post_req hooks are implemented correctly.
 
With dma_map_sg and dma_unmap_sg removed, the mmc_test gave very low
numbers, though blocking and non-blocking numbers are same.  Is it
an indication that pre_req and post_req hooks are not implemented
correctly?  If yes, can you please help to catch the mistakes?

Thanks.

mc0: Test case 39. Read performance with blocking req 4k to 4MB...
mmc0: Transfer of 32768 x 8 sectors (32768 x 4 KiB) took 56.875013015 seconds (2
359 kB/s, 2304 KiB/s, 576.14 IOPS)
mmc0: Transfer of 16384 x 16 sectors (16384 x 8 KiB) took 47.407562500 seconds (
2831 kB/s, 2764 KiB/s, 345.59 IOPS)
mmc0: Transfer of 8192 x 32 sectors (8192 x 16 KiB) took 42.708718750 seconds (3
142 kB/s, 3068 KiB/s, 191.81 IOPS)
mmc0: Transfer of 4096 x 64 sectors (4096 x 32 KiB) took 40.227125000 seconds (3
336 kB/s, 3258 KiB/s, 101.82 IOPS)
mmc0: Transfer of 2048 x 128 sectors (2048 x 64 KiB) took 38.91575 seconds (
3448 kB/s, 3368 KiB/s, 52.62 IOPS)
mmc0: Transfer of 1024 x 256 sectors (1024 x 128 KiB) took 38.249562498 seconds
(3509 kB/s, 3426 KiB/s, 26.77 IOPS)
mmc0: Transfer of 512 x 512 sectors (512 x 256 KiB) took 37.912342548 seconds (3
540 kB/s, 3457 KiB/s, 13.50 IOPS)
mmc0: Transfer of 256 x 1024 sectors (256 x 512 KiB) took 37.743876391 seconds (
3556 kB/s, 3472 KiB/s, 6.78 IOPS)
mmc0: Transfer of 128 x 2048 sectors (128 x 1024 KiB) took 37.658104019 seconds
(3564 kB/s, 3480 KiB/s, 3.39 IOPS)
mmc0: Transfer of 39 x 6630 sectors (39 x 3315 KiB) took 37.086429038 seconds (3
569 kB/s, 3486 KiB/s, 1.05 IOPS)
mmc0: Result: OK
mmc0: Test case 40. Read performance with none blocking req 4k to 4MB...
mmc0: Transfer of 32768 x 8 sectors (32768 x 4 KiB) took 56.732932555 seconds (2
365 kB/s, 2310 KiB/s, 577.58 IOPS)
mmc0: Transfer of 16384 x 16 sectors (16384 x 8 KiB) took 47.342812500 seconds (
2835 kB/s, 2768 KiB/s, 346.07 IOPS)
mmc0: Transfer of 8192 x 32 sectors (8192 x 16 KiB) took 42.673906250 seconds (3
145 kB/s, 3071 KiB/s, 191.96 IOPS)
mmc0: Transfer of 4096 x 64 sectors (4096 x 32 KiB) took 40.208218750 seconds (3
338 kB/s, 3259 KiB/s, 101.86 IOPS)
mmc0: Transfer of 2048 x 128 sectors (2048 x 64 KiB) took 38.90675 seconds (
3449 kB/s, 3368 KiB/s, 52.63 IOPS)
mmc0: Transfer of 1024 x 256 sectors (1024 x 128 KiB) took 38.24474 seconds
(3509 kB/s, 3427 KiB/s, 26.77 IOPS)
mmc0: Transfer of 512 x 512 sectors (512 x 256 KiB) took 37.909719946 seconds (3
540 kB/s, 3457 KiB/s, 13.50 IOPS)
mmc0: Transfer of 256 x 1024 sectors (256 x 512 KiB) took 37.741834105 seconds (
3556 kB/s, 3472 KiB/s, 6.78 IOPS)
mmc0: Transfer of 128 x 2048 sectors (128 x 1024 KiB) took 37.657555456 seconds
(3564 kB/s, 3480 KiB/s, 3.39 IOPS)
mmc0: Transfer of 39 x 6630 sectors (39 x 3315 KiB) took 37.086351431 seconds (3
569 kB/s, 3486 KiB/s, 1.05 IOPS)
mmc0: Result: OK
mmc0: Tests completed.

-- 
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] mmc: mxs-mmc: add support for pre_req and post_req

2011-04-21 Thread Per Forlin
On 21 April 2011 11:11, Shawn Guo shawn@freescale.com wrote:
 On Thu, Apr 21, 2011 at 10:46:18AM +0200, Per Forlin wrote:
 On 21 April 2011 08:29, Shawn Guo shawn@freescale.com wrote:
  On Wed, Apr 20, 2011 at 05:30:22PM +0200, Per Forlin wrote:
  [...]
  Remove dma_map and dma_unmap from your host driver and run the tests
  (obviously nonblocking and blocking will have the same results). If
  there is still no performance gain the cache penalty is very small on
  your platform and therefore nonblocking doesn't improve things much.
  Please let me know the result.
 
  Sorry, I could not understand.  What's the point to run the test when
  the driver is even broken.  The removal of  dma_map_sg and
  dma_unmap_sg makes mxs-mmc host driver broken.
 The point is only to get a measurement of the cost of handling
 dma_map_sg and dma_unmap_sg, this is the maximum time mmc nonblocking
 can save.
 The nonblocking mmc_test should save the total time of dma_map_sg and
 dma_unmap_sg, if the pre_req and post_req hooks are implemented
 correctly.
 Running without dma_map_sg and dma_unmap_sg will confirm if the
 pre_req and post_req hooks are implemented correctly.

 With dma_map_sg and dma_unmap_sg removed, the mmc_test gave very low
 numbers, though blocking and non-blocking numbers are same.  Is it
 an indication that pre_req and post_req hooks are not implemented
 correctly?
I think you could get the same numbers for the nonblocking with
dma_map and dma_unmap in place.

  If yes, can you please help to catch the mistakes?
I will take a look.

 --
 Regards,
 Shawn


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


Re: [PATCH 1/5] mmc: sdhci: make sdhci-pltfm device drivers self registered

2011-04-21 Thread Wolfram Sang
   +MODULE_LICENSE(GPL v2);
  
  Just to be sure: Did you double-check if the original licenses were v2
  or v2+?
  
 It seems to me that sdhci-cns3xxx.c, sdhci-dove.c, sdhci-esdhc-imx.c
 and sdhci-tegra.c all use v2.
 
 Actually I do not even know how v2+ is stated.  Do you have an example
 for me to refer?

Check davinci_mmc.c (or grep for 'any later version').

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


signature.asc
Description: Digital signature


Re: [PATCH] mmc: mxs-mmc: add support for pre_req and post_req

2011-04-21 Thread Per Forlin
On 21 April 2011 11:47, Per Forlin per.for...@linaro.org wrote:
 On 21 April 2011 11:11, Shawn Guo shawn@freescale.com wrote:
 On Thu, Apr 21, 2011 at 10:46:18AM +0200, Per Forlin wrote:
 On 21 April 2011 08:29, Shawn Guo shawn@freescale.com wrote:
  On Wed, Apr 20, 2011 at 05:30:22PM +0200, Per Forlin wrote:
  [...]
  Remove dma_map and dma_unmap from your host driver and run the tests
  (obviously nonblocking and blocking will have the same results). If
  there is still no performance gain the cache penalty is very small on
  your platform and therefore nonblocking doesn't improve things much.
  Please let me know the result.
 
  Sorry, I could not understand.  What's the point to run the test when
  the driver is even broken.  The removal of  dma_map_sg and
  dma_unmap_sg makes mxs-mmc host driver broken.
 The point is only to get a measurement of the cost of handling
 dma_map_sg and dma_unmap_sg, this is the maximum time mmc nonblocking
 can save.
 The nonblocking mmc_test should save the total time of dma_map_sg and
 dma_unmap_sg, if the pre_req and post_req hooks are implemented
 correctly.
 Running without dma_map_sg and dma_unmap_sg will confirm if the
 pre_req and post_req hooks are implemented correctly.

 With dma_map_sg and dma_unmap_sg removed, the mmc_test gave very low
 numbers, though blocking and non-blocking numbers are same.  Is it
 an indication that pre_req and post_req hooks are not implemented
 correctly?
 I think you could get the same numbers for the nonblocking with
 dma_map and dma_unmap in place.

  If yes, can you please help to catch the mistakes?
 I will take a look.

I found something:
static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct mxs_mmc_host *host = mmc_priv(mmc);

WARN_ON(host-mrq != NULL);
host-mrq = mrq;
mxs_mmc_start_cmd(host, mrq-cmd);
}

This is the execution flow:
pre_req()
mxs_mmc_request()
post_req()
wait_for_completion()
pre_req()

mxs_mmc_request() returns before the prepared value is used
post_req() will run dma_unmap and set the cookie to 0, this mean in
your case dma_unmap_sg will be called twice.
You need to store away the prepared data in mxs_mmc_request().
Look at my patch for mmci, function mmci_get_next_data. That function
deals with this issue.

I didn't see this issue when I only looked at the patch since no
changes are made in the request-function.

 --
 Regards,
 Shawn
Regards,
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


Re: [PATCH v6] mmc: Add mmc CMD+ACMD passthrough ioctl

2011-04-21 Thread Michał Mirosław
W dniu 21 kwietnia 2011 07:11 użytkownik Arnd Bergmann a...@arndb.de napisał:
 On Wednesday 20 April 2011 21:46:04 Michał Mirosław wrote:
 2011/4/20 Arnd Bergmann a...@arndb.de:
  No, please don't try to invent random new ways of doing this.
  Your example relies on the assumption that the task is calling
  the entry point for its native word size. Some architectures
  intentionally allow calling the 32 bit entry point from 64 bit
  tasks and vice versa, e.g. for user space emulators converting
  to a different ABI, and in that case is_compat_task() produces
  the wrong result. Don't ever rely on that.

 This doesn't make sense to me. If you call 32-bit entry point from
 64-bit process, you can't reliably pass pointers through the call
 (unless you limit 64-bit process to 32-bit address space).

 Do you know a working example of something using this kind of cross-call?

 There are people that use 32 bit programs on x86_64 in 64 bit mode
 and switch on the ADDR_LIMIT_32BIT personality, IIRC.
 This gives you more registers and lets you do 64 bit arithmetic
 while not using any more memory to store long pointers.
 There are a few problems with this, and the new x32 ABI will make it
 cleaner.

Ok. Thanks for the pointers.

  I'm okay with the anon union + ``compat_ptr(*(u32 *))`` part of your
  solution.  If everyone else thinks it is reasonable, I'll submit a v7
  with it.
  No need for a union or a ptr_size member in the struct. Just use
  a single __u64 and let the user cast the pointer to that. This
  will work on all architectures.

 Union is just hiding this cast (it will be done in kernel) and allows
 cleaner code for userspace (there's a single kernel and possibly
 multiple applications that will implement this call).

 As I explained, it doesn't work. Please read my earlier mails.

If you're referring to your mail:

Subject: Re: [PATCH v4] mmc: Add ioctl to let userspace apps send ACMDs
Date: Wed, 13 Apr 2011 01:00:39 +0200
Message-Id: 201104130100.39810.a...@arndb.de

Then I already provided an example of implementation that's
independent of endianness and avoids casts on userspace.

  However, I still think it should be implemented in compat_ioctl()
  because compat_blkdev_ioctl() expects it.  Either that, or I add to the
  big switch in compat_blkdev_driver_ioctl(), and spreading this change
  out to block/compat_ioctl.c does not seem like The Right Thing to me.
  Yes, you definitely need to fill the .compat_ioctl member. We don't want
  new entries in the switch statement, in particular none that are specific
  to a single driver.
 Hmm, you're right. fs/compat_ioctl.c falls back to plain .ioctl if
 .compat_ioctl == NULL.
 No, it doesn't.

I'll need to look at the code again then.

Best Regards,
Michał Mirosław
--
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: TMIO: add runtime PM calls to global suspend() / redume() methods

2011-04-21 Thread Guennadi Liakhovetski
The TMIO MMC driver cannot generally suspend itself at runtime even
with no card inserted, because otherwise it wouldn't be able to detect
new cards. But when the system goes down for a global suspend, we can
use runtime PM calls to let it activate platform-specific PM hooks,
e.g., to switch off respective power domains.

Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
---
 drivers/mmc/host/tmio_mmc.h |2 ++
 drivers/mmc/host/tmio_mmc_pio.c |6 ++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 249c724..58138a2 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -52,6 +52,8 @@ struct tmio_mmc_host {
void (*set_pwr)(struct platform_device *host, int state);
void (*set_clk_div)(struct platform_device *host, int state);
 
+   int pm_error;
+
/* pio related stuff */
struct scatterlist  *sg_ptr;
struct scatterlist  *sg_orig;
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index d1791ba..26598f1 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -980,6 +980,8 @@ int tmio_mmc_host_suspend(struct device *dev)
if (!ret)
tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
 
+   host-pm_error = pm_runtime_put_sync(dev);
+
return ret;
 }
 EXPORT_SYMBOL(tmio_mmc_host_suspend);
@@ -987,6 +989,10 @@ EXPORT_SYMBOL(tmio_mmc_host_suspend);
 int tmio_mmc_host_resume(struct device *dev)
 {
struct mmc_host *mmc = dev_get_drvdata(dev);
+   struct tmio_mmc_host *host = mmc_priv(mmc);
+
+   if (!host-pm_error)
+   pm_runtime_get_sync(dev);
 
tmio_mmc_reset(mmc_priv(mmc));
 
-- 
1.7.2.5

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


Re: [PATCH v6] mmc: Add mmc CMD+ACMD passthrough ioctl

2011-04-21 Thread Arnd Bergmann
On Wednesday 20 April 2011, Chris Ball wrote:
 On Wed, Apr 20 2011, John Calixto wrote:
  Have you had the chance to look at v6 of this patch?  If so, what do you
  think?
 
 Looks good to me.  Since Arnd's been reviewing, it'd be nice to get a
 Reviewed-by: tag from him and acknowledgement that his concerns are all
 addressed, and then I'll merge it.

Once the pointer passing is worked out, I think we have basically resolved
the technical issues. One more thing that I just noticed: The 
__u64 data_ptr needs to be aligned, otherwise you get a problem
on x86, which uses different alignment for 64 bit members in structures
between 32 and 64 bit ABIs. Putting the 64 bit members first in the data
structure, and adding padding at the end to have a size that is a multiple
of 8 bytes should take care of this.

I don't quite understand the timeout stuff in there, so I'm not sure how
I'd fill these from an application like qemu that blindly passes down
commands. I'd feel more comfortable if we didn't have to specify these
in the interface, but I have no strict objection if you think that passing
those is a reasonable requirement.

The more important question that is still unresolved however is the
nontechnical one:

Do we want users to use this interface for DRM applications?

I would still prefer having a more high-level interface for this, ideally
something where we just export a block device for the encrypted partition,
with an ioctl interface to do the authentication. Alternatively, I could
imagine an ioctl interface that exports each SD security command as a
separate ioctl command, including the block read/write ones.

The information to do this seems to be available in
http://issuu.com/sravan/docs/sd_card, which describes the ACMDs.
It shouldn't be too hard to implement them in a high-level API.
What I don't know is whether we have a clear policy about implementing
SD standard interfaces in the kernel that are not part of the redacted
specs.

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


Re: [PATCH v6] mmc: Add mmc CMD+ACMD passthrough ioctl

2011-04-21 Thread Arnd Bergmann
On Thursday 21 April 2011, Michał Mirosław wrote:
 Subject: Re: [PATCH v4] mmc: Add ioctl to let userspace apps send ACMDs
 Date: Wed, 13 Apr 2011 01:00:39 +0200
 Message-Id: 201104130100.39810.a...@arndb.de
 
 Then I already provided an example of implementation that's
 independent of endianness and avoids casts on userspace.
 

Yes, v4 got that aspect right, as far as I can tell, aside
from an incorrect cast (u8* instead of u8 __user *).

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


Re: [PATCH v6] mmc: Add mmc CMD+ACMD passthrough ioctl

2011-04-21 Thread Michał Mirosław
W dniu 21 kwietnia 2011 13:15 użytkownik Arnd Bergmann a...@arndb.de napisał:
 On Thursday 21 April 2011, Michał Mirosław wrote:
 Subject: Re: [PATCH v4] mmc: Add ioctl to let userspace apps send ACMDs
 Date: Wed, 13 Apr 2011 01:00:39 +0200
 Message-Id: 201104130100.39810.a...@arndb.de

 Then I already provided an example of implementation that's
 independent of endianness and avoids casts on userspace.

 Yes, v4 got that aspect right, as far as I can tell, aside
 from an incorrect cast (u8* instead of u8 __user *).

Just to have an understanding about the issue. In the mail I pointed
to, you argued that union will not work because of endianness
problems. I haven't seen other arguments against the union approach,
and I have provided a solution for this case.

BTW, kernel side can also avoid the cast if the union is extended with
32-bit field. This works because an address of a union is an address
of each of its fields. IOW all fields start at the same address
regardless if the they are 32 or 64 bits in size.

struct mmc_ioc_cmd {
  union {
__u64 __data_ptr_storage64;
__u32 __data_ptr_storage32;
void __user *data_ptr;
  };
  ...
};

[...]

static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
  struct mmc_ioc_cmd blk;

  if (cmd != MMC_IOC_CMD)
return -EINVAL;

  copy_from_user(compat_ptr(arg), blk) ...
  blk.data_ptr = compat_ptr(blk.__data_ptr_storage32);

  return mmc_blk_ioctl_cmd(bdev, blk);
}

Best Regards,
Michał Mirosław
--
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


[RESEND PATCH 0/4] mmc_spi: Add support for regulator framework

2011-04-21 Thread Antonio Ospite
Hi,

resending the patchset as I missed some recipients on the first round.

This patchset has the purpose of adding support for the regulator framework to 
the mmc_spi driver. The first three patches are preparatory cleanups to make 
the forth one more straightforward.

Maybe the fourth patch can be improved, I am open to any suggestions about it.

These changes take strong inspiration from the pxamci driver; they have been 
tested on a Motorola A910, which uses a regulator to powerup the MMC card 
connected to the SPI bus, a test from a current user of the mmc_spi driver 
would not hurt just to be sure no regressions have been introduced.

Thanks,
   Antonio

Antonio Ospite (4):
  mmc_spi.c: factor out the check for power capability
  mmc_spi.c: factor out the SD card shutdown sequence
  mmc_spi.c: factor out a mmc_spi_setpower() function
  mmc_spi.c: add support for the regulator framework

 drivers/mmc/host/mmc_spi.c |  194 +---
 1 files changed, 129 insertions(+), 65 deletions(-)

-- 
Antonio Ospite
http://ao2.it

PGP public key ID: 0x4553B001

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?
--
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


[RESEND PATCH 3/4] mmc_spi.c: factor out a mmc_spi_setpower() function

2011-04-21 Thread Antonio Ospite
Factor out a mmc_spi_setpower() function so to make changing it more
elegant without adding too much stuff to mmc_spi_set_ios().

Signed-off-by: Antonio Ospite osp...@studenti.unina.it
---
 drivers/mmc/host/mmc_spi.c |   43 +++
 1 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 9eae23c..0f3672d 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1221,6 +1221,26 @@ static void mmc_spi_shutdownsequence(struct mmc_spi_host 
*host)
}
 }
 
+static inline int mmc_spi_setpower(struct mmc_spi_host *host,
+   unsigned char power_mode,
+   unsigned int vdd)
+{
+   /* switch power on/off if possible, accounting for
+* max 250msec powerup time if needed.
+*/
+   if (mmc_spi_canpower(host)) {
+   switch (power_mode) {
+   case MMC_POWER_OFF:
+   case MMC_POWER_UP:
+   host-pdata-setpower(host-spi-dev, vdd);
+   if (power_mode == MMC_POWER_UP)
+   msleep(host-powerup_msecs);
+   }
+   }
+
+   return 0;
+}
+
 static char *mmc_powerstring(u8 power_mode)
 {
switch (power_mode) {
@@ -1236,24 +1256,23 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
struct mmc_spi_host *host = mmc_priv(mmc);
 
if (host-power_mode != ios-power_mode) {
+   int ret;
 
dev_dbg(host-spi-dev, mmc_spi: power %s (%d)%s\n,
mmc_powerstring(ios-power_mode),
ios-vdd,
mmc_spi_canpower(host) ? , can switch : );
 
-   /* switch power on/off if possible, accounting for
-* max 250msec powerup time if needed.
-*/
-   if (mmc_spi_canpower(host)) {
-   switch (ios-power_mode) {
-   case MMC_POWER_OFF:
-   case MMC_POWER_UP:
-   host-pdata-setpower(host-spi-dev,
-   ios-vdd);
-   if (ios-power_mode == MMC_POWER_UP)
-   msleep(host-powerup_msecs);
-   }
+   ret = mmc_spi_setpower(host, ios-power_mode, ios-vdd);
+   if (ret) {
+   dev_err(mmc_dev(mmc), unable to set power\n);
+   /*
+* The .set_ios() function in the mmc_host_ops
+* struct return void, and failing to set the
+* power should be rare so we print an error and
+* return here.
+*/
+   return;
}
 
/* See 6.4.1 in the simplified SD card physical spec 2.0 */
-- 
1.7.4.4

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


[RESEND PATCH 2/4] mmc_spi.c: factor out the SD card shutdown sequence

2011-04-21 Thread Antonio Ospite
Factor out the SD card shutdown sequence to a dedicated
mmc_spi_shutdownsequence() function in order to make mmc_spi_set_ios()
more readable, and also for symmetry with mmc_spi_initsequence() which
is already a dedicated function.

Signed-off-by: Antonio Ospite osp...@studenti.unina.it
---
 drivers/mmc/host/mmc_spi.c |   90 +++
 1 files changed, 48 insertions(+), 42 deletions(-)

diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 49f5725..9eae23c 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1176,6 +1176,51 @@ static void mmc_spi_initsequence(struct mmc_spi_host 
*host)
}
 }
 
+/* See Section 6.4.2, in SD Simplified Physical Layer Specification 2.0
+ *
+ * If powering down, ground all card inputs to avoid power delivery from data
+ * lines!  On a shared SPI bus, this will probably be temporary; 6.4.2 of
+ * the simplified SD spec says this must last at least 1msec.
+ *
+ *   - Clock low means CPOL 0, e.g. mode 0
+ *   - MOSI low comes from writing zero
+ *   - Chipselect is usually active low...
+ */
+static void mmc_spi_shutdownsequence(struct mmc_spi_host *host)
+{
+   int mres;
+   u8 nullbyte = 0;
+
+   host-spi-mode = ~(SPI_CPOL|SPI_CPHA);
+   mres = spi_setup(host-spi);
+   if (mres  0)
+   dev_dbg(host-spi-dev,
+   switch to SPI mode 0 failed\n);
+
+   if (spi_write(host-spi, nullbyte, 1)  0)
+   dev_dbg(host-spi-dev,
+   put spi signals to low failed\n);
+
+   /*
+* Now clock should be low due to spi mode 0;
+* MOSI should be low because of written 0x00;
+* chipselect should be low (it is active low)
+* power supply is off, so now MMC is off too!
+*
+* FIXME no, chipselect can be high since the
+* device is inactive and SPI_CS_HIGH is clear...
+*/
+   msleep(10);
+   if (mres == 0) {
+   host-spi-mode |= (SPI_CPOL|SPI_CPHA);
+   mres = spi_setup(host-spi);
+   if (mres  0)
+   dev_dbg(host-spi-dev,
+   switch back to SPI mode 3
+failed\n);
+   }
+}
+
 static char *mmc_powerstring(u8 power_mode)
 {
switch (power_mode) {
@@ -1215,49 +1260,10 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
if (ios-power_mode == MMC_POWER_ON)
mmc_spi_initsequence(host);
 
-   /* If powering down, ground all card inputs to avoid power
-* delivery from data lines!  On a shared SPI bus, this
-* will probably be temporary; 6.4.2 of the simplified SD
-* spec says this must last at least 1msec.
-*
-*   - Clock low means CPOL 0, e.g. mode 0
-*   - MOSI low comes from writing zero
-*   - Chipselect is usually active low...
-*/
+   /* See 6.4.2 in the simplified SD card physical spec 2.0 */
if (mmc_spi_canpower(host) 
-   ios-power_mode == MMC_POWER_OFF) {
-   int mres;
-   u8 nullbyte = 0;
-
-   host-spi-mode = ~(SPI_CPOL|SPI_CPHA);
-   mres = spi_setup(host-spi);
-   if (mres  0)
-   dev_dbg(host-spi-dev,
-   switch to SPI mode 0 failed\n);
-
-   if (spi_write(host-spi, nullbyte, 1)  0)
-   dev_dbg(host-spi-dev,
-   put spi signals to low failed\n);
-
-   /*
-* Now clock should be low due to spi mode 0;
-* MOSI should be low because of written 0x00;
-* chipselect should be low (it is active low)
-* power supply is off, so now MMC is off too!
-*
-* FIXME no, chipselect can be high since the
-* device is inactive and SPI_CS_HIGH is clear...
-*/
-   msleep(10);
-   if (mres == 0) {
-   host-spi-mode |= (SPI_CPOL|SPI_CPHA);
-   mres = spi_setup(host-spi);
-   if (mres  0)
-   dev_dbg(host-spi-dev,
-   switch back to SPI mode 3
-failed\n);
-   }
-   }
+   ios-power_mode == MMC_POWER_OFF)
+   mmc_spi_shutdownsequence(host);
 
host-power_mode = ios-power_mode;
}
-- 
1.7.4.4

--
To unsubscribe from this list: 

[RESEND PATCH 4/4] mmc_spi.c: add support for the regulator framework

2011-04-21 Thread Antonio Ospite
Add support for powering up SD cards driven by regulators.
This makes the mmc_spi driver work also with the Motorola A910 phone.

Signed-off-by: Antonio Ospite osp...@studenti.unina.it
---
 drivers/mmc/host/mmc_spi.c |   61 +++
 1 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 0f3672d..acc2ec8 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -31,6 +31,7 @@
 #include linux/dma-mapping.h
 #include linux/crc7.h
 #include linux/crc-itu-t.h
+#include linux/regulator/consumer.h
 #include linux/scatterlist.h
 
 #include linux/mmc/host.h
@@ -150,11 +151,13 @@ struct mmc_spi_host {
 */
void*ones;
dma_addr_t  ones_dma;
+
+   struct regulator*vcc;
 };
 
 static inline int mmc_spi_canpower(struct mmc_spi_host *host)
 {
-   return host-pdata  host-pdata-setpower;
+   return (host-pdata  host-pdata-setpower) || host-vcc;
 }
 
 //
@@ -1225,17 +1228,35 @@ static inline int mmc_spi_setpower(struct mmc_spi_host 
*host,
unsigned char power_mode,
unsigned int vdd)
 {
+   if (!mmc_spi_canpower(host))
+   return -ENOSYS;
+
/* switch power on/off if possible, accounting for
 * max 250msec powerup time if needed.
 */
-   if (mmc_spi_canpower(host)) {
-   switch (power_mode) {
-   case MMC_POWER_OFF:
-   case MMC_POWER_UP:
+   switch (power_mode) {
+   case MMC_POWER_OFF:
+   if (host-vcc) {
+   int ret = mmc_regulator_set_ocr(host-mmc,
+   host-vcc, 0);
+   if (ret)
+   return ret;
+   } else {
+   host-pdata-setpower(host-spi-dev, vdd);
+   }
+   break;
+
+   case MMC_POWER_UP:
+   if (host-vcc) {
+   int ret = mmc_regulator_set_ocr(host-mmc,
+   host-vcc, vdd);
+   if (ret)
+   return ret;
+   } else {
host-pdata-setpower(host-spi-dev, vdd);
-   if (power_mode == MMC_POWER_UP)
-   msleep(host-powerup_msecs);
}
+   msleep(host-powerup_msecs);
+   break;
}
 
return 0;
@@ -1420,12 +1441,28 @@ static int mmc_spi_probe(struct spi_device *spi)
 * and power switching gpios.
 */
host-pdata = mmc_spi_get_pdata(spi);
-   if (host-pdata)
-   mmc-ocr_avail = host-pdata-ocr_mask;
-   if (!mmc-ocr_avail) {
-   dev_warn(spi-dev, ASSUMING 3.2-3.4 V slot power\n);
-   mmc-ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
+#ifdef CONFIG_REGULATOR
+   host-vcc = regulator_get(mmc_dev(host-mmc), vmmc);
+
+   if (IS_ERR(host-vcc)) {
+   host-vcc = NULL;
+   } else {
+   host-mmc-ocr_avail = mmc_regulator_get_ocrmask(host-vcc);
+   if (host-pdata  host-pdata-ocr_mask)
+   dev_warn(mmc_dev(host-mmc),
+   ocr_mask/setpower will not be used\n);
}
+#endif
+   if (host-vcc == NULL) {
+   /* fall-back to platform data */
+   if (host-pdata)
+   mmc-ocr_avail = host-pdata-ocr_mask;
+   if (!mmc-ocr_avail) {
+   dev_warn(spi-dev, ASSUMING 3.2-3.4 V slot power\n);
+   mmc-ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+   }
+   }
+
if (mmc_spi_canpower(host)) {
host-powerup_msecs = host-pdata-powerup_msecs;
if (!host-powerup_msecs || host-powerup_msecs  250)
-- 
1.7.4.4

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


[RESEND PATCH 1/4] mmc_spi.c: factor out the check for power capability

2011-04-21 Thread Antonio Ospite
Factor out the 'canpower' condition into a dedicated function in order
to avoid repetition and to make changing the condition easier.

Signed-off-by: Antonio Ospite osp...@studenti.unina.it
---
 drivers/mmc/host/mmc_spi.c |   18 ++
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 7c1e16a..49f5725 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -152,6 +152,10 @@ struct mmc_spi_host {
dma_addr_t  ones_dma;
 };
 
+static inline int mmc_spi_canpower(struct mmc_spi_host *host)
+{
+   return host-pdata  host-pdata-setpower;
+}
 
 //
 
@@ -1187,19 +1191,16 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
struct mmc_spi_host *host = mmc_priv(mmc);
 
if (host-power_mode != ios-power_mode) {
-   int canpower;
-
-   canpower = host-pdata  host-pdata-setpower;
 
dev_dbg(host-spi-dev, mmc_spi: power %s (%d)%s\n,
mmc_powerstring(ios-power_mode),
ios-vdd,
-   canpower ? , can switch : );
+   mmc_spi_canpower(host) ? , can switch : );
 
/* switch power on/off if possible, accounting for
 * max 250msec powerup time if needed.
 */
-   if (canpower) {
+   if (mmc_spi_canpower(host)) {
switch (ios-power_mode) {
case MMC_POWER_OFF:
case MMC_POWER_UP:
@@ -1223,7 +1224,8 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
 *   - MOSI low comes from writing zero
 *   - Chipselect is usually active low...
 */
-   if (canpower  ios-power_mode == MMC_POWER_OFF) {
+   if (mmc_spi_canpower(host) 
+   ios-power_mode == MMC_POWER_OFF) {
int mres;
u8 nullbyte = 0;
 
@@ -1399,7 +1401,7 @@ static int mmc_spi_probe(struct spi_device *spi)
dev_warn(spi-dev, ASSUMING 3.2-3.4 V slot power\n);
mmc-ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
}
-   if (host-pdata  host-pdata-setpower) {
+   if (mmc_spi_canpower(host)) {
host-powerup_msecs = host-pdata-powerup_msecs;
if (!host-powerup_msecs || host-powerup_msecs  250)
host-powerup_msecs = 250;
@@ -1459,7 +1461,7 @@ static int mmc_spi_probe(struct spi_device *spi)
host-dma_dev ?  : , no DMA,
(host-pdata  host-pdata-get_ro)
?  : , no WP,
-   (host-pdata  host-pdata-setpower)
+   mmc_spi_canpower(host)
?  : , no poweroff,
(mmc-caps  MMC_CAP_NEEDS_POLL)
? , cd polling : );
-- 
1.7.4.4

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


Re: [PATCH v6] mmc: Add mmc CMD+ACMD passthrough ioctl

2011-04-21 Thread Arnd Bergmann
On Thursday 21 April 2011, Michał Mirosław wrote:
 W dniu 21 kwietnia 2011 13:15 użytkownik Arnd Bergmann a...@arndb.de 
 napisał:

 static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
 unsigned int cmd, unsigned long arg)
 {
   struct mmc_ioc_cmd blk;
 
   if (cmd != MMC_IOC_CMD)
 return -EINVAL;
 
   copy_from_user(compat_ptr(arg), blk) ...
   blk.data_ptr = compat_ptr(blk.__data_ptr_storage32);
 
   return mmc_blk_ioctl_cmd(bdev, blk);
 }

Yes, this works, but it requires having a compat_ioctl() handler function that
knows about the data structure, which we generally try to avoid.
The same method would even work if you only had a pointer member in the
structure and did not even attempt to make the structure compatible.

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


Re: [RESEND PATCH 4/4] mmc_spi.c: add support for the regulator framework

2011-04-21 Thread Mark Brown
On Thu, Apr 21, 2011 at 02:27:53PM +0200, Antonio Ospite wrote:

 +#ifdef CONFIG_REGULATOR
 + host-vcc = regulator_get(mmc_dev(host-mmc), vmmc);
 +
 + if (IS_ERR(host-vcc)) {
 + host-vcc = NULL;
 + } else {
 + host-mmc-ocr_avail = mmc_regulator_get_ocrmask(host-vcc);
 + if (host-pdata  host-pdata-ocr_mask)
 + dev_warn(mmc_dev(host-mmc),
 + ocr_mask/setpower will not be used\n);
   }
 +#endif

Why is this code conditional?  The regulator API will stub itself out
(by returning a null pointer, which plays well with your use of null) if
it's disabled.  I'm also not seeing any corresponding code to release
the regulator.
--
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 0/2] OF: add MMC binding helpers

2011-04-21 Thread Domenico Andreoli
Hi all,

  in working to add OF support to S3C MMC I discovered that some good
code has been already written for the MMC-over-SPI driver. This is
the first attempt to use it to build a common set of OF bindings for
MMC drivers.

Please tell me whether I'm on a good way or not.

cheers,
Domenico

-[ Domenico Andreoli, aka cavok
 --[ http://cavokz.wordpress.com/gpgkey/
   ---[ 3A0F 2F80 F79C 678A 8936  4FEE 0677 9033 A20E BC50
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] Add GPIO DT support to s3c24xx

2011-04-21 Thread Domenico Andreoli
From: Domenico Andreoli cav...@gmail.com

Assign proper OF node (= with matching physical base address) to each
s3c24xx GPIO chip.

Signed-off-by: Domenico Andreoli cav...@gmail.com

---
 arch/arm/plat-s3c24xx/gpiolib.c |   36 
 1 file changed, 36 insertions(+)

Index: b/arch/arm/plat-s3c24xx/gpiolib.c
===
--- a/arch/arm/plat-s3c24xx/gpiolib.c   2011-04-10 23:28:31.0 +0200
+++ b/arch/arm/plat-s3c24xx/gpiolib.c   2011-04-11 11:23:36.0 +0200
@@ -19,6 +19,8 @@
 #include linux/ioport.h
 #include linux/io.h
 #include linux/gpio.h
+#include linux/of.h
+#include linux/of_address.h
 
 #include plat/gpio-core.h
 #include plat/gpio-cfg.h
@@ -210,6 +212,39 @@
},
 };
 
+#ifdef CONFIG_OF_GPIO
+
+static void s3c24xx_attach_of_node(struct s3c_gpio_chip *chip)
+{
+   struct device_node *dn;
+   struct resource res;
+   const char *dt_compat;
+
+   if (chip-base == S3C2410_GPACON)
+   dt_compat = samsung,s3c2410-gpio-a;
+   else
+   dt_compat = samsung,s3c2410-gpio;
+
+   for_each_compatible_node(dn, NULL, dt_compat) {
+   if (of_address_to_resource(dn, 0, res)  0) {
+   printk(KERN_ERR %s: unable to translate DT address\n, 
dn-full_name);
+   continue;
+   }
+
+   if (chip-base == (res.start - S3C24XX_PA_GPIO + 
S3C24XX_VA_GPIO)) {
+   chip-chip.of_node = dn;
+   break;
+   }
+   }
+}
+
+#else
+
+static void s3c24xx_attach_of_node(struct s3c_gpio_chip *chip)
+{
+}
+
+#endif
 
 static __init int s3c24xx_gpiolib_init(void)
 {
@@ -220,6 +255,7 @@
if (!chip-config)
chip-config = s3c24xx_gpiocfg_default;
 
+   s3c24xx_attach_of_node(chip);
s3c_gpiolib_add(chip);
}
 

--
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 v6] mmc: Add mmc CMD+ACMD passthrough ioctl

2011-04-21 Thread Michał Mirosław
W dniu 21 kwietnia 2011 14:39 użytkownik Arnd Bergmann a...@arndb.de napisał:
 On Thursday 21 April 2011, Michał Mirosław wrote:
 W dniu 21 kwietnia 2011 13:15 użytkownik Arnd Bergmann a...@arndb.de 
 napisał:

 static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
     unsigned int cmd, unsigned long arg)
 {
   struct mmc_ioc_cmd blk;

   if (cmd != MMC_IOC_CMD)
     return -EINVAL;

   copy_from_user(compat_ptr(arg), blk) ...
   blk.data_ptr = compat_ptr(blk.__data_ptr_storage32);

   return mmc_blk_ioctl_cmd(bdev, blk);
 }

 Yes, this works, but it requires having a compat_ioctl() handler function that
 knows about the data structure, which we generally try to avoid.
 The same method would even work if you only had a pointer member in the
 structure and did not even attempt to make the structure compatible.

Not really. If the structures were different, you would need write
code to translate it fully (this doesn't really apply for this simple
case, where there is only one pointer at the end of the structure). My
example only fixes/converts pointers in place.

The compat/native handler could be made in one function that takes
another bool arg and ioctl handlers would look like the code below. In
this scheme you avoid having to duplicate ioctl handler at all and let
compiler optimize out conditionals (you can even force
__mmc_blk_ioctl() inline to make sure of it).

#ifndef CONFIG_COMPAT
static inline void *compat_ptr(unsigned long) { BUG(); return NULL; }
#endif

static int __mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
    unsigned int cmd, unsigned long arg, bool compat32)
{
  void __user *p;
...
  p = compat32 ? compat_ptr(arg) : (void *)arg;
...
  if (compat32)
    blk.data_ptr = compat_ptr(blk.__data_ptr_storage32);
...
}

static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
    unsigned int cmd, unsigned long arg)
{
  return __mmc_blk_ioctl(bdev, mode, cmd, arg, false);
}

#ifdef CONFIG_COMPAT
static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
    unsigned int cmd, unsigned long arg)
{
  return __mmc_blk_ioctl(bdev, mode, cmd, arg, true);
}
#endif
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Add OF binding helpers for MMC drivers

2011-04-21 Thread Grant Likely
On Thu, Apr 21, 2011 at 03:19:57PM +0200, Domenico Andreoli wrote:
 From: Domenico Andreoli cav...@gmail.com
 
 This patch adds helpers to manage OF binding of MMC DeviceTree configs.
 They don't cover all the MMC configuration cases, indeed are only a
 slight generalization of those found in the MMC-over-SPI driver. More
 will come later.

Can the mmc-over-spi driver be generalized to use this code too?

 
 Signed-off-by: Domenico Andreoli cav...@gmail.com
 ---
  drivers/of/Kconfig |4 +
  drivers/of/Makefile|1 +
  drivers/of/of_mmc.c|  165 
 +
  include/linux/of_mmc.h |   50 +++

Personally I think it makes more sense for this code to live in 
drivers/mmc/core.

  4 files changed, 220 insertions(+)
 
 Index: b/drivers/of/Kconfig
 ===
 --- a/drivers/of/Kconfig
 +++ b/drivers/of/Kconfig
 @@ -59,6 +59,10 @@ config OF_I2C
   help
 OpenFirmware I2C accessors
  
 +config OF_MMC
 + depends on MMC
 + def_bool y
 +
  config OF_NET
   depends on NETDEVICES
   def_bool y
 Index: b/drivers/of/Makefile
 ===
 --- a/drivers/of/Makefile
 +++ b/drivers/of/Makefile
 @@ -7,6 +7,7 @@ obj-$(CONFIG_OF_DEVICE) += device.o plat
  obj-$(CONFIG_OF_GPIO)   += gpio.o
  obj-$(CONFIG_OF_CLOCK)   += clock.o
  obj-$(CONFIG_OF_I2C) += of_i2c.o
 +obj-$(CONFIG_OF_MMC) += of_mmc.o
  obj-$(CONFIG_OF_NET) += of_net.o
  obj-$(CONFIG_OF_SPI) += of_spi.o
  obj-$(CONFIG_OF_MDIO)+= of_mdio.o
 Index: b/drivers/of/of_mmc.c
 ===
 --- /dev/null
 +++ b/drivers/of/of_mmc.c
 @@ -0,0 +1,165 @@
 +/*
 + * OF helpers for the MMC API
 + *
 + * Copyright (c) 2011 Domenico Andreoli
 + *
 + * Heavily inspired by the OF support to the MMC-over-SPI driver made
 + * by Anton Vorontsov
 + *
 + * This program is free software; you can redistribute  it and/or modify it
 + * under  the terms of  the GNU General  Public License as published by the
 + * Free Software Foundation;  either version 2 of the  License, or (at your
 + * option) any later version.
 + */
 +
 +#include linux/kernel.h
 +#include linux/module.h
 +#include linux/device.h
 +#include linux/err.h
 +#include linux/slab.h
 +#include linux/mmc/core.h
 +#include linux/gpio.h
 +#include linux/of.h
 +#include linux/of_mmc.h
 +#include linux/of_gpio.h
 +
 +static int of_read_mmc_gpio(struct of_mmc_crg *crg, int gpio_num)
 +{
 + int value, active_low;
 +
 + BUG_ON(gpio_num = NUM_MMC_GPIOS);
 +
 + /* hitting this means that DeviceTree left this gpio unspecified
 +  * by purpose but driver didn't take any measure to define its
 +  * behavior (i.e. aborting probe phase or disabling the feature).
 +  * driver needs to call of_is_valid_mmc_crg() for each expected
 +  * gpio to detect this case.
 +  */
 + if (WARN_ON(crg-gpios[gpio_num]  0))
 + return -1;
 +
 + value = gpio_get_value(crg-gpios[gpio_num]);
 + active_low = crg-alow_gpios[gpio_num];
 + return value ^ active_low;
 +}
 +
 +int of_get_mmc_cd_gpio(struct of_mmc_crg *crg)
 +{
 + return of_read_mmc_gpio(crg, CD_MMC_GPIO);
 +}
 +EXPORT_SYMBOL(of_get_mmc_cd_gpio);
 +
 +int of_get_mmc_ro_gpio(struct of_mmc_crg *crg)
 +{
 + return of_read_mmc_gpio(crg, WP_MMC_GPIO);
 +}
 +EXPORT_SYMBOL(of_get_mmc_ro_gpio);
 +
 +int of_is_valid_mmc_crg(struct of_mmc_crg *crg, int gpio_num)
 +{
 + BUG_ON(gpio_num = NUM_MMC_GPIOS);
 + return gpio_is_valid(crg-gpios[gpio_num]);
 +}
 +EXPORT_SYMBOL(of_is_valid_mmc_crg);
 +
 +int of_get_mmc_crg(struct device *dev, struct device_node *np,
 +   int cd_off, struct of_mmc_crg *crg)
 +{
 + int *gpio, *alow;
 + int i, ret;
 +
 + memset(crg, 0, sizeof(*crg));
 + crg-cd_irq = -1;
 +
 + gpio = crg-gpios;
 + alow = crg-alow_gpios;
 + for (i = 0; i  NUM_MMC_GPIOS; i++, gpio++, alow++) {
 + enum of_gpio_flags gpio_flags;
 + *gpio = of_get_gpio_flags(np, cd_off+i, gpio_flags);
 + *alow = !!(gpio_flags  OF_GPIO_ACTIVE_LOW);
 +
 + if (*gpio == -EEXIST || *gpio == -ENOENT) {
 + /* driver needs to define proper meaning of this missing
 +gpio (i.e. abort probe or disable the feature) */
 + pr_debug(%s: gpio #%d is not specified\n, __func__, 
 i);
 + continue;
 + }
 + if (*gpio  0) {
 + pr_debug(%s: invalid configuration\n, __func__);
 + ret = *gpio;
 + break;
 + }
 + if (!gpio_is_valid(*gpio)) {
 + pr_debug(%s: gpio #%d is not valid: %d\n, __func__, 
 i, *gpio);
 + ret = -EINVAL;
 + break;
 + }
 + ret = 

Re: [RFC] MMC: Block: Ensure hardware partitions don't mess with mmcblk device naming.

2011-04-21 Thread Chris Ball
Hi Andrei,

On Thu, Apr 21 2011, Andrei Warkentin wrote:
 Chris, unfortunately I am working OOF for next couple of days(I am
 happy I took my eMMC board with me), so I was not able to test second
 card (laptop only has 1 slot). Tested on your mmc tree with SDHCI and
 my MMC08G card. Would you mind testing above RFC change? Sorry again
 for the regression, g.

Sure, happy to test.  No need to feel too bad about the regression,
we're very early on in preparation for .40.

- Chris.
-- 
Chris Ball   c...@laptop.org   http://printf.net/
One Laptop Per Child
--
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: tmio: fix a recent regression: restore .set_ios(MMC_POWER_UP) handling

2011-04-21 Thread Chris Ball
Hi,

On Thu, Apr 21 2011, Guennadi Liakhovetski wrote:
 The aggressive clock gating for TMIO MMC patch has broken switching
 interface power on, using MFD or platform callbacks. Restore the
 ios-power_mode == MMC_POWER_UP  ios-clock == 0 case handling.

 Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
 ---

 This one should go in 2.6.39

  drivers/mmc/host/tmio_mmc_pio.c |   10 +-
  1 files changed, 5 insertions(+), 5 deletions(-)

 diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
 index 6e3271d..f4fac9f 100644
 --- a/drivers/mmc/host/tmio_mmc_pio.c
 +++ b/drivers/mmc/host/tmio_mmc_pio.c
 @@ -772,15 +772,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, 
 struct mmc_ios *ios)
   tmio_mmc_set_clock(host, ios-clock);
  
   /* Power sequence - OFF - UP - ON */
 - if (ios-power_mode == MMC_POWER_OFF || !ios-clock) {
 + if (ios-power_mode == MMC_POWER_UP) {
 + /* power up SD bus */
 + if (host-set_pwr)
 + host-set_pwr(host-pdev, 1);
 + } else if (ios-power_mode == MMC_POWER_OFF || !ios-clock) {
   /* power down SD bus */
   if (ios-power_mode == MMC_POWER_OFF  host-set_pwr)
   host-set_pwr(host-pdev, 0);
   tmio_mmc_clk_stop(host);
 - } else if (ios-power_mode == MMC_POWER_UP) {
 - /* power up SD bus */
 - if (host-set_pwr)
 - host-set_pwr(host-pdev, 1);
   } else {
   /* start bus clock */
   tmio_mmc_clk_start(host);

Thanks, pushed to mmc-next for .39.

Paul Parsons (CC'd) submitted a similar patch to fix the same regression.
Paul, please could you check that Guennadi's patch fixes your problem?

- Chris.
-- 
Chris Ball   c...@laptop.org   http://printf.net/
One Laptop Per Child
--
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: Fix read-only detection with JMicron 388 chip

2011-04-21 Thread Takashi Iwai
On HP laptops with JMicron 388 chip, the write-locked SD card isn't
detected correctly as read-only in many cases.  This is because the
PRESENT_STATE register becomes unsable just after plugging, and it
returns the WRITE_PROTECT bit wrongly at the first read.

This patch fixes the read-only detection by adding the own get_ro op
for checking the register more intensively with a relatively long
delay.

The patch is tested with 2.6.39-rc4 kernel.

Cc: Aries Lee aries...@jmicron.com
Signed-off-by: Takashi Iwai ti...@suse.de
---
 drivers/mmc/host/sdhci-pci.c |   34 ++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index a136be7..9037b2a 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -346,6 +346,35 @@ static void jmicron_enable_mmc(struct sdhci_host *host, 
int on)
writeb(scratch, host-ioaddr + 0xC0);
 }
 
+/* As PRESENT_STATE register becomes unstable just after plugging,
+ * need to check the RO-cap multiple times with a relatively long delay.
+ */
+
+#define SAMPLE_COUNT   5
+
+static unsigned int jmicron_get_ro(struct sdhci_host *host)
+{
+   int i, ro_count;
+
+   ro_count = 0;
+   for (i = 0; i  SAMPLE_COUNT; i++) {
+   int present = sdhci_readl(host, SDHCI_PRESENT_STATE);
+   if (!(present  SDHCI_WRITE_PROTECT)) {
+   if (++ro_count  SAMPLE_COUNT / 2)
+   return 1;
+   }
+   msleep(30);
+   }
+   return 0;
+}
+
+static int sdhci_pci_enable_dma(struct sdhci_host *host);
+
+static struct sdhci_ops jmicron_pci_ops = {
+   .enable_dma = sdhci_pci_enable_dma,
+   .get_ro = jmicron_get_ro,
+};
+
 static int jmicron_probe_slot(struct sdhci_pci_slot *slot)
 {
if (slot-chip-pdev-revision == 0) {
@@ -383,6 +412,11 @@ static int jmicron_probe_slot(struct sdhci_pci_slot *slot)
 
slot-host-mmc-caps |= MMC_CAP_BUS_WIDTH_TEST;
 
+   /* Replace the ops for unstable get_ro detection */
+   if (slot-chip-pdev-device == PCI_DEVICE_ID_JMICRON_JMB388_SD ||
+   slot-chip-pdev-device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
+   slot-host-ops = jmicron_pci_ops;
+
return 0;
 }
 
-- 
1.7.4.2

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


Re: [PATCH] mmc: Fix read-only detection with JMicron 388 chip

2011-04-21 Thread Chris Ball
Hi Takashi,

On Thu, Apr 21 2011, Takashi Iwai wrote:
 On HP laptops with JMicron 388 chip, the write-locked SD card isn't
 detected correctly as read-only in many cases.  This is because the
 PRESENT_STATE register becomes unsable just after plugging, and it
 returns the WRITE_PROTECT bit wrongly at the first read.

 This patch fixes the read-only detection by adding the own get_ro op
 for checking the register more intensively with a relatively long
 delay.

 The patch is tested with 2.6.39-rc4 kernel.

 Cc: Aries Lee aries...@jmicron.com
 Signed-off-by: Takashi Iwai ti...@suse.de
 ---
  drivers/mmc/host/sdhci-pci.c |   34 ++
  1 files changed, 34 insertions(+), 0 deletions(-)

 diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
 index a136be7..9037b2a 100644
 --- a/drivers/mmc/host/sdhci-pci.c
 +++ b/drivers/mmc/host/sdhci-pci.c
 @@ -346,6 +346,35 @@ static void jmicron_enable_mmc(struct sdhci_host *host, 
 int on)
   writeb(scratch, host-ioaddr + 0xC0);
  }
  
 +/* As PRESENT_STATE register becomes unstable just after plugging,
 + * need to check the RO-cap multiple times with a relatively long delay.
 + */
 +
 +#define SAMPLE_COUNT 5
 +
 +static unsigned int jmicron_get_ro(struct sdhci_host *host)
 +{
 + int i, ro_count;
 +
 + ro_count = 0;
 + for (i = 0; i  SAMPLE_COUNT; i++) {
 + int present = sdhci_readl(host, SDHCI_PRESENT_STATE);
 + if (!(present  SDHCI_WRITE_PROTECT)) {
 + if (++ro_count  SAMPLE_COUNT / 2)
 + return 1;
 + }
 + msleep(30);
 + }
 + return 0;
 +}
 +
 +static int sdhci_pci_enable_dma(struct sdhci_host *host);
 +
 +static struct sdhci_ops jmicron_pci_ops = {
 + .enable_dma = sdhci_pci_enable_dma,
 + .get_ro = jmicron_get_ro,
 +};
 +
  static int jmicron_probe_slot(struct sdhci_pci_slot *slot)
  {
   if (slot-chip-pdev-revision == 0) {
 @@ -383,6 +412,11 @@ static int jmicron_probe_slot(struct sdhci_pci_slot 
 *slot)
  
   slot-host-mmc-caps |= MMC_CAP_BUS_WIDTH_TEST;
  
 + /* Replace the ops for unstable get_ro detection */
 + if (slot-chip-pdev-device == PCI_DEVICE_ID_JMICRON_JMB388_SD ||
 + slot-chip-pdev-device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
 + slot-host-ops = jmicron_pci_ops;
 +
   return 0;
  }

I don't like overwriting ops here -- it's too magical, and now we have
to maintain the ops table in two places.  A quirk seems justified here,
even though we're trying to reduce them in general.  Can anyone find a
better solution?

Thanks,

- Chris.
-- 
Chris Ball   c...@laptop.org   http://printf.net/
One Laptop Per Child
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mmc: Fix read-only detection with JMicron 388 chip

2011-04-21 Thread Takashi Iwai
At Thu, 21 Apr 2011 12:40:26 -0400,
Chris Ball wrote:
 
 Hi Takashi,
 
 On Thu, Apr 21 2011, Takashi Iwai wrote:
  On HP laptops with JMicron 388 chip, the write-locked SD card isn't
  detected correctly as read-only in many cases.  This is because the
  PRESENT_STATE register becomes unsable just after plugging, and it
  returns the WRITE_PROTECT bit wrongly at the first read.
 
  This patch fixes the read-only detection by adding the own get_ro op
  for checking the register more intensively with a relatively long
  delay.
 
  The patch is tested with 2.6.39-rc4 kernel.
 
  Cc: Aries Lee aries...@jmicron.com
  Signed-off-by: Takashi Iwai ti...@suse.de
  ---
   drivers/mmc/host/sdhci-pci.c |   34 ++
   1 files changed, 34 insertions(+), 0 deletions(-)
 
  diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
  index a136be7..9037b2a 100644
  --- a/drivers/mmc/host/sdhci-pci.c
  +++ b/drivers/mmc/host/sdhci-pci.c
  @@ -346,6 +346,35 @@ static void jmicron_enable_mmc(struct sdhci_host 
  *host, int on)
  writeb(scratch, host-ioaddr + 0xC0);
   }
   
  +/* As PRESENT_STATE register becomes unstable just after plugging,
  + * need to check the RO-cap multiple times with a relatively long delay.
  + */
  +
  +#define SAMPLE_COUNT   5
  +
  +static unsigned int jmicron_get_ro(struct sdhci_host *host)
  +{
  +   int i, ro_count;
  +
  +   ro_count = 0;
  +   for (i = 0; i  SAMPLE_COUNT; i++) {
  +   int present = sdhci_readl(host, SDHCI_PRESENT_STATE);
  +   if (!(present  SDHCI_WRITE_PROTECT)) {
  +   if (++ro_count  SAMPLE_COUNT / 2)
  +   return 1;
  +   }
  +   msleep(30);
  +   }
  +   return 0;
  +}
  +
  +static int sdhci_pci_enable_dma(struct sdhci_host *host);
  +
  +static struct sdhci_ops jmicron_pci_ops = {
  +   .enable_dma = sdhci_pci_enable_dma,
  +   .get_ro = jmicron_get_ro,
  +};
  +
   static int jmicron_probe_slot(struct sdhci_pci_slot *slot)
   {
  if (slot-chip-pdev-revision == 0) {
  @@ -383,6 +412,11 @@ static int jmicron_probe_slot(struct sdhci_pci_slot 
  *slot)
   
  slot-host-mmc-caps |= MMC_CAP_BUS_WIDTH_TEST;
   
  +   /* Replace the ops for unstable get_ro detection */
  +   if (slot-chip-pdev-device == PCI_DEVICE_ID_JMICRON_JMB388_SD ||
  +   slot-chip-pdev-device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
  +   slot-host-ops = jmicron_pci_ops;
  +
  return 0;
   }
 
 I don't like overwriting ops here -- it's too magical, and now we have
 to maintain the ops table in two places.  A quirk seems justified here,
 even though we're trying to reduce them in general.

Well, I also used quirk bit in my very first version I worked for
2.6.32 kernel.  But when I looked at 2.6.39, quirks are almost full --
only the last one bit is left for bit 31.  So I didn't want to finish
it :)

  Can anyone find a better solution?
 
One way would be to copy the ops table itself in struct sdhci_host
instead of keeping the ops table pointer.  Then you can overwrite only
the specific op in each probe_slot callback.


thanks,

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


Re: [PATCH] mmc: Fix read-only detection with JMicron 388 chip

2011-04-21 Thread Chris Ball
Hi Takashi,

On Thu, Apr 21 2011, Takashi Iwai wrote:
 I don't like overwriting ops here -- it's too magical, and now we have
 to maintain the ops table in two places.  A quirk seems justified here,
 even though we're trying to reduce them in general.

 Well, I also used quirk bit in my very first version I worked for
 2.6.32 kernel.  But when I looked at 2.6.39, quirks are almost full --
 only the last one bit is left for bit 31.  So I didn't want to finish
 it :)

  Can anyone find a better solution?
  
 One way would be to copy the ops table itself in struct sdhci_host
 instead of keeping the ops table pointer.  Then you can overwrite only
 the specific op in each probe_slot callback.

I think I'd rather not touch ops at all and keep the code simple --
if you don't mind, please post a version with quirks, and I'll work
on freeing up a few bits.

Thanks,

- Chris.
-- 
Chris Ball   c...@laptop.org   http://printf.net/
One Laptop Per Child
--
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/RFC] MMC: remove unbalanced pm_runtime_suspend()

2011-04-21 Thread Rafael J. Wysocki
On Thursday, April 21, 2011, Alan Stern wrote:
 On Wed, 20 Apr 2011, Rafael J. Wysocki wrote:
 
  On Wednesday, April 20, 2011, Alan Stern wrote:
   On Wed, 20 Apr 2011, Rafael J. Wysocki wrote:
   
On Wednesday, April 20, 2011, Alan Stern wrote:
 On Wed, 20 Apr 2011, Guennadi Liakhovetski wrote:
...
 Ah, now I see the problem.  It looks like we did not give sufficient
 thought to the case where a device starts off (and therefore should
 finish up) in a powered-down state.  Calling pm_runtime_put_sync()
 after unbinding the device driver seems a little futile -- with no
 driver, the subsystem may not be able to power-down the device!
 
 Rafael, how do you think we should handle this?  Get rid of the 
 pm_runtime_get_no_resume() and pm_runtime_put_sync() calls in 
 dd.c:__device_release_driver()?

I think we need pm_runtime_barrier() in there.  Otherwise we risk
removing the driver while there's a runtime PM request pending.

But we can move the pm_runtime_put_sync() before driver_sysfs_remove().
   
   What happens if another runtime PM request is queued between the
   put_sync() and the remove callback?  We may need a safe way to prevent
   async runtime PM requests while still allowing synchronous requests.
  
  What about making a rule that it is invalid to schedule a future suspend
  or queue a resume request of a device whose driver is being removed?
  
  Arguably, we can't prevent people from shooting themselves in the foot this
  way or another and I'm not sure if this particular case is worth additional
  handling.
 
 After thinking about this, I tend to agree.  The synchronization 
 issues, combined with the unknown needs of the driver, make this very 
 difficult to handle in the PM core.
 
 Here's another possible approach: If a driver wants to leave its device 
 in a powered-down state after unbinding then it can invoke its own 
 runtime_suspend callback directly, in the following way:
 
   ... unregister all child devices below dev ...
   pm_runtime_disable(dev);
   if (dev-power.runtime_status != RPM_SUSPENDED) {
   pm_set_suspended(dev);
   my_runtime_suspend_callback(dev);
   }

I think this would work too, but then possibly many drivers would have to
do the same thing in their remove routines.

 There may be issues regarding coordination with the subsystem or the
 power domain; at the moment it's not clear what should be done.  Maybe
 the runtime-PM core should include an API for directly invoking the
 appropriate callbacks.

If we choose this approach, then yes, we should provide a suitable API, but
I'm still thinking it would be simpler to move the pm_runtime_put_sync() before 
driver_sysfs_remove() and make the rule as I said previously. :-)

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


Re: [PATCH] mmc: Fix read-only detection with JMicron 388 chip

2011-04-21 Thread Takashi Iwai
At Thu, 21 Apr 2011 13:36:03 -0400,
Chris Ball wrote:
 
 Hi Takashi,
 
 On Thu, Apr 21 2011, Takashi Iwai wrote:
  I don't like overwriting ops here -- it's too magical, and now we have
  to maintain the ops table in two places.  A quirk seems justified here,
  even though we're trying to reduce them in general.
 
  Well, I also used quirk bit in my very first version I worked for
  2.6.32 kernel.  But when I looked at 2.6.39, quirks are almost full --
  only the last one bit is left for bit 31.  So I didn't want to finish
  it :)
 
   Can anyone find a better solution?
   
  One way would be to copy the ops table itself in struct sdhci_host
  instead of keeping the ops table pointer.  Then you can overwrite only
  the specific op in each probe_slot callback.
 
 I think I'd rather not touch ops at all and keep the code simple --
 if you don't mind, please post a version with quirks, and I'll work
 on freeing up a few bits.

OK, I'll send shortly.


Takashi
--
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/RFC] MMC: remove unbalanced pm_runtime_suspend()

2011-04-21 Thread Alan Stern
On Thu, 21 Apr 2011, Rafael J. Wysocki wrote:

   What about making a rule that it is invalid to schedule a future suspend
   or queue a resume request of a device whose driver is being removed?
   
   Arguably, we can't prevent people from shooting themselves in the foot 
   this
   way or another and I'm not sure if this particular case is worth 
   additional
   handling.
  
  After thinking about this, I tend to agree.  The synchronization 
  issues, combined with the unknown needs of the driver, make this very 
  difficult to handle in the PM core.
  
  Here's another possible approach: If a driver wants to leave its device 
  in a powered-down state after unbinding then it can invoke its own 
  runtime_suspend callback directly, in the following way:
  
  ... unregister all child devices below dev ...
  pm_runtime_disable(dev);
  if (dev-power.runtime_status != RPM_SUSPENDED) {
  pm_set_suspended(dev);
  my_runtime_suspend_callback(dev);
  }
 
 I think this would work too, but then possibly many drivers would have to
 do the same thing in their remove routines.
 
  There may be issues regarding coordination with the subsystem or the
  power domain; at the moment it's not clear what should be done.  Maybe
  the runtime-PM core should include an API for directly invoking the
  appropriate callbacks.
 
 If we choose this approach, then yes, we should provide a suitable API, but
 I'm still thinking it would be simpler to move the pm_runtime_put_sync() 
 before driver_sysfs_remove() and make the rule as I said previously. :-)

The problem is synchronization.  At what point is the driver supposed 
to stop queuing runtime PM requests?  It would have to be sometime 
before the pm_runtime_barrier() call.  How is the driver supposed to 
know when that point is reached?  The remove routine isn't called until 
later.

Alan Stern

--
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/RFC] MMC: remove unbalanced pm_runtime_suspend()

2011-04-21 Thread Rafael J. Wysocki
On Thursday, April 21, 2011, Alan Stern wrote:
 On Thu, 21 Apr 2011, Rafael J. Wysocki wrote:
 
What about making a rule that it is invalid to schedule a future suspend
or queue a resume request of a device whose driver is being removed?

Arguably, we can't prevent people from shooting themselves in the foot 
this
way or another and I'm not sure if this particular case is worth 
additional
handling.
   
   After thinking about this, I tend to agree.  The synchronization 
   issues, combined with the unknown needs of the driver, make this very 
   difficult to handle in the PM core.
   
   Here's another possible approach: If a driver wants to leave its device 
   in a powered-down state after unbinding then it can invoke its own 
   runtime_suspend callback directly, in the following way:
   
 ... unregister all child devices below dev ...
 pm_runtime_disable(dev);
 if (dev-power.runtime_status != RPM_SUSPENDED) {
 pm_set_suspended(dev);
 my_runtime_suspend_callback(dev);
 }
  
  I think this would work too, but then possibly many drivers would have to
  do the same thing in their remove routines.
  
   There may be issues regarding coordination with the subsystem or the
   power domain; at the moment it's not clear what should be done.  Maybe
   the runtime-PM core should include an API for directly invoking the
   appropriate callbacks.
  
  If we choose this approach, then yes, we should provide a suitable API, but
  I'm still thinking it would be simpler to move the pm_runtime_put_sync() 
  before driver_sysfs_remove() and make the rule as I said previously. :-)
 
 The problem is synchronization.  At what point is the driver supposed 
 to stop queuing runtime PM requests?  It would have to be sometime 
 before the pm_runtime_barrier() call.  How is the driver supposed to 
 know when that point is reached?  The remove routine isn't called until 
 later.

Executing the driver's callback is not an ideal solution either, because
it simply may be insufficient (it may be necessary to execute the power
domain and/or subsystem callbacks, pretty much what rpm_suspend() does,
but without taking the usage counter into consideration).

Moreover,  if we want the driver's -remove() to do the cleanup anyway,
there's not much point in doing any cleanup before in the core.  Also,
there's a little problem that the bus -remove() is called before the
driver's -remove(), so it may not be entirely possible to power down
the device when the driver's -remove() is called already.

I think the current code is better than any of the alternatives considered
so far.

Rafael
--
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/RFC] MMC: remove unbalanced pm_runtime_suspend()

2011-04-21 Thread Alan Stern
On Thu, 21 Apr 2011, Rafael J. Wysocki wrote:

   If we choose this approach, then yes, we should provide a suitable API, 
   but
   I'm still thinking it would be simpler to move the pm_runtime_put_sync() 
   before driver_sysfs_remove() and make the rule as I said previously. :-)
  
  The problem is synchronization.  At what point is the driver supposed 
  to stop queuing runtime PM requests?  It would have to be sometime 
  before the pm_runtime_barrier() call.  How is the driver supposed to 
  know when that point is reached?  The remove routine isn't called until 
  later.
 
 Executing the driver's callback is not an ideal solution either, because
 it simply may be insufficient (it may be necessary to execute the power
 domain and/or subsystem callbacks, pretty much what rpm_suspend() does,
 but without taking the usage counter into consideration).

That's why I suggested a new API.  It could do the right callbacks.

 Moreover,  if we want the driver's -remove() to do the cleanup anyway,
 there's not much point in doing any cleanup before in the core.  Also,
 there's a little problem that the bus -remove() is called before the
 driver's -remove(), so it may not be entirely possible to power down
 the device when the driver's -remove() is called already.

Actually, the bus-remove() callback (if there is one) is responsible
for invoking the driver's callback.  The subsystem should be smart
enough to handle runtime PM requests while the driver's remove callback
is running.

 I think the current code is better than any of the alternatives considered
 so far.

Then you think Guennadi should leave his patch as it is, including the 
reversed put/get?

Alan Stern

--
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/RFC] MMC: remove unbalanced pm_runtime_suspend()

2011-04-21 Thread Rafael J. Wysocki
On Thursday, April 21, 2011, Alan Stern wrote:
 On Thu, 21 Apr 2011, Rafael J. Wysocki wrote:
 
If we choose this approach, then yes, we should provide a suitable API, 
but
I'm still thinking it would be simpler to move the 
pm_runtime_put_sync() before driver_sysfs_remove() and make the rule as 
I said previously. :-)
   
   The problem is synchronization.  At what point is the driver supposed 
   to stop queuing runtime PM requests?  It would have to be sometime 
   before the pm_runtime_barrier() call.  How is the driver supposed to 
   know when that point is reached?  The remove routine isn't called until 
   later.
  
  Executing the driver's callback is not an ideal solution either, because
  it simply may be insufficient (it may be necessary to execute the power
  domain and/or subsystem callbacks, pretty much what rpm_suspend() does,
  but without taking the usage counter into consideration).
 
 That's why I suggested a new API.  It could do the right callbacks.
 
  Moreover,  if we want the driver's -remove() to do the cleanup anyway,
  there's not much point in doing any cleanup before in the core.  Also,
  there's a little problem that the bus -remove() is called before the
  driver's -remove(), so it may not be entirely possible to power down
  the device when the driver's -remove() is called already.
 
 Actually, the bus-remove() callback (if there is one) is responsible
 for invoking the driver's callback.

Ah, sorry, I misread the code in __device_release_driver() (too little
coffee perhaps).

 The subsystem should be smart enough to handle runtime PM requests while
 the driver's remove callback is running.

If we make such a rule, we may as well remove all of the runtime PM
calls from __device_release_driver().
 
  I think the current code is better than any of the alternatives considered
  so far.
 
 Then you think Guennadi should leave his patch as it is, including the 
 reversed put/get?

This, or we need to remove the runtime PM calls from __device_release_driver().

I'm a bit worried about the driver_sysfs_remove() and the bus notifier that
in theory may affect the runtime PM callbacks potentially executed before
-remove() is called.

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


Re: [RFC] MMC: Block: Ensure hardware partitions don't mess with mmcblk device naming.

2011-04-21 Thread Chris Ball
Hi Andrei,

On Thu, Apr 21 2011, Andrei Warkentin wrote:
 With the hardware partitions support (which represent additional logical 
 devices
 present on MMC), devidx does not correspond with index used to form
 /dev/mmcblkX names. So use an additional allocated index for device names.

 Signed-off-by: Andrei Warkentin andr...@motorola.com
 ---
  drivers/mmc/card/block.c |   24 +---
  1 files changed, 17 insertions(+), 7 deletions(-)

 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
 index 9e30cf6..5572012 100644
 --- a/drivers/mmc/card/block.c
 +++ b/drivers/mmc/card/block.c
 @@ -75,6 +75,7 @@ static int max_devices;
  
  /* 256 minors, so at most 256 separate devices */
  static DECLARE_BITMAP(dev_use, 256);
 +static DECLARE_BITMAP(name_use, 256);
  
  /*
   * There is one mmc_blk_data per slot.
 @@ -88,6 +89,7 @@ struct mmc_blk_data {
   unsigned intusage;
   unsigned intread_only;
   unsigned intpart_type;
 + unsigned intname_idx;
  
   /*
* Only set in main mmc_blk_data associated
 @@ -776,6 +778,18 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct 
 mmc_card *card,
   }
  
   /*
 +  * !subname implies we are creating main mmc_blk_data that will be
 +  * associated with mmc_card with mmc_set_drvdata. Due to device 
 partitions,
 +  * devidx will not coincide with a per-physical card index anymore
 +  * so we keep track of a name index.
 +  */
 + if (!subname)
 + md-name_idx = find_first_zero_bit(name_use, max_devices);
 + else
 + md-name_idx = ((struct mmc_blk_data *)
 + dev_to_disk(parent)-private_data)-name_idx;
 +
 + /*
* Set the read-only status based on the supported commands
* and the write protect switch.
*/
 @@ -820,13 +834,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct 
 mmc_card *card,
* messages to tell when the card is present.
*/
  
 - if (subname)
 - snprintf(md-disk-disk_name, sizeof(md-disk-disk_name),
 -  mmcblk%d%s,
 -  mmc_get_devidx(dev_to_disk(parent)), subname);
 - else
 - snprintf(md-disk-disk_name, sizeof(md-disk-disk_name),
 -  mmcblk%d, devidx);
 + snprintf(md-disk-disk_name, sizeof(md-disk-disk_name),
 +  mmcblk%d%s, md-name_idx, subname ? subname : );
  
   blk_queue_logical_block_size(md-queue.queue, 512);
   set_capacity(md-disk, size);
 @@ -953,6 +962,7 @@ static void mmc_blk_remove_parts(struct mmc_card *card,
   struct list_head *pos, *q;
   struct mmc_blk_data *part_md;
  
 + __clear_bit(md-name_idx, name_use);
   list_for_each_safe(pos, q, md-part) {
   part_md = list_entry(pos, struct mmc_blk_data, part);
   list_del(pos);

This is crashing for me on insertion of the external card after boot:

[2.479319] mmc2: new high speed MMC card at address 0001
[2.485055] mmcblk0: mmc2:0001 SEM04G 3.68 GiB 
[2.489656] mmcblk0boot0: mmc2:0001 SEM04G partition 1 1.00 MiB
[2.495850] mmcblk0boot1: mmc2:0001 SEM04G partition 2 1.00 MiB
[2.503984]  mmcblk0: p1 p2
[2.509273]  mmcblk0boot1: unknown partition table
[2.515308]  mmcblk0boot0: unknown partition table
[2.524044] psmouse.c: Failed to enable mouse on ec touchpad (phys)
[2.532834] EXT3-fs: barriers not enabled
[4.996102] EXT3-fs (mmcblk0p2): warning: maximal mount count reached, 
running e2fsck is recommended
[5.007285] kjournald starting.  Commit interval 5 seconds
[5.014595] EXT3-fs (mmcblk0p2): using internal journal
[5.019791] EXT3-fs (mmcblk0p2): recovery complete
[5.026713] EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
[5.026725] VFS: Mounted root (ext3 filesystem) on device 179:2.
[5.039565] Freeing init memory: 116K

[olpc@localhost ~]$ 
[   33.642250] Unable to handle kernel NULL pointer dereference at virtual 
address 0021
[   33.653175] pgd = c0004000
[   33.656119] [0021] *pgd=
[   33.659673] Internal error: Oops: 17 [#1] PREEMPT
[   33.659673] last sysfs file: 
/sys/devices/platform/sdhci-pxa.0/mmc_host/mmc0/mmc0:d555/serial
[   33.672798] Modules linked in:
[   33.675826] CPU: 0Tainted: GW
(2.6.39-rc4-00194-ge20de60-dirty #4)
[   33.675826] PC is at sysfs_create_dir+0x24/0xd4
[   33.683258] LR is at kobject_add_internal+0x134/0x224
[   33.687761] pc : [c00f9880]lr : [c01b2600]psr: a013
[   33.692773] sp : dc131db8  ip :   fp : 
[   33.704168] r10: dcfe41fc  r9 : c05571e0  r8 : dc205408
[   33.704168] r7 : dcc61c68  r6 :   r5 : dcc61c68  r4 : dcf441b0
[   33.709357] r3 : dcc61c68  r2 :   r1 : 002f  r0 : dcf441b0
[   33.715834] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
kernel
[   33.722316] Control: 10c5387d  Table: 1cc44019  DAC: 0015
[   33.729568] 

v7 changelog for mmc ioctl patch

2011-04-21 Thread John Calixto
change history for this patch:

- v7
- simplify 32-bit/64-bit buffer pointer portability
- add pad member to struct mmc_ioc_cmd so its size is the same
  when built for either 32-bit or 64-bit.
- register ``0xB3`` in Documentation/ioctl/ioctl-number.txt

- v6
- refix 32+64 compat pointer for better portability
- copy userspace pointer *before* using
- apply upper limit to data buffer size
- add flag to allow normal CMD opcodes as well as ACMD opcodes
- remove unnecessary mutex grab

- v5
- fix 32-bit compiler warning about the 32+64 compat pointer

- v4
- replace postsleep udelay() with usleep_range()
- add cmd_timeout_ms field for R1B commands

- v3
- copy data from userspace before claiming host
- break out copy from userspace into its own function
- verify that caller has CAP_SYS_RAWIO
- rename ``struct sd_ioc_cmd`` to ``struct mmc_ioc_cmd`` because it
  applies generally, not just to SD
- make struct mmc_ioc_cmd the same between 32-bit and 64-bit to
  simplify compat_ioctl()
- export include/linux/mmc/ioctl.h when you ``make headers_install``

- v2
- make initialization of struct declarations match kernel style
- only allow ioctl() on whole block device, not partition
- remove extraneous printks
- implement compat_ioctl()
- remove version field from ``struct sd_ioc_cmd``

John
--
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 v7] mmc: Add mmc CMD+ACMD passthrough ioctl

2011-04-21 Thread John Calixto
Allows appropriately-privileged applications to send CMD (normal) and
ACMD (application-specific; preceded with CMD55) commands to
cards/devices on the mmc bus.  This is primarily useful for enabling the
security functionality built in to every SD card.

It can also be used as a generic passthrough (e.g. to enable virtual
machines to control mmc bus devices directly).  However, this use case
has not been tested rigorously.  Generic passthrough testing was only
conducted for a few non-security opcodes to prove the feasibility of the
passthrough.

Since any opcode can be sent using this passthrough, it is very possible
to render the card/device unusable.  Applications that use this ioctl
must have CAP_SYS_RAWIO.

Security commands tested on TI PCIxx12 (SDHCI), Sigma Designs SMP8652
SoC, TI OMAP3621 SoC, TI OMAP3630 SoC, Samsung S5PC110 SoC, Qualcomm
MSM7200A SoC.

Signed-off-by: John Calixto john.cali...@modsystems.com
Reviewed-by: Andrei Warkentin andr...@motorola.com
---
 Documentation/ioctl/ioctl-number.txt |1 +
 drivers/mmc/card/block.c |  201 ++
 drivers/mmc/core/sd_ops.c|3 +-
 include/linux/Kbuild |1 +
 include/linux/mmc/Kbuild |1 +
 include/linux/mmc/core.h |1 +
 include/linux/mmc/ioctl.h|   54 +
 7 files changed, 261 insertions(+), 1 deletions(-)
 create mode 100644 include/linux/mmc/Kbuild
 create mode 100644 include/linux/mmc/ioctl.h

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index a0a5d82..2a34d82 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -304,6 +304,7 @@ Code  Seq#(hex) Include FileComments
 0xB0   all RATIO devices   in development:
mailto:v...@ratio.de
 0xB1   00-1F   PPPoX   mailto:mostr...@styx.uwaterloo.ca
+0xB3   00  linux/mmc/ioctl.h
 0xC0   00-0F   linux/usb/iowarrior.h
 0xCB   00-1F   CBM serial IEC bus  in development:

mailto:michael.kl...@puffin.lb.shuttle.de
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 61d233a..758419a 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -31,7 +31,11 @@
 #include linux/mutex.h
 #include linux/scatterlist.h
 #include linux/string_helpers.h
+#include linux/delay.h
+#include linux/capability.h
+#include linux/compat.h
 
+#include linux/mmc/ioctl.h
 #include linux/mmc/card.h
 #include linux/mmc/host.h
 #include linux/mmc/mmc.h
@@ -158,11 +162,208 @@ mmc_blk_getgeo(struct block_device *bdev, struct 
hd_geometry *geo)
return 0;
 }
 
+struct mmc_blk_ioc_data {
+   struct mmc_ioc_cmd ic;
+   unsigned char *buf;
+   u64 buf_bytes;
+};
+
+static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
+   struct mmc_ioc_cmd __user *user)
+{
+   struct mmc_blk_ioc_data *idata;
+   int err;
+
+   idata = kzalloc(sizeof(*idata), GFP_KERNEL);
+   if (!idata) {
+   err = -ENOMEM;
+   goto copy_err;
+   }
+
+   if (copy_from_user(idata-ic, user, sizeof(idata-ic))) {
+   err = -EFAULT;
+   goto copy_err;
+   }
+
+   idata-buf_bytes = (u64) idata-ic.blksz * idata-ic.blocks;
+   if (idata-buf_bytes  MMC_IOC_MAX_BYTES) {
+   err = -EOVERFLOW;
+   goto copy_err;
+   }
+
+   idata-buf = kzalloc(idata-buf_bytes, GFP_KERNEL);
+   if (!idata-buf) {
+   err = -ENOMEM;
+   goto copy_err;
+   }
+
+   if (copy_from_user(idata-buf, (void __user *)(unsigned long)
+   idata-ic.data_ptr, idata-buf_bytes)) {
+   err = -EFAULT;
+   goto copy_err;
+   }
+
+   return idata;
+
+copy_err:
+   kfree(idata-buf);
+   kfree(idata);
+   return ERR_PTR(err);
+
+}
+
+static int mmc_blk_ioctl_cmd(struct block_device *bdev,
+   struct mmc_ioc_cmd __user *ic_ptr)
+{
+   struct mmc_blk_ioc_data *idata;
+   struct mmc_blk_data *md;
+   struct mmc_card *card;
+   struct mmc_command cmd = {0};
+   struct mmc_data data = {0};
+   struct mmc_request mrq = {0};
+   struct scatterlist sg;
+   int err;
+
+   /*
+* The caller must have CAP_SYS_RAWIO, and must be calling this on the
+* whole block device, not on a partition.  This prevents overspray
+* between sibling partitions.
+*/
+   if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev-bd_contains))
+   return -EPERM;
+
+   idata = mmc_blk_ioctl_copy_from_user(ic_ptr);
+   if (IS_ERR(idata))
+   return PTR_ERR(idata);
+
+   cmd.opcode = idata-ic.opcode;
+   cmd.arg = idata-ic.arg;
+   cmd.flags = idata-ic.flags;
+
+   data.sg = sg;
+   data.sg_len = 1;
+   data.blksz = 

Re: [PATCH] MMC: TMIO: add runtime PM calls to global suspend() / redume() methods

2011-04-21 Thread Simon Horman
Hi Guennadi,

On Thu, Apr 21, 2011 at 12:32:54PM +0200, Guennadi Liakhovetski wrote:
 The TMIO MMC driver cannot generally suspend itself at runtime even
 with no card inserted, because otherwise it wouldn't be able to detect
 new cards. But when the system goes down for a global suspend, we can
 use runtime PM calls to let it activate platform-specific PM hooks,
 e.g., to switch off respective power domains.
 
 Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
 ---
  drivers/mmc/host/tmio_mmc.h |2 ++
  drivers/mmc/host/tmio_mmc_pio.c |6 ++
  2 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
 index 249c724..58138a2 100644
 --- a/drivers/mmc/host/tmio_mmc.h
 +++ b/drivers/mmc/host/tmio_mmc.h
 @@ -52,6 +52,8 @@ struct tmio_mmc_host {
   void (*set_pwr)(struct platform_device *host, int state);
   void (*set_clk_div)(struct platform_device *host, int state);
  
 + int pm_error;

I wonder if instead of adding an whole int to effectively
store one bit we could use some of the spare space in the
sdio_irq_enabled element, which is also an int that effectively
stores one bit.

Perhaps a bitmask or a bitfield?

I was thinking of doing something similar when adding support
for multiple IRQ vectors, as my current code also needs, wait for it,
one bit :-)

 +
   /* pio related stuff */
   struct scatterlist  *sg_ptr;
   struct scatterlist  *sg_orig;
 diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
 index d1791ba..26598f1 100644
 --- a/drivers/mmc/host/tmio_mmc_pio.c
 +++ b/drivers/mmc/host/tmio_mmc_pio.c
 @@ -980,6 +980,8 @@ int tmio_mmc_host_suspend(struct device *dev)
   if (!ret)
   tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
  
 + host-pm_error = pm_runtime_put_sync(dev);
 +
   return ret;
  }
  EXPORT_SYMBOL(tmio_mmc_host_suspend);
 @@ -987,6 +989,10 @@ EXPORT_SYMBOL(tmio_mmc_host_suspend);
  int tmio_mmc_host_resume(struct device *dev)
  {
   struct mmc_host *mmc = dev_get_drvdata(dev);
 + struct tmio_mmc_host *host = mmc_priv(mmc);
 +
 + if (!host-pm_error)
 + pm_runtime_get_sync(dev);
  
   tmio_mmc_reset(mmc_priv(mmc));
  
 -- 
 1.7.2.5
 
--
To unsubscribe from this list: send the line unsubscribe linux-mmc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7] mmc: Add mmc CMD+ACMD passthrough ioctl

2011-04-21 Thread John Calixto
On Thu, 21 Apr 2011, John Calixto wrote:

snip

 +static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
 + struct mmc_ioc_cmd __user *user)
 +{
 + struct mmc_blk_ioc_data *idata;
 + int err;
 +
 + idata = kzalloc(sizeof(*idata), GFP_KERNEL);
 + if (!idata) {
 + err = -ENOMEM;
 + goto copy_err;
 + }
 +
 + if (copy_from_user(idata-ic, user, sizeof(idata-ic))) {
 + err = -EFAULT;
 + goto copy_err;
 + }
 +
 + idata-buf_bytes = (u64) idata-ic.blksz * idata-ic.blocks;
 + if (idata-buf_bytes  MMC_IOC_MAX_BYTES) {
 + err = -EOVERFLOW;
 + goto copy_err;
 + }
 +
 + idata-buf = kzalloc(idata-buf_bytes, GFP_KERNEL);
 + if (!idata-buf) {
 + err = -ENOMEM;
 + goto copy_err;
 + }
 +

Per Arnd's recommendation, I just cast the ``data_ptr`` to
``(void *)(unsigned long)`` to solve the compatibility issue with the
buffer pointer in struct mmc_ioc_cmd.

 + if (copy_from_user(idata-buf, (void __user *)(unsigned long)
 + idata-ic.data_ptr, idata-buf_bytes)) {
 + err = -EFAULT;
 + goto copy_err;
 + }
 +
 + return idata;
 +
 +copy_err:
 + kfree(idata-buf);
 + kfree(idata);
 + return ERR_PTR(err);
 +
 +}
 +

snip

I also left mmc_blk_ioctl() and mmc_blk_compat_ioctl() as they were in
v6.  IMHO, a __mmc_blk_ioctl() function that accepts a compat32 boolean
arg does not do much to enhance readability or functionality in this
case.  With the implementation in the 2 functions below, I intended to
make it clear that:

- mmc_blk_ioctl() is responsible for delegating to the appropriate
  handler based on the incoming ioctl cmd.  The ``if`` would be
  replaced with a ``switch`` when adding other values for cmd.

- mmc_blk_compat_ioctl() is responsible for converting the ioctl arg
  to something suitable for consumtption by mmc_blk_ioctl().

- when CONFIG_COMPAT is undefined, you get no code related to
  compatibility.

 +
 +static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
 + unsigned int cmd, unsigned long arg)
 +{
 + int ret = -EINVAL;
 + if (cmd == MMC_IOC_CMD)
 + ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg);
 + return ret;
 +}
 +
 +#ifdef CONFIG_COMPAT
 +static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
 + unsigned int cmd, unsigned long arg)
 +{
 + return mmc_blk_ioctl(bdev, mode, cmd, (unsigned long) compat_ptr(arg));
 +}
 +#endif
 +
  static const struct block_device_operations mmc_bdops = {
   .open   = mmc_blk_open,
   .release= mmc_blk_release,
   .getgeo = mmc_blk_getgeo,
   .owner  = THIS_MODULE,
 + .ioctl  = mmc_blk_ioctl,
 +#ifdef CONFIG_COMPAT
 + .compat_ioctl   = mmc_blk_compat_ioctl,
 +#endif
  };
  

snip

It makes a lot of sense to me to make sure that struct mmc_ioc_cmd is
the same size on 32-bit and 64-bit machines, since it is used by _IOWR()
to derive the value for MMC_IOC_CMD.  Any change in its size requires
having other compatibility logic to deal with a MMC_IOC_CMD32.

Note that as this struct has evolved, I also needed to add a ``__pad``
member to the struct to achieve the goal of keeping it the same size on
32-bit and 64-bit.  I could have used packing or alignment compiler
directives, but this seemed simplest to me (I can add up the bytes in my
head!):

 diff --git a/include/linux/mmc/ioctl.h b/include/linux/mmc/ioctl.h
 new file mode 100644
 index 000..225e1e1
 --- /dev/null
 +++ b/include/linux/mmc/ioctl.h
 @@ -0,0 +1,54 @@
 +#ifndef LINUX_MMC_IOCTL_H
 +#define LINUX_MMC_IOCTL_H
 +struct mmc_ioc_cmd {
 + /* Implies direction of data.  true = write, false = read */
 + int write_flag;
 +
 + /* Application-specific command.  true = precede with CMD55 */
 + int is_acmd;
 +
 + __u32 opcode;
 + __u32 arg;
 + __u32 response[4];  /* CMD response */
 + unsigned int flags;
 + unsigned int blksz;
 + unsigned int blocks;
 +
 + /*
 +  * Sleep at least postsleep_min_us useconds, and at most
 +  * postsleep_max_us useconds *after* issuing command.  Needed for some
 +  * read commands for which cards have no other way of indicating
 +  * they're ready for the next command (i.e. there is no equivalent of a
 +  * busy indicator for read operations).
 +  */
 + unsigned int postsleep_min_us;
 + unsigned int postsleep_max_us;
 +
 + /*
 +  * Override driver-computed timeouts.  Note the difference in units!
 +  */
 + unsigned int data_timeout_ns;
 + unsigned int cmd_timeout_ms;
 +
 + /*
 +  * For 64-bit machines, the next member, ``__u64 data_ptr``, wants to
 +  * be 8-byte aligned.  Make sure this struct is the same size when
 +  * built for 

Re: CMD23 plumbing and support patchset.

2011-04-21 Thread Andrei Warkentin
On Thu, Apr 21, 2011 at 1:30 AM, Andrei Warkentin andr...@motorola.com wrote:
 On Thu, Apr 21, 2011 at 1:29 AM, Andrei Warkentin andr...@motorola.com 
 wrote:
 Hi Chris,

 On Wed, Apr 20, 2011 at 8:44 PM, Chris Ball c...@laptop.org wrote:
 Hi,

 On Sat, Apr 16 2011, Andrei Warkentin wrote:
 This is the third version of the CMD23 plumbing and host driver support
 patch set.

 Changes:
 1) CMD23 support (used for features such as reliable writes) is decoupled
    from general multiblock trans through use of a quirk for affected cards.
 2) Newer Sandisk MMC products are whitelisted along with some known good 
 ones. All other
    MMC products do not use CMD23 for general transfers (seems like safest 
 choice for now).
    SD products unaffected.

 Just gave this a try on SEM04G, which is in the whitelist, but didn't
 see a performance increase (or decrease).  What are you using for a
 testcase?  I'm a little wary of running mmc_test on it.  :)


 Can you give me the manufacturing date? This is pretty interesting.

 You can see an improvement even if you do something like time block
 writes (O_DIRECT | O_SYNC, of course). But after all synthetic tests I
 measured the time it took to do 4 SQLite insertions and saw
 something like 30% improvement.


 And you're trying this on SDHCI I presume, right?

Is this on the same board as the other log you sent? Controller is
SDHCI-PXA? If you give me  /sys/block/mmcblk0/device/date,
I'll investigate why this improvement isn't helping you out.

A
--
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: tmio: fix a recent regression: restore .set_ios(MMC_POWER_UP) handling

2011-04-21 Thread Paul Parsons
Yes, Guennadi's patch fixes my problem.

As far as I can see the expression

(ios-clock == 0  ios-power_mode == MMC_POWER_ON)

will only be true if host-f_init == 0 at the time MMC_POWER_ON is invoked in 
mmc_power_up(). Presumably that case is intentional.

--- On Thu, 21/4/11, Chris Ball c...@laptop.org wrote:
 Paul Parsons (CC'd) submitted a similar patch to fix the
 same regression.
 Paul, please could you check that Guennadi's patch fixes
 your problem?

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