[PATCH 2/2] mtd: maps: physmap_of: Add GPIO VPP control
Pawel Moll
pawel.moll at arm.com
Thu Jul 12 12:38:41 EDT 2012
Add a GPIO control of the VPP signal and "vpp-gpios"
tree property, specifying the GPIO line in a standard
DT way, including polarity flags.
Signed-off-by: Pawel Moll <pawel.moll at arm.com>
---
.../devicetree/bindings/mtd/mtd-physmap.txt | 7 +++-
drivers/mtd/maps/physmap_of.c | 42 ++++++++++++++++++++
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
index a63c2bd7..28084cf 100644
--- a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
+++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
@@ -13,10 +13,13 @@ 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-gpios : (optional) specifies the GPIO line to control
+ VPP signal of the flash chip, the polarity is defined as a
+ standard flag (see Documentation/devicetree/bindings/gpio/gpio.txt
+ for more details and examples below)
- #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 +36,7 @@ Example:
reg = <ff000000 01000000>;
bank-width = <4>;
device-width = <1>;
+ vpp-gpios = <&pio2 1 0>; /* PIO2.1 active high */
#address-cells = <1>;
#size-cells = <1>;
fs at 0 {
@@ -55,6 +59,7 @@ Here an example with multiple "reg" tuples:
reg = <0 0x00000000 0x02000000
0 0x02000000 0x02000000>;
bank-width = <2>;
+ vpp-gpios = <&pio3 2 1>; /* PIO3.2 active low */
partition at 0 {
label = "test-part1";
reg = <0 0x04000000>;
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 2e6fb68..81caa77 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -17,12 +17,14 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/gpio.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/concat.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
@@ -74,6 +76,24 @@ static int of_flash_remove(struct platform_device *dev)
return 0;
}
+static void of_flash_set_vpp_high(struct map_info *map, int state)
+{
+ /* map_priv_1 = gpio, map_priv_2 = "reference counter" */
+ if (state && !map->map_priv_2++)
+ gpio_set_value(map->map_priv_1, 1);
+ else if (!state && !--map->map_priv_2)
+ gpio_set_value(map->map_priv_1, 0);
+}
+
+static void of_flash_set_vpp_low(struct map_info *map, int state)
+{
+ /* map_priv_1 = gpio, map_priv_2 = "reference counter" */
+ if (state && !map->map_priv_2++)
+ gpio_set_value(map->map_priv_1, 0);
+ else if (!state && !--map->map_priv_2)
+ gpio_set_value(map->map_priv_1, 1);
+}
+
/* 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 +189,9 @@ 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;
+ void (*set_vpp)(struct map_info *, int) = NULL;
+ int gpio_vpp;
+ enum of_gpio_flags gpio_flags;
match = of_match_device(of_flash_match, &dev->dev);
if (!match)
@@ -200,6 +223,23 @@ static int __devinit of_flash_probe(struct platform_device *dev)
dev_set_drvdata(&dev->dev, info);
+ gpio_vpp = of_get_named_gpio_flags(dp, "vpp-gpios", 0, &gpio_flags);
+ if (gpio_is_valid(gpio_vpp)) {
+ unsigned long dir = GPIOF_DIR_OUT;
+
+ if (gpio_flags & OF_GPIO_ACTIVE_LOW) {
+ set_vpp = of_flash_set_vpp_low;
+ dir |= GPIOF_INIT_HIGH;
+ } else {
+ set_vpp = of_flash_set_vpp_high;
+ dir |= GPIOF_INIT_LOW;
+ }
+ err = devm_gpio_request_one(&dev->dev, gpio_vpp, dir,
+ dev_name(&dev->dev));
+ if (err)
+ goto err_flash_remove;
+ }
+
mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
if (!mtd_list)
goto err_flash_remove;
@@ -235,6 +275,8 @@ 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);
+ info->list[i].map.set_vpp = set_vpp;
+ info->list[i].map.map_priv_1 = gpio_vpp;
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