Patchwork [2/2] mtd: maps: physmap_of: Add VPP regulator control

login
register
mail settings
Submitter Pawel Moll
Date July 18, 2012, 1:22 p.m.
Message ID <1342617721-14715-3-git-send-email-pawel.moll@arm.com>
Download mbox | patch
Permalink /patch/171676/
State New
Headers show

Comments

Pawel Moll - July 18, 2012, 1:22 p.m.
Add an optional regulator control of the VPP line and a
standard "vpp-supply" tree property.

Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
 .../devicetree/bindings/mtd/mtd-physmap.txt        |    4 ++-
 drivers/mtd/maps/physmap_of.c                      |   28 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

Patch

diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
index a63c2bd7..40cb554 100644
--- a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
+++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
@@ -13,10 +13,11 @@  file systems on embedded devices.
    device width times the number of interleaved chips.
  - device-width : (optional) Width of a single mtd chip.  If
    omitted, assumed to be equal to 'bank-width'.
+ - vpp-supply : (optional) phandle to a regulator controlling VPP
+   line of the chips.
  - #address-cells, #size-cells : Must be present if the device has
    sub-nodes representing partitions (see below).  In this case
    both #address-cells and #size-cells must be equal to 1.
-
 For JEDEC compatible devices, the following additional properties
 are defined:
 
@@ -33,6 +34,7 @@  Example:
 		reg = <ff000000 01000000>;
 		bank-width = <4>;
 		device-width = <1>;
+		vpp-supply = <&flash_vpp_reg>
 		#address-cells = <1>;
 		#size-cells = <1>;
 		fs@0 {
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 2e6fb68..9f34320 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -17,6 +17,7 @@ 
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/err.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
@@ -24,6 +25,7 @@ 
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
 struct of_flash_list {
@@ -74,6 +76,18 @@  static int of_flash_remove(struct platform_device *dev)
 	return 0;
 }
 
+static void of_flash_set_vpp_regulator(struct map_info *map, int state)
+{
+	/* map_priv_1 = VPP regulator pointer */
+	struct regulator *vpp_regulator = (struct regulator *)map->map_priv_1;
+
+	/* map_priv_2 = "reference counter" */
+	if (state && !map->map_priv_2++)
+		WARN_ON(regulator_enable(vpp_regulator));
+	else if (!state && !--map->map_priv_2)
+		WARN_ON(regulator_disable(vpp_regulator));
+}
+
 /* Helper function to handle probing of the obsolete "direct-mapped"
  * compatible binding, which has an extra "probe-type" property
  * describing the type of flash probe necessary. */
@@ -169,6 +183,7 @@  static int __devinit of_flash_probe(struct platform_device *dev)
 	struct mtd_info **mtd_list = NULL;
 	resource_size_t res_size;
 	struct mtd_part_parser_data ppdata;
+	struct regulator *vpp_regulator = NULL;
 
 	match = of_match_device(of_flash_match, &dev->dev);
 	if (!match)
@@ -200,6 +215,14 @@  static int __devinit of_flash_probe(struct platform_device *dev)
 
 	dev_set_drvdata(&dev->dev, info);
 
+	if (of_get_property(dp, "vpp-supply", NULL)) {
+		vpp_regulator = devm_regulator_get(&dev->dev, "vpp");
+		if (IS_ERR(vpp_regulator)) {
+			err = PTR_ERR(vpp_regulator);
+			goto err_flash_remove;
+		}
+	}
+
 	mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
 	if (!mtd_list)
 		goto err_flash_remove;
@@ -235,6 +258,11 @@  static int __devinit of_flash_probe(struct platform_device *dev)
 		info->list[i].map.phys = res.start;
 		info->list[i].map.size = res_size;
 		info->list[i].map.bankwidth = be32_to_cpup(width);
+		if (vpp_regulator) {
+			info->list[i].map.map_priv_1 =
+					(unsigned long)vpp_regulator;
+			info->list[i].map.set_vpp = of_flash_set_vpp_regulator;
+		}
 
 		err = -ENOMEM;
 		info->list[i].map.virt = ioremap(info->list[i].map.phys,