* [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
* 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-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 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
* 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-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-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
* [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
* 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
* [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
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).