All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] gpio: max732x: Update MAX732X driver to use modern kernel API
@ 2015-01-13 13:41 Semen Protsenko
  2015-01-13 13:41 ` [PATCH 1/4] gpio: max732x: Add device tree support Semen Protsenko
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Semen Protsenko @ 2015-01-13 13:41 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot
  Cc: Grant Likely, Mark Rutland, linux-gpio, linux-kernel, devicetree,
	Marc Zyngier, Grygorii Strashko, Illia Smyrnov

This patch series updates driver for MAX732X I/O expander to use modern kernel
API (like Device Tree). Basically, I was needed this driver to work with
kernel 3.8 on our ARM-based board, but it was in obsolete state (supporting
only platform data from board-file). First patch makes driver work with
data taken from device tree file (old platform data support also kept in place
for compatibility reasons).

After adding device tree support it came to me that current approach to
implement interrupt controller is to use irq-domain framework. Hence the second
patch (only affects the code for generating interrupts on level change on
expander's GPIO input lines).

Once driver became fully functional (using data from device tree), another
issue showed up: lockdep validator revealed possible dead-lock in driver code.
Third patch fixes this problem.

Finally, fourth patch adds binding documentation showing how to describe MAX732X
driver in device tree file.

Semen Protsenko (4):
  gpio: max732x: Add device tree support
  gpio: max732x: Rewrite IRQ code to use irq_domain API
  gpio: max732x: Fix possible deadlock
  gpio: max732x: Add DT binding documentation

 .../devicetree/bindings/gpio/gpio-max732x.txt      |   59 +++++++
 drivers/gpio/Kconfig                               |    1 +
 drivers/gpio/gpio-max732x.c                        |  174 ++++++++++++++------
 3 files changed, 187 insertions(+), 47 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-max732x.txt

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] gpio: max732x: Add device tree support
  2015-01-13 13:41 [PATCH 0/4] gpio: max732x: Update MAX732X driver to use modern kernel API Semen Protsenko
@ 2015-01-13 13:41 ` Semen Protsenko
  2015-01-15 16:52   ` Linus Walleij
  2015-01-13 13:41 ` [PATCH 2/4] gpio: max732x: Rewrite IRQ code to use irq_domain API Semen Protsenko
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Semen Protsenko @ 2015-01-13 13:41 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot
  Cc: Grant Likely, Mark Rutland, linux-gpio, linux-kernel, devicetree,
	Marc Zyngier, Grygorii Strashko, Illia Smyrnov

Signed-off-by: Semen Protsenko <semen.protsenko@globallogic.com>
---
 drivers/gpio/gpio-max732x.c |   62 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
index 6c67622..a642f78 100644
--- a/drivers/gpio/gpio-max732x.c
+++ b/drivers/gpio/gpio-max732x.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/i2c/max732x.h>
+#include <linux/of.h>
 
 
 /*
@@ -116,6 +117,22 @@ static const struct i2c_device_id max732x_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, max732x_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id max732x_of_table[] = {
+	{ .compatible = "maxim,max7319" },
+	{ .compatible = "maxim,max7320" },
+	{ .compatible = "maxim,max7321" },
+	{ .compatible = "maxim,max7322" },
+	{ .compatible = "maxim,max7323" },
+	{ .compatible = "maxim,max7324" },
+	{ .compatible = "maxim,max7325" },
+	{ .compatible = "maxim,max7326" },
+	{ .compatible = "maxim,max7327" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, max732x_of_table);
+#endif
+
 struct max732x_chip {
 	struct gpio_chip gpio_chip;
 
@@ -457,10 +474,12 @@ static int max732x_irq_setup(struct max732x_chip *chip,
 	int has_irq = max732x_features[id->driver_data] >> 32;
 	int ret;
 
-	if (pdata->irq_base && has_irq != INT_NONE) {
+	if (((pdata && pdata->irq_base) || client->irq)
+			&& has_irq != INT_NONE) {
 		int lvl;
 
-		chip->irq_base = pdata->irq_base;
+		if (pdata)
+			chip->irq_base = pdata->irq_base;
 		chip->irq_features = has_irq;
 		mutex_init(&chip->irq_lock);
 
@@ -515,7 +534,7 @@ static int max732x_irq_setup(struct max732x_chip *chip,
 	struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
 	int has_irq = max732x_features[id->driver_data] >> 32;
 
-	if (pdata->irq_base && has_irq != INT_NONE)
+	if (((pdata && pdata->irq_base) || client->irq) && has_irq != INT_NONE)
 		dev_warn(&client->dev, "interrupt support not compiled in\n");
 
 	return 0;
@@ -574,28 +593,47 @@ static int max732x_setup_gpio(struct max732x_chip *chip,
 	return port;
 }
 
+static struct max732x_platform_data *of_gpio_max732x(struct device *dev)
+{
+	struct max732x_platform_data *pdata;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	pdata->gpio_base = -1;
+
+	return pdata;
+}
+
 static int max732x_probe(struct i2c_client *client,
 				   const struct i2c_device_id *id)
 {
 	struct max732x_platform_data *pdata;
+	struct device_node *node;
 	struct max732x_chip *chip;
 	struct i2c_client *c;
 	uint16_t addr_a, addr_b;
 	int ret, nr_port;
 
 	pdata = dev_get_platdata(&client->dev);
-	if (pdata == NULL) {
+	node = client->dev.of_node;
+
+	if (!pdata && node)
+		pdata = of_gpio_max732x(&client->dev);
+
+	if (!pdata) {
 		dev_dbg(&client->dev, "no platform data\n");
 		return -EINVAL;
 	}
 
-	chip = devm_kzalloc(&client->dev, sizeof(struct max732x_chip),
-			GFP_KERNEL);
+	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	chip->client = client;
 
 	nr_port = max732x_setup_gpio(chip, id, pdata->gpio_base);
+	chip->gpio_chip.dev = &client->dev;
 
 	addr_a = (client->addr & 0x0f) | 0x60;
 	addr_b = (client->addr & 0x0f) | 0x50;
@@ -643,7 +681,7 @@ static int max732x_probe(struct i2c_client *client,
 	if (ret)
 		goto out_failed;
 
-	if (pdata->setup) {
+	if (pdata && pdata->setup) {
 		ret = pdata->setup(client, chip->gpio_chip.base,
 				chip->gpio_chip.ngpio, pdata->context);
 		if (ret < 0)
@@ -664,9 +702,10 @@ static int max732x_remove(struct i2c_client *client)
 {
 	struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
 	struct max732x_chip *chip = i2c_get_clientdata(client);
-	int ret;
 
-	if (pdata->teardown) {
+	if (pdata && pdata->teardown) {
+		int ret;
+
 		ret = pdata->teardown(client, chip->gpio_chip.base,
 				chip->gpio_chip.ngpio, pdata->context);
 		if (ret < 0) {
@@ -689,8 +728,9 @@ static int max732x_remove(struct i2c_client *client)
 
 static struct i2c_driver max732x_driver = {
 	.driver = {
-		.name	= "max732x",
-		.owner	= THIS_MODULE,
+		.name		= "max732x",
+		.owner		= THIS_MODULE,
+		.of_match_table	= of_match_ptr(max732x_of_table),
 	},
 	.probe		= max732x_probe,
 	.remove		= max732x_remove,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] gpio: max732x: Rewrite IRQ code to use irq_domain API
  2015-01-13 13:41 [PATCH 0/4] gpio: max732x: Update MAX732X driver to use modern kernel API Semen Protsenko
  2015-01-13 13:41 ` [PATCH 1/4] gpio: max732x: Add device tree support Semen Protsenko
@ 2015-01-13 13:41 ` Semen Protsenko
       [not found]   ` <1421156505-16600-3-git-send-email-semen.protsenko-hExfYMNmJl/Cnp4W7fqMDg@public.gmane.org>
  2015-01-13 13:41 ` [PATCH 3/4] gpio: max732x: Fix possible deadlock Semen Protsenko
  2015-01-13 13:41 ` [PATCH 4/4] gpio: max732x: Add DT binding documentation Semen Protsenko
  3 siblings, 1 reply; 10+ messages in thread
From: Semen Protsenko @ 2015-01-13 13:41 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot
  Cc: Grant Likely, Mark Rutland, linux-gpio, linux-kernel, devicetree,
	Marc Zyngier, Grygorii Strashko, Illia Smyrnov

Signed-off-by: Semen Protsenko <semen.protsenko@globallogic.com>
---
 drivers/gpio/Kconfig        |    1 +
 drivers/gpio/gpio-max732x.c |  100 ++++++++++++++++++++++++++++---------------
 2 files changed, 66 insertions(+), 35 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 633ec21..d81d441 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -519,6 +519,7 @@ config GPIO_MAX7300
 config GPIO_MAX732X
 	tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
 	depends on I2C
+	select IRQ_DOMAIN
 	help
 	  Say yes here to support the MAX7319, MAX7320-7327 series of I2C
 	  Port Expanders. Each IO port on these chips has a fixed role of
diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
index a642f78..f8f3e80 100644
--- a/drivers/gpio/gpio-max732x.c
+++ b/drivers/gpio/gpio-max732x.c
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/i2c.h>
 #include <linux/i2c/max732x.h>
 #include <linux/of.h>
@@ -149,13 +150,14 @@ struct max732x_chip {
 	uint8_t		reg_out[2];
 
 #ifdef CONFIG_GPIO_MAX732X_IRQ
-	struct mutex	irq_lock;
-	int		irq_base;
-	uint8_t		irq_mask;
-	uint8_t		irq_mask_cur;
-	uint8_t		irq_trig_raise;
-	uint8_t		irq_trig_fall;
-	uint8_t		irq_features;
+	struct irq_domain	*irq_domain;
+	struct mutex		irq_lock;
+	int			irq_base;
+	uint8_t			irq_mask;
+	uint8_t			irq_mask_cur;
+	uint8_t			irq_trig_raise;
+	uint8_t			irq_trig_fall;
+	uint8_t			irq_features;
 #endif
 };
 
@@ -341,21 +343,27 @@ static int max732x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
 	struct max732x_chip *chip;
 
 	chip = container_of(gc, struct max732x_chip, gpio_chip);
-	return chip->irq_base + off;
+
+	if (chip->irq_domain) {
+		return irq_create_mapping(chip->irq_domain,
+				chip->irq_base + off);
+	} else {
+		return -ENXIO;
+	}
 }
 
 static void max732x_irq_mask(struct irq_data *d)
 {
 	struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
 
-	chip->irq_mask_cur &= ~(1 << (d->irq - chip->irq_base));
+	chip->irq_mask_cur &= ~(1 << d->hwirq);
 }
 
 static void max732x_irq_unmask(struct irq_data *d)
 {
 	struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
 
-	chip->irq_mask_cur |= 1 << (d->irq - chip->irq_base);
+	chip->irq_mask_cur |= 1 << d->hwirq;
 }
 
 static void max732x_irq_bus_lock(struct irq_data *d)
@@ -377,7 +385,7 @@ static void max732x_irq_bus_sync_unlock(struct irq_data *d)
 static int max732x_irq_set_type(struct irq_data *d, unsigned int type)
 {
 	struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
-	uint16_t off = d->irq - chip->irq_base;
+	uint16_t off = d->hwirq;
 	uint16_t mask = 1 << off;
 
 	if (!(mask & chip->dir_input)) {
@@ -458,7 +466,7 @@ static irqreturn_t max732x_irq_handler(int irq, void *devid)
 
 	do {
 		level = __ffs(pending);
-		handle_nested_irq(level + chip->irq_base);
+		handle_nested_irq(irq_find_mapping(chip->irq_domain, level));
 
 		pending &= ~(1 << level);
 	} while (pending);
@@ -466,6 +474,44 @@ static irqreturn_t max732x_irq_handler(int irq, void *devid)
 	return IRQ_HANDLED;
 }
 
+static int max732x_irq_map(struct irq_domain *h, unsigned int virq,
+		irq_hw_number_t hw)
+{
+	struct max732x_chip *chip = h->host_data;
+
+	if (!(chip->dir_input & (1 << hw))) {
+		dev_err(&chip->client->dev,
+				"Attempt to map output line as IRQ line: %lu\n",
+				hw);
+		return -EPERM;
+	}
+
+	irq_set_chip_data(virq, chip);
+	irq_set_chip_and_handler(virq, &max732x_irq_chip,
+			handle_edge_irq);
+	irq_set_nested_thread(virq, 1);
+#ifdef CONFIG_ARM
+	/* ARM needs us to explicitly flag the IRQ as valid
+	 * and will set them noprobe when we do so. */
+	set_irq_flags(virq, IRQF_VALID);
+#else
+	irq_set_noprobe(virq);
+#endif
+
+	return 0;
+}
+
+static struct irq_domain_ops max732x_irq_domain_ops = {
+	.map	= max732x_irq_map,
+	.xlate	= irq_domain_xlate_twocell,
+};
+
+static void max732x_irq_teardown(struct max732x_chip *chip)
+{
+	if (chip->client->irq && chip->irq_domain)
+		irq_domain_remove(chip->irq_domain);
+}
+
 static int max732x_irq_setup(struct max732x_chip *chip,
 			     const struct i2c_device_id *id)
 {
@@ -476,28 +522,17 @@ static int max732x_irq_setup(struct max732x_chip *chip,
 
 	if (((pdata && pdata->irq_base) || client->irq)
 			&& has_irq != INT_NONE) {
-		int lvl;
-
 		if (pdata)
 			chip->irq_base = pdata->irq_base;
 		chip->irq_features = has_irq;
 		mutex_init(&chip->irq_lock);
 
-		for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
-			int irq = lvl + chip->irq_base;
-
-			if (!(chip->dir_input & (1 << lvl)))
-				continue;
-
-			irq_set_chip_data(irq, chip);
-			irq_set_chip_and_handler(irq, &max732x_irq_chip,
-						 handle_edge_irq);
-			irq_set_nested_thread(irq, 1);
-#ifdef CONFIG_ARM
-			set_irq_flags(irq, IRQF_VALID);
-#else
-			irq_set_noprobe(irq);
-#endif
+		chip->irq_domain = irq_domain_add_simple(client->dev.of_node,
+				chip->gpio_chip.ngpio, chip->irq_base,
+				&max732x_irq_domain_ops, chip);
+		if (!chip->irq_domain) {
+			dev_err(&client->dev, "Failed to create IRQ domain\n");
+			return -ENOMEM;
 		}
 
 		ret = request_threaded_irq(client->irq,
@@ -517,15 +552,10 @@ static int max732x_irq_setup(struct max732x_chip *chip,
 	return 0;
 
 out_failed:
-	chip->irq_base = 0;
+	max732x_irq_teardown(chip);
 	return ret;
 }
 
-static void max732x_irq_teardown(struct max732x_chip *chip)
-{
-	if (chip->irq_base)
-		free_irq(chip->client->irq, chip);
-}
 #else /* CONFIG_GPIO_MAX732X_IRQ */
 static int max732x_irq_setup(struct max732x_chip *chip,
 			     const struct i2c_device_id *id)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] gpio: max732x: Fix possible deadlock
  2015-01-13 13:41 [PATCH 0/4] gpio: max732x: Update MAX732X driver to use modern kernel API Semen Protsenko
  2015-01-13 13:41 ` [PATCH 1/4] gpio: max732x: Add device tree support Semen Protsenko
  2015-01-13 13:41 ` [PATCH 2/4] gpio: max732x: Rewrite IRQ code to use irq_domain API Semen Protsenko
@ 2015-01-13 13:41 ` Semen Protsenko
  2015-01-15 17:04   ` Linus Walleij
  2015-01-13 13:41 ` [PATCH 4/4] gpio: max732x: Add DT binding documentation Semen Protsenko
  3 siblings, 1 reply; 10+ messages in thread
From: Semen Protsenko @ 2015-01-13 13:41 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot
  Cc: Grant Likely, Mark Rutland, linux-gpio, linux-kernel, devicetree,
	Marc Zyngier, Grygorii Strashko, Illia Smyrnov

This patch was derived from next one:
"gpio: fix pca953x set_type 'scheduling while atomic' bug".

After adding entry that consumes max732x GPIO as interrupt line to dts
file, deadlock appears somewhere in max732x probe function.

Deadlock caught by lockdep (from kernel log):
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< cut here >>>>>>>>>>>>>>>>>>>>>>>>>>>
[    0.473419] ======================================================
[    0.473419] [ INFO: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected ]
[    0.473449] 3.x.xx-xxxxx-xxxxxxxx-dirty #2 Tainted: G        W
[    0.473449] ------------------------------------------------------
[    0.473449] swapper/0/1 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
[    0.473449]  (&lock->wait_lock){+.+...}, at: [<c072e350>] rt_mutex_trylock+0xc/0x74
[    0.473480]
[    0.473480] and this task is already holding:
[    0.473510]  (&chip->lock){......}, at: [<c0314514>] max732x_gpio_set_value+0x2c/0xa4
[    0.473541] which would create a new lock dependency:
[    0.473541]  (&chip->lock){......} -> (&lock->wait_lock){+.+...}

...

[    0.474273]  *** DEADLOCK ***
[    0.474273]
[    0.474273] 5 locks held by swapper/0/1:
[    0.474273]  #0:  (&__lockdep_no_validate__){......}, at: [<c03b2328>] __driver_attach+0x48/0x98
[    0.474304]  #1:  (&__lockdep_no_validate__){......}, at: [<c03b2338>] __driver_attach+0x58/0x98
[    0.474334]  #2:  (&chip->irq_lock){+.+...}, at: [<c0313e3c>] max732x_irq_bus_lock+0x14/0x20
[    0.474365]  #3:  (&irq_desc_lock_class){-.....}, at: [<c00a65a4>] __irq_get_desc_lock+0x48/0x88
[    0.474365]  #4:  (&chip->lock){......}, at: [<c0314514>] max732x_gpio
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< cut here >>>>>>>>>>>>>>>>>>>>>>>>>>>

Signed-off-by: Semen Protsenko <semen.protsenko@globallogic.com>
---
 drivers/gpio/gpio-max732x.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
index f8f3e80..5fbab13 100644
--- a/drivers/gpio/gpio-max732x.c
+++ b/drivers/gpio/gpio-max732x.c
@@ -377,8 +377,18 @@ static void max732x_irq_bus_lock(struct irq_data *d)
 static void max732x_irq_bus_sync_unlock(struct irq_data *d)
 {
 	struct max732x_chip *chip = irq_data_get_irq_chip_data(d);
+	uint16_t new_irqs;
+	uint16_t level;
 
 	max732x_irq_update_mask(chip);
+
+	new_irqs = chip->irq_trig_fall | chip->irq_trig_raise;
+	while (new_irqs) {
+		level = __ffs(new_irqs);
+		max732x_gpio_direction_input(&chip->gpio_chip, level);
+		new_irqs &= ~(1 << level);
+	}
+
 	mutex_unlock(&chip->irq_lock);
 }
 
@@ -410,7 +420,7 @@ static int max732x_irq_set_type(struct irq_data *d, unsigned int type)
 	else
 		chip->irq_trig_raise &= ~mask;
 
-	return max732x_gpio_direction_input(&chip->gpio_chip, off);
+	return 0;
 }
 
 static struct irq_chip max732x_irq_chip = {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] gpio: max732x: Add DT binding documentation
  2015-01-13 13:41 [PATCH 0/4] gpio: max732x: Update MAX732X driver to use modern kernel API Semen Protsenko
                   ` (2 preceding siblings ...)
  2015-01-13 13:41 ` [PATCH 3/4] gpio: max732x: Fix possible deadlock Semen Protsenko
@ 2015-01-13 13:41 ` Semen Protsenko
  2015-01-15 17:19   ` Linus Walleij
  3 siblings, 1 reply; 10+ messages in thread
From: Semen Protsenko @ 2015-01-13 13:41 UTC (permalink / raw)
  To: Linus Walleij, Alexandre Courbot
  Cc: Grant Likely, Mark Rutland, linux-gpio, linux-kernel, devicetree,
	Marc Zyngier, Grygorii Strashko, Illia Smyrnov

Add a devicetree binding documentation for the max732x driver.

Signed-off-by: Semen Protsenko <semen.protsenko@globallogic.com>
---
 .../devicetree/bindings/gpio/gpio-max732x.txt      |   59 ++++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-max732x.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-max732x.txt b/Documentation/devicetree/bindings/gpio/gpio-max732x.txt
new file mode 100644
index 0000000..5fdc843
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-max732x.txt
@@ -0,0 +1,59 @@
+* MAX732x-compatible I/O expanders
+
+Required properties:
+  - compatible: Should be one of the following:
+    - "maxim,max7319": For the Maxim MAX7319
+    - "maxim,max7320": For the Maxim MAX7320
+    - "maxim,max7321": For the Maxim MAX7321
+    - "maxim,max7322": For the Maxim MAX7322
+    - "maxim,max7323": For the Maxim MAX7323
+    - "maxim,max7324": For the Maxim MAX7324
+    - "maxim,max7325": For the Maxim MAX7325
+    - "maxim,max7326": For the Maxim MAX7326
+    - "maxim,max7327": For the Maxim MAX7327
+  - reg: I2C slave address for this device.
+  - gpio-controller: Marks the device node as a GPIO controller.
+  - #gpio-cells: Should be 2.
+    - first cell is the GPIO number
+    - second cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>.
+      Only the GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
+
+Optional properties:
+
+  The I/O expander can detect input state changes, and thus optionally act as
+  an interrupt controller. When the expander interrupt line is connected all the
+  following properties must be set. For more information please see the
+  interrupt controller device tree bindings documentation available at
+  Documentation/devicetree/bindings/interrupt-controller/interrupts.txt.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+  - #interrupt-cells: Number of cells to encode an interrupt source, shall be 2.
+    - first cell is the pin number
+    - second cell is used to specify flags
+  - interrupt-parent: phandle of the parent interrupt controller.
+  - interrupts: Interrupt specifier for the controllers interrupt.
+
+Please refer to gpio.txt in this directory for details of the common GPIO
+bindings used by client devices.
+
+Example 1. MAX7325 with interrupt support enabled (CONFIG_GPIO_MAX732X_IRQ=y):
+
+	expander: max7325@6d {
+		compatible = "maxim,max7325";
+		reg = <0x6d>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+Example 2. MAX7325 with interrupt support disabled (CONFIG_GPIO_MAX732X_IRQ=n):
+
+	expander: max7325@6d {
+		compatible = "maxim,max7325";
+		reg = <0x6d>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] gpio: max732x: Add device tree support
  2015-01-13 13:41 ` [PATCH 1/4] gpio: max732x: Add device tree support Semen Protsenko
@ 2015-01-15 16:52   ` Linus Walleij
  0 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2015-01-15 16:52 UTC (permalink / raw)
  To: Semen Protsenko
  Cc: Alexandre Courbot, Grant Likely, Mark Rutland, linux-gpio,
	linux-kernel, devicetree, Marc Zyngier, Grygorii Strashko,
	Illia Smyrnov

On Tue, Jan 13, 2015 at 2:41 PM, Semen Protsenko
<semen.protsenko@globallogic.com> wrote:

> Signed-off-by: Semen Protsenko <semen.protsenko@globallogic.com>

Patch applied.

Thanks for working on this driver, would you consider sending
a patch setting yourself as maintainer in the MAINTAINERS
file for this driver?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] gpio: max732x: Rewrite IRQ code to use irq_domain API
  2015-01-13 13:41 ` [PATCH 2/4] gpio: max732x: Rewrite IRQ code to use irq_domain API Semen Protsenko
@ 2015-01-15 17:03       ` Linus Walleij
  0 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2015-01-15 17:03 UTC (permalink / raw)
  To: Semen Protsenko
  Cc: Alexandre Courbot, Grant Likely, Mark Rutland,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Marc Zyngier,
	Grygorii Strashko, Illia Smyrnov

On Tue, Jan 13, 2015 at 2:41 PM, Semen Protsenko
<semen.protsenko-hExfYMNmJl/Cnp4W7fqMDg@public.gmane.org> wrote:

> Signed-off-by: Semen Protsenko <semen.protsenko-hExfYMNmJl/Cnp4W7fqMDg@public.gmane.org>

This makes the code *so* much better so patch applied, naturally.

But...

>  config GPIO_MAX732X
>         tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
>         depends on I2C
> +       select IRQ_DOMAIN

The most modern way would be to take another step and convert the
driver to GPIOLIB_IRQCHIP by stating

select GPIOLIB_IRQCHIP

here.

If you look at other drivers using GPIOLIB_IRQCHIP on an
i2c expander, say gpio-stmpe.c or gpio-tc3589x.c, you
can get a grip on how that works.

So please follow up with a patch converting the driver to
GPIOLIB_IRQCHIP on top of these patches :) if you
have time.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] gpio: max732x: Rewrite IRQ code to use irq_domain API
@ 2015-01-15 17:03       ` Linus Walleij
  0 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2015-01-15 17:03 UTC (permalink / raw)
  To: Semen Protsenko
  Cc: Alexandre Courbot, Grant Likely, Mark Rutland, linux-gpio,
	linux-kernel, devicetree, Marc Zyngier, Grygorii Strashko,
	Illia Smyrnov

On Tue, Jan 13, 2015 at 2:41 PM, Semen Protsenko
<semen.protsenko@globallogic.com> wrote:

> Signed-off-by: Semen Protsenko <semen.protsenko@globallogic.com>

This makes the code *so* much better so patch applied, naturally.

But...

>  config GPIO_MAX732X
>         tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
>         depends on I2C
> +       select IRQ_DOMAIN

The most modern way would be to take another step and convert the
driver to GPIOLIB_IRQCHIP by stating

select GPIOLIB_IRQCHIP

here.

If you look at other drivers using GPIOLIB_IRQCHIP on an
i2c expander, say gpio-stmpe.c or gpio-tc3589x.c, you
can get a grip on how that works.

So please follow up with a patch converting the driver to
GPIOLIB_IRQCHIP on top of these patches :) if you
have time.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] gpio: max732x: Fix possible deadlock
  2015-01-13 13:41 ` [PATCH 3/4] gpio: max732x: Fix possible deadlock Semen Protsenko
@ 2015-01-15 17:04   ` Linus Walleij
  0 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2015-01-15 17:04 UTC (permalink / raw)
  To: Semen Protsenko
  Cc: Alexandre Courbot, Grant Likely, Mark Rutland, linux-gpio,
	linux-kernel, devicetree, Marc Zyngier, Grygorii Strashko,
	Illia Smyrnov

On Tue, Jan 13, 2015 at 2:41 PM, Semen Protsenko
<semen.protsenko@globallogic.com> wrote:

> This patch was derived from next one:
> "gpio: fix pca953x set_type 'scheduling while atomic' bug".
>
> After adding entry that consumes max732x GPIO as interrupt line to dts
> file, deadlock appears somewhere in max732x probe function.

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] gpio: max732x: Add DT binding documentation
  2015-01-13 13:41 ` [PATCH 4/4] gpio: max732x: Add DT binding documentation Semen Protsenko
@ 2015-01-15 17:19   ` Linus Walleij
  0 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2015-01-15 17:19 UTC (permalink / raw)
  To: Semen Protsenko
  Cc: Alexandre Courbot, Grant Likely, Mark Rutland, linux-gpio,
	linux-kernel, devicetree, Marc Zyngier, Grygorii Strashko,
	Illia Smyrnov

On Tue, Jan 13, 2015 at 2:41 PM, Semen Protsenko
<semen.protsenko@globallogic.com> wrote:

> Add a devicetree binding documentation for the max732x driver.
>
> Signed-off-by: Semen Protsenko <semen.protsenko@globallogic.com>

Vanilla bindings, OK. Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-01-15 17:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-13 13:41 [PATCH 0/4] gpio: max732x: Update MAX732X driver to use modern kernel API Semen Protsenko
2015-01-13 13:41 ` [PATCH 1/4] gpio: max732x: Add device tree support Semen Protsenko
2015-01-15 16:52   ` Linus Walleij
2015-01-13 13:41 ` [PATCH 2/4] gpio: max732x: Rewrite IRQ code to use irq_domain API Semen Protsenko
     [not found]   ` <1421156505-16600-3-git-send-email-semen.protsenko-hExfYMNmJl/Cnp4W7fqMDg@public.gmane.org>
2015-01-15 17:03     ` Linus Walleij
2015-01-15 17:03       ` Linus Walleij
2015-01-13 13:41 ` [PATCH 3/4] gpio: max732x: Fix possible deadlock Semen Protsenko
2015-01-15 17:04   ` Linus Walleij
2015-01-13 13:41 ` [PATCH 4/4] gpio: max732x: Add DT binding documentation Semen Protsenko
2015-01-15 17:19   ` Linus Walleij

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.