new file mode 100644
@@ -0,0 +1,17 @@
+Bindings for gpio-generic
+
+Required properties:
+- compatible : should be "single-register-gpio"
+- ngpios: specifies the number of gpio mapped in the register from bit 0 to
+ bit ngpios-1. The value is limited to the number of bits of the
+ LONG type.
+
+Optional property:
+- big-endian: tells that register is big endian.
+
+Examples:
+
+ gpio_a {
+ compatible = "single-register-gpio";
+ ngpios = <32>;
+ };
@@ -61,6 +61,8 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.`
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/basic_mmio_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
static void bgpio_write8(void __iomem *reg, unsigned long data)
{
@@ -564,6 +566,46 @@ static void __iomem *bgpio_map(struct platform_device *pdev,
return ret;
}
+static const struct platform_device_id bgpio_id_table[] = {
+ {
+ "basic-mmio-gpio",
+ .driver_data = 0,
+ }, {
+ "basic-mmio-gpio-be",
+ .driver_data = BGPIOF_BIG_ENDIAN
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, bgpio_id_table);
+
+static const struct of_device_id bgpio_dt_ids[] = {
+ { .compatible = "single-register-gpio" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, bgpio_dt_ids);
+
+static int bgpio_parse_dt(struct device *dev)
+{
+ struct bgpio_pdata *pdata;
+
+ pdata = devm_kzalloc(dev, sizeof(struct bgpio_pdata),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ if (of_property_read_u32(dev->of_node, "ngpio", &pdata->ngpio)) {
+ dev_err(dev, "Failed to get field ngpio");
+ return -EINVAL;
+ }
+ pdata->base = -1;
+
+ if (of_device_is_big_endian(dev->of_node))
+ pdata->flags = BGPIOF_BIG_ENDIAN;
+
+ dev->platform_data = pdata;
+ return 0;
+}
+
static int bgpio_pdev_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -574,10 +616,21 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
void __iomem *dirout;
void __iomem *dirin;
unsigned long sz;
- unsigned long flags = pdev->id_entry->driver_data;
int err;
struct bgpio_chip *bgc;
- struct bgpio_pdata *pdata = dev_get_platdata(dev);
+ struct bgpio_pdata *pdata;
+
+ if (of_have_populated_dt()) {
+ err = bgpio_parse_dt(dev);
+ if (err < 0) {
+ dev_err(dev, "Failed to get DT data\n");
+ return err;
+ }
+ }
+ pdata = dev_get_platdata(dev);
+
+ if (!of_have_populated_dt())
+ pdata->flags = pdev->id_entry->driver_data;
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
if (!r)
@@ -609,7 +662,8 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
if (!bgc)
return -ENOMEM;
- err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, flags);
+ err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin,
+ pdata->flags);
if (err)
return err;
@@ -633,18 +687,6 @@ static int bgpio_pdev_remove(struct platform_device *pdev)
return bgpio_remove(bgc);
}
-static const struct platform_device_id bgpio_id_table[] = {
- {
- .name = "basic-mmio-gpio",
- .driver_data = 0,
- }, {
- .name = "basic-mmio-gpio-be",
- .driver_data = BGPIOF_BIG_ENDIAN,
- },
- { }
-};
-MODULE_DEVICE_TABLE(platform, bgpio_id_table);
-
static struct platform_driver bgpio_driver = {
.driver = {
.name = "basic-mmio-gpio",
@@ -22,6 +22,7 @@ struct bgpio_pdata {
const char *label;
int base;
int ngpio;
+ int flags;
};
struct device;
This patch adds support of device tree to the gpio-generic driver. Signed-off-by: Romain Baeriswyl <romain.baeriswyl@alitech.com> --- .../devicetree/bindings/gpio/gpio-generic.txt | 17 +++++ drivers/gpio/gpio-generic.c | 72 +++++++++++++++---- include/linux/basic_mmio_gpio.h | 1 + 3 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-generic.txt