[PATCH 2/2] mtd: maps: physmap_of: Add VPP regulator control
Pawel Moll
pawel.moll at arm.com
Wed Jul 18 09:22:01 EDT 2012
Add an optional regulator control of the VPP line and a
standard "vpp-supply" tree property.
Signed-off-by: Pawel Moll <pawel.moll at arm.com>
---
.../devicetree/bindings/mtd/mtd-physmap.txt | 4 ++-
drivers/mtd/maps/physmap_of.c | 28 ++++++++++++++++++++
2 files changed, 31 insertions(+), 1 deletion(-)
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 at 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,
--
1.7.9.5
More information about the linux-mtd
mailing list