Skip to contentSkip to conversation

Add device tree support for mc13892 regulator driver

PATCH Superseded Shawn Guo 4 participants 14 messages Nov 28, 2011 – Nov 30, 2011

Subsystems (4)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Shawn Guo

author
#0 lore raw

cover Add device tree support for mc13892 regulator driver

The first patch adds device tree probe support for mc13xxx mfd driver.

The patches #2 and #3 make small changes to regulator OF function for supporting the case like mc13892 regulator driver, where device_node does not have a struct device behind it. I'm sorry for that I did not notice them until I start porting mc13892 to the support

The patch #4 adds the actual device tree support for mc13892 regulator driver, and the last patch add mc13892 support into imx51-babbage device tree source.

Shawn Guo (5):
mfd: mc13xxx: add device tree probe support
regulator: fix label names used in device tree bindings
regulator: pass device_node to of_get_regulator_init_data()
regulator: mc13892: add device tree probe support arm/imx: add mc13892 support into imx51-babbage.dts

 .../devicetree/bindings/regulator/regulator.txt    |   10 +-
 arch/arm/boot/dts/imx51-babbage.dts                |  100 ++++++++++++++++-
 drivers/mfd/mc13xxx-core.c                         |  121 ++++++++++++++-----
 drivers/regulator/mc13892-regulator.c              |   43 +++++--
 drivers/regulator/mc13xxx-regulator-core.c         |   57 +++++++++
 drivers/regulator/mc13xxx.h                        |   20 ++++
 drivers/regulator/of_regulator.c                   |    7 +-
 include/linux/mfd/mc13xxx.h                        |    1 +
 include/linux/regulator/of_regulator.h             |    6 +-
 9 files changed, 311 insertions(+), 54 deletions(-)
author
#1 lore raw

PATCH 1/5 mfd: mc13xxx: add device tree probe support

It adds device tree probe support for mc13xxx mfd driver.

Cc Samuel Ortiz <[email protected]>
---
 drivers/mfd/mc13xxx-core.c |  121 ++++++++++++++++++++++++++++++++------------
 1 files changed, 89 insertions(+), 32 deletions(-)
drivers/mfd/mc13xxx-core.c +89 -32
index e9619ac..34332e7 100644
@@ -18,11 +18,15 @@
 #include <linux/spi/spi.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/mc13xxx.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 
 struct mc13xxx {
 	struct spi_device *spidev;
 	struct mutex lock;
-	int irq;
+	int irq_gpio;
+	int flags;
 
 	irq_handler_t irqhandler[MC13XXX_NUM_IRQ];
 	void *irqdata[MC13XXX_NUM_IRQ];
@@ -550,10 +554,7 @@ static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx)
 
 int mc13xxx_get_flags(struct mc13xxx *mc13xxx)
 {
-	struct mc13xxx_platform_data *pdata =
-		dev_get_platdata(&mc13xxx->spidev->dev);
-
-	return pdata->flags;
+	return mc13xxx->flags;
 }
 EXPORT_SYMBOL(mc13xxx_get_flags);
 
@@ -696,17 +697,68 @@ static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
 	return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0);
 }
 
+#ifdef CONFIG_OF
+static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx)
+{
+	struct device_node *np = mc13xxx->spidev->dev.of_node;
+
+	if (!np)
+		return -ENODEV;
+
+	if (of_get_property(np, "fsl,mc13xxx-uses-adc", NULL))
+		mc13xxx->flags |= MC13XXX_USE_ADC;
+
+	if (of_get_property(np, "fsl,mc13xxx-uses-codec", NULL))
+		mc13xxx->flags |= MC13XXX_USE_CODEC;
+
+	if (of_get_property(np, "fsl,mc13xxx-uses-rtc", NULL))
+		mc13xxx->flags |= MC13XXX_USE_RTC;
+
+	if (of_get_property(np, "fsl,mc13xxx-uses-touch", NULL))
+		mc13xxx->flags |= MC13XXX_USE_TOUCHSCREEN;
+
+	return 0;
+}
+#else
+static inline int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx)
+{
+	return -ENODEV;
+}
+#endif
+
+static const struct spi_device_id mc13xxx_device_id[] = {
+	{
+		.name = "mc13783",
+		.driver_data = MC13XXX_ID_MC13783,
+	}, {
+		.name = "mc13892",
+		.driver_data = MC13XXX_ID_MC13892,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(spi, mc13xxx_device_id);
+
+static const struct of_device_id mc13xxx_dt_ids[] = {
+	{ .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, },
+	{ .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids);
+
 static int mc13xxx_probe(struct spi_device *spi)
 {
+	struct device_node *np = spi->dev.of_node;
+	const struct of_device_id *of_id;
+	struct spi_driver *sdrv = to_spi_driver(spi->dev.driver);
 	struct mc13xxx *mc13xxx;
 	struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev);
 	enum mc13xxx_id id;
 	int ret;
 
-	if (!pdata) {
-		dev_err(&spi->dev, "invalid platform data\n");
-		return -EINVAL;
-	}
+	of_id = of_match_device(mc13xxx_dt_ids, &spi->dev);
+	if (of_id)
+		sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data];
 
 	mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL);
 	if (!mc13xxx)
@@ -735,6 +787,15 @@ static int mc13xxx_probe(struct spi_device *spi)
 	if (ret)
 		goto err_mask;
 
+	mc13xxx->irq_gpio = of_get_named_gpio(np, "mc13xxx-irq-gpios", 0);
+	if (gpio_is_valid(mc13xxx->irq_gpio)) {
+		ret = gpio_request_one(mc13xxx->irq_gpio, GPIOF_IN,
+				       "mc13xxx-irq");
+		if (ret)
+			goto err_mask;
+		spi->irq = gpio_to_irq(mc13xxx->irq_gpio);
+	}
+
 	ret = request_threaded_irq(spi->irq, NULL, mc13xxx_irq_thread,
 			IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx);
 
@@ -749,28 +810,33 @@ err_revision:
 
 	mc13xxx_unlock(mc13xxx);
 
-	if (pdata->flags & MC13XXX_USE_ADC)
+	if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata)
+		mc13xxx->flags = pdata->flags;
+
+	if (mc13xxx->flags & MC13XXX_USE_ADC)
 		mc13xxx_add_subdevice(mc13xxx, "%s-adc");
 
-	if (pdata->flags & MC13XXX_USE_CODEC)
+	if (mc13xxx->flags & MC13XXX_USE_CODEC)
 		mc13xxx_add_subdevice(mc13xxx, "%s-codec");
 
-	mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
-		&pdata->regulators, sizeof(pdata->regulators));
-
-	if (pdata->flags & MC13XXX_USE_RTC)
+	if (mc13xxx->flags & MC13XXX_USE_RTC)
 		mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
 
-	if (pdata->flags & MC13XXX_USE_TOUCHSCREEN)
+	if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN)
 		mc13xxx_add_subdevice(mc13xxx, "%s-ts");
 
-	if (pdata->leds)
+	if (pdata) {
+		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
+			&pdata->regulators, sizeof(pdata->regulators));
 		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
 				pdata->leds, sizeof(*pdata->leds));
-
-	if (pdata->buttons)
 		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton",
 				pdata->buttons, sizeof(*pdata->buttons));
+	} else {
+		mc13xxx_add_subdevice(mc13xxx, "%s-regulator");
+		mc13xxx_add_subdevice(mc13xxx, "%s-led");
+		mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton");
+	}
 
 	return 0;
 }
@@ -781,6 +847,9 @@ static int __devexit mc13xxx_remove(struct spi_device *spi)
 
 	free_irq(mc13xxx->spidev->irq, mc13xxx);
 
+	if (gpio_is_valid(mc13xxx->irq_gpio))
+		gpio_free(mc13xxx->irq_gpio);
+
 	mfd_remove_devices(&spi->dev);
 
 	kfree(mc13xxx);
@@ -788,25 +857,13 @@ static int __devexit mc13xxx_remove(struct spi_device *spi)
 	return 0;
 }
 
-static const struct spi_device_id mc13xxx_device_id[] = {
-	{
-		.name = "mc13783",
-		.driver_data = MC13XXX_ID_MC13783,
-	}, {
-		.name = "mc13892",
-		.driver_data = MC13XXX_ID_MC13892,
-	}, {
-		/* sentinel */
-	}
-};
-MODULE_DEVICE_TABLE(spi, mc13xxx_device_id);
-
 static struct spi_driver mc13xxx_driver = {
 	.id_table = mc13xxx_device_id,
 	.driver = {
 		.name = "mc13xxx",
 		.bus = &spi_bus_type,
 		.owner = THIS_MODULE,
+		.of_match_table = mc13xxx_dt_ids,
 	},
 	.probe = mc13xxx_probe,
 	.remove = __devexit_p(mc13xxx_remove),
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH 1/5 mfd: mc13xxx: add device tree probe support

[]...

Quoted 24 lines
drivers/mfd/mc13xxx-core.c +9 -4
+};
+MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids);
+
  static int mc13xxx_probe(struct spi_device *spi)
  {
+	struct device_node *np = spi->dev.of_node;
+	const struct of_device_id *of_id;
+	struct spi_driver *sdrv = to_spi_driver(spi->dev.driver);
  	struct mc13xxx *mc13xxx;
  	struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev);
  	enum mc13xxx_id id;
  	int ret;
 
-	if (!pdata) {
-		dev_err(&spi->dev, "invalid platform data\n");
-		return -EINVAL;
-	}
+	of_id = of_match_device(mc13xxx_dt_ids,&spi->dev);
+	if (of_id)
+		sdrv->id_table =&mc13xxx_device_id[(enum mc13xxx_id) of_id->data];
 
  	mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL);
  	if (!mc13xxx)

drivers/mfd/mc13xxx-core.c static int mc13xxx_probe(struct spi_device *spi) · line 796

Quoted 10 lines
drivers/mfd/mc13xxx-core.c +7 -0
@@ -735,6 +787,15 @@ static int mc13xxx_probe(struct spi_device *spi)
  	if (ret)
  		goto err_mask;
 
+	mc13xxx->irq_gpio = of_get_named_gpio(np, "mc13xxx-irq-gpios", 0);
+	if (gpio_is_valid(mc13xxx->irq_gpio)) {
+		ret = gpio_request_one(mc13xxx->irq_gpio, GPIOF_IN,
+				       "mc13xxx-irq");
+		if (ret)
+			goto err_mask;
+		spi->irq = gpio_to_irq(mc13xxx->irq_gpio);

This seems wrong, because its adding information about the irq actually being a gpio within the driver (which was otherwise hidden by the board files doing a gpio_to_irq()). What happens if on some device this is actually hooked to an irq line instead of a gpio?
There should be a better way to do this using Device tree.

#3 lore raw

PATCH 1/5 mfd: mc13xxx: add device tree probe support

Quoted 28 lines · Rajendra Nayak

[]...

Quoted 27 lines
drivers/mfd/mc13xxx-core.c +9 -4
+};
+MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids);
+
 static int mc13xxx_probe(struct spi_device *spi)
 {
+	struct device_node *np = spi->dev.of_node;
+	const struct of_device_id *of_id;
+	struct spi_driver *sdrv = to_spi_driver(spi->dev.driver);
 	struct mc13xxx *mc13xxx;
 	struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev);
 	enum mc13xxx_id id;
 	int ret;
 
-	if (!pdata) {
-		dev_err(&spi->dev, "invalid platform data\n");
-		return -EINVAL;
-	}
+	of_id = of_match_device(mc13xxx_dt_ids,&spi->dev);
+	if (of_id)
+		sdrv->id_table =&mc13xxx_device_id[(enum mc13xxx_id) of_id->data];
 
 	mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL);
 	if (!mc13xxx)
@@ -735,6 +787,15 @@ static int mc13xxx_probe(struct spi_device *spi)
 	if (ret)
 		goto err_mask;
 
Quoted 14 lines

drivers/mfd/mc13xxx-core.c static int mc13xxx_probe(struct spi_device *spi) · line 796

Quoted 7 lines
drivers/mfd/mc13xxx-core.c +7 -0
+	mc13xxx->irq_gpio = of_get_named_gpio(np, "mc13xxx-irq-gpios", 0);
+	if (gpio_is_valid(mc13xxx->irq_gpio)) {
+		ret = gpio_request_one(mc13xxx->irq_gpio, GPIOF_IN,
+				       "mc13xxx-irq");
+		if (ret)
+			goto err_mask;
+		spi->irq = gpio_to_irq(mc13xxx->irq_gpio);

This seems wrong, because its adding information about the irq actually being a gpio within the driver (which was otherwise hidden by the board files doing a gpio_to_irq()). What happens if on some device this is actually hooked to an irq line instead of a gpio?
There should be a better way to do this using Device tree.

Indeed. I should have 'interrupt-parent' and 'interrupts' encoded as below, so that 'spi->irq = irq_of_parse_and_map(nc, 0);' in of_spi.c can get the irq set up properly.

pmic: mc13892 at 0 {
	#address-cells = <1>;
	#size-cells = <0>;
	compatible = "fsl,mc13892";
	spi-max-frequency = <6000000>;
	reg = <0>;
	interrupt-parent = <&gpio0>;
	interrupts = <8>;
};

Thanks for catching this.

Signature · 2 lines
Regards,
Shawn
author
#4 lore raw

PATCH 2/5 regulator: fix label names used in device tree bindings

In reply to Shawn Guo

Device tree compiler does not recognize '-' in label name. Instead, '_' works fine.

Cc Mark Brown <[email protected]>
Cc Liam Girdwood <[email protected]>
---
 .../devicetree/bindings/regulator/regulator.txt    |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
Documentation/devicetree/bindings/regulator/regulator.txt +5 -5
index 82bef20..5b7a408 100644
@@ -32,15 +32,15 @@ its just seen as a special case of a regulator being a
 consumer itself.
 
 Example of a consumer device node (mmc) referencing two
-regulators (twl-reg1 and twl-reg2),
+regulators (twl_reg1 and twl_reg2),
 
-	twl-reg1: regulator at 0 {
+	twl_reg1: regulator at 0 {
 		...
 		...
 		...
 	};
 
-	twl-reg2: regulator at 1 {
+	twl_reg2: regulator at 1 {
 		...
 		...
 		...
@@ -49,6 +49,6 @@ regulators (twl-reg1 and twl-reg2),
 	mmc: mmc at 0x0 {
 		...
 		...
-		vmmc-supply = <&twl-reg1>;
-		vmmcaux-supply = <&twl-reg2>;
+		vmmc-supply = <&twl_reg1>;
+		vmmcaux-supply = <&twl_reg2>;
 	};
Signature · 1 line
1.7.4.1
Applied
#5 lore raw

PATCH 2/5 regulator: fix label names used in device tree bindings

Quoted 2 lines · Shawn Guo

Device tree compiler does not recognize '-' in label name. Instead, '_' works fine.

Applied, thanks.

#6 lore raw

PATCH 2/5 regulator: fix label names used in device tree bindings

In reply to Shawn Guo
Quoted 2 lines · Shawn Guo

Device tree compiler does not recognize '-' in label name. Instead, '_' works fine.

Thanks, that does seem to be the case. I figured it myself when I added them in actual .dts files but missed updating the bindings.

author
#7 lore raw

PATCH 3/5 regulator: pass device_node to of_get_regulator_init_data()

In reply to Shawn Guo

It's not always true that the device_node of regulator can be found at dev->of_node, because in some cases the regulator nodes in device tree do not even have 'struct device' behind them.

The patch adds device_node as a new parameter to of_get_regulator_init_data(), so that caller can pass in the node of regulator directly.

Cc Mark Brown <[email protected]>
Cc Liam Girdwood <[email protected]>
---
 drivers/regulator/of_regulator.c       |    7 ++++---
 include/linux/regulator/of_regulator.h |    6 ++++--
 2 files changed, 8 insertions(+), 5 deletions(-)
drivers/regulator/of_regulator.c +4 -3
index acd7045..6caf641 100644
@@ -66,18 +66,19 @@ static void of_get_regulation_constraints(struct device_node *np,
  * tree node, returns a pointer to the populated struture or NULL if memory
  * alloc fails.
  */
-struct regulator_init_data *of_get_regulator_init_data(struct device *dev)
+struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
+						struct device_node *node)
 {
 	struct regulator_init_data *init_data;
 
-	if (!dev->of_node)
+	if (!node)
 		return NULL;
 
 	init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
 	if (!init_data)
 		return NULL; /* Out of memory? */
 
-	of_get_regulation_constraints(dev->of_node, &init_data);
+	of_get_regulation_constraints(node, &init_data);
 	return init_data;
 }
 EXPORT_SYMBOL_GPL(of_get_regulator_init_data);
include/linux/regulator/of_regulator.h +4 -2
index d83a98d..769704f 100644
@@ -8,10 +8,12 @@
 
 #if defined(CONFIG_OF)
 extern struct regulator_init_data
-	*of_get_regulator_init_data(struct device *dev);
+	*of_get_regulator_init_data(struct device *dev,
+				    struct device_node *node);
 #else
 static inline struct regulator_init_data
-	*of_get_regulator_init_data(struct device *dev)
+	*of_get_regulator_init_data(struct device *dev,
+				    struct device_node *node)
 {
 	return NULL;
 }
Signature · 1 line
1.7.4.1
#8 lore raw

PATCH 3/5 regulator: pass device_node to of_get_regulator_init_data()

Quoted 4 lines · Shawn Guo
---
 drivers/regulator/of_regulator.c       |    7 ++++---
 include/linux/regulator/of_regulator.h |    6 ++++--
 2 files changed, 8 insertions(+), 5 deletions(-)

Clearly this is going to break the build as you've not updated the users.

#9 lore raw

PATCH 3/5 regulator: pass device_node to of_get_regulator_init_data()

Quoted 9 lines · Mark Brown
Quoted 4 lines · Shawn Guo
---
 drivers/regulator/of_regulator.c       |    7 ++++---
 include/linux/regulator/of_regulator.h |    6 ++++--
 2 files changed, 8 insertions(+), 5 deletions(-)

Clearly this is going to break the build as you've not updated the users.

Sorry, I missed that regulator/fixed.c is already using the api. Will fix it in v2.

Signature · 2 lines
Regards,
Shawn
author
#10 lore raw

PATCH 4/5 regulator: mc13892: add device tree probe support

In reply to Shawn Guo

It adds device tree probe support for mc13892-regulator driver.

Cc Mark Brown <[email protected]>
Cc Liam Girdwood <[email protected]>
---
 drivers/regulator/mc13892-regulator.c      |   43 +++++++++++++++-----
 drivers/regulator/mc13xxx-regulator-core.c |   57 ++++++++++++++++++++++++++++
 drivers/regulator/mc13xxx.h                |   20 ++++++++++
 include/linux/mfd/mc13xxx.h                |    1 +
 4 files changed, 110 insertions(+), 11 deletions(-)
drivers/regulator/mc13892-regulator.c +32 -11
index 2824804..46bfa4a 100644
@@ -527,18 +527,27 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
 	struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
 	struct mc13xxx_regulator_platform_data *pdata =
 		dev_get_platdata(&pdev->dev);
-	struct mc13xxx_regulator_init_data *init_data;
+	struct mc13xxx_regulator_init_data *mc13xxx_data;
 	int i, ret;
+	int num_regulators = 0;
 	u32 val;
 
+	num_regulators = mc13xxx_get_num_regulators_dt(pdev);
+	if (num_regulators <= 0 && pdata)
+		num_regulators = pdata->num_regulators;
+	if (num_regulators <= 0)
+		return -EINVAL;
+
 	priv = kzalloc(sizeof(*priv) +
-		pdata->num_regulators * sizeof(priv->regulators[0]),
+		num_regulators * sizeof(priv->regulators[0]),
 		GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
+	priv->num_regulators = num_regulators;
 	priv->mc13xxx_regulators = mc13892_regulators;
 	priv->mc13xxx = mc13892;
+	platform_set_drvdata(pdev, priv);
 
 	mc13xxx_lock(mc13892);
 	ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val);
@@ -569,11 +578,27 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
 		= mc13892_vcam_set_mode;
 	mc13892_regulators[MC13892_VCAM].desc.ops->get_mode
 		= mc13892_vcam_get_mode;
-	for (i = 0; i < pdata->num_regulators; i++) {
-		init_data = &pdata->regulators[i];
+
+	mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators,
+					ARRAY_SIZE(mc13892_regulators));
+	for (i = 0; i < num_regulators; i++) {
+		struct regulator_init_data *init_data;
+		struct regulator_desc *desc;
+		struct device_node *node = NULL;
+		int id;
+
+		if (mc13xxx_data) {
+			id = mc13xxx_data[i].id;
+			init_data = mc13xxx_data[i].init_data;
+			node = mc13xxx_data[i].node;
+		} else {
+			id = pdata->regulators[i].id;
+			init_data = pdata->regulators[i].init_data;
+		}
+		desc = &mc13892_regulators[id].desc;
+
 		priv->regulators[i] = regulator_register(
-			&mc13892_regulators[init_data->id].desc,
-			&pdev->dev, init_data->init_data, priv, NULL);
+			desc, &pdev->dev, init_data, priv, node);
 
 		if (IS_ERR(priv->regulators[i])) {
 			dev_err(&pdev->dev, "failed to register regulator %s\n",
@@ -583,8 +608,6 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
 		}
 	}
 
-	platform_set_drvdata(pdev, priv);
-
 	return 0;
 err:
 	while (--i >= 0)
@@ -600,13 +623,11 @@ err_free:
 static int __devexit mc13892_regulator_remove(struct platform_device *pdev)
 {
 	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
-	struct mc13xxx_regulator_platform_data *pdata =
-		dev_get_platdata(&pdev->dev);
 	int i;
 
 	platform_set_drvdata(pdev, NULL);
 
-	for (i = 0; i < pdata->num_regulators; i++)
+	for (i = 0; i < priv->num_regulators; i++)
 		regulator_unregister(priv->regulators[i]);
 
 	kfree(priv);
drivers/regulator/mc13xxx-regulator-core.c +57 -0

75 lines not on this page · raw message

drivers/regulator/mc13xxx.h +20 -0
index 2775826..419aee5 100644
@@ -29,6 +29,7 @@ struct mc13xxx_regulator_priv {
 	struct mc13xxx *mc13xxx;
 	u32 powermisc_pwgt_state;
 	struct mc13xxx_regulator *mc13xxx_regulators;
+	int num_regulators;
 	struct regulator_dev *regulators[];
 };
 
@@ -42,6 +43,25 @@ extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
 		int min_uV, int max_uV, unsigned *selector);
 extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev);
 
+#ifdef CONFIG_OF
+extern int mc13xxx_get_num_regulators_dt(struct platform_device *pdev);
+extern struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
+	struct platform_device *pdev, struct mc13xxx_regulator *regulators,
+	int num_regulators);
+#else
+static inline int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
+{
+	return -ENODEV;
+}
+
+static inline struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
+	struct platform_device *pdev, struct mc13xxx_regulator *regulators,
+	int num_regulators)
+{
+	return NULL;
+}
+#endif
+
 extern struct regulator_ops mc13xxx_regulator_ops;
 extern struct regulator_ops mc13xxx_fixed_regulator_ops;
 
include/linux/mfd/mc13xxx.h +1 -0
index 3816c2f..a98e2a3 100644
@@ -69,6 +69,7 @@ struct regulator_init_data;
 struct mc13xxx_regulator_init_data {
 	int id;
 	struct regulator_init_data *init_data;
+	struct device_node *node;
 };
 
 struct mc13xxx_regulator_platform_data {
Signature · 1 line
1.7.4.1
#11 lore raw

PATCH 4/5 regulator: mc13892: add device tree probe support

Quoted 1 line · Shawn Guo

It adds device tree probe support for mc13892-regulator driver.

You haven't documented the binding here at all. Documentation is mandatory for all device tree bindings.

#12 lore raw

PATCH 4/5 regulator: mc13892: add device tree probe support

Quoted 5 lines · Mark Brown
Quoted 1 line · Shawn Guo

It adds device tree probe support for mc13892-regulator driver.

You haven't documented the binding here at all. Documentation is mandatory for all device tree bindings.

It reminds me that I should add binding document for mc13xxx mfd driver. However, there is basically nothing to add for mc13892-regulator binding, as it has nothing specific but all that have already documented in Documentation/devicetree/bindings/regulator/regulator.txt.

Signature · 2 lines
Regards,
Shawn
author
#13 lore raw

PATCH 5/5 arm/imx: add mc13892 support into imx51-babbage.dts

In reply to Shawn Guo

It adds mc13892 support into imx51-babbage device tree source.

Cc Sascha Hauer <[email protected]>
---
 arch/arm/boot/dts/imx51-babbage.dts |  100 ++++++++++++++++++++++++++++++++++-
 1 files changed, 99 insertions(+), 1 deletions(-)
arch/arm/boot/dts/imx51-babbage.dts +99 -1
index f8766af..97d832b 100644
@@ -31,12 +31,14 @@
 				esdhc at 70004000 { /* ESDHC1 */
 					fsl,cd-internal;
 					fsl,wp-internal;
+					vmmc-supply = <&vsd_reg>;
 					status = "okay";
 				};
 
 				esdhc at 70008000 { /* ESDHC2 */
 					cd-gpios = <&gpio0 6 0>; /* GPIO1_6 */
 					wp-gpios = <&gpio0 5 0>; /* GPIO1_5 */
+					vmmc-supply = <&vsd_reg>;
 					status = "okay";
 				};
 
@@ -58,7 +60,103 @@
 						spi-max-frequency = <6000000>;
 						reg = <0>;
 						mc13xxx-irq-gpios = <&gpio0 8 0>; /* GPIO1_8 */
-						fsl,mc13xxx-uses-regulator;
+
+						regulators {
+							sw1_reg: mc13892__sw1 {
+								regulator-min-microvolt = <600000>;
+								regulator-max-microvolt = <1375000>;
+								regulator-boot-on;
+								regulator-always-on;
+							};
+
+							sw2_reg: mc13892__sw2 {
+								regulator-min-microvolt = <900000>;
+								regulator-max-microvolt = <1850000>;
+								regulator-boot-on;
+								regulator-always-on;
+							};
+
+							sw3_reg: mc13892__sw3 {
+								regulator-min-microvolt = <1100000>;
+								regulator-max-microvolt = <1850000>;
+								regulator-boot-on;
+								regulator-always-on;
+							};
+
+							sw4_reg: mc13892__sw4 {
+								regulator-min-microvolt = <1100000>;
+								regulator-max-microvolt = <1850000>;
+								regulator-boot-on;
+								regulator-always-on;
+							};
+
+							viohi_reg: mc13892__viohi {
+								regulator-boot-on;
+								regulator-always-on;
+							};
+
+							vpll_reg: mc13892__vpll {
+								regulator-min-microvolt = <1050000>;
+								regulator-max-microvolt = <1800000>;
+								regulator-boot-on;
+								regulator-always-on;
+							};
+
+							vdig_reg: mc13892__vdig {
+								regulator-min-microvolt = <1650000>;
+								regulator-max-microvolt = <1650000>;
+								regulator-boot-on;
+							};
+
+							vsd_reg: mc13892__vsd {
+								regulator-min-microvolt = <1800000>;
+								regulator-max-microvolt = <3150000>;
+							};
+
+							vusb2_reg: mc13892__vusb2 {
+								regulator-min-microvolt = <2400000>;
+								regulator-max-microvolt = <2775000>;
+								regulator-boot-on;
+								regulator-always-on;
+							};
+
+							vvideo_reg: mc13892__vvideo {
+								regulator-min-microvolt = <2775000>;
+								regulator-max-microvolt = <2775000>;
+							};
+
+							vaudio_reg: mc13892__vaudio {
+								regulator-min-microvolt = <2300000>;
+								regulator-max-microvolt = <3000000>;
+							};
+
+							vcam_reg: mc13892__vcam {
+								regulator-min-microvolt = <2500000>;
+								regulator-max-microvolt = <3000000>;
+							};
+
+							vgen1_reg: mc13892__vgen1 {
+								regulator-min-microvolt = <1200000>;
+								regulator-max-microvolt = <1200000>;
+							};
+
+							vgen2_reg: mc13892__vgen2 {
+								regulator-min-microvolt = <1200000>;
+								regulator-max-microvolt = <3150000>;
+								regulator-always-on;
+							};
+
+							vgen3_reg: mc13892__vgen3 {
+								regulator-min-microvolt = <1800000>;
+								regulator-max-microvolt = <2900000>;
+								regulator-always-on;
+							};
+
+							vusb_reg: mc13892__vusb {
+								regulator-boot-on;
+								regulator-always-on;
+							};
+						};
 					};
 
 					flash: at45db321d at 1 {
Signature · 1 line
1.7.4.1