linux-mmc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates
@ 2012-05-25 15:14 Guennadi Liakhovetski
  2012-05-25 15:14 ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
                   ` (6 more replies)
  0 siblings, 7 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Hi all

as follow ups to this email I'll send 6 patch series, which are updates to 
the following 2 patch series:

http://thread.gmane.org/gmane.linux.ports.sh.devel/14448
http://thread.gmane.org/gmane.linux.ports.sh.devel/14673

I have further split the latter of the above to make reviewing easier. 
These series address different topics, but since they touch the same 
files, it would be easier to also commit them in the same order. Some 
patches also touch files under arch/arm and arch/sh, they will require 
respective acks. The patches have been developed, based on "next" of 21 
May.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates
  2012-05-25 15:14 [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
@ 2012-05-25 15:14 ` Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling Guennadi Liakhovetski
                     ` (2 more replies)
  2012-05-25 15:14 ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
                   ` (5 subsequent siblings)
  6 siblings, 3 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

This is a respin of
http://thread.gmane.org/gmane.linux.ports.sh.devel/14448
with no functional changes, since there have been to comments to v1. The 
only change is, that the patch-series
http://thread.gmane.org/gmane.linux.ports.sh.devel/14425
has been dropped for now, on which v1 of this series has been based. So, 
v1 wouldn't apply to current upstream trees.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling
  2012-05-25 15:14 ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
@ 2012-05-25 15:14   ` Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 2/3 v3] mmc: sh_mmcif: fix clock management Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 3/3 v3] mmc: sh_mmcif: re-read the clock frequency every time the clock is turned on Guennadi Liakhovetski
  2 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

A check for NULL platform data can be conveniently made in the very
beginning of probing. Replace numbered error-handling labels in .probe()
with meaningful names to make any future reorganisation simpler.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mmcif.c |   41 ++++++++++++++++++++---------------------
 1 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 724b35e..01db31c 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1247,11 +1247,16 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	int ret = 0, irq[2];
 	struct mmc_host *mmc;
 	struct sh_mmcif_host *host;
-	struct sh_mmcif_plat_data *pd;
+	struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
 	struct resource *res;
 	void __iomem *reg;
 	char clk_name[8];
 
+	if (!pd) {
+		dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
+		return -ENXIO;
+	}
+
 	irq[0] = platform_get_irq(pdev, 0);
 	irq[1] = platform_get_irq(pdev, 1);
 	if (irq[0] < 0 || irq[1] < 0) {
@@ -1268,16 +1273,11 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "ioremap error.\n");
 		return -ENOMEM;
 	}
-	pd = pdev->dev.platform_data;
-	if (!pd) {
-		dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
-		ret = -ENXIO;
-		goto clean_up;
-	}
+
 	mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev);
 	if (!mmc) {
 		ret = -ENOMEM;
-		goto clean_up;
+		goto ealloch;
 	}
 	host		= mmc_priv(mmc);
 	host->mmc	= mmc;
@@ -1289,7 +1289,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	if (IS_ERR(host->hclk)) {
 		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
 		ret = PTR_ERR(host->hclk);
-		goto clean_up1;
+		goto eclkget;
 	}
 	clk_enable(host->hclk);
 	host->clk = clk_get_rate(host->hclk);
@@ -1319,7 +1319,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 
 	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
-		goto clean_up2;
+		goto eresume;
 
 	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
 
@@ -1328,17 +1328,17 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
 	if (ret) {
 		dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
-		goto clean_up3;
+		goto ereqirq0;
 	}
 	ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
 	if (ret) {
 		dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
-		goto clean_up4;
+		goto ereqirq1;
 	}
 
 	ret = mmc_add_host(mmc);
 	if (ret < 0)
-		goto clean_up5;
+		goto emmcaddh;
 
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
@@ -1347,20 +1347,19 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 		sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
 	return ret;
 
-clean_up5:
+emmcaddh:
 	free_irq(irq[1], host);
-clean_up4:
+ereqirq1:
 	free_irq(irq[0], host);
-clean_up3:
+ereqirq0:
 	pm_runtime_suspend(&pdev->dev);
-clean_up2:
+eresume:
 	pm_runtime_disable(&pdev->dev);
 	clk_disable(host->hclk);
-clean_up1:
+eclkget:
 	mmc_free_host(mmc);
-clean_up:
-	if (reg)
-		iounmap(reg);
+ealloch:
+	iounmap(reg);
 	return ret;
 }
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/3 v3] mmc: sh_mmcif: fix clock management
  2012-05-25 15:14 ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling Guennadi Liakhovetski
@ 2012-05-25 15:14   ` Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 3/3 v3] mmc: sh_mmcif: re-read the clock frequency every time the clock is turned on Guennadi Liakhovetski
  2 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Regardless, whether the MMC bus clock is the same, as the PM clock on this
specific interface, it has to be managed separately. Its proper management
should also include enabling and disabling of the clock, whenever the
interface is becoming active or going idle respectively.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mmcif.c |   46 +++++++++++++++++++++---------------------
 1 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 01db31c..e5e8198 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -948,6 +948,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		}
 		if (host->power) {
 			pm_runtime_put(&host->pd->dev);
+			clk_disable(host->hclk);
 			host->power = false;
 			if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
 				p->down_pwr(host->pd);
@@ -960,6 +961,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		if (!host->power) {
 			if (p->set_pwr)
 				p->set_pwr(host->pd, ios->power_mode);
+			clk_enable(host->hclk);
 			pm_runtime_get_sync(&host->pd->dev);
 			host->power = true;
 			sh_mmcif_sync_reset(host);
@@ -1284,22 +1286,11 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	host->addr	= reg;
 	host->timeout	= 1000;
 
-	snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
-	host->hclk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(host->hclk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		ret = PTR_ERR(host->hclk);
-		goto eclkget;
-	}
-	clk_enable(host->hclk);
-	host->clk = clk_get_rate(host->hclk);
 	host->pd = pdev;
 
 	spin_lock_init(&host->lock);
 
 	mmc->ops = &sh_mmcif_ops;
-	mmc->f_max = host->clk / 2;
-	mmc->f_min = host->clk / 512;
 	if (pd->ocr)
 		mmc->ocr_avail = pd->ocr;
 	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
@@ -1311,18 +1302,30 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
 	mmc->max_seg_size = mmc->max_req_size;
 
-	sh_mmcif_sync_reset(host);
 	platform_set_drvdata(pdev, host);
 
 	pm_runtime_enable(&pdev->dev);
 	host->power = false;
 
+	snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
+	host->hclk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(host->hclk)) {
+		ret = PTR_ERR(host->hclk);
+		dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
+		goto eclkget;
+	}
+	clk_enable(host->hclk);
+	host->clk = clk_get_rate(host->hclk);
+	mmc->f_max = host->clk / 2;
+	mmc->f_min = host->clk / 512;
+
 	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
 		goto eresume;
 
 	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
 
+	sh_mmcif_sync_reset(host);
 	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
 
 	ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
@@ -1336,6 +1339,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 		goto ereqirq1;
 	}
 
+	clk_disable(host->hclk);
 	ret = mmc_add_host(mmc);
 	if (ret < 0)
 		goto emmcaddh;
@@ -1354,9 +1358,10 @@ ereqirq1:
 ereqirq0:
 	pm_runtime_suspend(&pdev->dev);
 eresume:
-	pm_runtime_disable(&pdev->dev);
 	clk_disable(host->hclk);
+	clk_put(host->hclk);
 eclkget:
+	pm_runtime_disable(&pdev->dev);
 	mmc_free_host(mmc);
 ealloch:
 	iounmap(reg);
@@ -1369,6 +1374,7 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 	int irq[2];
 
 	host->dying = true;
+	clk_enable(host->hclk);
 	pm_runtime_get_sync(&pdev->dev);
 
 	dev_pm_qos_hide_latency_limit(&pdev->dev);
@@ -1394,9 +1400,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, NULL);
 
-	clk_disable(host->hclk);
 	mmc_free_host(host->mmc);
 	pm_runtime_put_sync(&pdev->dev);
+	clk_disable(host->hclk);
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
@@ -1405,24 +1411,18 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 #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);
+	struct sh_mmcif_host *host = dev_get_drvdata(dev);
 	int ret = mmc_suspend_host(host->mmc);
 
-	if (!ret) {
+	if (!ret)
 		sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
-		clk_disable(host->hclk);
-	}
 
 	return ret;
 }
 
 static int sh_mmcif_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
-
-	clk_enable(host->hclk);
+	struct sh_mmcif_host *host = dev_get_drvdata(dev);
 
 	return mmc_resume_host(host->mmc);
 }
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/3 v3] mmc: sh_mmcif: re-read the clock frequency every time the clock is turned on
  2012-05-25 15:14 ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 2/3 v3] mmc: sh_mmcif: fix clock management Guennadi Liakhovetski
@ 2012-05-25 15:14   ` Guennadi Liakhovetski
  2 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

With aggressive clock gating the clock can be disabled during interface
inactivity. During this time its frequency can be changed by another its
user. Therefore when the interface is activated again and the clock is
re-enabled, its frequency has to be re-read.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v2: also move clk_enable() inside sh_mmcif_clk_update(), check its return 
value in .probe()

 drivers/mmc/host/sh_mmcif.c |   23 ++++++++++++++++++-----
 1 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index e5e8198..bdf42d5 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -916,6 +916,19 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	sh_mmcif_start_cmd(host, mrq);
 }
 
+static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
+{
+	int ret = clk_enable(host->hclk);
+
+	if (!ret) {
+		host->clk = clk_get_rate(host->hclk);
+		host->mmc->f_max = host->clk / 2;
+		host->mmc->f_min = host->clk / 512;
+	}
+
+	return ret;
+}
+
 static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct sh_mmcif_host *host = mmc_priv(mmc);
@@ -961,7 +974,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		if (!host->power) {
 			if (p->set_pwr)
 				p->set_pwr(host->pd, ios->power_mode);
-			clk_enable(host->hclk);
+			sh_mmcif_clk_update(host);
 			pm_runtime_get_sync(&host->pd->dev);
 			host->power = true;
 			sh_mmcif_sync_reset(host);
@@ -1314,10 +1327,9 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
 		goto eclkget;
 	}
-	clk_enable(host->hclk);
-	host->clk = clk_get_rate(host->hclk);
-	mmc->f_max = host->clk / 2;
-	mmc->f_min = host->clk / 512;
+	ret = sh_mmcif_clk_update(host);
+	if (ret < 0)
+		goto eclkupdate;
 
 	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
@@ -1359,6 +1371,7 @@ ereqirq0:
 	pm_runtime_suspend(&pdev->dev);
 eresume:
 	clk_disable(host->hclk);
+eclkupdate:
 	clk_put(host->hclk);
 eclkget:
 	pm_runtime_disable(&pdev->dev);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support
  2012-05-25 15:14 [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
  2012-05-25 15:14 ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
@ 2012-05-25 15:14 ` Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback Guennadi Liakhovetski
                     ` (4 more replies)
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
                   ` (4 subsequent siblings)
  6 siblings, 5 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

This series is an update for patches 1-3,7,8 from
http://thread.gmane.org/gmane.linux.ports.sh.devel/14673

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback
  2012-05-25 15:14 ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
@ 2012-05-25 15:14   ` Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 2/5 v3] sh: ecovec: remove unused .down_pwr() MMCIF callback Guennadi Liakhovetski
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

>From the original version of sh_mmcif the .set_pwr() callback has only been
used to turn the card's power on, and the .down_pwr() callback has been
used to turn it off. .set_pwr() can be used for both these tasks, which is
also how it is implemented by the only user of this API: the SH7724 ecovec
board.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mmcif.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index bdf42d5..3834b21 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -963,8 +963,8 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			pm_runtime_put(&host->pd->dev);
 			clk_disable(host->hclk);
 			host->power = false;
-			if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
-				p->down_pwr(host->pd);
+			if (p->set_pwr && ios->power_mode == MMC_POWER_OFF)
+				p->set_pwr(host->pd, 0);
 		}
 		host->state = STATE_IDLE;
 		return;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/5 v3] sh: ecovec: remove unused .down_pwr() MMCIF callback
  2012-05-25 15:14 ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback Guennadi Liakhovetski
@ 2012-05-25 15:14   ` Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 3/5 v3] mmc: sh_mmcif: remove unused .down_pwr() callback Guennadi Liakhovetski
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown, Paul Mundt

.down_pwr() on ecovec was equivalent to .set_pwr(0). Now that .down_pwr()
is no longer used by the driver, it can be removed.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

Paul, would be good to get your ack to this one to push all this patches 
via one tree and make preserving the merge order easier. Thanks.

 arch/sh/boards/mach-ecovec24/setup.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 4158d70..dbedfda 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -904,11 +904,6 @@ static void mmcif_set_pwr(struct platform_device *pdev, int state)
 	gpio_set_value(GPIO_PTB7, state);
 }
 
-static void mmcif_down_pwr(struct platform_device *pdev)
-{
-	gpio_set_value(GPIO_PTB7, 0);
-}
-
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
 		.name	= "SH_MMCIF",
@@ -930,7 +925,6 @@ static struct resource sh_mmcif_resources[] = {
 
 static struct sh_mmcif_plat_data sh_mmcif_plat = {
 	.set_pwr	= mmcif_set_pwr,
-	.down_pwr	= mmcif_down_pwr,
 	.sup_pclk	= 0, /* SH7724: Max Pclk/2 */
 	.caps		= MMC_CAP_4_BIT_DATA |
 			  MMC_CAP_8_BIT_DATA |
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/5 v3] mmc: sh_mmcif: remove unused .down_pwr() callback
  2012-05-25 15:14 ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 2/5 v3] sh: ecovec: remove unused .down_pwr() MMCIF callback Guennadi Liakhovetski
@ 2012-05-25 15:14   ` Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
  2012-05-25 15:14   ` [PATCH 5/5 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
  4 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

This patch shall only be applied after the previous one. If the previous 
one has to go via the sh tree, we can postpone this one until a later 
merge, no big problem with that.

 include/linux/mmc/sh_mmcif.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h
index 05f0e3d..cb84340 100644
--- a/include/linux/mmc/sh_mmcif.h
+++ b/include/linux/mmc/sh_mmcif.h
@@ -39,7 +39,6 @@ struct sh_mmcif_dma {
 
 struct sh_mmcif_plat_data {
 	void (*set_pwr)(struct platform_device *pdev, int state);
-	void (*down_pwr)(struct platform_device *pdev);
 	int (*get_cd)(struct platform_device *pdef);
 	struct sh_mmcif_dma	*dma;		/* Deprecated. Instead */
 	unsigned int		slave_id_tx;	/* use embedded slave_id_[tr]x */
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-25 15:14 ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
                     ` (2 preceding siblings ...)
  2012-05-25 15:14   ` [PATCH 3/5 v3] mmc: sh_mmcif: remove unused .down_pwr() callback Guennadi Liakhovetski
@ 2012-05-25 15:14   ` Guennadi Liakhovetski
  2012-05-28  3:20     ` Ulf Hansson
  2012-05-28 14:45     ` Mark Brown
  2012-05-25 15:14   ` [PATCH 5/5 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
  4 siblings, 2 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

Add a function to get a regulator, supplying card's Vdd on a specific host.
If such a regulator is found, the function checks, whether a valid OCR mask
can be obtained from this regulator.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v3: remove bogus attempts to ignore the dummy regulator, drop the check 
for whether the regulator can change status, do not assign 
MMC_CAP_POWER_OFF_CARD automatically. Thanks to Mark and Magnus for 
comments.

 drivers/mmc/core/core.c  |   17 +++++++++++++++++
 include/linux/mmc/host.h |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0b6141d..0f92ec0 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1013,6 +1013,23 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
 }
 EXPORT_SYMBOL(mmc_regulator_set_ocr);
 
+struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
+{
+	struct device *dev = mmc_dev(mmc);
+	struct regulator *supply = devm_regulator_get(dev, "vmmc");
+	int ret;
+
+	if (IS_ERR(supply))
+		return NULL;
+
+	ret = mmc_regulator_get_ocrmask(supply);
+	if (ret > 0)
+		mmc->ocr_avail = ret;
+
+	return supply;
+}
+EXPORT_SYMBOL(mmc_regulator_get_vmmc);
+
 #endif /* CONFIG_REGULATOR */
 
 /*
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 0707d22..368b317 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -364,6 +364,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
 			struct regulator *supply,
 			unsigned short vdd_bit);
+struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc);
 #else
 static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
 {
@@ -376,6 +377,11 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
 {
 	return 0;
 }
+
+static inline struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
+{
+	return NULL;
+}
 #endif
 
 int mmc_card_awake(struct mmc_host *host);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 5/5 v3] mmc: sh_mmcif: add regulator support
  2012-05-25 15:14 ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
                     ` (3 preceding siblings ...)
  2012-05-25 15:14   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
@ 2012-05-25 15:14   ` Guennadi Liakhovetski
  4 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:14 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

Add regulator support to the sh_mmcif driver, but also preserve the current
power-callback.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v3: don't (yet) give preference to using the regulator over the .set_pwr() 
platform callback, call them both if both are available. Thanks to Mark 
and Magnus.

 drivers/mmc/host/sh_mmcif.c |   41 ++++++++++++++++++++++++++++++++++-------
 1 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 3834b21..f952978 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -207,6 +207,8 @@ enum mmcif_wait_for {
 	MMCIF_WAIT_FOR_STOP,
 };
 
+struct regulator;
+
 struct sh_mmcif_host {
 	struct mmc_host *mmc;
 	struct mmc_request *mrq;
@@ -231,6 +233,8 @@ struct sh_mmcif_host {
 	bool power;
 	bool card_present;
 
+	struct regulator	*vdd;
+
 	/* DMA support */
 	struct dma_chan		*chan_rx;
 	struct dma_chan		*chan_tx;
@@ -929,10 +933,21 @@ static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
 	return ret;
 }
 
+static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios)
+{
+	struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
+
+	if (pd->set_pwr)
+		pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF);
+	if (host->vdd)
+		/* Errors ignored... */
+		mmc_regulator_set_ocr(host->mmc, host->vdd,
+				      ios->power_mode ? ios->vdd : 0);
+}
+
 static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct sh_mmcif_host *host = mmc_priv(mmc);
-	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&host->lock, flags);
@@ -950,6 +965,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			sh_mmcif_request_dma(host, host->pd->dev.platform_data);
 			host->card_present = true;
 		}
+		sh_mmcif_set_power(host, ios);
 	} else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
 		/* clock stop */
 		sh_mmcif_clock_control(host, 0);
@@ -963,8 +979,8 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			pm_runtime_put(&host->pd->dev);
 			clk_disable(host->hclk);
 			host->power = false;
-			if (p->set_pwr && ios->power_mode == MMC_POWER_OFF)
-				p->set_pwr(host->pd, 0);
+			if (ios->power_mode == MMC_POWER_OFF)
+				sh_mmcif_set_power(host, ios);
 		}
 		host->state = STATE_IDLE;
 		return;
@@ -972,8 +988,6 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
 	if (ios->clock) {
 		if (!host->power) {
-			if (p->set_pwr)
-				p->set_pwr(host->pd, ios->power_mode);
 			sh_mmcif_clk_update(host);
 			pm_runtime_get_sync(&host->pd->dev);
 			host->power = true;
@@ -1257,6 +1271,19 @@ static void mmcif_timeout_work(struct work_struct *work)
 	mmc_request_done(host->mmc, mrq);
 }
 
+static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
+{
+	struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
+	struct mmc_host *mmc = host->mmc;
+
+	host->vdd = mmc_regulator_get_vmmc(mmc);
+
+	if (!mmc->ocr_avail)
+		mmc->ocr_avail = pd->ocr;
+	else if (pd->ocr)
+		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
+}
+
 static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 {
 	int ret = 0, irq[2];
@@ -1304,8 +1331,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	spin_lock_init(&host->lock);
 
 	mmc->ops = &sh_mmcif_ops;
-	if (pd->ocr)
-		mmc->ocr_avail = pd->ocr;
+	sh_mmcif_init_ocr(host);
+
 	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
 	if (pd->caps)
 		mmc->caps |= pd->caps;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates
  2012-05-25 15:14 [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
  2012-05-25 15:14 ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
  2012-05-25 15:14 ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
@ 2012-05-25 15:15 ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending Guennadi Liakhovetski
                     ` (7 more replies)
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                   ` (3 subsequent siblings)
  6 siblings, 8 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

This is an update for patches 9-14,16,18 from
http://thread.gmane.org/gmane.linux.ports.sh.devel/14673

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 2/8 v3] mmc: tmio: don't needlessly enable interrupts during probing Guennadi Liakhovetski
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

The call to pm_runtime_put() in tmio-mmc's .set_ios() method can switch
off the supplying clock or even power down the whole unit. Therefore,
calling tmio_mmc_clk_stop() after that can be redundant, put it before.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 9a7996a..0d2643b 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -809,11 +809,11 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	} else if (ios->power_mode != MMC_POWER_UP) {
 		if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
 			host->set_pwr(host->pdev, 0);
+		tmio_mmc_clk_stop(host);
 		if (host->power) {
 			host->power = false;
 			pm_runtime_put(dev);
 		}
-		tmio_mmc_clk_stop(host);
 	}
 
 	switch (ios->bus_width) {
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/8 v3] mmc: tmio: don't needlessly enable interrupts during probing
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 3/8 v3] mmc: tmio: add callbacks to enable-update and disable the interface clock Guennadi Liakhovetski
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

We don't have to force-enable MMC interrupts in our .probe() method,
mmc_add_host() will trigger card detection, that will enable all the
necessary interrupts.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |   21 +++++++++++----------
 1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 0d2643b..8cd3637 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -948,6 +948,17 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	_host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
 	tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
+
+	/* Unmask the IRQs we want to know about */
+	if (!_host->chan_rx)
+		irq_mask |= TMIO_MASK_READOP;
+	if (!_host->chan_tx)
+		irq_mask |= TMIO_MASK_WRITEOP;
+	if (!_host->native_hotplug)
+		irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
+
+	_host->sdcard_irq_mask &= ~irq_mask;
+
 	if (pdata->flags & TMIO_MMC_SDIO_IRQ)
 		tmio_mmc_enable_sdio_irq(mmc, 0);
 
@@ -965,16 +976,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
-	/* Unmask the IRQs we want to know about */
-	if (!_host->chan_rx)
-		irq_mask |= TMIO_MASK_READOP;
-	if (!_host->chan_tx)
-		irq_mask |= TMIO_MASK_WRITEOP;
-	if (!_host->native_hotplug)
-		irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
-
-	tmio_mmc_enable_mmc_irqs(_host, irq_mask);
-
 	if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
 		ret = mmc_cd_gpio_request(mmc, pdata->cd_gpio);
 		if (ret < 0) {
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/8 v3] mmc: tmio: add callbacks to enable-update and disable the interface clock
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 2/8 v3] mmc: tmio: don't needlessly enable interrupts during probing Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 4/8 v3] mmc: sdhi: implement tmio-mmc clock enable-update and disable callbacks Guennadi Liakhovetski
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Every time the clockc is enabled after possibly being disabled, we have
to re-read its frequency and update our configuration.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |   35 ++++++++++++++++++++++++++++++++---
 include/linux/mfd/tmio.h        |    3 +++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 8cd3637..579f990 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -751,6 +751,22 @@ fail:
 	mmc_request_done(mmc, mrq);
 }
 
+static int tmio_mmc_clk_update(struct mmc_host *mmc)
+{
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct tmio_mmc_data *pdata = host->pdata;
+	int ret;
+
+	if (!pdata->clk_enable)
+		return -ENOTSUPP;
+
+	ret = pdata->clk_enable(host->pdev, &mmc->f_max);
+	if (!ret)
+		mmc->f_min = mmc->f_max / 512;
+
+	return ret;
+}
+
 /* Set MMC clock / power.
  * Note: This controller uses a simple divider scheme therefore it cannot
  * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
@@ -797,6 +813,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	 */
 	if (ios->power_mode == MMC_POWER_ON && ios->clock) {
 		if (!host->power) {
+			tmio_mmc_clk_update(mmc);
 			pm_runtime_get_sync(dev);
 			host->power = true;
 		}
@@ -811,8 +828,11 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			host->set_pwr(host->pdev, 0);
 		tmio_mmc_clk_stop(host);
 		if (host->power) {
+			struct tmio_mmc_data *pdata = host->pdata;
 			host->power = false;
 			pm_runtime_put(dev);
+			if (pdata->clk_disable)
+				pdata->clk_disable(host->pdev);
 		}
 	}
 
@@ -904,8 +924,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	mmc->ops = &tmio_mmc_ops;
 	mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
-	mmc->f_max = pdata->hclk;
-	mmc->f_min = mmc->f_max / 512;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
 	mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
@@ -927,6 +945,11 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	if (ret < 0)
 		goto pm_disable;
 
+	if (tmio_mmc_clk_update(mmc) < 0) {
+		mmc->f_max = pdata->hclk;
+		mmc->f_min = mmc->f_max / 512;
+	}
+
 	/*
 	 * There are 4 different scenarios for the card detection:
 	 *  1) an external gpio irq handles the cd (best for power savings)
@@ -972,7 +995,13 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	/* See if we also get DMA */
 	tmio_mmc_request_dma(_host, pdata);
 
-	mmc_add_host(mmc);
+	ret = mmc_add_host(mmc);
+	if (pdata->clk_disable)
+		pdata->clk_disable(pdev);
+	if (ret < 0) {
+		tmio_mmc_host_remove(_host);
+		return ret;
+	}
 
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index f5171db..b332c4c 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -110,6 +110,9 @@ struct tmio_mmc_data {
 	void (*set_clk_div)(struct platform_device *host, int state);
 	int (*get_cd)(struct platform_device *host);
 	int (*write16_hook)(struct tmio_mmc_host *host, int addr);
+	/* clock management callbacks */
+	int (*clk_enable)(struct platform_device *pdev, unsigned int *f);
+	void (*clk_disable)(struct platform_device *pdev);
 };
 
 /*
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 4/8 v3] mmc: sdhi: implement tmio-mmc clock enable-update and disable callbacks
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
                     ` (2 preceding siblings ...)
  2012-05-25 15:15   ` [PATCH 3/8 v3] mmc: tmio: add callbacks to enable-update and disable the interface clock Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 5/8 v3] mmc: tmio: add regulator support Guennadi Liakhovetski
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Instead of delivering one static clock frequency value, read from the
hardware during probing, enable the tmio-mmc driver to re-read the
frequency dynamically.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 934b68e..d8b167c 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -39,6 +39,27 @@ struct sh_mobile_sdhi {
 	struct tmio_mmc_dma dma_priv;
 };
 
+static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int *f)
+{
+	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
+	int ret = clk_enable(priv->clk);
+	if (ret < 0)
+		return ret;
+
+	*f = clk_get_rate(priv->clk);
+	return 0;
+}
+
+static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
+	clk_disable(priv->clk);
+}
+
 static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
 {
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
@@ -132,9 +153,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 		goto eclkget;
 	}
 
-	mmc_data->hclk = clk_get_rate(priv->clk);
 	mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
 	mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+	mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
+	mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
 	mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
 	if (p) {
 		mmc_data->flags = p->tmio_flags;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 5/8 v3] mmc: tmio: add regulator support
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
                     ` (3 preceding siblings ...)
  2012-05-25 15:15   ` [PATCH 4/8 v3] mmc: sdhi: implement tmio-mmc clock enable-update and disable callbacks Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 6/8 v3] mmc: sdhi: do not install dummy callbacks Guennadi Liakhovetski
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

Currently the TMIO MMC driver derives the OCR mask from the platform data
and uses a platform callback to turn card power on and off. This patch adds
regulator support to the driver.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v3: similar to MMCIF don't prefer regulator over platform callback, call 
both. Thanks to all, who commented.

 drivers/mmc/host/tmio_mmc.h     |    3 +++
 drivers/mmc/host/tmio_mmc_pio.c |   35 +++++++++++++++++++++++++++--------
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index d857f5c..3a8dcfb 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -39,6 +39,7 @@
 #define TMIO_MASK_IRQ     (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
 
 struct tmio_mmc_data;
+struct regulator;
 
 struct tmio_mmc_host {
 	void __iomem *ctl;
@@ -55,6 +56,8 @@ struct tmio_mmc_host {
 	void (*set_pwr)(struct platform_device *host, int state);
 	void (*set_clk_div)(struct platform_device *host, int state);
 
+	struct regulator	*vdd;
+
 	/* 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 579f990..baa0959 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -767,6 +767,16 @@ static int tmio_mmc_clk_update(struct mmc_host *mmc)
 	return ret;
 }
 
+static void tmio_mmc_set_power(struct tmio_mmc_host *host, struct mmc_ios *ios)
+{
+	if (host->set_pwr)
+		host->set_pwr(host->pdev, ios->power_mode != MMC_POWER_OFF);
+	if (host->vdd)
+		/* Errors ignored... */
+		mmc_regulator_set_ocr(host->mmc, host->vdd,
+				      ios->power_mode ? ios->vdd : 0);
+}
+
 /* Set MMC clock / power.
  * Note: This controller uses a simple divider scheme therefore it cannot
  * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
@@ -819,13 +829,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		}
 		tmio_mmc_set_clock(host, ios->clock);
 		/* power up SD bus */
-		if (host->set_pwr)
-			host->set_pwr(host->pdev, 1);
+		tmio_mmc_set_power(host, ios);
 		/* start bus clock */
 		tmio_mmc_clk_start(host);
 	} else if (ios->power_mode != MMC_POWER_UP) {
-		if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
-			host->set_pwr(host->pdev, 0);
+		if (ios->power_mode == MMC_POWER_OFF)
+			tmio_mmc_set_power(host, ios);
 		tmio_mmc_clk_stop(host);
 		if (host->power) {
 			struct tmio_mmc_data *pdata = host->pdata;
@@ -885,6 +894,19 @@ static const struct mmc_host_ops tmio_mmc_ops = {
 	.enable_sdio_irq = tmio_mmc_enable_sdio_irq,
 };
 
+static void tmio_mmc_init_ocr(struct tmio_mmc_host *host)
+{
+	struct tmio_mmc_data *pdata = host->pdata;
+	struct mmc_host *mmc = host->mmc;
+
+	host->vdd = mmc_regulator_get_vmmc(mmc);
+
+	if (!mmc->ocr_avail)
+		mmc->ocr_avail = pdata->ocr_mask ? : MMC_VDD_32_33 | MMC_VDD_33_34;
+	else if (pdata->ocr_mask)
+		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
+}
+
 int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 				  struct platform_device *pdev,
 				  struct tmio_mmc_data *pdata)
@@ -930,10 +952,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 		mmc->max_segs;
 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
 	mmc->max_seg_size = mmc->max_req_size;
-	if (pdata->ocr_mask)
-		mmc->ocr_avail = pdata->ocr_mask;
-	else
-		mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	tmio_mmc_init_ocr(_host);
 
 	_host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD ||
 				  mmc->caps & MMC_CAP_NEEDS_POLL ||
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 6/8 v3] mmc: sdhi: do not install dummy callbacks
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
                     ` (4 preceding siblings ...)
  2012-05-25 15:15   ` [PATCH 5/8 v3] mmc: tmio: add regulator support Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 7/8 v3] mmc: tmio: use MMC opcode defines instead of numbers Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 8/8 v3] mmc: tmio: remove a duplicated comment line Guennadi Liakhovetski
  7 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Currently the SDHI glue for the TMIO MMC driver installs dummy .get_cd() and
.set_pwr() callbacks even if the platform didn't supply them. This is not
necessary, since the TMIO MMC driver itself checks for NULL callbacks. This
is also dubious if the platform provides a regulator for SD-card power
switching. It is better to only install those callbacks, if they are really
provided by the platform.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c |   14 ++++++--------
 1 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index d8b167c..42f07fa 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -64,18 +64,14 @@ static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
 {
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 
-	if (p && p->set_pwr)
-		p->set_pwr(pdev, state);
+	p->set_pwr(pdev, state);
 }
 
 static int sh_mobile_sdhi_get_cd(struct platform_device *pdev)
 {
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 
-	if (p && p->get_cd)
-		return p->get_cd(pdev);
-	else
-		return -ENOSYS;
+	return p->get_cd(pdev);
 }
 
 static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
@@ -153,8 +149,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 		goto eclkget;
 	}
 
-	mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
-	mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+	if (p->set_pwr)
+		mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+	if (p->get_cd)
+		mmc_data->get_cd = sh_mobile_sdhi_get_cd;
 	mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
 	mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
 	mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 7/8 v3] mmc: tmio: use MMC opcode defines instead of numbers
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
                     ` (5 preceding siblings ...)
  2012-05-25 15:15   ` [PATCH 6/8 v3] mmc: sdhi: do not install dummy callbacks Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 8/8 v3] mmc: tmio: remove a duplicated comment line Guennadi Liakhovetski
  7 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

mmc.h defines macros for most frequently used MMC opcodes. Use them instead
of hard-coded numbers.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index baa0959..a4f1c59 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -36,6 +36,7 @@
 #include <linux/mfd/tmio.h>
 #include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
 #include <linux/mmc/tmio.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
@@ -305,8 +306,8 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
 	int c = cmd->opcode;
 	u32 irq_mask = TMIO_MASK_CMD;
 
-	/* Command 12 is handled by hardware */
-	if (cmd->opcode == 12 && !cmd->arg) {
+	/* CMD12 is handled by hardware */
+	if (cmd->opcode == MMC_STOP_TRANSMISSION && !cmd->arg) {
 		sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001);
 		return 0;
 	}
@@ -449,7 +450,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
 	}
 
 	if (stop) {
-		if (stop->opcode == 12 && !stop->arg)
+		if (stop->opcode == MMC_STOP_TRANSMISSION && !stop->arg)
 			sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000);
 		else
 			BUG();
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 8/8 v3] mmc: tmio: remove a duplicated comment line
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
                     ` (6 preceding siblings ...)
  2012-05-25 15:15   ` [PATCH 7/8 v3] mmc: tmio: use MMC opcode defines instead of numbers Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  7 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index a4f1c59..b731859 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -980,7 +980,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	 *  While we increment the runtime PM counter for all scenarios when
 	 *  the mmc core activates us by calling an appropriate set_ios(), we
 	 *  must additionally ensure that in case 2) the tmio mmc hardware stays
-	 *  additionally ensure that in case 2) the tmio mmc hardware stays
 	 *  powered on during runtime for the card detection to work.
 	 */
 	if (_host->native_hotplug)
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions
  2012-05-25 15:14 [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                   ` (2 preceding siblings ...)
  2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
@ 2012-05-25 15:15 ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions Guennadi Liakhovetski
                     ` (9 more replies)
  2012-05-25 15:16 ` [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi Guennadi Liakhovetski
                   ` (2 subsequent siblings)
  6 siblings, 10 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

This is an update of patches 15,17,19-23 from the previous version

http://thread.gmane.org/gmane.linux.ports.sh.devel/14673

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 02/10 v3] mmc: use a more generic name for slot function types and fields Guennadi Liakhovetski
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, S, Venkatraman

GPIOs can be used in MMC/SD-card slots not only for hotplug detection, but
also to implement the write-protection pin. Rename cd-gpio helpers to
slot-gpio to make addition of further slot GPIO functions possible.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v3: use the IRQF_ONESHOT flag, thanks to Venkatraman for the comment.

 drivers/mmc/core/Makefile                    |    2 +-
 drivers/mmc/core/{cd-gpio.c => slot-gpio.c}  |   48 +++++++++++++-------------
 drivers/mmc/host/tmio_mmc_pio.c              |    6 ++--
 include/linux/mmc/{cd-gpio.h => slot-gpio.h} |    8 ++--
 4 files changed, 32 insertions(+), 32 deletions(-)
 rename drivers/mmc/core/{cd-gpio.c => slot-gpio.c} (53%)
 rename include/linux/mmc/{cd-gpio.h => slot-gpio.h} (68%)

diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index dca4428..38ed210 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -7,6 +7,6 @@ mmc_core-y			:= core.o bus.o host.o \
 				   mmc.o mmc_ops.o sd.o sd_ops.o \
 				   sdio.o sdio_ops.o sdio_bus.o \
 				   sdio_cis.o sdio_io.o sdio_irq.o \
-				   quirks.o cd-gpio.o
+				   quirks.o slot-gpio.o
 
 mmc_core-$(CONFIG_DEBUG_FS)	+= debugfs.o
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/slot-gpio.c
similarity index 53%
rename from drivers/mmc/core/cd-gpio.c
rename to drivers/mmc/core/slot-gpio.c
index f13e38d..9796710 100644
--- a/drivers/mmc/core/cd-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -12,72 +12,72 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 
-struct mmc_cd_gpio {
-	unsigned int gpio;
-	char label[0];
+struct mmc_gpio {
+	unsigned int cd_gpio;
+	char cd_label[0];
 };
 
-static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
+static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 {
 	/* Schedule a card detection after a debounce timeout */
 	mmc_detect_change(dev_id, msecs_to_jiffies(100));
 	return IRQ_HANDLED;
 }
 
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	size_t len = strlen(dev_name(host->parent)) + 4;
-	struct mmc_cd_gpio *cd;
+	struct mmc_gpio *ctx;
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
 	if (irq < 0)
 		return irq;
 
-	cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
-	if (!cd)
+	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
+	if (!ctx)
 		return -ENOMEM;
 
-	snprintf(cd->label, len, "%s cd", dev_name(host->parent));
+	snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
 
-	ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
+	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
 	if (ret < 0)
 		goto egpioreq;
 
-	ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
-				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				   cd->label, host);
+	ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			ctx->cd_label, host);
 	if (ret < 0)
 		goto eirqreq;
 
-	cd->gpio = gpio;
+	ctx->cd_gpio = gpio;
 	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = cd;
+	host->hotplug.handler_priv = ctx;
 
 	return 0;
 
 eirqreq:
 	gpio_free(gpio);
 egpioreq:
-	kfree(cd);
+	kfree(ctx);
 	return ret;
 }
-EXPORT_SYMBOL(mmc_cd_gpio_request);
+EXPORT_SYMBOL(mmc_gpio_request_cd);
 
-void mmc_cd_gpio_free(struct mmc_host *host)
+void mmc_gpio_free_cd(struct mmc_host *host)
 {
-	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
+	struct mmc_gpio *ctx = host->hotplug.handler_priv;
 
-	if (!cd)
+	if (!ctx)
 		return;
 
 	free_irq(host->hotplug.irq, host);
-	gpio_free(cd->gpio);
-	kfree(cd);
+	gpio_free(ctx->cd_gpio);
+	kfree(ctx);
 }
-EXPORT_SYMBOL(mmc_cd_gpio_free);
+EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index b731859..5261934 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -34,9 +34,9 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/mfd/tmio.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/mmc/tmio.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
@@ -1025,7 +1025,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
 	if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
-		ret = mmc_cd_gpio_request(mmc, pdata->cd_gpio);
+		ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio);
 		if (ret < 0) {
 			tmio_mmc_host_remove(_host);
 			return ret;
@@ -1057,7 +1057,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 		 * This means we can miss a card-eject, but this is anyway
 		 * possible, because of delayed processing of hotplug events.
 		 */
-		mmc_cd_gpio_free(mmc);
+		mmc_gpio_free_cd(mmc);
 
 	if (!host->native_hotplug)
 		pm_runtime_get_sync(&pdev->dev);
diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/slot-gpio.h
similarity index 68%
rename from include/linux/mmc/cd-gpio.h
rename to include/linux/mmc/slot-gpio.h
index cefaba0..edfaa32 100644
--- a/include/linux/mmc/cd-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -8,11 +8,11 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef MMC_CD_GPIO_H
-#define MMC_CD_GPIO_H
+#ifndef MMC_SLOT_GPIO_H
+#define MMC_SLOT_GPIO_H
 
 struct mmc_host;
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio);
-void mmc_cd_gpio_free(struct mmc_host *host);
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_cd(struct mmc_host *host);
 
 #endif
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 02/10 v3] mmc: use a more generic name for slot function types and fields
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 03/10 v3] mmc: add two capability flags for CD and WP signal polarity Guennadi Liakhovetski
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

struct mmc_host::hotplug is becoming a generic hook for slot functions.
Rename it accordingly.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/host.c      |    2 ++
 drivers/mmc/core/slot-gpio.c |    8 ++++----
 include/linux/mmc/host.h     |   17 ++++++++++++++---
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 91c84c7..b8c5290 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -327,6 +327,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 
 	mmc_host_clk_init(host);
 
+	host->slot.cd_irq = -EINVAL;
+
 	spin_lock_init(&host->lock);
 	init_waitqueue_head(&host->wq);
 	INIT_DELAYED_WORK(&host->detect, mmc_rescan);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 9796710..468e5a0 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -56,8 +56,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 		goto eirqreq;
 
 	ctx->cd_gpio = gpio;
-	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = ctx;
+	host->slot.cd_irq = irq;
+	host->slot.handler_priv = ctx;
 
 	return 0;
 
@@ -71,12 +71,12 @@ EXPORT_SYMBOL(mmc_gpio_request_cd);
 
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
-	struct mmc_gpio *ctx = host->hotplug.handler_priv;
+	struct mmc_gpio *ctx = host->slot.handler_priv;
 
 	if (!ctx)
 		return;
 
-	free_irq(host->hotplug.irq, host);
+	free_irq(host->slot.cd_irq, host);
 	gpio_free(ctx->cd_gpio);
 	kfree(ctx);
 }
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 368b317..725413d 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -150,8 +150,19 @@ struct mmc_async_req {
 	int (*err_check) (struct mmc_card *, struct mmc_async_req *);
 };
 
-struct mmc_hotplug {
-	unsigned int irq;
+/**
+ * struct mmc_slot - MMC slot functions
+ *
+ * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @handler_priv:	MMC/SD-card slot context
+ *
+ * Some MMC/SD host controllers implement slot-functions like card and
+ * write-protect detection natively. However, a large number of controllers
+ * leave these functions to the CPU. This struct provides a hook to attach
+ * such slot-function drivers.
+ */
+struct mmc_slot {
+	int cd_irq;
 	void *handler_priv;
 };
 
@@ -290,7 +301,7 @@ struct mmc_host {
 
 	struct delayed_work	detect;
 	int			detect_change;	/* card detect flag */
-	struct mmc_hotplug	hotplug;
+	struct mmc_slot		slot;
 
 	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
 	unsigned int		bus_refs;	/* reference counter */
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 03/10 v3] mmc: add two capability flags for CD and WP signal polarity
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions Guennadi Liakhovetski
  2012-05-25 15:15   ` [PATCH 02/10 v3] mmc: use a more generic name for slot function types and fields Guennadi Liakhovetski
@ 2012-05-25 15:15   ` Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 04/10 v3] mmc: add CD GPIO polling support to slot functions Guennadi Liakhovetski
                     ` (6 subsequent siblings)
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:15 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

To handle CD and WP SD/MMC slot pins we need generic flags to specify their
polarity.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 include/linux/mmc/host.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 725413d..1b3a917 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -249,6 +249,8 @@ struct mmc_host {
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_INVERTED_CD	(1 << 10)	/* Card-detect signal active low */
+#define MMC_CAP2_INVERTED_RO	(1 << 11)	/* Write-protect signal active low */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 04/10 v3] mmc: add CD GPIO polling support to slot functions
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                     ` (2 preceding siblings ...)
  2012-05-25 15:15   ` [PATCH 03/10 v3] mmc: add two capability flags for CD and WP signal polarity Guennadi Liakhovetski
@ 2012-05-25 15:16   ` Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 05/10 v3] mmc: convert slot functions to managed allocation Guennadi Liakhovetski
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

A simple extension of mmc slot functions add support for CD GPIO polling
for cases, where the GPIO cannot produce interrupts or this is for some
reason not desired.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/slot-gpio.c  |   45 +++++++++++++++++++++++++++++++---------
 include/linux/mmc/slot-gpio.h |    2 +
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 468e5a0..d70b790 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -29,6 +29,18 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+int mmc_gpio_get_cd(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->cd_gpio) ^
+		!(host->caps2 & MMC_CAP2_INVERTED_CD);
+}
+EXPORT_SYMBOL(mmc_gpio_get_cd);
+
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	size_t len = strlen(dev_name(host->parent)) + 4;
@@ -36,9 +48,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
-	if (irq < 0)
-		return irq;
-
 	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
@@ -49,20 +58,32 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	if (ret < 0)
 		goto egpioreq;
 
-	ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+	/*
+	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
+	 * still prefer to poll, e.g., because that IRQ number is already used
+	 * by another unit and cannot be shared.
+	 */
+	if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL)
+		irq = -EINVAL;
+
+	if (irq >= 0) {
+		ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
 			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 			ctx->cd_label, host);
-	if (ret < 0)
-		goto eirqreq;
+		if (ret < 0)
+			irq = ret;
+	}
 
-	ctx->cd_gpio = gpio;
 	host->slot.cd_irq = irq;
+
+	if (irq < 0)
+		host->caps |= MMC_CAP_NEEDS_POLL;
+
+	ctx->cd_gpio = gpio;
 	host->slot.handler_priv = ctx;
 
 	return 0;
 
-eirqreq:
-	gpio_free(gpio);
 egpioreq:
 	kfree(ctx);
 	return ret;
@@ -76,8 +97,12 @@ void mmc_gpio_free_cd(struct mmc_host *host)
 	if (!ctx)
 		return;
 
-	free_irq(host->slot.cd_irq, host);
+	if (host->slot.cd_irq >= 0) {
+		free_irq(host->slot.cd_irq, host);
+		host->slot.cd_irq = -EINVAL;
+	}
 	gpio_free(ctx->cd_gpio);
+	host->slot.handler_priv = NULL;
 	kfree(ctx);
 }
 EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index edfaa32..1a977d7 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -12,6 +12,8 @@
 #define MMC_SLOT_GPIO_H
 
 struct mmc_host;
+
+int mmc_gpio_get_cd(struct mmc_host *host);
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
 void mmc_gpio_free_cd(struct mmc_host *host);
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 05/10 v3] mmc: convert slot functions to managed allocation
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                     ` (3 preceding siblings ...)
  2012-05-25 15:16   ` [PATCH 04/10 v3] mmc: add CD GPIO polling support to slot functions Guennadi Liakhovetski
@ 2012-05-25 15:16   ` Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 06/10 v3] mmc: add WP pin handler to slot functions Guennadi Liakhovetski
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

This prepares for the addition of further slot functions.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/host.c      |    2 +
 drivers/mmc/core/slot-gpio.c |   49 +++++++++++++++++++++++++++++++----------
 include/linux/mmc/host.h     |    3 ++
 3 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index b8c5290..74cf29a5 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -32,6 +32,7 @@
 static void mmc_host_classdev_release(struct device *dev)
 {
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
+	mutex_destroy(&host->slot.lock);
 	kfree(host);
 }
 
@@ -327,6 +328,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 
 	mmc_host_clk_init(host);
 
+	mutex_init(&host->slot.lock);
 	host->slot.cd_irq = -EINVAL;
 
 	spin_lock_init(&host->lock);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index d70b790..f14c8a1 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -29,6 +29,33 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int mmc_gpio_alloc(struct mmc_host *host)
+{
+	size_t len = strlen(dev_name(host->parent)) + 4;
+	struct mmc_gpio *ctx;
+
+	mutex_lock(&host->slot.lock);
+
+	ctx = host->slot.handler_priv;
+	if (!ctx) {
+		/*
+		 * devm_kzalloc() can be called after device_initialize(), even
+		 * before device_add(), i.e., between mmc_alloc_host() and
+		 * mmc_add_host()
+		 */
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
+				   GFP_KERNEL);
+		if (ctx) {
+			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			host->slot.handler_priv = ctx;
+		}
+	}
+
+	mutex_unlock(&host->slot.lock);
+
+	return ctx ? 0 : -ENOMEM;
+}
+
 int mmc_gpio_get_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -43,20 +70,24 @@ EXPORT_SYMBOL(mmc_gpio_get_cd);
 
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
-	size_t len = strlen(dev_name(host->parent)) + 4;
 	struct mmc_gpio *ctx;
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
-	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
-	if (!ctx)
-		return -ENOMEM;
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
 
-	snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+	ctx = host->slot.handler_priv;
 
 	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
 	if (ret < 0)
-		goto egpioreq;
+		/*
+		 * don't bother freeing gpio. It might still get used by other
+		 * slot functions, in any case it will be freed, when the device
+		 * is destroyed.
+		 */
+		return ret;
 
 	/*
 	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
@@ -83,10 +114,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	host->slot.handler_priv = ctx;
 
 	return 0;
-
-egpioreq:
-	kfree(ctx);
-	return ret;
 }
 EXPORT_SYMBOL(mmc_gpio_request_cd);
 
@@ -102,7 +129,5 @@ void mmc_gpio_free_cd(struct mmc_host *host)
 		host->slot.cd_irq = -EINVAL;
 	}
 	gpio_free(ctx->cd_gpio);
-	host->slot.handler_priv = NULL;
-	kfree(ctx);
 }
 EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 1b3a917..3f3c8c9 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -11,6 +11,7 @@
 #define LINUX_MMC_HOST_H
 
 #include <linux/leds.h>
+#include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/fault-inject.h>
@@ -154,6 +155,7 @@ struct mmc_async_req {
  * struct mmc_slot - MMC slot functions
  *
  * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @lock:		protect the @handler_priv pointer
  * @handler_priv:	MMC/SD-card slot context
  *
  * Some MMC/SD host controllers implement slot-functions like card and
@@ -163,6 +165,7 @@ struct mmc_async_req {
  */
 struct mmc_slot {
 	int cd_irq;
+	struct mutex lock;
 	void *handler_priv;
 };
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 06/10 v3] mmc: add WP pin handler to slot functions
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                     ` (4 preceding siblings ...)
  2012-05-25 15:16   ` [PATCH 05/10 v3] mmc: convert slot functions to managed allocation Guennadi Liakhovetski
@ 2012-05-25 15:16   ` Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 07/10 v3] mmc: tmio: support caps2 flags Guennadi Liakhovetski
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Card Write-Protect pin is often implemented, using a GPIO, which makes it
simple to provide a generic handler for it.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/slot-gpio.c  |   51 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/mmc/slot-gpio.h |    4 +++
 2 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index f14c8a1..074edc2 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -18,7 +18,9 @@
 #include <linux/slab.h>
 
 struct mmc_gpio {
+	unsigned int ro_gpio;
 	unsigned int cd_gpio;
+	char *ro_label;
 	char cd_label[0];
 };
 
@@ -43,10 +45,12 @@ static int mmc_gpio_alloc(struct mmc_host *host)
 		 * before device_add(), i.e., between mmc_alloc_host() and
 		 * mmc_add_host()
 		 */
-		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len,
 				   GFP_KERNEL);
 		if (ctx) {
+			ctx->ro_label = ctx->cd_label + len;
 			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent));
 			host->slot.handler_priv = ctx;
 		}
 	}
@@ -56,6 +60,18 @@ static int mmc_gpio_alloc(struct mmc_host *host)
 	return ctx ? 0 : -ENOMEM;
 }
 
+int mmc_gpio_get_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->ro_gpio) ^
+		!(host->caps2 & MMC_CAP2_INVERTED_RO);
+}
+EXPORT_SYMBOL(mmc_gpio_get_ro);
+
 int mmc_gpio_get_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -68,6 +84,28 @@ int mmc_gpio_get_cd(struct mmc_host *host)
 }
 EXPORT_SYMBOL(mmc_gpio_get_cd);
 
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
+{
+	struct mmc_gpio *ctx;
+	int ret;
+
+	if (!gpio_is_valid(gpio))
+		return -EINVAL;
+
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
+
+	ctx = host->slot.handler_priv;
+
+	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
+	if (ret < 0)
+		return ret;;
+
+	return 0;
+}
+EXPORT_SYMBOL(mmc_gpio_request_ro);
+
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	struct mmc_gpio *ctx;
@@ -117,6 +155,17 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 }
 EXPORT_SYMBOL(mmc_gpio_request_cd);
 
+void mmc_gpio_free_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return;
+
+	gpio_free(ctx->ro_gpio);
+}
+EXPORT_SYMBOL(mmc_gpio_free_ro);
+
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index 1a977d7..7d88d27 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -13,6 +13,10 @@
 
 struct mmc_host;
 
+int mmc_gpio_get_ro(struct mmc_host *host);
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_ro(struct mmc_host *host);
+
 int mmc_gpio_get_cd(struct mmc_host *host);
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
 void mmc_gpio_free_cd(struct mmc_host *host);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 07/10 v3] mmc: tmio: support caps2 flags
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                     ` (5 preceding siblings ...)
  2012-05-25 15:16   ` [PATCH 06/10 v3] mmc: add WP pin handler to slot functions Guennadi Liakhovetski
@ 2012-05-25 15:16   ` Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 08/10 v3] mmc: sh_mobile_sdhi: " Guennadi Liakhovetski
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Allow tmio mmc glue drivers pass mmc_host::caps2 flags down to the mmc
layer.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    1 +
 include/linux/mfd/tmio.h        |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 5261934..5509554 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -947,6 +947,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	mmc->ops = &tmio_mmc_ops;
 	mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
+	mmc->caps2 = pdata->capabilities2;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
 	mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index b332c4c..d83af39 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -101,6 +101,7 @@ struct tmio_mmc_host;
 struct tmio_mmc_data {
 	unsigned int			hclk;
 	unsigned long			capabilities;
+	unsigned long			capabilities2;
 	unsigned long			flags;
 	u32				ocr_mask;	/* available voltages */
 	struct tmio_mmc_dma		*dma;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 08/10 v3] mmc: sh_mobile_sdhi: support caps2 flags
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                     ` (6 preceding siblings ...)
  2012-05-25 15:16   ` [PATCH 07/10 v3] mmc: tmio: support caps2 flags Guennadi Liakhovetski
@ 2012-05-25 15:16   ` Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 09/10 v3] ARM: mach-shmobile: specify inverted SDHI card-detect signal polarity Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 10/10 v3] mmc: tmio: use generic GPIO CD and WP handlers Guennadi Liakhovetski
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Let SDHI platforms specify mmc_host::caps2 flags in their platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c  |    1 +
 include/linux/mmc/sh_mobile_sdhi.h |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 42f07fa..1e7c5c4 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -162,6 +162,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 			mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
 		mmc_data->ocr_mask = p->tmio_ocr_mask;
 		mmc_data->capabilities |= p->tmio_caps;
+		mmc_data->capabilities2 |= p->tmio_caps2;
 		mmc_data->cd_gpio = p->cd_gpio;
 
 		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
index e94e620..b65679f 100644
--- a/include/linux/mmc/sh_mobile_sdhi.h
+++ b/include/linux/mmc/sh_mobile_sdhi.h
@@ -23,6 +23,7 @@ struct sh_mobile_sdhi_info {
 	int dma_slave_rx;
 	unsigned long tmio_flags;
 	unsigned long tmio_caps;
+	unsigned long tmio_caps2;
 	u32 tmio_ocr_mask;	/* available MMC voltages */
 	unsigned int cd_gpio;
 	struct tmio_mmc_data *pdata;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 09/10 v3] ARM: mach-shmobile: specify inverted SDHI card-detect signal polarity
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                     ` (7 preceding siblings ...)
  2012-05-25 15:16   ` [PATCH 08/10 v3] mmc: sh_mobile_sdhi: " Guennadi Liakhovetski
@ 2012-05-25 15:16   ` Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 10/10 v3] mmc: tmio: use generic GPIO CD and WP handlers Guennadi Liakhovetski
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

On mackerel and ag5evm the SDHI0 CD signal is inverted (active low). To
prepare for the generic GPIO CD handler the MMC_CAP2_INVERTED_CD flag
has to be specified in platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 arch/arm/mach-shmobile/board-ag5evm.c   |    1 +
 arch/arm/mach-shmobile/board-mackerel.c |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 5a6f22f..545fd06 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -370,6 +370,7 @@ static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
 	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD,
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED,
+	.tmio_caps2	= MMC_CAP2_INVERTED_CD,
 	.tmio_ocr_mask	= MMC_VDD_27_28 | MMC_VDD_28_29,
 	.cd_gpio	= GPIO_PORT251,
 };
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index b577f7c..5881bb1 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1047,6 +1047,7 @@ static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
 	.tmio_flags	= TMIO_MMC_USE_GPIO_CD,
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
+	.tmio_caps2	= MMC_CAP2_INVERTED_CD,
 	.cd_gpio	= GPIO_PORT172,
 };
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 10/10 v3] mmc: tmio: use generic GPIO CD and WP handlers
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                     ` (8 preceding siblings ...)
  2012-05-25 15:16   ` [PATCH 09/10 v3] ARM: mach-shmobile: specify inverted SDHI card-detect signal polarity Guennadi Liakhovetski
@ 2012-05-25 15:16   ` Guennadi Liakhovetski
  9 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

The tmio-mmc driver is already using the generic GPIO CD handler in IRQ
mode. This patch adds support for CD polling mode and also checks for
availability of a WP GPIO.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 5261934..1eed200 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -871,6 +871,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_ro(mmc);
+	if (ret >= 0)
+		return ret;
 
 	return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
 		 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
@@ -880,6 +883,9 @@ static int tmio_mmc_get_cd(struct mmc_host *mmc)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_cd(mmc);
+	if (ret >= 0)
+		return ret;
 
 	if (!pdata->get_cd)
 		return -ENOSYS;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi
  2012-05-25 15:14 [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                   ` (3 preceding siblings ...)
  2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
@ 2012-05-25 15:16 ` Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 1/2 v3] mmc: sdhi: add OF support, make platform data optional Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 2/2 v3] mmc: sh-mmcif: " Guennadi Liakhovetski
  2012-05-25 15:17 ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
  6 siblings, 2 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Olof Johansson

I removed most OF support code from the previous version. In this version 
I'm only adding the bare minimum with no support for any mmc- or 
driver-specific properties. They can be added slowly as need arises.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/2 v3] mmc: sdhi: add OF support, make platform data optional
  2012-05-25 15:16 ` [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi Guennadi Liakhovetski
@ 2012-05-25 15:16   ` Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 2/2 v3] mmc: sh-mmcif: " Guennadi Liakhovetski
  1 sibling, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Olof Johansson

Add primitive support for OF to the SDHI TMIO glue, which also makes it
necessary to be able to run without platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c |   26 +++++++++++++++++---------
 1 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 1e7c5c4..3defd77 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/mmc/host.h>
@@ -133,9 +134,8 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 	}
 
 	mmc_data = &priv->mmc_data;
-	p->pdata = mmc_data;
 
-	if (p->init) {
+	if (p && p->init) {
 		ret = p->init(pdev, &sdhi_ops);
 		if (ret)
 			goto einit;
@@ -149,10 +149,6 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 		goto eclkget;
 	}
 
-	if (p->set_pwr)
-		mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
-	if (p->get_cd)
-		mmc_data->get_cd = sh_mobile_sdhi_get_cd;
 	mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
 	mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
 	mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
@@ -164,6 +160,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 		mmc_data->capabilities |= p->tmio_caps;
 		mmc_data->capabilities2 |= p->tmio_caps2;
 		mmc_data->cd_gpio = p->cd_gpio;
+		if (p->set_pwr)
+			mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+		if (p->get_cd)
+			mmc_data->get_cd = sh_mobile_sdhi_get_cd;
 
 		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
 			priv->param_tx.slave_id = p->dma_slave_tx;
@@ -269,7 +269,7 @@ eirq_card_detect:
 eprobe:
 	clk_put(priv->clk);
 eclkget:
-	if (p->cleanup)
+	if (p && p->cleanup)
 		p->cleanup(pdev);
 einit:
 	kfree(priv);
@@ -284,7 +284,8 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 	int i = 0, irq;
 
-	p->pdata = NULL;
+	if (p)
+		p->pdata = NULL;
 
 	tmio_mmc_host_remove(host);
 
@@ -297,7 +298,7 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
 
 	clk_put(priv->clk);
 
-	if (p->cleanup)
+	if (p && p->cleanup)
 		p->cleanup(pdev);
 
 	kfree(priv);
@@ -312,11 +313,18 @@ static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
 	.runtime_resume = tmio_mmc_host_runtime_resume,
 };
 
+static const struct of_device_id sh_mobile_sdhi_of_match[] = {
+	{ .compatible = "renesas,shmobile-sdhi" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match);
+
 static struct platform_driver sh_mobile_sdhi_driver = {
 	.driver		= {
 		.name	= "sh_mobile_sdhi",
 		.owner	= THIS_MODULE,
 		.pm	= &tmio_mmc_dev_pm_ops,
+		.of_match_table = sh_mobile_sdhi_of_match,
 	},
 	.probe		= sh_mobile_sdhi_probe,
 	.remove		= __devexit_p(sh_mobile_sdhi_remove),
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/2 v3] mmc: sh-mmcif: add OF support, make platform data optional
  2012-05-25 15:16 ` [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi Guennadi Liakhovetski
  2012-05-25 15:16   ` [PATCH 1/2 v3] mmc: sdhi: add OF support, make platform data optional Guennadi Liakhovetski
@ 2012-05-25 15:17   ` Guennadi Liakhovetski
  1 sibling, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:17 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, Olof Johansson

Add primitive OF support to the sh-mmcif driver, which also makes it
necessary to be able to run without platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mmcif.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index f952978..53a3ff3 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -54,6 +54,7 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sh_mmcif.h>
+#include <linux/mod_devicetable.h>
 #include <linux/pagemap.h>
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
@@ -388,6 +389,9 @@ static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
 	struct sh_dmae_slave *tx, *rx;
 	host->dma_active = false;
 
+	if (!pdata)
+		return;
+
 	/* We can only either use DMA for both Tx and Rx or not use it at all */
 	if (pdata->dma) {
 		dev_warn(&host->pd->dev,
@@ -448,13 +452,14 @@ static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
 static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
 {
 	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+	bool sup_pclk = p ? p->sup_pclk : false;
 
 	sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
 	sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR);
 
 	if (!clk)
 		return;
-	if (p->sup_pclk && clk == host->clk)
+	if (sup_pclk && clk == host->clk)
 		sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
 	else
 		sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
@@ -937,7 +942,7 @@ static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios)
 {
 	struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
 
-	if (pd->set_pwr)
+	if (pd && pd->set_pwr)
 		pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF);
 	if (host->vdd)
 		/* Errors ignored... */
@@ -1005,7 +1010,7 @@ static int sh_mmcif_get_cd(struct mmc_host *mmc)
 	struct sh_mmcif_host *host = mmc_priv(mmc);
 	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
 
-	if (!p->get_cd)
+	if (!p || !p->get_cd)
 		return -ENOSYS;
 	else
 		return p->get_cd(host->pd);
@@ -1278,6 +1283,9 @@ static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
 
 	host->vdd = mmc_regulator_get_vmmc(mmc);
 
+	if (!pd)
+		return;
+
 	if (!mmc->ocr_avail)
 		mmc->ocr_avail = pd->ocr;
 	else if (pd->ocr)
@@ -1294,11 +1302,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	void __iomem *reg;
 	char clk_name[8];
 
-	if (!pd) {
-		dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
-		return -ENXIO;
-	}
-
 	irq[0] = platform_get_irq(pdev, 0);
 	irq[1] = platform_get_irq(pdev, 1);
 	if (irq[0] < 0 || irq[1] < 0) {
@@ -1334,7 +1337,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	sh_mmcif_init_ocr(host);
 
 	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
-	if (pd->caps)
+	if (pd && pd->caps)
 		mmc->caps |= pd->caps;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
@@ -1471,6 +1474,12 @@ static int sh_mmcif_resume(struct device *dev)
 #define sh_mmcif_resume		NULL
 #endif	/* CONFIG_PM */
 
+static const struct of_device_id mmcif_of_match[] = {
+	{ .compatible = "renesas,sh-mmcif" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mmcif_of_match);
+
 static const struct dev_pm_ops sh_mmcif_dev_pm_ops = {
 	.suspend = sh_mmcif_suspend,
 	.resume = sh_mmcif_resume,
@@ -1482,6 +1491,8 @@ static struct platform_driver sh_mmcif_driver = {
 	.driver		= {
 		.name	= DRIVER_NAME,
 		.pm	= &sh_mmcif_dev_pm_ops,
+		.owner	= THIS_MODULE,
+		.of_match_table = mmcif_of_match,
 	},
 };
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data
  2012-05-25 15:14 [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                   ` (4 preceding siblings ...)
  2012-05-25 15:16 ` [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi Guennadi Liakhovetski
@ 2012-05-25 15:17 ` Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators Guennadi Liakhovetski
                     ` (2 more replies)
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
  6 siblings, 3 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:17 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

The patches in this series update ecovec and mackerel to use voltage 
regulators and GPIO slot functions, available for SDHI and MMCIF blocks.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators
  2012-05-25 15:17 ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
@ 2012-05-25 15:17   ` Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 2/3 v3] ARM: mach-shmobile: switch all SDHI instances on mackerel to use GPIO CD Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 3/3 v3] ARM: mach-shmobile: specify IRQ names on mackerel SDHI0 interface Guennadi Liakhovetski
  2 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:17 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Power on the CN11 and CN12 SD/MMC slots on ecovec is controlled by GPIOs,
which makes it possible to use the fixed voltage regulator driver to switch
card power on and off.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 arch/sh/boards/mach-ecovec24/setup.c |   85 ++++++++++++++++++++++++---------
 1 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index dbedfda..5ba295d 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -19,6 +19,9 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/usb/renesas_usbhs.h>
 #include <linux/i2c.h>
@@ -518,12 +521,66 @@ static struct i2c_board_info ts_i2c_clients = {
 	.irq		= IRQ0,
 };
 
+static struct regulator_consumer_supply cn12_power_consumers[] =
+{
+	REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+};
+
+static struct regulator_init_data cn12_power_init_data = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(cn12_power_consumers),
+	.consumer_supplies      = cn12_power_consumers,
+};
+
+static struct fixed_voltage_config cn12_power_info = {
+	.supply_name = "CN12 SD/MMC Vdd",
+	.microvolts = 3300000,
+	.gpio = GPIO_PTB7,
+	.enable_high = 1,
+	.init_data = &cn12_power_init_data,
+};
+
+static struct platform_device cn12_power = {
+	.name = "reg-fixed-voltage",
+	.id   = 0,
+	.dev  = {
+		.platform_data = &cn12_power_info,
+	},
+};
+
 #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
 /* SDHI0 */
-static void sdhi0_set_pwr(struct platform_device *pdev, int state)
+static struct regulator_consumer_supply sdhi0_power_consumers[] =
 {
-	gpio_set_value(GPIO_PTB6, state);
-}
+	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct regulator_init_data sdhi0_power_init_data = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(sdhi0_power_consumers),
+	.consumer_supplies      = sdhi0_power_consumers,
+};
+
+static struct fixed_voltage_config sdhi0_power_info = {
+	.supply_name = "CN11 SD/MMC Vdd",
+	.microvolts = 3300000,
+	.gpio = GPIO_PTB6,
+	.enable_high = 1,
+	.init_data = &sdhi0_power_init_data,
+};
+
+static struct platform_device sdhi0_power = {
+	.name = "reg-fixed-voltage",
+	.id   = 1,
+	.dev  = {
+		.platform_data = &sdhi0_power_info,
+	},
+};
 
 static int sdhi0_get_cd(struct platform_device *pdev)
 {
@@ -533,7 +590,6 @@ static int sdhi0_get_cd(struct platform_device *pdev)
 static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
-	.set_pwr	= sdhi0_set_pwr,
 	.tmio_caps      = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD |
 			  MMC_CAP_NEEDS_POLL,
 	.get_cd		= sdhi0_get_cd,
@@ -564,11 +620,6 @@ static struct platform_device sdhi0_device = {
 
 #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SDHI1 */
-static void sdhi1_set_pwr(struct platform_device *pdev, int state)
-{
-	gpio_set_value(GPIO_PTB7, state);
-}
-
 static int sdhi1_get_cd(struct platform_device *pdev)
 {
 	return !gpio_get_value(GPIO_PTW7);
@@ -579,7 +630,6 @@ static struct sh_mobile_sdhi_info sdhi1_info = {
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI1_RX,
 	.tmio_caps      = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD |
 			  MMC_CAP_NEEDS_POLL,
-	.set_pwr	= sdhi1_set_pwr,
 	.get_cd		= sdhi1_get_cd,
 };
 
@@ -899,11 +949,6 @@ static struct platform_device vou_device = {
 
 #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SH_MMCIF */
-static void mmcif_set_pwr(struct platform_device *pdev, int state)
-{
-	gpio_set_value(GPIO_PTB7, state);
-}
-
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
 		.name	= "SH_MMCIF",
@@ -924,12 +969,10 @@ static struct resource sh_mmcif_resources[] = {
 };
 
 static struct sh_mmcif_plat_data sh_mmcif_plat = {
-	.set_pwr	= mmcif_set_pwr,
 	.sup_pclk	= 0, /* SH7724: Max Pclk/2 */
 	.caps		= MMC_CAP_4_BIT_DATA |
 			  MMC_CAP_8_BIT_DATA |
 			  MMC_CAP_NEEDS_POLL,
-	.ocr		= MMC_VDD_32_33 | MMC_VDD_33_34,
 };
 
 static struct platform_device sh_mmcif_device = {
@@ -954,7 +997,9 @@ static struct platform_device *ecovec_devices[] __initdata = {
 	&ceu0_device,
 	&ceu1_device,
 	&keysc_device,
+	&cn12_power,
 #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+	&sdhi0_power,
 	&sdhi0_device,
 #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 	&sdhi1_device,
@@ -1252,8 +1297,6 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_SDHI0D2,  NULL);
 	gpio_request(GPIO_FN_SDHI0D1,  NULL);
 	gpio_request(GPIO_FN_SDHI0D0,  NULL);
-	gpio_request(GPIO_PTB6, NULL);
-	gpio_direction_output(GPIO_PTB6, 0);
 #else
 	/* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */
 	gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
@@ -1282,8 +1325,6 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_MMC_D0, NULL);
 	gpio_request(GPIO_FN_MMC_CLK, NULL);
 	gpio_request(GPIO_FN_MMC_CMD, NULL);
-	gpio_request(GPIO_PTB7, NULL);
-	gpio_direction_output(GPIO_PTB7, 0);
 
 	cn12_enabled = true;
 #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
@@ -1295,8 +1336,6 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_SDHI1D2,  NULL);
 	gpio_request(GPIO_FN_SDHI1D1,  NULL);
 	gpio_request(GPIO_FN_SDHI1D0,  NULL);
-	gpio_request(GPIO_PTB7, NULL);
-	gpio_direction_output(GPIO_PTB7, 0);
 
 	/* Card-detect, used on CN12 with SDHI1 */
 	gpio_request(GPIO_PTW7, NULL);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/3 v3] ARM: mach-shmobile: switch all SDHI instances on mackerel to use GPIO CD
  2012-05-25 15:17 ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators Guennadi Liakhovetski
@ 2012-05-25 15:17   ` Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 3/3 v3] ARM: mach-shmobile: specify IRQ names on mackerel SDHI0 interface Guennadi Liakhovetski
  2 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:17 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

All 3 SDHI instances on mackerel use GPIOs for card-detection and can be
switched to use the generic GPIO CD helper. SDHI0 card-detect is configured
to produce interrupts, SDHI1 and SDHI2 are polled.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 arch/arm/mach-shmobile/board-mackerel.c |   46 +++++++++++++++----------------
 1 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 5881bb1..45854a9 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1032,15 +1032,6 @@ static struct platform_device nand_flash_device = {
 	},
 };
 
-/*
- * The card detect pin of the top SD/MMC slot (CN7) is active low and is
- * connected to GPIO A22 of SH7372 (GPIO_PORT41).
- */
-static int slot_cn7_get_cd(struct platform_device *pdev)
-{
-	return !gpio_get_value(GPIO_PORT41);
-}
-
 /* SDHI0 */
 static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
@@ -1084,14 +1075,17 @@ static struct platform_device sdhi0_device = {
 
 #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SDHI1 */
+
+/* GPIO_PORT41 can trigger IRQ8, but it is used by USBHS1, we have to poll */
 static struct sh_mobile_sdhi_info sdhi1_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI1_TX,
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI1_RX,
 	.tmio_ocr_mask	= MMC_VDD_165_195,
-	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE,
+	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_USE_GPIO_CD,
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
 			  MMC_CAP_NEEDS_POLL,
-	.get_cd		= slot_cn7_get_cd,
+	.tmio_caps2	= MMC_CAP2_INVERTED_CD,
+	.cd_gpio	= GPIO_PORT41,
 };
 
 static struct resource sdhi1_resources[] = {
@@ -1129,23 +1123,20 @@ static struct platform_device sdhi1_device = {
 };
 #endif
 
+/* SDHI2 */
+
 /*
  * The card detect pin of the top SD/MMC slot (CN23) is active low and is
  * connected to GPIO SCIFB_SCK of SH7372 (GPIO_PORT162).
  */
-static int slot_cn23_get_cd(struct platform_device *pdev)
-{
-	return !gpio_get_value(GPIO_PORT162);
-}
-
-/* SDHI2 */
 static struct sh_mobile_sdhi_info sdhi2_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI2_TX,
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI2_RX,
-	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE,
+	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_USE_GPIO_CD,
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
 			  MMC_CAP_NEEDS_POLL,
-	.get_cd		= slot_cn23_get_cd,
+	.tmio_caps2	= MMC_CAP2_INVERTED_CD,
+	.cd_gpio	= GPIO_PORT162,
 };
 
 static struct resource sdhi2_resources[] = {
@@ -1183,6 +1174,16 @@ static struct platform_device sdhi2_device = {
 };
 
 /* SH_MMCIF */
+
+/*
+ * The card detect pin of the top SD/MMC slot (CN7) is active low and is
+ * connected to GPIO A22 of SH7372 (GPIO_PORT41).
+ */
+static int slot_cn7_get_cd(struct platform_device *pdev)
+{
+	return !gpio_get_value(GPIO_PORT41);
+}
+
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
 		.name	= "MMCIF",
@@ -1521,10 +1522,11 @@ static void __init mackerel_init(void)
 	gpio_request(GPIO_FN_SDHID1_2, NULL);
 	gpio_request(GPIO_FN_SDHID1_1, NULL);
 	gpio_request(GPIO_FN_SDHID1_0, NULL);
-#endif
+#else
 	/* card detect pin for MMC slot (CN7) */
 	gpio_request(GPIO_PORT41, NULL);
 	gpio_direction_input(GPIO_PORT41);
+#endif
 
 	/* enable SDHI2 */
 	gpio_request(GPIO_FN_SDHICMD2, NULL);
@@ -1534,10 +1536,6 @@ static void __init mackerel_init(void)
 	gpio_request(GPIO_FN_SDHID2_1, NULL);
 	gpio_request(GPIO_FN_SDHID2_0, NULL);
 
-	/* card detect pin for microSD slot (CN23) */
-	gpio_request(GPIO_PORT162, NULL);
-	gpio_direction_input(GPIO_PORT162);
-
 	/* MMCIF */
 	gpio_request(GPIO_FN_MMCD0_0, NULL);
 	gpio_request(GPIO_FN_MMCD0_1, NULL);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/3 v3] ARM: mach-shmobile: specify IRQ names on mackerel SDHI0 interface
  2012-05-25 15:17 ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators Guennadi Liakhovetski
  2012-05-25 15:17   ` [PATCH 2/3 v3] ARM: mach-shmobile: switch all SDHI instances on mackerel to use GPIO CD Guennadi Liakhovetski
@ 2012-05-25 15:17   ` Guennadi Liakhovetski
  2 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:17 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm

Using named IRQs helps the driver to act more selectively when configuring
the interface.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 arch/arm/mach-shmobile/board-mackerel.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 45854a9..15c8a08 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1050,14 +1050,17 @@ static struct resource sdhi0_resources[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
+		.name	= SH_MOBILE_SDHI_IRQ_CARD_DETECT,
 		.start	= evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
 		.flags	= IORESOURCE_IRQ,
 	},
 	[2] = {
+		.name	= SH_MOBILE_SDHI_IRQ_SDCARD,
 		.start	= evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
 		.flags	= IORESOURCE_IRQ,
 	},
 	[3] = {
+		.name	= SH_MOBILE_SDHI_IRQ_SDIO,
 		.start	= evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
 		.flags	= IORESOURCE_IRQ,
 	},
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 90+ messages in thread

* Re: [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates
  2012-05-25 15:14 [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                   ` (5 preceding siblings ...)
  2012-05-25 15:17 ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
@ 2012-05-25 15:31 ` Guennadi Liakhovetski
  2012-05-25 15:45   ` Guennadi Liakhovetski
                     ` (38 more replies)
  6 siblings, 39 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:31 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, linux-sh

On Fri, 25 May 2012, Guennadi Liakhovetski wrote:

> Hi all
> 
> as follow ups to this email I'll send 6 patch series, which are updates to 
> the following 2 patch series:

Ok, sure, this couldn't go without a glitch - I forgot to CC linux-sh. So, 
what I will do, I will push all these patches to linux-sh only - without 
other recepients. Would be nice, if reviewers could at least cc both MLs - 
linux-sh and linux-mmc, but even if someone replies to only one of them, 
I'll try to make sure to reply to all relevant recepients with a full 
quote of the original review.

Sorry for the inconvenience.

Thanks
Guennadi

> 
> http://thread.gmane.org/gmane.linux.ports.sh.devel/14448
> http://thread.gmane.org/gmane.linux.ports.sh.devel/14673
> 
> I have further split the latter of the above to make reviewing easier. 
> These series address different topics, but since they touch the same 
> files, it would be easier to also commit them in the same order. Some 
> patches also touch files under arch/arm and arch/sh, they will require 
> respective acks. The patches have been developed, based on "next" of 21 
> May.
> 
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
                     ` (37 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Hi all

as follow ups to this email I'll send 6 patch series, which are updates to 
the following 2 patch series:

http://thread.gmane.org/gmane.linux.ports.sh.devel/14448
http://thread.gmane.org/gmane.linux.ports.sh.devel/14673

I have further split the latter of the above to make reviewing easier. 
These series address different topics, but since they touch the same 
files, it would be easier to also commit them in the same order. Some 
patches also touch files under arch/arm and arch/sh, they will require 
respective acks. The patches have been developed, based on "next" of 21 
May.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
  2012-05-25 15:45   ` Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling Guennadi Liakhovetski
                     ` (36 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

This is a respin of
http://thread.gmane.org/gmane.linux.ports.sh.devel/14448
with no functional changes, since there have been to comments to v1. The 
only change is, that the patch-series
http://thread.gmane.org/gmane.linux.ports.sh.devel/14425
has been dropped for now, on which v1 of this series has been based. So, 
v1 wouldn't apply to current upstream trees.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
  2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 2/3 v3] mmc: sh_mmcif: fix clock management Guennadi Liakhovetski
                     ` (35 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

A check for NULL platform data can be conveniently made in the very
beginning of probing. Replace numbered error-handling labels in .probe()
with meaningful names to make any future reorganisation simpler.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mmcif.c |   41 ++++++++++++++++++++---------------------
 1 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 724b35e..01db31c 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1247,11 +1247,16 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	int ret = 0, irq[2];
 	struct mmc_host *mmc;
 	struct sh_mmcif_host *host;
-	struct sh_mmcif_plat_data *pd;
+	struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
 	struct resource *res;
 	void __iomem *reg;
 	char clk_name[8];
 
+	if (!pd) {
+		dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
+		return -ENXIO;
+	}
+
 	irq[0] = platform_get_irq(pdev, 0);
 	irq[1] = platform_get_irq(pdev, 1);
 	if (irq[0] < 0 || irq[1] < 0) {
@@ -1268,16 +1273,11 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "ioremap error.\n");
 		return -ENOMEM;
 	}
-	pd = pdev->dev.platform_data;
-	if (!pd) {
-		dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
-		ret = -ENXIO;
-		goto clean_up;
-	}
+
 	mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev);
 	if (!mmc) {
 		ret = -ENOMEM;
-		goto clean_up;
+		goto ealloch;
 	}
 	host		= mmc_priv(mmc);
 	host->mmc	= mmc;
@@ -1289,7 +1289,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	if (IS_ERR(host->hclk)) {
 		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
 		ret = PTR_ERR(host->hclk);
-		goto clean_up1;
+		goto eclkget;
 	}
 	clk_enable(host->hclk);
 	host->clk = clk_get_rate(host->hclk);
@@ -1319,7 +1319,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 
 	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
-		goto clean_up2;
+		goto eresume;
 
 	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
 
@@ -1328,17 +1328,17 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
 	if (ret) {
 		dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
-		goto clean_up3;
+		goto ereqirq0;
 	}
 	ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
 	if (ret) {
 		dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
-		goto clean_up4;
+		goto ereqirq1;
 	}
 
 	ret = mmc_add_host(mmc);
 	if (ret < 0)
-		goto clean_up5;
+		goto emmcaddh;
 
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
@@ -1347,20 +1347,19 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 		sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
 	return ret;
 
-clean_up5:
+emmcaddh:
 	free_irq(irq[1], host);
-clean_up4:
+ereqirq1:
 	free_irq(irq[0], host);
-clean_up3:
+ereqirq0:
 	pm_runtime_suspend(&pdev->dev);
-clean_up2:
+eresume:
 	pm_runtime_disable(&pdev->dev);
 	clk_disable(host->hclk);
-clean_up1:
+eclkget:
 	mmc_free_host(mmc);
-clean_up:
-	if (reg)
-		iounmap(reg);
+ealloch:
+	iounmap(reg);
 	return ret;
 }
 
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/3 v3] mmc: sh_mmcif: fix clock management
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (2 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 3/3 v3] mmc: sh_mmcif: re-read the clock frequency every time the clock is turned on Guennadi Liakhovetski
                     ` (34 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Regardless, whether the MMC bus clock is the same, as the PM clock on this
specific interface, it has to be managed separately. Its proper management
should also include enabling and disabling of the clock, whenever the
interface is becoming active or going idle respectively.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mmcif.c |   46 +++++++++++++++++++++---------------------
 1 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 01db31c..e5e8198 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -948,6 +948,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		}
 		if (host->power) {
 			pm_runtime_put(&host->pd->dev);
+			clk_disable(host->hclk);
 			host->power = false;
 			if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
 				p->down_pwr(host->pd);
@@ -960,6 +961,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		if (!host->power) {
 			if (p->set_pwr)
 				p->set_pwr(host->pd, ios->power_mode);
+			clk_enable(host->hclk);
 			pm_runtime_get_sync(&host->pd->dev);
 			host->power = true;
 			sh_mmcif_sync_reset(host);
@@ -1284,22 +1286,11 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	host->addr	= reg;
 	host->timeout	= 1000;
 
-	snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
-	host->hclk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(host->hclk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		ret = PTR_ERR(host->hclk);
-		goto eclkget;
-	}
-	clk_enable(host->hclk);
-	host->clk = clk_get_rate(host->hclk);
 	host->pd = pdev;
 
 	spin_lock_init(&host->lock);
 
 	mmc->ops = &sh_mmcif_ops;
-	mmc->f_max = host->clk / 2;
-	mmc->f_min = host->clk / 512;
 	if (pd->ocr)
 		mmc->ocr_avail = pd->ocr;
 	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
@@ -1311,18 +1302,30 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
 	mmc->max_seg_size = mmc->max_req_size;
 
-	sh_mmcif_sync_reset(host);
 	platform_set_drvdata(pdev, host);
 
 	pm_runtime_enable(&pdev->dev);
 	host->power = false;
 
+	snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
+	host->hclk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(host->hclk)) {
+		ret = PTR_ERR(host->hclk);
+		dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
+		goto eclkget;
+	}
+	clk_enable(host->hclk);
+	host->clk = clk_get_rate(host->hclk);
+	mmc->f_max = host->clk / 2;
+	mmc->f_min = host->clk / 512;
+
 	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
 		goto eresume;
 
 	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
 
+	sh_mmcif_sync_reset(host);
 	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
 
 	ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
@@ -1336,6 +1339,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 		goto ereqirq1;
 	}
 
+	clk_disable(host->hclk);
 	ret = mmc_add_host(mmc);
 	if (ret < 0)
 		goto emmcaddh;
@@ -1354,9 +1358,10 @@ ereqirq1:
 ereqirq0:
 	pm_runtime_suspend(&pdev->dev);
 eresume:
-	pm_runtime_disable(&pdev->dev);
 	clk_disable(host->hclk);
+	clk_put(host->hclk);
 eclkget:
+	pm_runtime_disable(&pdev->dev);
 	mmc_free_host(mmc);
 ealloch:
 	iounmap(reg);
@@ -1369,6 +1374,7 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 	int irq[2];
 
 	host->dying = true;
+	clk_enable(host->hclk);
 	pm_runtime_get_sync(&pdev->dev);
 
 	dev_pm_qos_hide_latency_limit(&pdev->dev);
@@ -1394,9 +1400,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, NULL);
 
-	clk_disable(host->hclk);
 	mmc_free_host(host->mmc);
 	pm_runtime_put_sync(&pdev->dev);
+	clk_disable(host->hclk);
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
@@ -1405,24 +1411,18 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 #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);
+	struct sh_mmcif_host *host = dev_get_drvdata(dev);
 	int ret = mmc_suspend_host(host->mmc);
 
-	if (!ret) {
+	if (!ret)
 		sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
-		clk_disable(host->hclk);
-	}
 
 	return ret;
 }
 
 static int sh_mmcif_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
-
-	clk_enable(host->hclk);
+	struct sh_mmcif_host *host = dev_get_drvdata(dev);
 
 	return mmc_resume_host(host->mmc);
 }
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/3 v3] mmc: sh_mmcif: re-read the clock frequency every time the clock is turned on
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (3 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 2/3 v3] mmc: sh_mmcif: fix clock management Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
                     ` (33 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

With aggressive clock gating the clock can be disabled during interface
inactivity. During this time its frequency can be changed by another its
user. Therefore when the interface is activated again and the clock is
re-enabled, its frequency has to be re-read.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v2: also move clk_enable() inside sh_mmcif_clk_update(), check its return 
value in .probe()

 drivers/mmc/host/sh_mmcif.c |   23 ++++++++++++++++++-----
 1 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index e5e8198..bdf42d5 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -916,6 +916,19 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	sh_mmcif_start_cmd(host, mrq);
 }
 
+static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
+{
+	int ret = clk_enable(host->hclk);
+
+	if (!ret) {
+		host->clk = clk_get_rate(host->hclk);
+		host->mmc->f_max = host->clk / 2;
+		host->mmc->f_min = host->clk / 512;
+	}
+
+	return ret;
+}
+
 static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct sh_mmcif_host *host = mmc_priv(mmc);
@@ -961,7 +974,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		if (!host->power) {
 			if (p->set_pwr)
 				p->set_pwr(host->pd, ios->power_mode);
-			clk_enable(host->hclk);
+			sh_mmcif_clk_update(host);
 			pm_runtime_get_sync(&host->pd->dev);
 			host->power = true;
 			sh_mmcif_sync_reset(host);
@@ -1314,10 +1327,9 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
 		goto eclkget;
 	}
-	clk_enable(host->hclk);
-	host->clk = clk_get_rate(host->hclk);
-	mmc->f_max = host->clk / 2;
-	mmc->f_min = host->clk / 512;
+	ret = sh_mmcif_clk_update(host);
+	if (ret < 0)
+		goto eclkupdate;
 
 	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
@@ -1359,6 +1371,7 @@ ereqirq0:
 	pm_runtime_suspend(&pdev->dev);
 eresume:
 	clk_disable(host->hclk);
+eclkupdate:
 	clk_put(host->hclk);
 eclkget:
 	pm_runtime_disable(&pdev->dev);
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (4 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 3/3 v3] mmc: sh_mmcif: re-read the clock frequency every time the clock is turned on Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback Guennadi Liakhovetski
                     ` (32 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

This series is an update for patches 1-3,7,8 from
http://thread.gmane.org/gmane.linux.ports.sh.devel/14673

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (5 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 2/5 v3] sh: ecovec: remove unused .down_pwr() MMCIF callback Guennadi Liakhovetski
                     ` (31 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

>From the original version of sh_mmcif the .set_pwr() callback has only been
used to turn the card's power on, and the .down_pwr() callback has been
used to turn it off. .set_pwr() can be used for both these tasks, which is
also how it is implemented by the only user of this API: the SH7724 ecovec
board.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mmcif.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index bdf42d5..3834b21 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -963,8 +963,8 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			pm_runtime_put(&host->pd->dev);
 			clk_disable(host->hclk);
 			host->power = false;
-			if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
-				p->down_pwr(host->pd);
+			if (p->set_pwr && ios->power_mode == MMC_POWER_OFF)
+				p->set_pwr(host->pd, 0);
 		}
 		host->state = STATE_IDLE;
 		return;
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/5 v3] sh: ecovec: remove unused .down_pwr() MMCIF callback
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (6 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 3/5 v3] mmc: sh_mmcif: remove unused .down_pwr() callback Guennadi Liakhovetski
                     ` (30 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown, Paul Mundt

.down_pwr() on ecovec was equivalent to .set_pwr(0). Now that .down_pwr()
is no longer used by the driver, it can be removed.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

Paul, would be good to get your ack to this one to push all this patches 
via one tree and make preserving the merge order easier. Thanks.

 arch/sh/boards/mach-ecovec24/setup.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 4158d70..dbedfda 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -904,11 +904,6 @@ static void mmcif_set_pwr(struct platform_device *pdev, int state)
 	gpio_set_value(GPIO_PTB7, state);
 }
 
-static void mmcif_down_pwr(struct platform_device *pdev)
-{
-	gpio_set_value(GPIO_PTB7, 0);
-}
-
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
 		.name	= "SH_MMCIF",
@@ -930,7 +925,6 @@ static struct resource sh_mmcif_resources[] = {
 
 static struct sh_mmcif_plat_data sh_mmcif_plat = {
 	.set_pwr	= mmcif_set_pwr,
-	.down_pwr	= mmcif_down_pwr,
 	.sup_pclk	= 0, /* SH7724: Max Pclk/2 */
 	.caps		= MMC_CAP_4_BIT_DATA |
 			  MMC_CAP_8_BIT_DATA |
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/5 v3] mmc: sh_mmcif: remove unused .down_pwr() callback
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (7 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 2/5 v3] sh: ecovec: remove unused .down_pwr() MMCIF callback Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
                     ` (29 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

This patch shall only be applied after the previous one. If the previous 
one has to go via the sh tree, we can postpone this one until a later 
merge, no big problem with that.

 include/linux/mmc/sh_mmcif.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h
index 05f0e3d..cb84340 100644
--- a/include/linux/mmc/sh_mmcif.h
+++ b/include/linux/mmc/sh_mmcif.h
@@ -39,7 +39,6 @@ struct sh_mmcif_dma {
 
 struct sh_mmcif_plat_data {
 	void (*set_pwr)(struct platform_device *pdev, int state);
-	void (*down_pwr)(struct platform_device *pdev);
 	int (*get_cd)(struct platform_device *pdef);
 	struct sh_mmcif_dma	*dma;		/* Deprecated. Instead */
 	unsigned int		slave_id_tx;	/* use embedded slave_id_[tr]x */
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (8 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 3/5 v3] mmc: sh_mmcif: remove unused .down_pwr() callback Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-28 14:46     ` Mark Brown
  2012-05-25 15:45   ` [PATCH 5/5 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
                     ` (28 subsequent siblings)
  38 siblings, 1 reply; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

Add a function to get a regulator, supplying card's Vdd on a specific host.
If such a regulator is found, the function checks, whether a valid OCR mask
can be obtained from this regulator.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v3: remove bogus attempts to ignore the dummy regulator, drop the check 
for whether the regulator can change status, do not assign 
MMC_CAP_POWER_OFF_CARD automatically. Thanks to Mark and Magnus for 
comments.

 drivers/mmc/core/core.c  |   17 +++++++++++++++++
 include/linux/mmc/host.h |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0b6141d..0f92ec0 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1013,6 +1013,23 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
 }
 EXPORT_SYMBOL(mmc_regulator_set_ocr);
 
+struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
+{
+	struct device *dev = mmc_dev(mmc);
+	struct regulator *supply = devm_regulator_get(dev, "vmmc");
+	int ret;
+
+	if (IS_ERR(supply))
+		return NULL;
+
+	ret = mmc_regulator_get_ocrmask(supply);
+	if (ret > 0)
+		mmc->ocr_avail = ret;
+
+	return supply;
+}
+EXPORT_SYMBOL(mmc_regulator_get_vmmc);
+
 #endif /* CONFIG_REGULATOR */
 
 /*
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 0707d22..368b317 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -364,6 +364,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
 			struct regulator *supply,
 			unsigned short vdd_bit);
+struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc);
 #else
 static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
 {
@@ -376,6 +377,11 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
 {
 	return 0;
 }
+
+static inline struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
+{
+	return NULL;
+}
 #endif
 
 int mmc_card_awake(struct mmc_host *host);
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 5/5 v3] mmc: sh_mmcif: add regulator support
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (9 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
                     ` (27 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

Add regulator support to the sh_mmcif driver, but also preserve the current
power-callback.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v3: don't (yet) give preference to using the regulator over the .set_pwr() 
platform callback, call them both if both are available. Thanks to Mark 
and Magnus.

 drivers/mmc/host/sh_mmcif.c |   41 ++++++++++++++++++++++++++++++++++-------
 1 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 3834b21..f952978 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -207,6 +207,8 @@ enum mmcif_wait_for {
 	MMCIF_WAIT_FOR_STOP,
 };
 
+struct regulator;
+
 struct sh_mmcif_host {
 	struct mmc_host *mmc;
 	struct mmc_request *mrq;
@@ -231,6 +233,8 @@ struct sh_mmcif_host {
 	bool power;
 	bool card_present;
 
+	struct regulator	*vdd;
+
 	/* DMA support */
 	struct dma_chan		*chan_rx;
 	struct dma_chan		*chan_tx;
@@ -929,10 +933,21 @@ static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
 	return ret;
 }
 
+static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios)
+{
+	struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
+
+	if (pd->set_pwr)
+		pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF);
+	if (host->vdd)
+		/* Errors ignored... */
+		mmc_regulator_set_ocr(host->mmc, host->vdd,
+				      ios->power_mode ? ios->vdd : 0);
+}
+
 static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct sh_mmcif_host *host = mmc_priv(mmc);
-	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&host->lock, flags);
@@ -950,6 +965,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			sh_mmcif_request_dma(host, host->pd->dev.platform_data);
 			host->card_present = true;
 		}
+		sh_mmcif_set_power(host, ios);
 	} else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
 		/* clock stop */
 		sh_mmcif_clock_control(host, 0);
@@ -963,8 +979,8 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			pm_runtime_put(&host->pd->dev);
 			clk_disable(host->hclk);
 			host->power = false;
-			if (p->set_pwr && ios->power_mode == MMC_POWER_OFF)
-				p->set_pwr(host->pd, 0);
+			if (ios->power_mode == MMC_POWER_OFF)
+				sh_mmcif_set_power(host, ios);
 		}
 		host->state = STATE_IDLE;
 		return;
@@ -972,8 +988,6 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
 	if (ios->clock) {
 		if (!host->power) {
-			if (p->set_pwr)
-				p->set_pwr(host->pd, ios->power_mode);
 			sh_mmcif_clk_update(host);
 			pm_runtime_get_sync(&host->pd->dev);
 			host->power = true;
@@ -1257,6 +1271,19 @@ static void mmcif_timeout_work(struct work_struct *work)
 	mmc_request_done(host->mmc, mrq);
 }
 
+static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
+{
+	struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
+	struct mmc_host *mmc = host->mmc;
+
+	host->vdd = mmc_regulator_get_vmmc(mmc);
+
+	if (!mmc->ocr_avail)
+		mmc->ocr_avail = pd->ocr;
+	else if (pd->ocr)
+		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
+}
+
 static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 {
 	int ret = 0, irq[2];
@@ -1304,8 +1331,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	spin_lock_init(&host->lock);
 
 	mmc->ops = &sh_mmcif_ops;
-	if (pd->ocr)
-		mmc->ocr_avail = pd->ocr;
+	sh_mmcif_init_ocr(host);
+
 	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
 	if (pd->caps)
 		mmc->caps |= pd->caps;
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (10 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 5/5 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending Guennadi Liakhovetski
                     ` (26 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

This is an update for patches 9-14,16,18 from
http://thread.gmane.org/gmane.linux.ports.sh.devel/14673

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (11 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 2/8 v3] mmc: tmio: don't needlessly enable interrupts during probing Guennadi Liakhovetski
                     ` (25 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

The call to pm_runtime_put() in tmio-mmc's .set_ios() method can switch
off the supplying clock or even power down the whole unit. Therefore,
calling tmio_mmc_clk_stop() after that can be redundant, put it before.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 9a7996a..0d2643b 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -809,11 +809,11 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	} else if (ios->power_mode != MMC_POWER_UP) {
 		if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
 			host->set_pwr(host->pdev, 0);
+		tmio_mmc_clk_stop(host);
 		if (host->power) {
 			host->power = false;
 			pm_runtime_put(dev);
 		}
-		tmio_mmc_clk_stop(host);
 	}
 
 	switch (ios->bus_width) {
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/8 v3] mmc: tmio: don't needlessly enable interrupts during probing
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (12 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 3/8 v3] mmc: tmio: add callbacks to enable-update and disable the interface clock Guennadi Liakhovetski
                     ` (24 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

We don't have to force-enable MMC interrupts in our .probe() method,
mmc_add_host() will trigger card detection, that will enable all the
necessary interrupts.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |   21 +++++++++++----------
 1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 0d2643b..8cd3637 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -948,6 +948,17 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	_host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
 	tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
+
+	/* Unmask the IRQs we want to know about */
+	if (!_host->chan_rx)
+		irq_mask |= TMIO_MASK_READOP;
+	if (!_host->chan_tx)
+		irq_mask |= TMIO_MASK_WRITEOP;
+	if (!_host->native_hotplug)
+		irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
+
+	_host->sdcard_irq_mask &= ~irq_mask;
+
 	if (pdata->flags & TMIO_MMC_SDIO_IRQ)
 		tmio_mmc_enable_sdio_irq(mmc, 0);
 
@@ -965,16 +976,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
-	/* Unmask the IRQs we want to know about */
-	if (!_host->chan_rx)
-		irq_mask |= TMIO_MASK_READOP;
-	if (!_host->chan_tx)
-		irq_mask |= TMIO_MASK_WRITEOP;
-	if (!_host->native_hotplug)
-		irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
-
-	tmio_mmc_enable_mmc_irqs(_host, irq_mask);
-
 	if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
 		ret = mmc_cd_gpio_request(mmc, pdata->cd_gpio);
 		if (ret < 0) {
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/8 v3] mmc: tmio: add callbacks to enable-update and disable the interface clock
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (13 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 2/8 v3] mmc: tmio: don't needlessly enable interrupts during probing Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 4/8 v3] mmc: sdhi: implement tmio-mmc clock enable-update and disable callbacks Guennadi Liakhovetski
                     ` (23 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Every time the clockc is enabled after possibly being disabled, we have
to re-read its frequency and update our configuration.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |   35 ++++++++++++++++++++++++++++++++---
 include/linux/mfd/tmio.h        |    3 +++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 8cd3637..579f990 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -751,6 +751,22 @@ fail:
 	mmc_request_done(mmc, mrq);
 }
 
+static int tmio_mmc_clk_update(struct mmc_host *mmc)
+{
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct tmio_mmc_data *pdata = host->pdata;
+	int ret;
+
+	if (!pdata->clk_enable)
+		return -ENOTSUPP;
+
+	ret = pdata->clk_enable(host->pdev, &mmc->f_max);
+	if (!ret)
+		mmc->f_min = mmc->f_max / 512;
+
+	return ret;
+}
+
 /* Set MMC clock / power.
  * Note: This controller uses a simple divider scheme therefore it cannot
  * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
@@ -797,6 +813,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	 */
 	if (ios->power_mode == MMC_POWER_ON && ios->clock) {
 		if (!host->power) {
+			tmio_mmc_clk_update(mmc);
 			pm_runtime_get_sync(dev);
 			host->power = true;
 		}
@@ -811,8 +828,11 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 			host->set_pwr(host->pdev, 0);
 		tmio_mmc_clk_stop(host);
 		if (host->power) {
+			struct tmio_mmc_data *pdata = host->pdata;
 			host->power = false;
 			pm_runtime_put(dev);
+			if (pdata->clk_disable)
+				pdata->clk_disable(host->pdev);
 		}
 	}
 
@@ -904,8 +924,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	mmc->ops = &tmio_mmc_ops;
 	mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
-	mmc->f_max = pdata->hclk;
-	mmc->f_min = mmc->f_max / 512;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
 	mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
@@ -927,6 +945,11 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	if (ret < 0)
 		goto pm_disable;
 
+	if (tmio_mmc_clk_update(mmc) < 0) {
+		mmc->f_max = pdata->hclk;
+		mmc->f_min = mmc->f_max / 512;
+	}
+
 	/*
 	 * There are 4 different scenarios for the card detection:
 	 *  1) an external gpio irq handles the cd (best for power savings)
@@ -972,7 +995,13 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	/* See if we also get DMA */
 	tmio_mmc_request_dma(_host, pdata);
 
-	mmc_add_host(mmc);
+	ret = mmc_add_host(mmc);
+	if (pdata->clk_disable)
+		pdata->clk_disable(pdev);
+	if (ret < 0) {
+		tmio_mmc_host_remove(_host);
+		return ret;
+	}
 
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index f5171db..b332c4c 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -110,6 +110,9 @@ struct tmio_mmc_data {
 	void (*set_clk_div)(struct platform_device *host, int state);
 	int (*get_cd)(struct platform_device *host);
 	int (*write16_hook)(struct tmio_mmc_host *host, int addr);
+	/* clock management callbacks */
+	int (*clk_enable)(struct platform_device *pdev, unsigned int *f);
+	void (*clk_disable)(struct platform_device *pdev);
 };
 
 /*
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 4/8 v3] mmc: sdhi: implement tmio-mmc clock enable-update and disable callbacks
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (14 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 3/8 v3] mmc: tmio: add callbacks to enable-update and disable the interface clock Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 5/8 v3] mmc: tmio: add regulator support Guennadi Liakhovetski
                     ` (22 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Instead of delivering one static clock frequency value, read from the
hardware during probing, enable the tmio-mmc driver to re-read the
frequency dynamically.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 934b68e..d8b167c 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -39,6 +39,27 @@ struct sh_mobile_sdhi {
 	struct tmio_mmc_dma dma_priv;
 };
 
+static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int *f)
+{
+	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
+	int ret = clk_enable(priv->clk);
+	if (ret < 0)
+		return ret;
+
+	*f = clk_get_rate(priv->clk);
+	return 0;
+}
+
+static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
+	clk_disable(priv->clk);
+}
+
 static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
 {
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
@@ -132,9 +153,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 		goto eclkget;
 	}
 
-	mmc_data->hclk = clk_get_rate(priv->clk);
 	mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
 	mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+	mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
+	mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
 	mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
 	if (p) {
 		mmc_data->flags = p->tmio_flags;
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 5/8 v3] mmc: tmio: add regulator support
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (15 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 4/8 v3] mmc: sdhi: implement tmio-mmc clock enable-update and disable callbacks Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 6/8 v3] mmc: sdhi: do not install dummy callbacks Guennadi Liakhovetski
                     ` (21 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Mark Brown

Currently the TMIO MMC driver derives the OCR mask from the platform data
and uses a platform callback to turn card power on and off. This patch adds
regulator support to the driver.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v3: similar to MMCIF don't prefer regulator over platform callback, call 
both. Thanks to all, who commented.

 drivers/mmc/host/tmio_mmc.h     |    3 +++
 drivers/mmc/host/tmio_mmc_pio.c |   35 +++++++++++++++++++++++++++--------
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index d857f5c..3a8dcfb 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -39,6 +39,7 @@
 #define TMIO_MASK_IRQ     (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
 
 struct tmio_mmc_data;
+struct regulator;
 
 struct tmio_mmc_host {
 	void __iomem *ctl;
@@ -55,6 +56,8 @@ struct tmio_mmc_host {
 	void (*set_pwr)(struct platform_device *host, int state);
 	void (*set_clk_div)(struct platform_device *host, int state);
 
+	struct regulator	*vdd;
+
 	/* 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 579f990..baa0959 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -767,6 +767,16 @@ static int tmio_mmc_clk_update(struct mmc_host *mmc)
 	return ret;
 }
 
+static void tmio_mmc_set_power(struct tmio_mmc_host *host, struct mmc_ios *ios)
+{
+	if (host->set_pwr)
+		host->set_pwr(host->pdev, ios->power_mode != MMC_POWER_OFF);
+	if (host->vdd)
+		/* Errors ignored... */
+		mmc_regulator_set_ocr(host->mmc, host->vdd,
+				      ios->power_mode ? ios->vdd : 0);
+}
+
 /* Set MMC clock / power.
  * Note: This controller uses a simple divider scheme therefore it cannot
  * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
@@ -819,13 +829,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		}
 		tmio_mmc_set_clock(host, ios->clock);
 		/* power up SD bus */
-		if (host->set_pwr)
-			host->set_pwr(host->pdev, 1);
+		tmio_mmc_set_power(host, ios);
 		/* start bus clock */
 		tmio_mmc_clk_start(host);
 	} else if (ios->power_mode != MMC_POWER_UP) {
-		if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
-			host->set_pwr(host->pdev, 0);
+		if (ios->power_mode == MMC_POWER_OFF)
+			tmio_mmc_set_power(host, ios);
 		tmio_mmc_clk_stop(host);
 		if (host->power) {
 			struct tmio_mmc_data *pdata = host->pdata;
@@ -885,6 +894,19 @@ static const struct mmc_host_ops tmio_mmc_ops = {
 	.enable_sdio_irq = tmio_mmc_enable_sdio_irq,
 };
 
+static void tmio_mmc_init_ocr(struct tmio_mmc_host *host)
+{
+	struct tmio_mmc_data *pdata = host->pdata;
+	struct mmc_host *mmc = host->mmc;
+
+	host->vdd = mmc_regulator_get_vmmc(mmc);
+
+	if (!mmc->ocr_avail)
+		mmc->ocr_avail = pdata->ocr_mask ? : MMC_VDD_32_33 | MMC_VDD_33_34;
+	else if (pdata->ocr_mask)
+		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
+}
+
 int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 				  struct platform_device *pdev,
 				  struct tmio_mmc_data *pdata)
@@ -930,10 +952,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 		mmc->max_segs;
 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
 	mmc->max_seg_size = mmc->max_req_size;
-	if (pdata->ocr_mask)
-		mmc->ocr_avail = pdata->ocr_mask;
-	else
-		mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	tmio_mmc_init_ocr(_host);
 
 	_host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD ||
 				  mmc->caps & MMC_CAP_NEEDS_POLL ||
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 6/8 v3] mmc: sdhi: do not install dummy callbacks
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (16 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 5/8 v3] mmc: tmio: add regulator support Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 7/8 v3] mmc: tmio: use MMC opcode defines instead of numbers Guennadi Liakhovetski
                     ` (20 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Currently the SDHI glue for the TMIO MMC driver installs dummy .get_cd() and
.set_pwr() callbacks even if the platform didn't supply them. This is not
necessary, since the TMIO MMC driver itself checks for NULL callbacks. This
is also dubious if the platform provides a regulator for SD-card power
switching. It is better to only install those callbacks, if they are really
provided by the platform.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c |   14 ++++++--------
 1 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index d8b167c..42f07fa 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -64,18 +64,14 @@ static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
 {
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 
-	if (p && p->set_pwr)
-		p->set_pwr(pdev, state);
+	p->set_pwr(pdev, state);
 }
 
 static int sh_mobile_sdhi_get_cd(struct platform_device *pdev)
 {
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 
-	if (p && p->get_cd)
-		return p->get_cd(pdev);
-	else
-		return -ENOSYS;
+	return p->get_cd(pdev);
 }
 
 static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
@@ -153,8 +149,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 		goto eclkget;
 	}
 
-	mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
-	mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+	if (p->set_pwr)
+		mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+	if (p->get_cd)
+		mmc_data->get_cd = sh_mobile_sdhi_get_cd;
 	mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
 	mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
 	mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 7/8 v3] mmc: tmio: use MMC opcode defines instead of numbers
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (17 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 6/8 v3] mmc: sdhi: do not install dummy callbacks Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 8/8 v3] mmc: tmio: remove a duplicated comment line Guennadi Liakhovetski
                     ` (19 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

mmc.h defines macros for most frequently used MMC opcodes. Use them instead
of hard-coded numbers.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index baa0959..a4f1c59 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -36,6 +36,7 @@
 #include <linux/mfd/tmio.h>
 #include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
 #include <linux/mmc/tmio.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
@@ -305,8 +306,8 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
 	int c = cmd->opcode;
 	u32 irq_mask = TMIO_MASK_CMD;
 
-	/* Command 12 is handled by hardware */
-	if (cmd->opcode == 12 && !cmd->arg) {
+	/* CMD12 is handled by hardware */
+	if (cmd->opcode == MMC_STOP_TRANSMISSION && !cmd->arg) {
 		sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001);
 		return 0;
 	}
@@ -449,7 +450,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
 	}
 
 	if (stop) {
-		if (stop->opcode == 12 && !stop->arg)
+		if (stop->opcode == MMC_STOP_TRANSMISSION && !stop->arg)
 			sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000);
 		else
 			BUG();
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 8/8 v3] mmc: tmio: remove a duplicated comment line
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (18 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 7/8 v3] mmc: tmio: use MMC opcode defines instead of numbers Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
                     ` (18 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index a4f1c59..b731859 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -980,7 +980,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	 *  While we increment the runtime PM counter for all scenarios when
 	 *  the mmc core activates us by calling an appropriate set_ios(), we
 	 *  must additionally ensure that in case 2) the tmio mmc hardware stays
-	 *  additionally ensure that in case 2) the tmio mmc hardware stays
 	 *  powered on during runtime for the card detection to work.
 	 */
 	if (_host->native_hotplug)
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (19 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 8/8 v3] mmc: tmio: remove a duplicated comment line Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions Guennadi Liakhovetski
                     ` (17 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

This is an update of patches 15,17,19-23 from the previous version

http://thread.gmane.org/gmane.linux.ports.sh.devel/14673

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (20 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 02/10 v3] mmc: use a more generic name for slot function types and fields Guennadi Liakhovetski
                     ` (16 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, S, Venkatraman

GPIOs can be used in MMC/SD-card slots not only for hotplug detection, but
also to implement the write-protection pin. Rename cd-gpio helpers to
slot-gpio to make addition of further slot GPIO functions possible.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v3: use the IRQF_ONESHOT flag, thanks to Venkatraman for the comment.

 drivers/mmc/core/Makefile                    |    2 +-
 drivers/mmc/core/{cd-gpio.c => slot-gpio.c}  |   48 +++++++++++++-------------
 drivers/mmc/host/tmio_mmc_pio.c              |    6 ++--
 include/linux/mmc/{cd-gpio.h => slot-gpio.h} |    8 ++--
 4 files changed, 32 insertions(+), 32 deletions(-)
 rename drivers/mmc/core/{cd-gpio.c => slot-gpio.c} (53%)
 rename include/linux/mmc/{cd-gpio.h => slot-gpio.h} (68%)

diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index dca4428..38ed210 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -7,6 +7,6 @@ mmc_core-y			:= core.o bus.o host.o \
 				   mmc.o mmc_ops.o sd.o sd_ops.o \
 				   sdio.o sdio_ops.o sdio_bus.o \
 				   sdio_cis.o sdio_io.o sdio_irq.o \
-				   quirks.o cd-gpio.o
+				   quirks.o slot-gpio.o
 
 mmc_core-$(CONFIG_DEBUG_FS)	+= debugfs.o
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/slot-gpio.c
similarity index 53%
rename from drivers/mmc/core/cd-gpio.c
rename to drivers/mmc/core/slot-gpio.c
index f13e38d..9796710 100644
--- a/drivers/mmc/core/cd-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -12,72 +12,72 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 
-struct mmc_cd_gpio {
-	unsigned int gpio;
-	char label[0];
+struct mmc_gpio {
+	unsigned int cd_gpio;
+	char cd_label[0];
 };
 
-static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
+static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 {
 	/* Schedule a card detection after a debounce timeout */
 	mmc_detect_change(dev_id, msecs_to_jiffies(100));
 	return IRQ_HANDLED;
 }
 
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	size_t len = strlen(dev_name(host->parent)) + 4;
-	struct mmc_cd_gpio *cd;
+	struct mmc_gpio *ctx;
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
 	if (irq < 0)
 		return irq;
 
-	cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
-	if (!cd)
+	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
+	if (!ctx)
 		return -ENOMEM;
 
-	snprintf(cd->label, len, "%s cd", dev_name(host->parent));
+	snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
 
-	ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
+	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
 	if (ret < 0)
 		goto egpioreq;
 
-	ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
-				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				   cd->label, host);
+	ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			ctx->cd_label, host);
 	if (ret < 0)
 		goto eirqreq;
 
-	cd->gpio = gpio;
+	ctx->cd_gpio = gpio;
 	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = cd;
+	host->hotplug.handler_priv = ctx;
 
 	return 0;
 
 eirqreq:
 	gpio_free(gpio);
 egpioreq:
-	kfree(cd);
+	kfree(ctx);
 	return ret;
 }
-EXPORT_SYMBOL(mmc_cd_gpio_request);
+EXPORT_SYMBOL(mmc_gpio_request_cd);
 
-void mmc_cd_gpio_free(struct mmc_host *host)
+void mmc_gpio_free_cd(struct mmc_host *host)
 {
-	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
+	struct mmc_gpio *ctx = host->hotplug.handler_priv;
 
-	if (!cd)
+	if (!ctx)
 		return;
 
 	free_irq(host->hotplug.irq, host);
-	gpio_free(cd->gpio);
-	kfree(cd);
+	gpio_free(ctx->cd_gpio);
+	kfree(ctx);
 }
-EXPORT_SYMBOL(mmc_cd_gpio_free);
+EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index b731859..5261934 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -34,9 +34,9 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/mfd/tmio.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/mmc/tmio.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
@@ -1025,7 +1025,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
 	if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
-		ret = mmc_cd_gpio_request(mmc, pdata->cd_gpio);
+		ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio);
 		if (ret < 0) {
 			tmio_mmc_host_remove(_host);
 			return ret;
@@ -1057,7 +1057,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 		 * This means we can miss a card-eject, but this is anyway
 		 * possible, because of delayed processing of hotplug events.
 		 */
-		mmc_cd_gpio_free(mmc);
+		mmc_gpio_free_cd(mmc);
 
 	if (!host->native_hotplug)
 		pm_runtime_get_sync(&pdev->dev);
diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/slot-gpio.h
similarity index 68%
rename from include/linux/mmc/cd-gpio.h
rename to include/linux/mmc/slot-gpio.h
index cefaba0..edfaa32 100644
--- a/include/linux/mmc/cd-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -8,11 +8,11 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef MMC_CD_GPIO_H
-#define MMC_CD_GPIO_H
+#ifndef MMC_SLOT_GPIO_H
+#define MMC_SLOT_GPIO_H
 
 struct mmc_host;
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio);
-void mmc_cd_gpio_free(struct mmc_host *host);
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_cd(struct mmc_host *host);
 
 #endif
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 02/10 v3] mmc: use a more generic name for slot function types and fields
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (21 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 03/10 v3] mmc: add two capability flags for CD and WP signal polarity Guennadi Liakhovetski
                     ` (15 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

struct mmc_host::hotplug is becoming a generic hook for slot functions.
Rename it accordingly.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/host.c      |    2 ++
 drivers/mmc/core/slot-gpio.c |    8 ++++----
 include/linux/mmc/host.h     |   17 ++++++++++++++---
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 91c84c7..b8c5290 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -327,6 +327,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 
 	mmc_host_clk_init(host);
 
+	host->slot.cd_irq = -EINVAL;
+
 	spin_lock_init(&host->lock);
 	init_waitqueue_head(&host->wq);
 	INIT_DELAYED_WORK(&host->detect, mmc_rescan);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 9796710..468e5a0 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -56,8 +56,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 		goto eirqreq;
 
 	ctx->cd_gpio = gpio;
-	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = ctx;
+	host->slot.cd_irq = irq;
+	host->slot.handler_priv = ctx;
 
 	return 0;
 
@@ -71,12 +71,12 @@ EXPORT_SYMBOL(mmc_gpio_request_cd);
 
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
-	struct mmc_gpio *ctx = host->hotplug.handler_priv;
+	struct mmc_gpio *ctx = host->slot.handler_priv;
 
 	if (!ctx)
 		return;
 
-	free_irq(host->hotplug.irq, host);
+	free_irq(host->slot.cd_irq, host);
 	gpio_free(ctx->cd_gpio);
 	kfree(ctx);
 }
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 368b317..725413d 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -150,8 +150,19 @@ struct mmc_async_req {
 	int (*err_check) (struct mmc_card *, struct mmc_async_req *);
 };
 
-struct mmc_hotplug {
-	unsigned int irq;
+/**
+ * struct mmc_slot - MMC slot functions
+ *
+ * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @handler_priv:	MMC/SD-card slot context
+ *
+ * Some MMC/SD host controllers implement slot-functions like card and
+ * write-protect detection natively. However, a large number of controllers
+ * leave these functions to the CPU. This struct provides a hook to attach
+ * such slot-function drivers.
+ */
+struct mmc_slot {
+	int cd_irq;
 	void *handler_priv;
 };
 
@@ -290,7 +301,7 @@ struct mmc_host {
 
 	struct delayed_work	detect;
 	int			detect_change;	/* card detect flag */
-	struct mmc_hotplug	hotplug;
+	struct mmc_slot		slot;
 
 	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
 	unsigned int		bus_refs;	/* reference counter */
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 03/10 v3] mmc: add two capability flags for CD and WP signal polarity
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (22 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 02/10 v3] mmc: use a more generic name for slot function types and fields Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 04/10 v3] mmc: add CD GPIO polling support to slot functions Guennadi Liakhovetski
                     ` (14 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

To handle CD and WP SD/MMC slot pins we need generic flags to specify their
polarity.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 include/linux/mmc/host.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 725413d..1b3a917 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -249,6 +249,8 @@ struct mmc_host {
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_INVERTED_CD	(1 << 10)	/* Card-detect signal active low */
+#define MMC_CAP2_INVERTED_RO	(1 << 11)	/* Write-protect signal active low */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 04/10 v3] mmc: add CD GPIO polling support to slot functions
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (23 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 03/10 v3] mmc: add two capability flags for CD and WP signal polarity Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 05/10 v3] mmc: convert slot functions to managed allocation Guennadi Liakhovetski
                     ` (13 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

A simple extension of mmc slot functions add support for CD GPIO polling
for cases, where the GPIO cannot produce interrupts or this is for some
reason not desired.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/slot-gpio.c  |   45 +++++++++++++++++++++++++++++++---------
 include/linux/mmc/slot-gpio.h |    2 +
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 468e5a0..d70b790 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -29,6 +29,18 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+int mmc_gpio_get_cd(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->cd_gpio) ^
+		!(host->caps2 & MMC_CAP2_INVERTED_CD);
+}
+EXPORT_SYMBOL(mmc_gpio_get_cd);
+
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	size_t len = strlen(dev_name(host->parent)) + 4;
@@ -36,9 +48,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
-	if (irq < 0)
-		return irq;
-
 	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
@@ -49,20 +58,32 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	if (ret < 0)
 		goto egpioreq;
 
-	ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+	/*
+	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
+	 * still prefer to poll, e.g., because that IRQ number is already used
+	 * by another unit and cannot be shared.
+	 */
+	if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL)
+		irq = -EINVAL;
+
+	if (irq >= 0) {
+		ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
 			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 			ctx->cd_label, host);
-	if (ret < 0)
-		goto eirqreq;
+		if (ret < 0)
+			irq = ret;
+	}
 
-	ctx->cd_gpio = gpio;
 	host->slot.cd_irq = irq;
+
+	if (irq < 0)
+		host->caps |= MMC_CAP_NEEDS_POLL;
+
+	ctx->cd_gpio = gpio;
 	host->slot.handler_priv = ctx;
 
 	return 0;
 
-eirqreq:
-	gpio_free(gpio);
 egpioreq:
 	kfree(ctx);
 	return ret;
@@ -76,8 +97,12 @@ void mmc_gpio_free_cd(struct mmc_host *host)
 	if (!ctx)
 		return;
 
-	free_irq(host->slot.cd_irq, host);
+	if (host->slot.cd_irq >= 0) {
+		free_irq(host->slot.cd_irq, host);
+		host->slot.cd_irq = -EINVAL;
+	}
 	gpio_free(ctx->cd_gpio);
+	host->slot.handler_priv = NULL;
 	kfree(ctx);
 }
 EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index edfaa32..1a977d7 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -12,6 +12,8 @@
 #define MMC_SLOT_GPIO_H
 
 struct mmc_host;
+
+int mmc_gpio_get_cd(struct mmc_host *host);
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
 void mmc_gpio_free_cd(struct mmc_host *host);
 
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 05/10 v3] mmc: convert slot functions to managed allocation
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (24 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 04/10 v3] mmc: add CD GPIO polling support to slot functions Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 06/10 v3] mmc: add WP pin handler to slot functions Guennadi Liakhovetski
                     ` (12 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

This prepares for the addition of further slot functions.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/host.c      |    2 +
 drivers/mmc/core/slot-gpio.c |   49 +++++++++++++++++++++++++++++++----------
 include/linux/mmc/host.h     |    3 ++
 3 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index b8c5290..74cf29a5 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -32,6 +32,7 @@
 static void mmc_host_classdev_release(struct device *dev)
 {
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
+	mutex_destroy(&host->slot.lock);
 	kfree(host);
 }
 
@@ -327,6 +328,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 
 	mmc_host_clk_init(host);
 
+	mutex_init(&host->slot.lock);
 	host->slot.cd_irq = -EINVAL;
 
 	spin_lock_init(&host->lock);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index d70b790..f14c8a1 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -29,6 +29,33 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int mmc_gpio_alloc(struct mmc_host *host)
+{
+	size_t len = strlen(dev_name(host->parent)) + 4;
+	struct mmc_gpio *ctx;
+
+	mutex_lock(&host->slot.lock);
+
+	ctx = host->slot.handler_priv;
+	if (!ctx) {
+		/*
+		 * devm_kzalloc() can be called after device_initialize(), even
+		 * before device_add(), i.e., between mmc_alloc_host() and
+		 * mmc_add_host()
+		 */
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
+				   GFP_KERNEL);
+		if (ctx) {
+			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			host->slot.handler_priv = ctx;
+		}
+	}
+
+	mutex_unlock(&host->slot.lock);
+
+	return ctx ? 0 : -ENOMEM;
+}
+
 int mmc_gpio_get_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -43,20 +70,24 @@ EXPORT_SYMBOL(mmc_gpio_get_cd);
 
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
-	size_t len = strlen(dev_name(host->parent)) + 4;
 	struct mmc_gpio *ctx;
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
-	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
-	if (!ctx)
-		return -ENOMEM;
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
 
-	snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+	ctx = host->slot.handler_priv;
 
 	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
 	if (ret < 0)
-		goto egpioreq;
+		/*
+		 * don't bother freeing gpio. It might still get used by other
+		 * slot functions, in any case it will be freed, when the device
+		 * is destroyed.
+		 */
+		return ret;
 
 	/*
 	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
@@ -83,10 +114,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	host->slot.handler_priv = ctx;
 
 	return 0;
-
-egpioreq:
-	kfree(ctx);
-	return ret;
 }
 EXPORT_SYMBOL(mmc_gpio_request_cd);
 
@@ -102,7 +129,5 @@ void mmc_gpio_free_cd(struct mmc_host *host)
 		host->slot.cd_irq = -EINVAL;
 	}
 	gpio_free(ctx->cd_gpio);
-	host->slot.handler_priv = NULL;
-	kfree(ctx);
 }
 EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 1b3a917..3f3c8c9 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -11,6 +11,7 @@
 #define LINUX_MMC_HOST_H
 
 #include <linux/leds.h>
+#include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/fault-inject.h>
@@ -154,6 +155,7 @@ struct mmc_async_req {
  * struct mmc_slot - MMC slot functions
  *
  * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @lock:		protect the @handler_priv pointer
  * @handler_priv:	MMC/SD-card slot context
  *
  * Some MMC/SD host controllers implement slot-functions like card and
@@ -163,6 +165,7 @@ struct mmc_async_req {
  */
 struct mmc_slot {
 	int cd_irq;
+	struct mutex lock;
 	void *handler_priv;
 };
 
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 06/10 v3] mmc: add WP pin handler to slot functions
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (25 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 05/10 v3] mmc: convert slot functions to managed allocation Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 07/10 v3] mmc: tmio: support caps2 flags Guennadi Liakhovetski
                     ` (11 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Card Write-Protect pin is often implemented, using a GPIO, which makes it
simple to provide a generic handler for it.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/slot-gpio.c  |   51 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/mmc/slot-gpio.h |    4 +++
 2 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index f14c8a1..074edc2 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -18,7 +18,9 @@
 #include <linux/slab.h>
 
 struct mmc_gpio {
+	unsigned int ro_gpio;
 	unsigned int cd_gpio;
+	char *ro_label;
 	char cd_label[0];
 };
 
@@ -43,10 +45,12 @@ static int mmc_gpio_alloc(struct mmc_host *host)
 		 * before device_add(), i.e., between mmc_alloc_host() and
 		 * mmc_add_host()
 		 */
-		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len,
 				   GFP_KERNEL);
 		if (ctx) {
+			ctx->ro_label = ctx->cd_label + len;
 			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent));
 			host->slot.handler_priv = ctx;
 		}
 	}
@@ -56,6 +60,18 @@ static int mmc_gpio_alloc(struct mmc_host *host)
 	return ctx ? 0 : -ENOMEM;
 }
 
+int mmc_gpio_get_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->ro_gpio) ^
+		!(host->caps2 & MMC_CAP2_INVERTED_RO);
+}
+EXPORT_SYMBOL(mmc_gpio_get_ro);
+
 int mmc_gpio_get_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -68,6 +84,28 @@ int mmc_gpio_get_cd(struct mmc_host *host)
 }
 EXPORT_SYMBOL(mmc_gpio_get_cd);
 
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
+{
+	struct mmc_gpio *ctx;
+	int ret;
+
+	if (!gpio_is_valid(gpio))
+		return -EINVAL;
+
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
+
+	ctx = host->slot.handler_priv;
+
+	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
+	if (ret < 0)
+		return ret;;
+
+	return 0;
+}
+EXPORT_SYMBOL(mmc_gpio_request_ro);
+
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	struct mmc_gpio *ctx;
@@ -117,6 +155,17 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 }
 EXPORT_SYMBOL(mmc_gpio_request_cd);
 
+void mmc_gpio_free_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return;
+
+	gpio_free(ctx->ro_gpio);
+}
+EXPORT_SYMBOL(mmc_gpio_free_ro);
+
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index 1a977d7..7d88d27 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -13,6 +13,10 @@
 
 struct mmc_host;
 
+int mmc_gpio_get_ro(struct mmc_host *host);
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_ro(struct mmc_host *host);
+
 int mmc_gpio_get_cd(struct mmc_host *host);
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
 void mmc_gpio_free_cd(struct mmc_host *host);
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 07/10 v3] mmc: tmio: support caps2 flags
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (26 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 06/10 v3] mmc: add WP pin handler to slot functions Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 08/10 v3] mmc: sh_mobile_sdhi: " Guennadi Liakhovetski
                     ` (10 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Allow tmio mmc glue drivers pass mmc_host::caps2 flags down to the mmc
layer.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    1 +
 include/linux/mfd/tmio.h        |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 5261934..5509554 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -947,6 +947,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	mmc->ops = &tmio_mmc_ops;
 	mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
+	mmc->caps2 = pdata->capabilities2;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
 	mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index b332c4c..d83af39 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -101,6 +101,7 @@ struct tmio_mmc_host;
 struct tmio_mmc_data {
 	unsigned int			hclk;
 	unsigned long			capabilities;
+	unsigned long			capabilities2;
 	unsigned long			flags;
 	u32				ocr_mask;	/* available voltages */
 	struct tmio_mmc_dma		*dma;
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 08/10 v3] mmc: sh_mobile_sdhi: support caps2 flags
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (27 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 07/10 v3] mmc: tmio: support caps2 flags Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 09/10 v3] ARM: mach-shmobile: specify inverted SDHI card-detect signal polarity Guennadi Liakhovetski
                     ` (9 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Let SDHI platforms specify mmc_host::caps2 flags in their platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c  |    1 +
 include/linux/mmc/sh_mobile_sdhi.h |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 42f07fa..1e7c5c4 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -162,6 +162,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 			mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
 		mmc_data->ocr_mask = p->tmio_ocr_mask;
 		mmc_data->capabilities |= p->tmio_caps;
+		mmc_data->capabilities2 |= p->tmio_caps2;
 		mmc_data->cd_gpio = p->cd_gpio;
 
 		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
index e94e620..b65679f 100644
--- a/include/linux/mmc/sh_mobile_sdhi.h
+++ b/include/linux/mmc/sh_mobile_sdhi.h
@@ -23,6 +23,7 @@ struct sh_mobile_sdhi_info {
 	int dma_slave_rx;
 	unsigned long tmio_flags;
 	unsigned long tmio_caps;
+	unsigned long tmio_caps2;
 	u32 tmio_ocr_mask;	/* available MMC voltages */
 	unsigned int cd_gpio;
 	struct tmio_mmc_data *pdata;
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 09/10 v3] ARM: mach-shmobile: specify inverted SDHI card-detect signal polarity
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (28 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 08/10 v3] mmc: sh_mobile_sdhi: " Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 10/10 v3] mmc: tmio: use generic GPIO CD and WP handlers Guennadi Liakhovetski
                     ` (8 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

On mackerel and ag5evm the SDHI0 CD signal is inverted (active low). To
prepare for the generic GPIO CD handler the MMC_CAP2_INVERTED_CD flag
has to be specified in platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 arch/arm/mach-shmobile/board-ag5evm.c   |    1 +
 arch/arm/mach-shmobile/board-mackerel.c |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 5a6f22f..545fd06 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -370,6 +370,7 @@ static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
 	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD,
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED,
+	.tmio_caps2	= MMC_CAP2_INVERTED_CD,
 	.tmio_ocr_mask	= MMC_VDD_27_28 | MMC_VDD_28_29,
 	.cd_gpio	= GPIO_PORT251,
 };
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index b577f7c..5881bb1 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1047,6 +1047,7 @@ static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
 	.tmio_flags	= TMIO_MMC_USE_GPIO_CD,
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
+	.tmio_caps2	= MMC_CAP2_INVERTED_CD,
 	.cd_gpio	= GPIO_PORT172,
 };
 
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 10/10 v3] mmc: tmio: use generic GPIO CD and WP handlers
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (29 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 09/10 v3] ARM: mach-shmobile: specify inverted SDHI card-detect signal polarity Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi Guennadi Liakhovetski
                     ` (7 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

The tmio-mmc driver is already using the generic GPIO CD handler in IRQ
mode. This patch adds support for CD polling mode and also checks for
availability of a WP GPIO.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 5261934..1eed200 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -871,6 +871,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_ro(mmc);
+	if (ret >= 0)
+		return ret;
 
 	return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
 		 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
@@ -880,6 +883,9 @@ static int tmio_mmc_get_cd(struct mmc_host *mmc)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_cd(mmc);
+	if (ret >= 0)
+		return ret;
 
 	if (!pdata->get_cd)
 		return -ENOSYS;
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (30 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 10/10 v3] mmc: tmio: use generic GPIO CD and WP handlers Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 1/2 v3] mmc: sdhi: add OF support, make platform data optional Guennadi Liakhovetski
                     ` (6 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Olof Johansson

I removed most OF support code from the previous version. In this version 
I'm only adding the bare minimum with no support for any mmc- or 
driver-specific properties. They can be added slowly as need arises.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/2 v3] mmc: sdhi: add OF support, make platform data optional
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (31 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 2/2 v3] mmc: sh-mmcif: " Guennadi Liakhovetski
                     ` (5 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Olof Johansson

Add primitive support for OF to the SDHI TMIO glue, which also makes it
necessary to be able to run without platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c |   26 +++++++++++++++++---------
 1 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 1e7c5c4..3defd77 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/mmc/host.h>
@@ -133,9 +134,8 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 	}
 
 	mmc_data = &priv->mmc_data;
-	p->pdata = mmc_data;
 
-	if (p->init) {
+	if (p && p->init) {
 		ret = p->init(pdev, &sdhi_ops);
 		if (ret)
 			goto einit;
@@ -149,10 +149,6 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 		goto eclkget;
 	}
 
-	if (p->set_pwr)
-		mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
-	if (p->get_cd)
-		mmc_data->get_cd = sh_mobile_sdhi_get_cd;
 	mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
 	mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
 	mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
@@ -164,6 +160,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 		mmc_data->capabilities |= p->tmio_caps;
 		mmc_data->capabilities2 |= p->tmio_caps2;
 		mmc_data->cd_gpio = p->cd_gpio;
+		if (p->set_pwr)
+			mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+		if (p->get_cd)
+			mmc_data->get_cd = sh_mobile_sdhi_get_cd;
 
 		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
 			priv->param_tx.slave_id = p->dma_slave_tx;
@@ -269,7 +269,7 @@ eirq_card_detect:
 eprobe:
 	clk_put(priv->clk);
 eclkget:
-	if (p->cleanup)
+	if (p && p->cleanup)
 		p->cleanup(pdev);
 einit:
 	kfree(priv);
@@ -284,7 +284,8 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 	int i = 0, irq;
 
-	p->pdata = NULL;
+	if (p)
+		p->pdata = NULL;
 
 	tmio_mmc_host_remove(host);
 
@@ -297,7 +298,7 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
 
 	clk_put(priv->clk);
 
-	if (p->cleanup)
+	if (p && p->cleanup)
 		p->cleanup(pdev);
 
 	kfree(priv);
@@ -312,11 +313,18 @@ static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
 	.runtime_resume = tmio_mmc_host_runtime_resume,
 };
 
+static const struct of_device_id sh_mobile_sdhi_of_match[] = {
+	{ .compatible = "renesas,shmobile-sdhi" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match);
+
 static struct platform_driver sh_mobile_sdhi_driver = {
 	.driver		= {
 		.name	= "sh_mobile_sdhi",
 		.owner	= THIS_MODULE,
 		.pm	= &tmio_mmc_dev_pm_ops,
+		.of_match_table = sh_mobile_sdhi_of_match,
 	},
 	.probe		= sh_mobile_sdhi_probe,
 	.remove		= __devexit_p(sh_mobile_sdhi_remove),
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/2 v3] mmc: sh-mmcif: add OF support, make platform data optional
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (32 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 1/2 v3] mmc: sdhi: add OF support, make platform data optional Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
                     ` (4 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm, Olof Johansson

Add primitive OF support to the sh-mmcif driver, which also makes it
necessary to be able to run without platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mmcif.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index f952978..53a3ff3 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -54,6 +54,7 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sh_mmcif.h>
+#include <linux/mod_devicetable.h>
 #include <linux/pagemap.h>
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
@@ -388,6 +389,9 @@ static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
 	struct sh_dmae_slave *tx, *rx;
 	host->dma_active = false;
 
+	if (!pdata)
+		return;
+
 	/* We can only either use DMA for both Tx and Rx or not use it at all */
 	if (pdata->dma) {
 		dev_warn(&host->pd->dev,
@@ -448,13 +452,14 @@ static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
 static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
 {
 	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+	bool sup_pclk = p ? p->sup_pclk : false;
 
 	sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
 	sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR);
 
 	if (!clk)
 		return;
-	if (p->sup_pclk && clk == host->clk)
+	if (sup_pclk && clk == host->clk)
 		sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
 	else
 		sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
@@ -937,7 +942,7 @@ static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios)
 {
 	struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
 
-	if (pd->set_pwr)
+	if (pd && pd->set_pwr)
 		pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF);
 	if (host->vdd)
 		/* Errors ignored... */
@@ -1005,7 +1010,7 @@ static int sh_mmcif_get_cd(struct mmc_host *mmc)
 	struct sh_mmcif_host *host = mmc_priv(mmc);
 	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
 
-	if (!p->get_cd)
+	if (!p || !p->get_cd)
 		return -ENOSYS;
 	else
 		return p->get_cd(host->pd);
@@ -1278,6 +1283,9 @@ static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
 
 	host->vdd = mmc_regulator_get_vmmc(mmc);
 
+	if (!pd)
+		return;
+
 	if (!mmc->ocr_avail)
 		mmc->ocr_avail = pd->ocr;
 	else if (pd->ocr)
@@ -1294,11 +1302,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	void __iomem *reg;
 	char clk_name[8];
 
-	if (!pd) {
-		dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
-		return -ENXIO;
-	}
-
 	irq[0] = platform_get_irq(pdev, 0);
 	irq[1] = platform_get_irq(pdev, 1);
 	if (irq[0] < 0 || irq[1] < 0) {
@@ -1334,7 +1337,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 	sh_mmcif_init_ocr(host);
 
 	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
-	if (pd->caps)
+	if (pd && pd->caps)
 		mmc->caps |= pd->caps;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
@@ -1471,6 +1474,12 @@ static int sh_mmcif_resume(struct device *dev)
 #define sh_mmcif_resume		NULL
 #endif	/* CONFIG_PM */
 
+static const struct of_device_id mmcif_of_match[] = {
+	{ .compatible = "renesas,sh-mmcif" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mmcif_of_match);
+
 static const struct dev_pm_ops sh_mmcif_dev_pm_ops = {
 	.suspend = sh_mmcif_suspend,
 	.resume = sh_mmcif_resume,
@@ -1482,6 +1491,8 @@ static struct platform_driver sh_mmcif_driver = {
 	.driver		= {
 		.name	= DRIVER_NAME,
 		.pm	= &sh_mmcif_dev_pm_ops,
+		.owner	= THIS_MODULE,
+		.of_match_table = mmcif_of_match,
 	},
 };
 
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (33 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 2/2 v3] mmc: sh-mmcif: " Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators Guennadi Liakhovetski
                     ` (3 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

The patches in this series update ecovec and mackerel to use voltage 
regulators and GPIO slot functions, available for SDHI and MMCIF blocks.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 90+ messages in thread

* [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (34 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 2/3 v3] ARM: mach-shmobile: switch all SDHI instances on mackerel to use GPIO CD Guennadi Liakhovetski
                     ` (2 subsequent siblings)
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Power on the CN11 and CN12 SD/MMC slots on ecovec is controlled by GPIOs,
which makes it possible to use the fixed voltage regulator driver to switch
card power on and off.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 arch/sh/boards/mach-ecovec24/setup.c |   85 ++++++++++++++++++++++++---------
 1 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index dbedfda..5ba295d 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -19,6 +19,9 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/usb/renesas_usbhs.h>
 #include <linux/i2c.h>
@@ -518,12 +521,66 @@ static struct i2c_board_info ts_i2c_clients = {
 	.irq		= IRQ0,
 };
 
+static struct regulator_consumer_supply cn12_power_consumers[] =
+{
+	REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+};
+
+static struct regulator_init_data cn12_power_init_data = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(cn12_power_consumers),
+	.consumer_supplies      = cn12_power_consumers,
+};
+
+static struct fixed_voltage_config cn12_power_info = {
+	.supply_name = "CN12 SD/MMC Vdd",
+	.microvolts = 3300000,
+	.gpio = GPIO_PTB7,
+	.enable_high = 1,
+	.init_data = &cn12_power_init_data,
+};
+
+static struct platform_device cn12_power = {
+	.name = "reg-fixed-voltage",
+	.id   = 0,
+	.dev  = {
+		.platform_data = &cn12_power_info,
+	},
+};
+
 #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
 /* SDHI0 */
-static void sdhi0_set_pwr(struct platform_device *pdev, int state)
+static struct regulator_consumer_supply sdhi0_power_consumers[] =
 {
-	gpio_set_value(GPIO_PTB6, state);
-}
+	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct regulator_init_data sdhi0_power_init_data = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(sdhi0_power_consumers),
+	.consumer_supplies      = sdhi0_power_consumers,
+};
+
+static struct fixed_voltage_config sdhi0_power_info = {
+	.supply_name = "CN11 SD/MMC Vdd",
+	.microvolts = 3300000,
+	.gpio = GPIO_PTB6,
+	.enable_high = 1,
+	.init_data = &sdhi0_power_init_data,
+};
+
+static struct platform_device sdhi0_power = {
+	.name = "reg-fixed-voltage",
+	.id   = 1,
+	.dev  = {
+		.platform_data = &sdhi0_power_info,
+	},
+};
 
 static int sdhi0_get_cd(struct platform_device *pdev)
 {
@@ -533,7 +590,6 @@ static int sdhi0_get_cd(struct platform_device *pdev)
 static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
-	.set_pwr	= sdhi0_set_pwr,
 	.tmio_caps      = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD |
 			  MMC_CAP_NEEDS_POLL,
 	.get_cd		= sdhi0_get_cd,
@@ -564,11 +620,6 @@ static struct platform_device sdhi0_device = {
 
 #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SDHI1 */
-static void sdhi1_set_pwr(struct platform_device *pdev, int state)
-{
-	gpio_set_value(GPIO_PTB7, state);
-}
-
 static int sdhi1_get_cd(struct platform_device *pdev)
 {
 	return !gpio_get_value(GPIO_PTW7);
@@ -579,7 +630,6 @@ static struct sh_mobile_sdhi_info sdhi1_info = {
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI1_RX,
 	.tmio_caps      = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD |
 			  MMC_CAP_NEEDS_POLL,
-	.set_pwr	= sdhi1_set_pwr,
 	.get_cd		= sdhi1_get_cd,
 };
 
@@ -899,11 +949,6 @@ static struct platform_device vou_device = {
 
 #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SH_MMCIF */
-static void mmcif_set_pwr(struct platform_device *pdev, int state)
-{
-	gpio_set_value(GPIO_PTB7, state);
-}
-
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
 		.name	= "SH_MMCIF",
@@ -924,12 +969,10 @@ static struct resource sh_mmcif_resources[] = {
 };
 
 static struct sh_mmcif_plat_data sh_mmcif_plat = {
-	.set_pwr	= mmcif_set_pwr,
 	.sup_pclk	= 0, /* SH7724: Max Pclk/2 */
 	.caps		= MMC_CAP_4_BIT_DATA |
 			  MMC_CAP_8_BIT_DATA |
 			  MMC_CAP_NEEDS_POLL,
-	.ocr		= MMC_VDD_32_33 | MMC_VDD_33_34,
 };
 
 static struct platform_device sh_mmcif_device = {
@@ -954,7 +997,9 @@ static struct platform_device *ecovec_devices[] __initdata = {
 	&ceu0_device,
 	&ceu1_device,
 	&keysc_device,
+	&cn12_power,
 #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+	&sdhi0_power,
 	&sdhi0_device,
 #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 	&sdhi1_device,
@@ -1252,8 +1297,6 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_SDHI0D2,  NULL);
 	gpio_request(GPIO_FN_SDHI0D1,  NULL);
 	gpio_request(GPIO_FN_SDHI0D0,  NULL);
-	gpio_request(GPIO_PTB6, NULL);
-	gpio_direction_output(GPIO_PTB6, 0);
 #else
 	/* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */
 	gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
@@ -1282,8 +1325,6 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_MMC_D0, NULL);
 	gpio_request(GPIO_FN_MMC_CLK, NULL);
 	gpio_request(GPIO_FN_MMC_CMD, NULL);
-	gpio_request(GPIO_PTB7, NULL);
-	gpio_direction_output(GPIO_PTB7, 0);
 
 	cn12_enabled = true;
 #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
@@ -1295,8 +1336,6 @@ static int __init arch_setup(void)
 	gpio_request(GPIO_FN_SDHI1D2,  NULL);
 	gpio_request(GPIO_FN_SDHI1D1,  NULL);
 	gpio_request(GPIO_FN_SDHI1D0,  NULL);
-	gpio_request(GPIO_PTB7, NULL);
-	gpio_direction_output(GPIO_PTB7, 0);
 
 	/* Card-detect, used on CN12 with SDHI1 */
 	gpio_request(GPIO_PTW7, NULL);
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 2/3 v3] ARM: mach-shmobile: switch all SDHI instances on mackerel to use GPIO CD
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (35 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 15:45   ` [PATCH 3/3 v3] ARM: mach-shmobile: specify IRQ names on mackerel SDHI0 interface Guennadi Liakhovetski
  2012-05-25 16:01   ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

All 3 SDHI instances on mackerel use GPIOs for card-detection and can be
switched to use the generic GPIO CD helper. SDHI0 card-detect is configured
to produce interrupts, SDHI1 and SDHI2 are polled.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 arch/arm/mach-shmobile/board-mackerel.c |   46 +++++++++++++++----------------
 1 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 5881bb1..45854a9 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1032,15 +1032,6 @@ static struct platform_device nand_flash_device = {
 	},
 };
 
-/*
- * The card detect pin of the top SD/MMC slot (CN7) is active low and is
- * connected to GPIO A22 of SH7372 (GPIO_PORT41).
- */
-static int slot_cn7_get_cd(struct platform_device *pdev)
-{
-	return !gpio_get_value(GPIO_PORT41);
-}
-
 /* SDHI0 */
 static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
@@ -1084,14 +1075,17 @@ static struct platform_device sdhi0_device = {
 
 #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SDHI1 */
+
+/* GPIO_PORT41 can trigger IRQ8, but it is used by USBHS1, we have to poll */
 static struct sh_mobile_sdhi_info sdhi1_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI1_TX,
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI1_RX,
 	.tmio_ocr_mask	= MMC_VDD_165_195,
-	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE,
+	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_USE_GPIO_CD,
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
 			  MMC_CAP_NEEDS_POLL,
-	.get_cd		= slot_cn7_get_cd,
+	.tmio_caps2	= MMC_CAP2_INVERTED_CD,
+	.cd_gpio	= GPIO_PORT41,
 };
 
 static struct resource sdhi1_resources[] = {
@@ -1129,23 +1123,20 @@ static struct platform_device sdhi1_device = {
 };
 #endif
 
+/* SDHI2 */
+
 /*
  * The card detect pin of the top SD/MMC slot (CN23) is active low and is
  * connected to GPIO SCIFB_SCK of SH7372 (GPIO_PORT162).
  */
-static int slot_cn23_get_cd(struct platform_device *pdev)
-{
-	return !gpio_get_value(GPIO_PORT162);
-}
-
-/* SDHI2 */
 static struct sh_mobile_sdhi_info sdhi2_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI2_TX,
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI2_RX,
-	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE,
+	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_USE_GPIO_CD,
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
 			  MMC_CAP_NEEDS_POLL,
-	.get_cd		= slot_cn23_get_cd,
+	.tmio_caps2	= MMC_CAP2_INVERTED_CD,
+	.cd_gpio	= GPIO_PORT162,
 };
 
 static struct resource sdhi2_resources[] = {
@@ -1183,6 +1174,16 @@ static struct platform_device sdhi2_device = {
 };
 
 /* SH_MMCIF */
+
+/*
+ * The card detect pin of the top SD/MMC slot (CN7) is active low and is
+ * connected to GPIO A22 of SH7372 (GPIO_PORT41).
+ */
+static int slot_cn7_get_cd(struct platform_device *pdev)
+{
+	return !gpio_get_value(GPIO_PORT41);
+}
+
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
 		.name	= "MMCIF",
@@ -1521,10 +1522,11 @@ static void __init mackerel_init(void)
 	gpio_request(GPIO_FN_SDHID1_2, NULL);
 	gpio_request(GPIO_FN_SDHID1_1, NULL);
 	gpio_request(GPIO_FN_SDHID1_0, NULL);
-#endif
+#else
 	/* card detect pin for MMC slot (CN7) */
 	gpio_request(GPIO_PORT41, NULL);
 	gpio_direction_input(GPIO_PORT41);
+#endif
 
 	/* enable SDHI2 */
 	gpio_request(GPIO_FN_SDHICMD2, NULL);
@@ -1534,10 +1536,6 @@ static void __init mackerel_init(void)
 	gpio_request(GPIO_FN_SDHID2_1, NULL);
 	gpio_request(GPIO_FN_SDHID2_0, NULL);
 
-	/* card detect pin for microSD slot (CN23) */
-	gpio_request(GPIO_PORT162, NULL);
-	gpio_direction_input(GPIO_PORT162);
-
 	/* MMCIF */
 	gpio_request(GPIO_FN_MMCD0_0, NULL);
 	gpio_request(GPIO_FN_MMCD0_1, NULL);
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* [PATCH 3/3 v3] ARM: mach-shmobile: specify IRQ names on mackerel SDHI0 interface
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (36 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 2/3 v3] ARM: mach-shmobile: switch all SDHI instances on mackerel to use GPIO CD Guennadi Liakhovetski
@ 2012-05-25 15:45   ` Guennadi Liakhovetski
  2012-05-25 16:01   ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 15:45 UTC (permalink / raw)
  To: linux-sh, linux-mmc; +Cc: Chris Ball, Magnus Damm

Using named IRQs helps the driver to act more selectively when configuring
the interface.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 arch/arm/mach-shmobile/board-mackerel.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 45854a9..15c8a08 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1050,14 +1050,17 @@ static struct resource sdhi0_resources[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
+		.name	= SH_MOBILE_SDHI_IRQ_CARD_DETECT,
 		.start	= evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
 		.flags	= IORESOURCE_IRQ,
 	},
 	[2] = {
+		.name	= SH_MOBILE_SDHI_IRQ_SDCARD,
 		.start	= evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
 		.flags	= IORESOURCE_IRQ,
 	},
 	[3] = {
+		.name	= SH_MOBILE_SDHI_IRQ_SDIO,
 		.start	= evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
 		.flags	= IORESOURCE_IRQ,
 	},
-- 
1.7.2.5

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

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* Re: [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates
  2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
                     ` (37 preceding siblings ...)
  2012-05-25 15:45   ` [PATCH 3/3 v3] ARM: mach-shmobile: specify IRQ names on mackerel SDHI0 interface Guennadi Liakhovetski
@ 2012-05-25 16:01   ` Guennadi Liakhovetski
  38 siblings, 0 replies; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-05-25 16:01 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Magnus Damm, linux-sh

On Fri, 25 May 2012, Guennadi Liakhovetski wrote:

> On Fri, 25 May 2012, Guennadi Liakhovetski wrote:
> 
> > Hi all
> > 
> > as follow ups to this email I'll send 6 patch series, which are updates to 
> > the following 2 patch series:
> 
> Ok, sure, this couldn't go without a glitch - I forgot to CC linux-sh. So, 
> what I will do, I will push all these patches to linux-sh only - without 
> other recepients. Would be nice, if reviewers could at least cc both MLs - 
> linux-sh and linux-mmc, but even if someone replies to only one of them, 
> I'll try to make sure to reply to all relevant recepients with a full 
> quote of the original review.

Yes, I know, thank you for your kind words :-D It's Friday, 17:59, +30° 
Celsius (or more) :-)

SORRY

Guennadi

> Sorry for the inconvenience.
> 
> Thanks
> Guennadi
> 
> > 
> > http://thread.gmane.org/gmane.linux.ports.sh.devel/14448
> > http://thread.gmane.org/gmane.linux.ports.sh.devel/14673
> > 
> > I have further split the latter of the above to make reviewing easier. 
> > These series address different topics, but since they touch the same 
> > files, it would be easier to also commit them in the same order. Some 
> > patches also touch files under arch/arm and arch/sh, they will require 
> > respective acks. The patches have been developed, based on "next" of 21 
> > May.
> > 
> > Thanks
> > Guennadi
> > ---
> > Guennadi Liakhovetski, Ph.D.
> > Freelance Open-Source Software Developer
> > http://www.open-technology.de/
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> 
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-25 15:14   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
@ 2012-05-28  3:20     ` Ulf Hansson
  2012-05-28  3:32       ` Philip Rakity
  2012-05-28 14:45     ` Mark Brown
  1 sibling, 1 reply; 90+ messages in thread
From: Ulf Hansson @ 2012-05-28  3:20 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: linux-mmc, Chris Ball, Magnus Damm, Mark Brown

Hi Guennadi,

On 25 May 2012 17:14, Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote:
> Add a function to get a regulator, supplying card's Vdd on a specific host.
> If such a regulator is found, the function checks, whether a valid OCR mask
> can be obtained from this regulator.
>
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
>
> v3: remove bogus attempts to ignore the dummy regulator, drop the check
> for whether the regulator can change status, do not assign
> MMC_CAP_POWER_OFF_CARD automatically. Thanks to Mark and Magnus for
> comments.
>
>  drivers/mmc/core/core.c  |   17 +++++++++++++++++
>  include/linux/mmc/host.h |    6 ++++++
>  2 files changed, 23 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 0b6141d..0f92ec0 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -1013,6 +1013,23 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
>  }
>  EXPORT_SYMBOL(mmc_regulator_set_ocr);
>
> +struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
> +{
> +       struct device *dev = mmc_dev(mmc);
> +       struct regulator *supply = devm_regulator_get(dev, "vmmc");
> +       int ret;
> +
> +       if (IS_ERR(supply))
> +               return NULL;
> +
> +       ret = mmc_regulator_get_ocrmask(supply);
> +       if (ret > 0)

Could we have an "else" were a dev_warn prints some info and as well
the "ret" maybe?

> +               mmc->ocr_avail = ret;
> +
> +       return supply;
> +}
> +EXPORT_SYMBOL(mmc_regulator_get_vmmc);
> +
>  #endif /* CONFIG_REGULATOR */
>
>  /*
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 0707d22..368b317 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -364,6 +364,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply);
>  int mmc_regulator_set_ocr(struct mmc_host *mmc,
>                        struct regulator *supply,
>                        unsigned short vdd_bit);
> +struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc);
>  #else
>  static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
>  {
> @@ -376,6 +377,11 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
>  {
>        return 0;
>  }
> +
> +static inline struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
> +{
> +       return NULL;
> +}
>  #endif
>

Some follow-up thoughts, if mmc_regulator_get_vmmc is supposed to be
used from the host drivers, the mmc_regulator_get_ocrmask function do
no longer have to be an exported function, but instead a static
function on core.c I suppose this can be fixed in separate patch,
where we also add mmc_regulator_get_vmmc for all host drivers?

Kind regards
Ulf Hansson

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-28  3:20     ` Ulf Hansson
@ 2012-05-28  3:32       ` Philip Rakity
  2012-05-28  8:12         ` Adrian Hunter
  0 siblings, 1 reply; 90+ messages in thread
From: Philip Rakity @ 2012-05-28  3:32 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Guennadi Liakhovetski, linux-mmc@vger.kernel.org, Chris Ball,
	Magnus Damm, Mark Brown



I have started looking at this area and I am rather confused.  It seems to me two "dedicated" regulators are required.
One regulator controls VDD (vcc) and this is the regulator called vmmc.  This regulator MAY support the ability to switch voltages and MAY support the ability to be turned on and off.
The other regulator supports signal voltage (vccq) for UHS and SDXC cards.  Currently this is not in sdhci.c (I have a patch for this in preparation).  Use of this regulator requires that the VDD regulator be capable of being set to 1.8 or 3.3v and be capable of being turned on/off.  on/off support is needed is the switch to 1.8v signaling fails for any reason.



On May 27, 2012, at 8:20 PM, Ulf Hansson wrote:

> Hi Guennadi,
> 
> On 25 May 2012 17:14, Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote:
>> Add a function to get a regulator, supplying card's Vdd on a specific host.
>> If such a regulator is found, the function checks, whether a valid OCR mask
>> can be obtained from this regulator.
>> 
>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
>> ---
>> 
>> v3: remove bogus attempts to ignore the dummy regulator, drop the check
>> for whether the regulator can change status, do not assign
>> MMC_CAP_POWER_OFF_CARD automatically. Thanks to Mark and Magnus for
>> comments.
>> 
>>  drivers/mmc/core/core.c  |   17 +++++++++++++++++
>>  include/linux/mmc/host.h |    6 ++++++
>>  2 files changed, 23 insertions(+), 0 deletions(-)
>> 
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index 0b6141d..0f92ec0 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -1013,6 +1013,23 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
>>  }
>>  EXPORT_SYMBOL(mmc_regulator_set_ocr);
>> 
>> +struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
>> +{
>> +       struct device *dev = mmc_dev(mmc);
>> +       struct regulator *supply = devm_regulator_get(dev, "vmmc");
>> +       int ret;
>> +
>> +       if (IS_ERR(supply))
>> +               return NULL;
>> +
>> +       ret = mmc_regulator_get_ocrmask(supply);
>> +       if (ret > 0)
> 
> Could we have an "else" were a dev_warn prints some info and as well
> the "ret" maybe?
> 
>> +               mmc->ocr_avail = ret;
>> +
>> +       return supply;
>> +}
>> +EXPORT_SYMBOL(mmc_regulator_get_vmmc);
>> +
>>  #endif /* CONFIG_REGULATOR */
>> 
>>  /*
>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>> index 0707d22..368b317 100644
>> --- a/include/linux/mmc/host.h
>> +++ b/include/linux/mmc/host.h
>> @@ -364,6 +364,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply);
>>  int mmc_regulator_set_ocr(struct mmc_host *mmc,
>>                        struct regulator *supply,
>>                        unsigned short vdd_bit);
>> +struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc);
>>  #else
>>  static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
>>  {
>> @@ -376,6 +377,11 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
>>  {
>>        return 0;
>>  }
>> +
>> +static inline struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
>> +{
>> +       return NULL;
>> +}
>>  #endif
>> 
> 
> Some follow-up thoughts, if mmc_regulator_get_vmmc is supposed to be
> used from the host drivers, the mmc_regulator_get_ocrmask function do
> no longer have to be an exported function, but instead a static
> function on core.c I suppose this can be fixed in separate patch,
> where we also add mmc_regulator_get_vmmc for all host drivers?


 have started looking at this area and I am rather confused.  It seems to me two "dedicated" regulators are required.
One regulator controls VDD (vcc) and this is the regulator called vmmc.  This regulator MAY support the ability to switch voltages and MAY support the ability to be turned on and off.  The main sdhci.c code needs to check the voltages supported by the regulator against the voltages that the host controller supports and adjust the  mmc capabilities to the common set.  I don't think we do this at the moment.

The other regulator supports signal voltage (vccq) for UHS and SDXC cards.  Currently this is not in sdhci.c (I have a patch for this in preparation).  Use of this regulator requires that the vccq regulator be capable of being set to 1.8 or 3.3v and the VDD (vmmc) regulator be capable of being turned on/off.  on/off support is needed is the switch to 1.8v signaling fails for any reason.



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


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-28  3:32       ` Philip Rakity
@ 2012-05-28  8:12         ` Adrian Hunter
  2012-05-28 14:43           ` Mark Brown
  0 siblings, 1 reply; 90+ messages in thread
From: Adrian Hunter @ 2012-05-28  8:12 UTC (permalink / raw)
  To: Philip Rakity
  Cc: Ulf Hansson, Guennadi Liakhovetski, linux-mmc@vger.kernel.org,
	Chris Ball, Magnus Damm, Mark Brown

On 28/05/12 06:32, Philip Rakity wrote:
> 
> 
> I have started looking at this area and I am rather confused.  It seems to me two "dedicated" regulators are required.

It probably pays not to assume too much about regulators.  For example:

Sometimes vccq is always on, so there may be just 1 regulator for vcc.

wl12xx/SDIO is setup with a fake regulator that actually controls
the enable line.

There is a case where power is supplied at a different voltage than
spec'ed i.e. commit 6e8201f57c9359c9c5dc8f9805c15a4392492a10

> One regulator controls VDD (vcc) and this is the regulator called vmmc.  This regulator MAY support the ability to switch voltages and MAY support the ability to be turned on and off.
> The other regulator supports signal voltage (vccq) for UHS and SDXC cards.  Currently this is not in sdhci.c (I have a patch for this in preparation).  Use of this regulator requires that the VDD regulator be capable of being set to 1.8 or 3.3v and be capable of being turned on/off.  on/off support is needed is the switch to 1.8v signaling fails for any reason.
> 
> 
> 
> On May 27, 2012, at 8:20 PM, Ulf Hansson wrote:
> 
>> Hi Guennadi,
>>
>> On 25 May 2012 17:14, Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote:
>>> Add a function to get a regulator, supplying card's Vdd on a specific host.
>>> If such a regulator is found, the function checks, whether a valid OCR mask
>>> can be obtained from this regulator.
>>>
>>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
>>> ---
>>>
>>> v3: remove bogus attempts to ignore the dummy regulator, drop the check
>>> for whether the regulator can change status, do not assign
>>> MMC_CAP_POWER_OFF_CARD automatically. Thanks to Mark and Magnus for
>>> comments.
>>>
>>>  drivers/mmc/core/core.c  |   17 +++++++++++++++++
>>>  include/linux/mmc/host.h |    6 ++++++
>>>  2 files changed, 23 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>> index 0b6141d..0f92ec0 100644
>>> --- a/drivers/mmc/core/core.c
>>> +++ b/drivers/mmc/core/core.c
>>> @@ -1013,6 +1013,23 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
>>>  }
>>>  EXPORT_SYMBOL(mmc_regulator_set_ocr);
>>>
>>> +struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
>>> +{
>>> +       struct device *dev = mmc_dev(mmc);
>>> +       struct regulator *supply = devm_regulator_get(dev, "vmmc");
>>> +       int ret;
>>> +
>>> +       if (IS_ERR(supply))
>>> +               return NULL;
>>> +
>>> +       ret = mmc_regulator_get_ocrmask(supply);
>>> +       if (ret > 0)
>>
>> Could we have an "else" were a dev_warn prints some info and as well
>> the "ret" maybe?
>>
>>> +               mmc->ocr_avail = ret;
>>> +
>>> +       return supply;
>>> +}
>>> +EXPORT_SYMBOL(mmc_regulator_get_vmmc);
>>> +
>>>  #endif /* CONFIG_REGULATOR */
>>>
>>>  /*
>>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>>> index 0707d22..368b317 100644
>>> --- a/include/linux/mmc/host.h
>>> +++ b/include/linux/mmc/host.h
>>> @@ -364,6 +364,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply);
>>>  int mmc_regulator_set_ocr(struct mmc_host *mmc,
>>>                        struct regulator *supply,
>>>                        unsigned short vdd_bit);
>>> +struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc);
>>>  #else
>>>  static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
>>>  {
>>> @@ -376,6 +377,11 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
>>>  {
>>>        return 0;
>>>  }
>>> +
>>> +static inline struct regulator *mmc_regulator_get_vmmc(struct mmc_host *mmc)
>>> +{
>>> +       return NULL;
>>> +}
>>>  #endif
>>>
>>
>> Some follow-up thoughts, if mmc_regulator_get_vmmc is supposed to be
>> used from the host drivers, the mmc_regulator_get_ocrmask function do
>> no longer have to be an exported function, but instead a static
>> function on core.c I suppose this can be fixed in separate patch,
>> where we also add mmc_regulator_get_vmmc for all host drivers?
> 
> 
>  have started looking at this area and I am rather confused.  It seems to me two "dedicated" regulators are required.
> One regulator controls VDD (vcc) and this is the regulator called vmmc.  This regulator MAY support the ability to switch voltages and MAY support the ability to be turned on and off.  The main sdhci.c code needs to check the voltages supported by the regulator against the voltages that the host controller supports and adjust the  mmc capabilities to the common set.  I don't think we do this at the moment.
> 
> The other regulator supports signal voltage (vccq) for UHS and SDXC cards.  Currently this is not in sdhci.c (I have a patch for this in preparation).  Use of this regulator requires that the vccq regulator be capable of being set to 1.8 or 3.3v and the VDD (vmmc) regulator be capable of being turned on/off.  on/off support is needed is the switch to 1.8v signaling fails for any reason.
> 
> 
> 
>>
>> Kind regards
>> Ulf Hansson
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-28  8:12         ` Adrian Hunter
@ 2012-05-28 14:43           ` Mark Brown
  2012-06-11 12:39             ` Guennadi Liakhovetski
  0 siblings, 1 reply; 90+ messages in thread
From: Mark Brown @ 2012-05-28 14:43 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Philip Rakity, Ulf Hansson, Guennadi Liakhovetski,
	linux-mmc@vger.kernel.org, Chris Ball, Magnus Damm

[-- Attachment #1: Type: text/plain, Size: 1292 bytes --]

On Mon, May 28, 2012 at 11:12:18AM +0300, Adrian Hunter wrote:
> On 28/05/12 06:32, Philip Rakity wrote:

> > I have started looking at this area and I am rather confused.  It seems to me two "dedicated" regulators are required.

> It probably pays not to assume too much about regulators.  For example:

> Sometimes vccq is always on, so there may be just 1 regulator for vcc.

Even if the supply is always on you can easily provide an always on
regulator.  From the point of view of the consumer if there are two
physical supplies needed it's much clearer and easier to just code that
and deal with the fact that we might have no control over them
externally, there's nothing device specific about that process.

> wl12xx/SDIO is setup with a fake regulator that actually controls
> the enable line.

Which enable line is this?  If it's not for the regulator why wouldn't
other boards control this line?

> There is a case where power is supplied at a different voltage than
> spec'ed i.e. commit 6e8201f57c9359c9c5dc8f9805c15a4392492a10

The commit message there is really unclear so it's very hard to
understand what the commit is supposed to do...  for one thing it's not
entirely obvious what the connection with fixed voltage regulators is or
why there might be an intermittent issue.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-25 15:14   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
  2012-05-28  3:20     ` Ulf Hansson
@ 2012-05-28 14:45     ` Mark Brown
  2012-06-11 11:03       ` Guennadi Liakhovetski
  1 sibling, 1 reply; 90+ messages in thread
From: Mark Brown @ 2012-05-28 14:45 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: linux-mmc, Chris Ball, Magnus Damm

[-- Attachment #1: Type: text/plain, Size: 402 bytes --]

On Fri, May 25, 2012 at 05:14:52PM +0200, Guennadi Liakhovetski wrote:
> Add a function to get a regulator, supplying card's Vdd on a specific host.
> If such a regulator is found, the function checks, whether a valid OCR mask
> can be obtained from this regulator.

Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

but

> +EXPORT_SYMBOL(mmc_regulator_get_vmmc);

regulator is all _GPL...

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-25 15:45   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
@ 2012-05-28 14:46     ` Mark Brown
  0 siblings, 0 replies; 90+ messages in thread
From: Mark Brown @ 2012-05-28 14:46 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: linux-sh, linux-mmc, Chris Ball, Magnus Damm

[-- Attachment #1: Type: text/plain, Size: 392 bytes --]

On Fri, May 25, 2012 at 05:45:24PM +0200, Guennadi Liakhovetski wrote:
> Add a function to get a regulator, supplying card's Vdd on a specific host.
> If such a regulator is found, the function checks, whether a valid OCR mask
> can be obtained from this regulator.

This appears to be identical to the version I just reviewed...

Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-28 14:45     ` Mark Brown
@ 2012-06-11 11:03       ` Guennadi Liakhovetski
  2012-06-11 13:41         ` Chris Ball
  0 siblings, 1 reply; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-11 11:03 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-mmc, Chris Ball, Magnus Damm, linux-sh

Hi Mark

On Mon, 28 May 2012, Mark Brown wrote:

> On Fri, May 25, 2012 at 05:14:52PM +0200, Guennadi Liakhovetski wrote:
> > Add a function to get a regulator, supplying card's Vdd on a specific host.
> > If such a regulator is found, the function checks, whether a valid OCR mask
> > can be obtained from this regulator.
> 
> Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

Thanks for the review!

> but
> 
> > +EXPORT_SYMBOL(mmc_regulator_get_vmmc);
> 
> regulator is all _GPL...

Yes, but existing mmc-regulator functions use EXPORT_SYMBOL(), e.g.,

EXPORT_SYMBOL(mmc_regulator_get_ocrmask);

which indeed seem to do the "old evil binary-only module trick": re-export 
functions, dropping the "_GPL" suffix. Looks like they should be fixed...

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-05-28 14:43           ` Mark Brown
@ 2012-06-11 12:39             ` Guennadi Liakhovetski
  2012-06-11 14:23               ` Mark Brown
  0 siblings, 1 reply; 90+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-11 12:39 UTC (permalink / raw)
  To: Mark Brown
  Cc: Adrian Hunter, Philip Rakity, Ulf Hansson,
	linux-mmc@vger.kernel.org, Chris Ball, Magnus Damm

On Mon, 28 May 2012, Mark Brown wrote:

> On Mon, May 28, 2012 at 11:12:18AM +0300, Adrian Hunter wrote:
> > On 28/05/12 06:32, Philip Rakity wrote:
> 
> > > I have started looking at this area and I am rather confused.  It 
> > > seems to me two "dedicated" regulators are required.
> 
> > It probably pays not to assume too much about regulators.  For example:
> 
> > Sometimes vccq is always on, so there may be just 1 regulator for vcc.
> 
> Even if the supply is always on you can easily provide an always on
> regulator.  From the point of view of the consumer if there are two
> physical supplies needed it's much clearer and easier to just code that
> and deal with the fact that we might have no control over them
> externally, there's nothing device specific about that process.

Mark, I'm not sure I understand your above comment correctly. The 
function, that I add in this patch doesn't do much now, that we removed 
all the "smart" regulator capability checking and the automatic MMC flag 
assignment from it. But still it does something rather important: it fixes 
a standard name for MMC Vdd regulators and initialises the ocr-mask 
automatically, if a regulator has been found.

IIUC, to satisfy Philip's requirement for a second regulator it would 
suffice to just issue one more devm_regulator_get() and let the caller 
deal with any errors. Is this what you're suggesting or are you against 
adding the second regulator? We could of course also add it later, but 
that would change the function prototype (unless we add regulator pointers 
to struct mmc_host itself). Whith existing users such changes are a bit 
messy...

Thanks
Guennadi

> > wl12xx/SDIO is setup with a fake regulator that actually controls
> > the enable line.
> 
> Which enable line is this?  If it's not for the regulator why wouldn't
> other boards control this line?
> 
> > There is a case where power is supplied at a different voltage than
> > spec'ed i.e. commit 6e8201f57c9359c9c5dc8f9805c15a4392492a10
> 
> The commit message there is really unclear so it's very hard to
> understand what the commit is supposed to do...  for one thing it's not
> entirely obvious what the connection with fixed voltage regulators is or
> why there might be an intermittent issue.

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-06-11 11:03       ` Guennadi Liakhovetski
@ 2012-06-11 13:41         ` Chris Ball
  0 siblings, 0 replies; 90+ messages in thread
From: Chris Ball @ 2012-06-11 13:41 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: Mark Brown, linux-mmc, Magnus Damm, linux-sh

Hi,

On Mon, Jun 11 2012, Guennadi Liakhovetski wrote:
> Yes, but existing mmc-regulator functions use EXPORT_SYMBOL(), e.g.,
>
> EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
>
> which indeed seem to do the "old evil binary-only module trick": re-export 
> functions, dropping the "_GPL" suffix. Looks like they should be fixed...

Yuck, thanks for noticing that.  Happy to fix it:


Subject: [PATCH] mmc: core: Export regulator_* functions as GPL

The regulator API functions we're wrapping are exported as GPL, so our
wrappers for the same functions should be too.

Reported-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Chris Ball <cjb@laptop.org>
---
 drivers/mmc/core/core.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0b6141d..c689877 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -941,7 +941,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply)
 
 	return result;
 }
-EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
+EXPORT_SYMBOL_GPL(mmc_regulator_get_ocrmask);
 
 /**
  * mmc_regulator_set_ocr - set regulator to match host->ios voltage
@@ -1011,7 +1011,7 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
 			"could not set regulator OCR (%d)\n", result);
 	return result;
 }
-EXPORT_SYMBOL(mmc_regulator_set_ocr);
+EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
 
 #endif /* CONFIG_REGULATOR */
 
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply related	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-06-11 12:39             ` Guennadi Liakhovetski
@ 2012-06-11 14:23               ` Mark Brown
  2012-06-11 14:36                 ` Philip Rakity
  0 siblings, 1 reply; 90+ messages in thread
From: Mark Brown @ 2012-06-11 14:23 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Adrian Hunter, Philip Rakity, Ulf Hansson,
	linux-mmc@vger.kernel.org, Chris Ball, Magnus Damm

[-- Attachment #1: Type: text/plain, Size: 1225 bytes --]

On Mon, Jun 11, 2012 at 02:39:29PM +0200, Guennadi Liakhovetski wrote:
> On Mon, 28 May 2012, Mark Brown wrote:

> > Even if the supply is always on you can easily provide an always on
> > regulator.  From the point of view of the consumer if there are two
> > physical supplies needed it's much clearer and easier to just code that
> > and deal with the fact that we might have no control over them
> > externally, there's nothing device specific about that process.

> Mark, I'm not sure I understand your above comment correctly. The 
> function, that I add in this patch doesn't do much now, that we removed 

> IIUC, to satisfy Philip's requirement for a second regulator it would 
> suffice to just issue one more devm_regulator_get() and let the caller 
> deal with any errors. Is this what you're suggesting or are you against 
> adding the second regulator? We could of course also add it later, but 
> that would change the function prototype (unless we add regulator pointers 
> to struct mmc_host itself). Whith existing users such changes are a bit 
> messy...

Yes, that's what I'm suggesting.  I guess you could wrap the two
regulators up in a small struct without it being too invasive?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-06-11 14:23               ` Mark Brown
@ 2012-06-11 14:36                 ` Philip Rakity
  2012-06-11 14:43                   ` Ulf Hansson
  0 siblings, 1 reply; 90+ messages in thread
From: Philip Rakity @ 2012-06-11 14:36 UTC (permalink / raw)
  To: Mark Brown
  Cc: Guennadi Liakhovetski, Adrian Hunter, Ulf Hansson,
	linux-mmc@vger.kernel.org, Chris Ball, Magnus Damm


On Jun 11, 2012, at 7:23 AM, Mark Brown wrote:

> On Mon, Jun 11, 2012 at 02:39:29PM +0200, Guennadi Liakhovetski wrote:
>> On Mon, 28 May 2012, Mark Brown wrote:
> 
>>> Even if the supply is always on you can easily provide an always on
>>> regulator.  From the point of view of the consumer if there are two
>>> physical supplies needed it's much clearer and easier to just code that
>>> and deal with the fact that we might have no control over them
>>> externally, there's nothing device specific about that process.
> 
>> Mark, I'm not sure I understand your above comment correctly. The 
>> function, that I add in this patch doesn't do much now, that we removed 
> 
>> IIUC, to satisfy Philip's requirement for a second regulator it would 
>> suffice to just issue one more devm_regulator_get() and let the caller 
>> deal with any errors. Is this what you're suggesting or are you against 
>> adding the second regulator? We could of course also add it later, but 
>> that would change the function prototype (unless we add regulator pointers 
>> to struct mmc_host itself). Whith existing users such changes are a bit 
>> messy...
> 
> Yes, that's what I'm suggesting.  I guess you could wrap the two
> regulators up in a small struct without it being too invasive?


Some background notes:
Historically SD cards operated with the same vccq (signaling for dat and clk pins)
and vcc (core) voltage.
usually 3.3v --> we would use one regulator to supply both.  The power (regulator)
was always on and as far as the SD code was concerned never exposed
(eg regulator_get (vmmc) returned an error).

Now enter UHS cards.  They allow (require) the vccq voltage change from
3.3v to 1.8v when operating in UHS mode (DDR50, SDR50, SDR104).
They also note that when a voltage switch is done to move the card 
into UHS mode (3.3V to 1.8V) the switch may fail.  In this case vcc
needs to turned off and then back on to cause the card to reinitialize.

This led me to the conclusion two regulators are required.
vccq must be switchable between 3.3 and 1.8
vcc must be able to be turned off/on and may be switchable to a lower voltage.

Note: embedded MMC is different (eMMC).  Since it is embedded it is
assumed by the spec that the board designed knows that they are doing
and the correct voltages are supplied. 




^ permalink raw reply	[flat|nested] 90+ messages in thread

* Re: [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd
  2012-06-11 14:36                 ` Philip Rakity
@ 2012-06-11 14:43                   ` Ulf Hansson
  0 siblings, 0 replies; 90+ messages in thread
From: Ulf Hansson @ 2012-06-11 14:43 UTC (permalink / raw)
  To: Philip Rakity
  Cc: Mark Brown, Guennadi Liakhovetski, Adrian Hunter, Ulf Hansson,
	linux-mmc@vger.kernel.org, Chris Ball, Magnus Damm

On 06/11/2012 04:36 PM, Philip Rakity wrote:
>
> On Jun 11, 2012, at 7:23 AM, Mark Brown wrote:
>
>> On Mon, Jun 11, 2012 at 02:39:29PM +0200, Guennadi Liakhovetski wrote:
>>> On Mon, 28 May 2012, Mark Brown wrote:
>>
>>>> Even if the supply is always on you can easily provide an always on
>>>> regulator.  From the point of view of the consumer if there are two
>>>> physical supplies needed it's much clearer and easier to just code that
>>>> and deal with the fact that we might have no control over them
>>>> externally, there's nothing device specific about that process.
>>
>>> Mark, I'm not sure I understand your above comment correctly. The
>>> function, that I add in this patch doesn't do much now, that we removed
>>
>>> IIUC, to satisfy Philip's requirement for a second regulator it would
>>> suffice to just issue one more devm_regulator_get() and let the caller
>>> deal with any errors. Is this what you're suggesting or are you against
>>> adding the second regulator? We could of course also add it later, but
>>> that would change the function prototype (unless we add regulator pointers
>>> to struct mmc_host itself). Whith existing users such changes are a bit
>>> messy...
>>
>> Yes, that's what I'm suggesting.  I guess you could wrap the two
>> regulators up in a small struct without it being too invasive?
>
>
> Some background notes:
> Historically SD cards operated with the same vccq (signaling for dat and clk pins)
> and vcc (core) voltage.
> usually 3.3v -->  we would use one regulator to supply both.  The power (regulator)
> was always on and as far as the SD code was concerned never exposed
> (eg regulator_get (vmmc) returned an error).
>
> Now enter UHS cards.  They allow (require) the vccq voltage change from
> 3.3v to 1.8v when operating in UHS mode (DDR50, SDR50, SDR104).
> They also note that when a voltage switch is done to move the card
> into UHS mode (3.3V to 1.8V) the switch may fail.  In this case vcc
> needs to turned off and then back on to cause the card to reinitialize.
>
> This led me to the conclusion two regulators are required.
> vccq must be switchable between 3.3 and 1.8
> vcc must be able to be turned off/on and may be switchable to a lower voltage.
>
> Note: embedded MMC is different (eMMC).  Since it is embedded it is
> assumed by the spec that the board designed knows that they are doing
> and the correct voltages are supplied.
>

Just some additional input;
In eMMC scenario you have two regulators as well. One called vcc (power 
to the card) and one called vccq (io-voltage). Very much depending on 
the hw board design, you may use one, two or no regulator at all for 
these power(s).

Kind regards
Ulf Hansson

^ permalink raw reply	[flat|nested] 90+ messages in thread

end of thread, other threads:[~2012-06-11 14:44 UTC | newest]

Thread overview: 90+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-25 15:14 [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
2012-05-25 15:14 ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
2012-05-25 15:14   ` [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling Guennadi Liakhovetski
2012-05-25 15:14   ` [PATCH 2/3 v3] mmc: sh_mmcif: fix clock management Guennadi Liakhovetski
2012-05-25 15:14   ` [PATCH 3/3 v3] mmc: sh_mmcif: re-read the clock frequency every time the clock is turned on Guennadi Liakhovetski
2012-05-25 15:14 ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
2012-05-25 15:14   ` [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback Guennadi Liakhovetski
2012-05-25 15:14   ` [PATCH 2/5 v3] sh: ecovec: remove unused .down_pwr() MMCIF callback Guennadi Liakhovetski
2012-05-25 15:14   ` [PATCH 3/5 v3] mmc: sh_mmcif: remove unused .down_pwr() callback Guennadi Liakhovetski
2012-05-25 15:14   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
2012-05-28  3:20     ` Ulf Hansson
2012-05-28  3:32       ` Philip Rakity
2012-05-28  8:12         ` Adrian Hunter
2012-05-28 14:43           ` Mark Brown
2012-06-11 12:39             ` Guennadi Liakhovetski
2012-06-11 14:23               ` Mark Brown
2012-06-11 14:36                 ` Philip Rakity
2012-06-11 14:43                   ` Ulf Hansson
2012-05-28 14:45     ` Mark Brown
2012-06-11 11:03       ` Guennadi Liakhovetski
2012-06-11 13:41         ` Chris Ball
2012-05-25 15:14   ` [PATCH 5/5 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
2012-05-25 15:15 ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 2/8 v3] mmc: tmio: don't needlessly enable interrupts during probing Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 3/8 v3] mmc: tmio: add callbacks to enable-update and disable the interface clock Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 4/8 v3] mmc: sdhi: implement tmio-mmc clock enable-update and disable callbacks Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 5/8 v3] mmc: tmio: add regulator support Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 6/8 v3] mmc: sdhi: do not install dummy callbacks Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 7/8 v3] mmc: tmio: use MMC opcode defines instead of numbers Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 8/8 v3] mmc: tmio: remove a duplicated comment line Guennadi Liakhovetski
2012-05-25 15:15 ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 02/10 v3] mmc: use a more generic name for slot function types and fields Guennadi Liakhovetski
2012-05-25 15:15   ` [PATCH 03/10 v3] mmc: add two capability flags for CD and WP signal polarity Guennadi Liakhovetski
2012-05-25 15:16   ` [PATCH 04/10 v3] mmc: add CD GPIO polling support to slot functions Guennadi Liakhovetski
2012-05-25 15:16   ` [PATCH 05/10 v3] mmc: convert slot functions to managed allocation Guennadi Liakhovetski
2012-05-25 15:16   ` [PATCH 06/10 v3] mmc: add WP pin handler to slot functions Guennadi Liakhovetski
2012-05-25 15:16   ` [PATCH 07/10 v3] mmc: tmio: support caps2 flags Guennadi Liakhovetski
2012-05-25 15:16   ` [PATCH 08/10 v3] mmc: sh_mobile_sdhi: " Guennadi Liakhovetski
2012-05-25 15:16   ` [PATCH 09/10 v3] ARM: mach-shmobile: specify inverted SDHI card-detect signal polarity Guennadi Liakhovetski
2012-05-25 15:16   ` [PATCH 10/10 v3] mmc: tmio: use generic GPIO CD and WP handlers Guennadi Liakhovetski
2012-05-25 15:16 ` [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi Guennadi Liakhovetski
2012-05-25 15:16   ` [PATCH 1/2 v3] mmc: sdhi: add OF support, make platform data optional Guennadi Liakhovetski
2012-05-25 15:17   ` [PATCH 2/2 v3] mmc: sh-mmcif: " Guennadi Liakhovetski
2012-05-25 15:17 ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
2012-05-25 15:17   ` [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators Guennadi Liakhovetski
2012-05-25 15:17   ` [PATCH 2/3 v3] ARM: mach-shmobile: switch all SDHI instances on mackerel to use GPIO CD Guennadi Liakhovetski
2012-05-25 15:17   ` [PATCH 3/3 v3] ARM: mach-shmobile: specify IRQ names on mackerel SDHI0 interface Guennadi Liakhovetski
2012-05-25 15:31 ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski
2012-05-25 15:45   ` Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 0/3:1/6 v3] mmc: sh-mmcif: clock management updates Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 1/3 v3] mmc: sh_mmcif: simplify and use meaningful label names in error-handling Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 2/3 v3] mmc: sh_mmcif: fix clock management Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 3/3 v3] mmc: sh_mmcif: re-read the clock frequency every time the clock is turned on Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 0/5:2/6 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 1/5 v3] mmc: sh_mmcif: remove redundant .down_pwr() callback Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 2/5 v3] sh: ecovec: remove unused .down_pwr() MMCIF callback Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 3/5 v3] mmc: sh_mmcif: remove unused .down_pwr() callback Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 4/5 v3] mmc: add a function to get a regulator, supplying card's Vdd Guennadi Liakhovetski
2012-05-28 14:46     ` Mark Brown
2012-05-25 15:45   ` [PATCH 5/5 v3] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 0/8:3/6 v3] mmc: tmio: clock and PM updates Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 1/8 v3] mmc: tmio: stop interface clock before runtime PM suspending Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 2/8 v3] mmc: tmio: don't needlessly enable interrupts during probing Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 3/8 v3] mmc: tmio: add callbacks to enable-update and disable the interface clock Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 4/8 v3] mmc: sdhi: implement tmio-mmc clock enable-update and disable callbacks Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 5/8 v3] mmc: tmio: add regulator support Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 6/8 v3] mmc: sdhi: do not install dummy callbacks Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 7/8 v3] mmc: tmio: use MMC opcode defines instead of numbers Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 8/8 v3] mmc: tmio: remove a duplicated comment line Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 00/10:4/6 v3] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 01/10 v3] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 02/10 v3] mmc: use a more generic name for slot function types and fields Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 03/10 v3] mmc: add two capability flags for CD and WP signal polarity Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 04/10 v3] mmc: add CD GPIO polling support to slot functions Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 05/10 v3] mmc: convert slot functions to managed allocation Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 06/10 v3] mmc: add WP pin handler to slot functions Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 07/10 v3] mmc: tmio: support caps2 flags Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 08/10 v3] mmc: sh_mobile_sdhi: " Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 09/10 v3] ARM: mach-shmobile: specify inverted SDHI card-detect signal polarity Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 10/10 v3] mmc: tmio: use generic GPIO CD and WP handlers Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 0/2:5/6 v3] mmc: add primitive OF support to sh-mmcif and sdhi Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 1/2 v3] mmc: sdhi: add OF support, make platform data optional Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 2/2 v3] mmc: sh-mmcif: " Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 0/3:6/6 v3] sh, ARM: mach-shmobile: update MMC platform data Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 1/3 v3] sh: ecovec: switch MMC power control to regulators Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 2/3 v3] ARM: mach-shmobile: switch all SDHI instances on mackerel to use GPIO CD Guennadi Liakhovetski
2012-05-25 15:45   ` [PATCH 3/3 v3] ARM: mach-shmobile: specify IRQ names on mackerel SDHI0 interface Guennadi Liakhovetski
2012-05-25 16:01   ` [PATCH 0/0/6 v3] mmc core, tmio / sdhi and sh-mmcif updates Guennadi Liakhovetski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).