All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC] sh: ecovec: switch MMC power control to regulator
  2012-04-20 16:59 ` Guennadi Liakhovetski
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

Power on the CN12 SD/MMC slot on ecovec is controlled by a GPIO, which
makes it possible to use the gpio-regulator driver to produce a primitive
voltage regulator.

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

As mentioned in the introductory mail, this patch is mostly an 
implementation example.

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

diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index a2f70e6..96561ec 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -19,6 +19,10 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/gpio-regulator.h>
+#include <linux/regulator/machine.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/usb/renesas_usbhs.h>
 #include <linux/i2c.h>
@@ -872,10 +876,45 @@ 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)
+static struct regulator_consumer_supply mmcif_power_consumers[]  {
-	gpio_set_value(GPIO_PTB7, state);
-}
+	REGULATOR_SUPPLY("MMC Vdd", "sh_mmcif.0"),
+};
+
+static struct regulator_init_data mmcif_power_init_data = {
+	.constraints = {
+		.min_uV         = 3300000,
+		.max_uV         = 3300000,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(mmcif_power_consumers),
+	.consumer_supplies      = mmcif_power_consumers,
+};
+
+static struct gpio_regulator_state mmcif_power_states[] = {
+	{ .value = 3300000, .gpios = 0 },
+};
+
+static struct gpio_regulator_config mmcif_power_info = {
+	.supply_name = "CN12 SD/MMC Vdd",
+
+	.enable_gpio = GPIO_PTB7,
+	.enable_high = 1,
+
+	.states = mmcif_power_states,
+	.nr_states = ARRAY_SIZE(mmcif_power_states),
+
+	.type = REGULATOR_VOLTAGE,
+	.init_data = &mmcif_power_init_data,
+};
+
+static struct platform_device mmcif_power = {
+	.name = "gpio-regulator",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &mmcif_power_info,
+	},
+};
 
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
@@ -897,12 +936,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 = {
@@ -942,6 +979,7 @@ static struct platform_device *ecovec_devices[] __initdata = {
 	&irda_device,
 	&vou_device,
 #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
+	&mmcif_power,
 	&sh_mmcif_device,
 #endif
 };
@@ -1254,8 +1292,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)
-- 
1.7.2.5


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

* [PATCH/RFC] sh: ecovec: switch MMC power control to regulator
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

Power on the CN12 SD/MMC slot on ecovec is controlled by a GPIO, which
makes it possible to use the gpio-regulator driver to produce a primitive
voltage regulator.

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

As mentioned in the introductory mail, this patch is mostly an 
implementation example.

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

diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index a2f70e6..96561ec 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -19,6 +19,10 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/gpio-regulator.h>
+#include <linux/regulator/machine.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/usb/renesas_usbhs.h>
 #include <linux/i2c.h>
@@ -872,10 +876,45 @@ 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)
+static struct regulator_consumer_supply mmcif_power_consumers[] =
 {
-	gpio_set_value(GPIO_PTB7, state);
-}
+	REGULATOR_SUPPLY("MMC Vdd", "sh_mmcif.0"),
+};
+
+static struct regulator_init_data mmcif_power_init_data = {
+	.constraints = {
+		.min_uV         = 3300000,
+		.max_uV         = 3300000,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(mmcif_power_consumers),
+	.consumer_supplies      = mmcif_power_consumers,
+};
+
+static struct gpio_regulator_state mmcif_power_states[] = {
+	{ .value = 3300000, .gpios = 0 },
+};
+
+static struct gpio_regulator_config mmcif_power_info = {
+	.supply_name = "CN12 SD/MMC Vdd",
+
+	.enable_gpio = GPIO_PTB7,
+	.enable_high = 1,
+
+	.states = mmcif_power_states,
+	.nr_states = ARRAY_SIZE(mmcif_power_states),
+
+	.type = REGULATOR_VOLTAGE,
+	.init_data = &mmcif_power_init_data,
+};
+
+static struct platform_device mmcif_power = {
+	.name = "gpio-regulator",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &mmcif_power_info,
+	},
+};
 
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
@@ -897,12 +936,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 = {
@@ -942,6 +979,7 @@ static struct platform_device *ecovec_devices[] __initdata = {
 	&irda_device,
 	&vou_device,
 #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
+	&mmcif_power,
 	&sh_mmcif_device,
 #endif
 };
@@ -1254,8 +1292,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)
-- 
1.7.2.5


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

* [PATCH 0/5] mmc: sh_mmcif: add regulator support
@ 2012-04-20 16:59 ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

Hi all

The first 3 patches in this series are preparatory, patches 2 and 3 can be 
pushed with later kernel versions to simplify dependencies. Patch 4 
actually adds regulator support. Patch 5 is not (necessarily) for 
inclusion. It's just an implementation example for ecovec. Since ecovec's 
CN12 slot is a combined SD/MMC slot, driven by the SDHI controller in SD 
mode, it might make sense to wait until regulators are supported by SDHI 
too, after which a single regulator device in ecovec platform data can be 
used for both.

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

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

* [PATCH 0/5] mmc: sh_mmcif: add regulator support
@ 2012-04-20 16:59 ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

Hi all

The first 3 patches in this series are preparatory, patches 2 and 3 can be 
pushed with later kernel versions to simplify dependencies. Patch 4 
actually adds regulator support. Patch 5 is not (necessarily) for 
inclusion. It's just an implementation example for ecovec. Since ecovec's 
CN12 slot is a combined SD/MMC slot, driven by the SDHI controller in SD 
mode, it might make sense to wait until regulators are supported by SDHI 
too, after which a single regulator device in ecovec platform data can be 
used for both.

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

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

* [PATCH 1/5] mmc: sh_mmcif: remove redundant .down_pwr() callback
  2012-04-20 16:59 ` Guennadi Liakhovetski
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

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 ed59392..19c7576 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -957,8 +957,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] 20+ messages in thread

* [PATCH 1/5] mmc: sh_mmcif: remove redundant .down_pwr() callback
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

>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 ed59392..19c7576 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -957,8 +957,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] 20+ messages in thread

* [PATCH 2/5] sh: ecovec: remove unused .down_pwr() MMCIF callback
  2012-04-20 16:59 ` Guennadi Liakhovetski
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

.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>
---
 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 d12fe9d..a2f70e6 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -877,11 +877,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",
@@ -903,7 +898,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] 20+ messages in thread

* [PATCH 2/5] sh: ecovec: remove unused .down_pwr() MMCIF callback
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

.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>
---
 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 d12fe9d..a2f70e6 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -877,11 +877,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",
@@ -903,7 +898,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] 20+ messages in thread

* [PATCH 3/5] mmc: sh_mmcif: remove unused .down_pwr() callback
  2012-04-20 16:59 ` Guennadi Liakhovetski
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 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] 20+ messages in thread

* [PATCH 3/5] mmc: sh_mmcif: remove unused .down_pwr() callback
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 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] 20+ messages in thread

* [PATCH 4/5] mmc: sh_mmcif: add regulator support
  2012-04-20 16:59 ` Guennadi Liakhovetski
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

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

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

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 19c7576..a5dadd2 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -58,6 +58,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
 
@@ -231,6 +232,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;
@@ -923,10 +926,21 @@ static void sh_mmcif_clk_update(struct sh_mmcif_host *host)
 	host->mmc->f_min = host->clk / 512;
 }
 
+static void sh_mmcif_set_power(struct sh_mmcif_host *host, bool on)
+{
+	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+
+	if (host->vdd)
+		/* Errors ignored... */
+		mmc_regulator_set_ocr(host->mmc, host->vdd,
+				      on ? host->mmc->ios.vdd : 0);
+	else if (p->set_pwr)
+		p->set_pwr(host->pd, on);
+}
+
 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);
@@ -944,6 +958,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, true);
 	} else if (ios->power_mode = MMC_POWER_OFF || !ios->clock) {
 		/* clock stop */
 		sh_mmcif_clock_control(host, 0);
@@ -957,8 +972,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, false);
 		}
 		host->state = STATE_IDLE;
 		return;
@@ -966,8 +981,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);
 			clk_enable(host->hclk);
 			sh_mmcif_clk_update(host);
 			pm_runtime_get_sync(&host->pd->dev);
@@ -1252,6 +1265,25 @@ 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 *p = host->pd->dev.platform_data;
+	struct mmc_host *mmc = host->mmc;
+
+	host->vdd = regulator_get(mmc_dev(mmc), "MMC Vdd");
+	if (IS_ERR(host->vdd)) {
+		host->vdd = NULL;
+	} else {
+		mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vdd);
+		if (p->ocr || p->set_pwr)
+			dev_warn(mmc_dev(mmc),
+				"Platform OCR mask / .s_power() are ignored\n");
+	}
+
+	if (!host->vdd)
+		mmc->ocr_avail = p->ocr;
+}
+
 static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 {
 	int ret = 0, irq[2];
@@ -1298,8 +1330,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;
@@ -1365,6 +1397,7 @@ eresume:
 	clk_disable(host->hclk);
 	clk_put(host->hclk);
 eclkget:
+	regulator_put(host->vdd);
 	pm_runtime_disable(&pdev->dev);
 	mmc_free_host(mmc);
 ealloch:
@@ -1407,6 +1440,7 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 	mmc_free_host(host->mmc);
 	pm_runtime_put_sync(&pdev->dev);
 	clk_disable(host->hclk);
+	regulator_put(host->vdd);
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
-- 
1.7.2.5


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

* [PATCH 4/5] mmc: sh_mmcif: add regulator support
@ 2012-04-20 16:59   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 16:59 UTC (permalink / raw)
  To: linux-mmc; +Cc: Liam Girdwood, Mark Brown, Magnus Damm, linux-sh

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

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

diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 19c7576..a5dadd2 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -58,6 +58,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
 
@@ -231,6 +232,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;
@@ -923,10 +926,21 @@ static void sh_mmcif_clk_update(struct sh_mmcif_host *host)
 	host->mmc->f_min = host->clk / 512;
 }
 
+static void sh_mmcif_set_power(struct sh_mmcif_host *host, bool on)
+{
+	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+
+	if (host->vdd)
+		/* Errors ignored... */
+		mmc_regulator_set_ocr(host->mmc, host->vdd,
+				      on ? host->mmc->ios.vdd : 0);
+	else if (p->set_pwr)
+		p->set_pwr(host->pd, on);
+}
+
 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);
@@ -944,6 +958,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, true);
 	} else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
 		/* clock stop */
 		sh_mmcif_clock_control(host, 0);
@@ -957,8 +972,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, false);
 		}
 		host->state = STATE_IDLE;
 		return;
@@ -966,8 +981,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);
 			clk_enable(host->hclk);
 			sh_mmcif_clk_update(host);
 			pm_runtime_get_sync(&host->pd->dev);
@@ -1252,6 +1265,25 @@ 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 *p = host->pd->dev.platform_data;
+	struct mmc_host *mmc = host->mmc;
+
+	host->vdd = regulator_get(mmc_dev(mmc), "MMC Vdd");
+	if (IS_ERR(host->vdd)) {
+		host->vdd = NULL;
+	} else {
+		mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vdd);
+		if (p->ocr || p->set_pwr)
+			dev_warn(mmc_dev(mmc),
+				"Platform OCR mask / .s_power() are ignored\n");
+	}
+
+	if (!host->vdd)
+		mmc->ocr_avail = p->ocr;
+}
+
 static int __devinit sh_mmcif_probe(struct platform_device *pdev)
 {
 	int ret = 0, irq[2];
@@ -1298,8 +1330,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;
@@ -1365,6 +1397,7 @@ eresume:
 	clk_disable(host->hclk);
 	clk_put(host->hclk);
 eclkget:
+	regulator_put(host->vdd);
 	pm_runtime_disable(&pdev->dev);
 	mmc_free_host(mmc);
 ealloch:
@@ -1407,6 +1440,7 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 	mmc_free_host(host->mmc);
 	pm_runtime_put_sync(&pdev->dev);
 	clk_disable(host->hclk);
+	regulator_put(host->vdd);
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
-- 
1.7.2.5


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

* Re: [PATCH/RFC] sh: ecovec: switch MMC power control to regulator
  2012-04-20 16:59   ` Guennadi Liakhovetski
@ 2012-04-20 17:07     ` Mark Brown
  -1 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2012-04-20 17:07 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: linux-mmc, Liam Girdwood, Magnus Damm, linux-sh

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

On Fri, Apr 20, 2012 at 06:59:41PM +0200, Guennadi Liakhovetski wrote:

> +static struct gpio_regulator_state mmcif_power_states[] = {
> +	{ .value = 3300000, .gpios = 0 },
> +};

It doesn't make much odds but if you've only got one voltage the fixed
voltage regulator is a little more idiomatic here (there's some overlap
as they've been evolving separately.  No harm in gpio-regulator though.

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

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

* Re: [PATCH/RFC] sh: ecovec: switch MMC power control to regulator
@ 2012-04-20 17:07     ` Mark Brown
  0 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2012-04-20 17:07 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: linux-mmc, Liam Girdwood, Magnus Damm, linux-sh

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

On Fri, Apr 20, 2012 at 06:59:41PM +0200, Guennadi Liakhovetski wrote:

> +static struct gpio_regulator_state mmcif_power_states[] = {
> +	{ .value = 3300000, .gpios = 0 },
> +};

It doesn't make much odds but if you've only got one voltage the fixed
voltage regulator is a little more idiomatic here (there's some overlap
as they've been evolving separately.  No harm in gpio-regulator though.

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

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

* Re: [PATCH/RFC 5/5] sh: ecovec: switch MMC power control to regulator
  2012-04-20 17:07     ` Mark Brown
@ 2012-04-20 19:56       ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 19:56 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-mmc, Liam Girdwood, Magnus Damm, linux-sh

(this patch should have been 5/5, as you have guessed:-))

On Fri, 20 Apr 2012, Mark Brown wrote:

> On Fri, Apr 20, 2012 at 06:59:41PM +0200, Guennadi Liakhovetski wrote:
> 
> > +static struct gpio_regulator_state mmcif_power_states[] = {
> > +	{ .value = 3300000, .gpios = 0 },
> > +};
> 
> It doesn't make much odds but if you've only got one voltage the fixed
> voltage regulator is a little more idiomatic here (there's some overlap
> as they've been evolving separately.  No harm in gpio-regulator though.

Indeed, that would have been even easier, thanks for the suggestion, Mark!

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

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

* Re: [PATCH/RFC 5/5] sh: ecovec: switch MMC power control to regulator
@ 2012-04-20 19:56       ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-20 19:56 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-mmc, Liam Girdwood, Magnus Damm, linux-sh

(this patch should have been 5/5, as you have guessed:-))

On Fri, 20 Apr 2012, Mark Brown wrote:

> On Fri, Apr 20, 2012 at 06:59:41PM +0200, Guennadi Liakhovetski wrote:
> 
> > +static struct gpio_regulator_state mmcif_power_states[] = {
> > +	{ .value = 3300000, .gpios = 0 },
> > +};
> 
> It doesn't make much odds but if you've only got one voltage the fixed
> voltage regulator is a little more idiomatic here (there's some overlap
> as they've been evolving separately.  No harm in gpio-regulator though.

Indeed, that would have been even easier, thanks for the suggestion, Mark!

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

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

* Re: [PATCH/RFC] sh: ecovec: switch MMC power control to regulator
  2012-04-20 17:07     ` Mark Brown
@ 2012-04-24 11:46       ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-24 11:46 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-mmc, Liam Girdwood, Magnus Damm, linux-sh

Hi

On Fri, 20 Apr 2012, Mark Brown wrote:

> On Fri, Apr 20, 2012 at 06:59:41PM +0200, Guennadi Liakhovetski wrote:
> 
> > +static struct gpio_regulator_state mmcif_power_states[] = {
> > +	{ .value = 3300000, .gpios = 0 },
> > +};
> 
> It doesn't make much odds but if you've only got one voltage the fixed
> voltage regulator is a little more idiomatic here (there's some overlap
> as they've been evolving separately.  No harm in gpio-regulator though.

One more question in this respect: I see, that most other MMC drivers use 
"vmmc" as supply name. How important is it for all MMC drivers to use the 
same name? Shall I use it for MMCIF and TMIO-MMC too?

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

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

* Re: [PATCH/RFC] sh: ecovec: switch MMC power control to regulator
@ 2012-04-24 11:46       ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-04-24 11:46 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-mmc, Liam Girdwood, Magnus Damm, linux-sh

Hi

On Fri, 20 Apr 2012, Mark Brown wrote:

> On Fri, Apr 20, 2012 at 06:59:41PM +0200, Guennadi Liakhovetski wrote:
> 
> > +static struct gpio_regulator_state mmcif_power_states[] = {
> > +	{ .value = 3300000, .gpios = 0 },
> > +};
> 
> It doesn't make much odds but if you've only got one voltage the fixed
> voltage regulator is a little more idiomatic here (there's some overlap
> as they've been evolving separately.  No harm in gpio-regulator though.

One more question in this respect: I see, that most other MMC drivers use 
"vmmc" as supply name. How important is it for all MMC drivers to use the 
same name? Shall I use it for MMCIF and TMIO-MMC too?

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

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

* Re: [PATCH/RFC] sh: ecovec: switch MMC power control to regulator
  2012-04-24 11:46       ` Guennadi Liakhovetski
@ 2012-04-24 12:14         ` Mark Brown
  -1 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2012-04-24 12:14 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: linux-mmc, Liam Girdwood, Magnus Damm, linux-sh

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

On Tue, Apr 24, 2012 at 01:46:09PM +0200, Guennadi Liakhovetski wrote:

> One more question in this respect: I see, that most other MMC drivers use 
> "vmmc" as supply name. How important is it for all MMC drivers to use the 
> same name? Shall I use it for MMCIF and TMIO-MMC too?

The only thing from a regulator API point of view is that the name
should be something that users can easily match up with the schematic -
the general advice is that it should correspond to the name given in the
chip datasheet as that can be tied in with relative ease, though so long
as it's clear it doesn't *really* matter.

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

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

* Re: [PATCH/RFC] sh: ecovec: switch MMC power control to regulator
@ 2012-04-24 12:14         ` Mark Brown
  0 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2012-04-24 12:14 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: linux-mmc, Liam Girdwood, Magnus Damm, linux-sh

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

On Tue, Apr 24, 2012 at 01:46:09PM +0200, Guennadi Liakhovetski wrote:

> One more question in this respect: I see, that most other MMC drivers use 
> "vmmc" as supply name. How important is it for all MMC drivers to use the 
> same name? Shall I use it for MMCIF and TMIO-MMC too?

The only thing from a regulator API point of view is that the name
should be something that users can easily match up with the schematic -
the general advice is that it should correspond to the name given in the
chip datasheet as that can be tied in with relative ease, though so long
as it's clear it doesn't *really* matter.

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

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

end of thread, other threads:[~2012-04-24 12:14 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-20 16:59 [PATCH 0/5] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
2012-04-20 16:59 ` Guennadi Liakhovetski
2012-04-20 16:59 ` [PATCH/RFC] sh: ecovec: switch MMC power control to regulator Guennadi Liakhovetski
2012-04-20 16:59   ` Guennadi Liakhovetski
2012-04-20 17:07   ` Mark Brown
2012-04-20 17:07     ` Mark Brown
2012-04-20 19:56     ` [PATCH/RFC 5/5] " Guennadi Liakhovetski
2012-04-20 19:56       ` Guennadi Liakhovetski
2012-04-24 11:46     ` [PATCH/RFC] " Guennadi Liakhovetski
2012-04-24 11:46       ` Guennadi Liakhovetski
2012-04-24 12:14       ` Mark Brown
2012-04-24 12:14         ` Mark Brown
2012-04-20 16:59 ` [PATCH 1/5] mmc: sh_mmcif: remove redundant .down_pwr() callback Guennadi Liakhovetski
2012-04-20 16:59   ` Guennadi Liakhovetski
2012-04-20 16:59 ` [PATCH 2/5] sh: ecovec: remove unused .down_pwr() MMCIF callback Guennadi Liakhovetski
2012-04-20 16:59   ` Guennadi Liakhovetski
2012-04-20 16:59 ` [PATCH 3/5] mmc: sh_mmcif: remove unused .down_pwr() callback Guennadi Liakhovetski
2012-04-20 16:59   ` Guennadi Liakhovetski
2012-04-20 16:59 ` [PATCH 4/5] mmc: sh_mmcif: add regulator support Guennadi Liakhovetski
2012-04-20 16:59   ` Guennadi Liakhovetski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.