This patch adds device tree support to the block GPIO API.

Signed-off-by: Roland Stigge <sti...@antcom.de>

---
 Documentation/devicetree/bindings/gpio/gpio-block.txt |   36 +++++++
 drivers/gpio/Makefile                                 |    1 
 drivers/gpio/gpioblock-of.c                           |   84 ++++++++++++++++++
 3 files changed, 121 insertions(+)

--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio-block.txt
@@ -0,0 +1,36 @@
+Block GPIO definition
+=====================
+
+This binding specifies arbitrary blocks of gpios, combining gpios from one or
+more GPIO controllers together, to form a word for r/w access.
+
+Required property:
+- compatible: must be "linux,gpio-block"
+
+Required subnodes:
+- the name will be the registered name of the block
+- property "gpios" is a list of gpios for the respective block
+
+Example:
+
+        blockgpio {
+                compatible = "linux,gpio-block";
+
+                block0 {
+                        gpios = <&gpio 3 0 0>,
+                                <&gpio 3 1 0>;
+                };
+                block1 {
+                        gpios = <&gpio 4 1 0>,
+                                <&gpio 4 3 0>,
+                                <&gpio 4 2 0>,
+                                <&gpio 4 4 0>,
+                                <&gpio 4 5 0>,
+                                <&gpio 4 6 0>,
+                                <&gpio 4 7 0>,
+                                <&gpio 4 8 0>,
+                                <&gpio 4 9 0>,
+                                <&gpio 4 10 0>,
+                                <&gpio 4 19 0>;
+                };
+        };
--- linux-2.6.orig/drivers/gpio/Makefile
+++ linux-2.6/drivers/gpio/Makefile
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)    += -DDEBUG
 
 obj-$(CONFIG_GPIOLIB)          += gpiolib.o devres.o
 obj-$(CONFIG_OF_GPIO)          += gpiolib-of.o
+obj-$(CONFIG_OF_GPIO)          += gpioblock-of.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC)     += gpio-generic.o
--- /dev/null
+++ linux-2.6/drivers/gpio/gpioblock-of.c
@@ -0,0 +1,84 @@
+/*
+ * OF implementation for Block GPIO
+ *
+ * Copyright (C) 2012 Roland Stigge <sti...@antcom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+static int __devinit gpioblock_of_probe(struct platform_device *pdev)
+{
+       struct device_node *block;
+       unsigned *gpios;
+       int ngpio;
+       int ret;
+       struct gpio_block *gb;
+
+       for_each_available_child_of_node(pdev->dev.of_node, block) {
+               int i;
+
+               ngpio = of_gpio_count(block);
+               gpios = kzalloc(ngpio * sizeof(*gpios), GFP_KERNEL);
+               if (!gpios)
+                       return -ENOMEM;
+               for (i = 0; i < ngpio; i++) {
+                       ret = of_get_gpio(block, i);
+                       if (ret < 0)
+                               return ret; /* expect -EPROBE_DEFER */
+                       gpios[i] = ret;
+               }
+               gb = gpio_block_create(gpios, ngpio, block->name);
+               if (IS_ERR(gb)) {
+                       dev_err(&pdev->dev,
+                               "Error creating GPIO block from device tree\n");
+                       return PTR_ERR(gb);
+               }
+               ret = gpio_block_register(gb);
+               if (ret < 0) {
+                       gpio_block_free(gb);
+                       return ret;
+               }
+               kfree(gpios);
+               dev_info(&pdev->dev, "Registered gpio block %s: %d gpios\n",
+                        block->name, ngpio);
+       }
+       return 0;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id gpioblock_of_match[] __devinitdata = {
+       { .compatible = "linux,gpio-block", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, gpioblock_of_match);
+#endif
+
+static struct platform_driver gpioblock_of_driver = {
+       .driver = {
+               .name = "gpio-block",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(gpioblock_of_match),
+
+       },
+       .probe  = gpioblock_of_probe,
+};
+
+module_platform_driver(gpioblock_of_driver);
+
+MODULE_DESCRIPTION("GPIO Block driver");
+MODULE_AUTHOR("Roland Stigge <sti...@antcom.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpioblock-of");
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to