All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] Reform EP93xx GPIO
@ 2018-08-22 20:41 ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

This series is a spin-off of a patch from Arnd that started to
decouple the EP93xx GPIO driver from the code inside
arch/arm.

The driver needed some modernization and in the end I managed
to convert two of the banks to use GPIOLIB_IRQCHIP and use
a proper irqdomain.

The F bank presents a special problem that I need to think
about, because since there is one IRQ per GPIO line it is
essentially a hierarchical irqdomain.

This was tested on the SIM.ONE where I rigged lines on some
of the GPIOs on a board connector. It's crude but gives
interrupts and behave as expected before and after these
changes, the main visible change being that the hardware
IRQ line on each port appears in /proc/interrupts.

It would be great if some EP93xx users could test this
(especially something using bank F) so I can get it into
shape and merge as a baseline for further refactorings.

Arnd Bergmann (1):
  ARM/gpio: ep93xx: build standalone

Linus Walleij (10):
  gpio: ep93xx: Cut down variable names
  gpio: ep93xx: Switch to SPDX license tag
  gpio: ep93xx: Pass around struct gpio_chip
  gpio: ep93xx: Rename has_debounce to has_irq
  gpio: ep93xx: Properly call the chained IRQ handler
  gpio: ep93xx: Do not pingpong irq numbers
  gpio: ep93xx: Use the hwirq and port
  gpio: ep93xx: Use for_each_set_bit() in IRQ handler
  gpio: ep93xx: Cut gpio_to_irq() usage
  gpio: ep93xx: Switch A and B to use GPIOLIB_IRQCHIP

 arch/arm/mach-ep93xx/core.c |   9 ++
 drivers/gpio/Kconfig        |   1 +
 drivers/gpio/gpio-ep93xx.c  | 297 +++++++++++++++++++++---------------
 3 files changed, 181 insertions(+), 126 deletions(-)

-- 
2.17.1

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

* [PATCH 00/11] Reform EP93xx GPIO
@ 2018-08-22 20:41 ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

This series is a spin-off of a patch from Arnd that started to
decouple the EP93xx GPIO driver from the code inside
arch/arm.

The driver needed some modernization and in the end I managed
to convert two of the banks to use GPIOLIB_IRQCHIP and use
a proper irqdomain.

The F bank presents a special problem that I need to think
about, because since there is one IRQ per GPIO line it is
essentially a hierarchical irqdomain.

This was tested on the SIM.ONE where I rigged lines on some
of the GPIOs on a board connector. It's crude but gives
interrupts and behave as expected before and after these
changes, the main visible change being that the hardware
IRQ line on each port appears in /proc/interrupts.

It would be great if some EP93xx users could test this
(especially something using bank F) so I can get it into
shape and merge as a baseline for further refactorings.

Arnd Bergmann (1):
  ARM/gpio: ep93xx: build standalone

Linus Walleij (10):
  gpio: ep93xx: Cut down variable names
  gpio: ep93xx: Switch to SPDX license tag
  gpio: ep93xx: Pass around struct gpio_chip
  gpio: ep93xx: Rename has_debounce to has_irq
  gpio: ep93xx: Properly call the chained IRQ handler
  gpio: ep93xx: Do not pingpong irq numbers
  gpio: ep93xx: Use the hwirq and port
  gpio: ep93xx: Use for_each_set_bit() in IRQ handler
  gpio: ep93xx: Cut gpio_to_irq() usage
  gpio: ep93xx: Switch A and B to use GPIOLIB_IRQCHIP

 arch/arm/mach-ep93xx/core.c |   9 ++
 drivers/gpio/Kconfig        |   1 +
 drivers/gpio/gpio-ep93xx.c  | 297 +++++++++++++++++++++---------------
 3 files changed, 181 insertions(+), 126 deletions(-)

-- 
2.17.1

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

* [PATCH 01/11] ARM/gpio: ep93xx: build standalone
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, arm, Arnd Bergmann, linux-arm-kernel

From: Arnd Bergmann <arnd@arndb.de>

As a preparation for multiplatform support, this ensures
that the ep93xx gpio driver can be built without any of
the platform specific header files. We pass the IRQ numbers
as a resource now, and use the virtual mmio base from the
already existing resource, rather than relying on the
hardwired virtual address from the header file.

Some numbers are now hardcoded that came from macros
in the past, but for all I can tell, the driver already
relied on the specific values.

Cc: arm@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Arnd/other ARM SoC person:
Please provide an ACK for this patch so I can merge it
with the rest of the refactorings into the GPIO tree.
---
 arch/arm/mach-ep93xx/core.c |  9 +++++++
 drivers/gpio/gpio-ep93xx.c  | 48 ++++++++++++++++++-------------------
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 574dfdc527ed..b82b632789f7 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -141,6 +141,15 @@ EXPORT_SYMBOL_GPL(ep93xx_chip_revision);
  *************************************************************************/
 static struct resource ep93xx_gpio_resource[] = {
 	DEFINE_RES_MEM(EP93XX_GPIO_PHYS_BASE, 0xcc),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO_AB),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO0MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO1MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO2MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO3MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO4MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO5MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO6MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO7MUX),
 };
 
 static struct platform_device ep93xx_gpio_device = {
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 45d384039e9b..654525d6a9f1 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -22,11 +22,20 @@
 /* FIXME: this is here for gpio_to_irq() - get rid of this! */
 #include <linux/gpio.h>
 
-#include <mach/hardware.h>
-#include <mach/gpio-ep93xx.h>
-
 #define irq_to_gpio(irq)	((irq) - gpio_to_irq(0))
 
+void __iomem *ep93xx_gpio_base; /* FIXME: put this into irq_data */
+#define EP93XX_GPIO_REG(x) (ep93xx_gpio_base + (x))
+#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
+#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0)
+#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
+
+/* Maximum value for gpio line identifiers */
+#define EP93XX_GPIO_LINE_MAX 63
+
+/* Maximum value for irq capable line identifiers */
+#define EP93XX_GPIO_LINE_MAX_IRQ 23
+
 struct ep93xx_gpio {
 	void __iomem		*mmio_base;
 	struct gpio_chip	gc[8];
@@ -87,7 +96,7 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 	status = readb(EP93XX_GPIO_A_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
+			int gpio_irq = gpio_to_irq(0) + i;
 			generic_handle_irq(gpio_irq);
 		}
 	}
@@ -95,7 +104,7 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 	status = readb(EP93XX_GPIO_B_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
+			int gpio_irq = gpio_to_irq(8) + i;
 			generic_handle_irq(gpio_irq);
 		}
 	}
@@ -110,7 +119,7 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 	 */
 	unsigned int irq = irq_desc_get_irq(desc);
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
-	int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
+	int gpio_irq = gpio_to_irq(16) + port_f_idx;
 
 	generic_handle_irq(gpio_irq);
 }
@@ -228,9 +237,10 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
 	.irq_set_type	= ep93xx_gpio_irq_type,
 };
 
-static void ep93xx_gpio_init_irq(void)
+static void ep93xx_gpio_init_irq(struct platform_device *pdev)
 {
 	int gpio_irq;
+	int i;
 
 	for (gpio_irq = gpio_to_irq(0);
 	     gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
@@ -239,24 +249,11 @@ static void ep93xx_gpio_init_irq(void)
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 
-	irq_set_chained_handler(IRQ_EP93XX_GPIO_AB,
+	irq_set_chained_handler(platform_get_irq(pdev, 0),
 				ep93xx_gpio_ab_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO0MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO1MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO2MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO3MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO4MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO5MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO6MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO7MUX,
-				ep93xx_gpio_f_irq_handler);
+	for (i = 1; i <= 8; i++)
+		irq_set_chained_handler(platform_get_irq(pdev, i),
+					ep93xx_gpio_f_irq_handler);
 }
 
 
@@ -362,6 +359,7 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
 	ep93xx_gpio->mmio_base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(ep93xx_gpio->mmio_base))
 		return PTR_ERR(ep93xx_gpio->mmio_base);
+	ep93xx_gpio_base = ep93xx_gpio->mmio_base;
 
 	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
 		struct gpio_chip *gc = &ep93xx_gpio->gc[i];
@@ -373,7 +371,7 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
 				bank->label);
 	}
 
-	ep93xx_gpio_init_irq();
+	ep93xx_gpio_init_irq(pdev);
 
 	return 0;
 }
-- 
2.17.1

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

* [PATCH 01/11] ARM/gpio: ep93xx: build standalone
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

From: Arnd Bergmann <arnd@arndb.de>

As a preparation for multiplatform support, this ensures
that the ep93xx gpio driver can be built without any of
the platform specific header files. We pass the IRQ numbers
as a resource now, and use the virtual mmio base from the
already existing resource, rather than relying on the
hardwired virtual address from the header file.

Some numbers are now hardcoded that came from macros
in the past, but for all I can tell, the driver already
relied on the specific values.

Cc: arm at kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Arnd/other ARM SoC person:
Please provide an ACK for this patch so I can merge it
with the rest of the refactorings into the GPIO tree.
---
 arch/arm/mach-ep93xx/core.c |  9 +++++++
 drivers/gpio/gpio-ep93xx.c  | 48 ++++++++++++++++++-------------------
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 574dfdc527ed..b82b632789f7 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -141,6 +141,15 @@ EXPORT_SYMBOL_GPL(ep93xx_chip_revision);
  *************************************************************************/
 static struct resource ep93xx_gpio_resource[] = {
 	DEFINE_RES_MEM(EP93XX_GPIO_PHYS_BASE, 0xcc),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO_AB),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO0MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO1MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO2MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO3MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO4MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO5MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO6MUX),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO7MUX),
 };
 
 static struct platform_device ep93xx_gpio_device = {
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 45d384039e9b..654525d6a9f1 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -22,11 +22,20 @@
 /* FIXME: this is here for gpio_to_irq() - get rid of this! */
 #include <linux/gpio.h>
 
-#include <mach/hardware.h>
-#include <mach/gpio-ep93xx.h>
-
 #define irq_to_gpio(irq)	((irq) - gpio_to_irq(0))
 
+void __iomem *ep93xx_gpio_base; /* FIXME: put this into irq_data */
+#define EP93XX_GPIO_REG(x) (ep93xx_gpio_base + (x))
+#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
+#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0)
+#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
+
+/* Maximum value for gpio line identifiers */
+#define EP93XX_GPIO_LINE_MAX 63
+
+/* Maximum value for irq capable line identifiers */
+#define EP93XX_GPIO_LINE_MAX_IRQ 23
+
 struct ep93xx_gpio {
 	void __iomem		*mmio_base;
 	struct gpio_chip	gc[8];
@@ -87,7 +96,7 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 	status = readb(EP93XX_GPIO_A_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
+			int gpio_irq = gpio_to_irq(0) + i;
 			generic_handle_irq(gpio_irq);
 		}
 	}
@@ -95,7 +104,7 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 	status = readb(EP93XX_GPIO_B_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
+			int gpio_irq = gpio_to_irq(8) + i;
 			generic_handle_irq(gpio_irq);
 		}
 	}
@@ -110,7 +119,7 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 	 */
 	unsigned int irq = irq_desc_get_irq(desc);
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
-	int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
+	int gpio_irq = gpio_to_irq(16) + port_f_idx;
 
 	generic_handle_irq(gpio_irq);
 }
@@ -228,9 +237,10 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
 	.irq_set_type	= ep93xx_gpio_irq_type,
 };
 
-static void ep93xx_gpio_init_irq(void)
+static void ep93xx_gpio_init_irq(struct platform_device *pdev)
 {
 	int gpio_irq;
+	int i;
 
 	for (gpio_irq = gpio_to_irq(0);
 	     gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
@@ -239,24 +249,11 @@ static void ep93xx_gpio_init_irq(void)
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 
-	irq_set_chained_handler(IRQ_EP93XX_GPIO_AB,
+	irq_set_chained_handler(platform_get_irq(pdev, 0),
 				ep93xx_gpio_ab_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO0MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO1MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO2MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO3MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO4MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO5MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO6MUX,
-				ep93xx_gpio_f_irq_handler);
-	irq_set_chained_handler(IRQ_EP93XX_GPIO7MUX,
-				ep93xx_gpio_f_irq_handler);
+	for (i = 1; i <= 8; i++)
+		irq_set_chained_handler(platform_get_irq(pdev, i),
+					ep93xx_gpio_f_irq_handler);
 }
 
 
@@ -362,6 +359,7 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
 	ep93xx_gpio->mmio_base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(ep93xx_gpio->mmio_base))
 		return PTR_ERR(ep93xx_gpio->mmio_base);
+	ep93xx_gpio_base = ep93xx_gpio->mmio_base;
 
 	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
 		struct gpio_chip *gc = &ep93xx_gpio->gc[i];
@@ -373,7 +371,7 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
 				bank->label);
 	}
 
-	ep93xx_gpio_init_irq();
+	ep93xx_gpio_init_irq(pdev);
 
 	return 0;
 }
-- 
2.17.1

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

* [PATCH 02/11] gpio: ep93xx: Cut down variable names
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

In order to clean up the driver I need to cut a few trees,
sorry, variable names, so I can see the forest, sorry driver
properly.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 654525d6a9f1..3bfd0e46f7ed 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -37,7 +37,7 @@ void __iomem *ep93xx_gpio_base; /* FIXME: put this into irq_data */
 #define EP93XX_GPIO_LINE_MAX_IRQ 23
 
 struct ep93xx_gpio {
-	void __iomem		*mmio_base;
+	void __iomem		*base;
 	struct gpio_chip	gc[8];
 };
 
@@ -323,10 +323,10 @@ static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 }
 
 static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
-	void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
+	void __iomem *base, struct ep93xx_gpio_bank *bank)
 {
-	void __iomem *data = mmio_base + bank->data;
-	void __iomem *dir =  mmio_base + bank->dir;
+	void __iomem *data = base + bank->data;
+	void __iomem *dir =  base + bank->dir;
 	int err;
 
 	err = bgpio_init(gc, dev, 1, data, NULL, NULL, dir, NULL, 0);
@@ -346,27 +346,27 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
 
 static int ep93xx_gpio_probe(struct platform_device *pdev)
 {
-	struct ep93xx_gpio *ep93xx_gpio;
+	struct ep93xx_gpio *epg;
 	struct resource *res;
 	int i;
 	struct device *dev = &pdev->dev;
 
-	ep93xx_gpio = devm_kzalloc(dev, sizeof(struct ep93xx_gpio), GFP_KERNEL);
-	if (!ep93xx_gpio)
+	epg = devm_kzalloc(dev, sizeof(*epg), GFP_KERNEL);
+	if (!epg)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ep93xx_gpio->mmio_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(ep93xx_gpio->mmio_base))
-		return PTR_ERR(ep93xx_gpio->mmio_base);
-	ep93xx_gpio_base = ep93xx_gpio->mmio_base;
+	epg->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(epg->base))
+		return PTR_ERR(epg->base);
+	ep93xx_gpio_base = epg->base;
 
 	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
-		struct gpio_chip *gc = &ep93xx_gpio->gc[i];
+		struct gpio_chip *gc = &epg->gc[i];
 		struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
 
 		if (ep93xx_gpio_add_bank(gc, &pdev->dev,
-					 ep93xx_gpio->mmio_base, bank))
+					 epg->base, bank))
 			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
 				bank->label);
 	}
-- 
2.17.1

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

* [PATCH 02/11] gpio: ep93xx: Cut down variable names
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

In order to clean up the driver I need to cut a few trees,
sorry, variable names, so I can see the forest, sorry driver
properly.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 654525d6a9f1..3bfd0e46f7ed 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -37,7 +37,7 @@ void __iomem *ep93xx_gpio_base; /* FIXME: put this into irq_data */
 #define EP93XX_GPIO_LINE_MAX_IRQ 23
 
 struct ep93xx_gpio {
-	void __iomem		*mmio_base;
+	void __iomem		*base;
 	struct gpio_chip	gc[8];
 };
 
@@ -323,10 +323,10 @@ static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 }
 
 static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
-	void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
+	void __iomem *base, struct ep93xx_gpio_bank *bank)
 {
-	void __iomem *data = mmio_base + bank->data;
-	void __iomem *dir =  mmio_base + bank->dir;
+	void __iomem *data = base + bank->data;
+	void __iomem *dir =  base + bank->dir;
 	int err;
 
 	err = bgpio_init(gc, dev, 1, data, NULL, NULL, dir, NULL, 0);
@@ -346,27 +346,27 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
 
 static int ep93xx_gpio_probe(struct platform_device *pdev)
 {
-	struct ep93xx_gpio *ep93xx_gpio;
+	struct ep93xx_gpio *epg;
 	struct resource *res;
 	int i;
 	struct device *dev = &pdev->dev;
 
-	ep93xx_gpio = devm_kzalloc(dev, sizeof(struct ep93xx_gpio), GFP_KERNEL);
-	if (!ep93xx_gpio)
+	epg = devm_kzalloc(dev, sizeof(*epg), GFP_KERNEL);
+	if (!epg)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ep93xx_gpio->mmio_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(ep93xx_gpio->mmio_base))
-		return PTR_ERR(ep93xx_gpio->mmio_base);
-	ep93xx_gpio_base = ep93xx_gpio->mmio_base;
+	epg->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(epg->base))
+		return PTR_ERR(epg->base);
+	ep93xx_gpio_base = epg->base;
 
 	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
-		struct gpio_chip *gc = &ep93xx_gpio->gc[i];
+		struct gpio_chip *gc = &epg->gc[i];
 		struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
 
 		if (ep93xx_gpio_add_bank(gc, &pdev->dev,
-					 ep93xx_gpio->mmio_base, bank))
+					 epg->base, bank))
 			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
 				bank->label);
 	}
-- 
2.17.1

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

* [PATCH 03/11] gpio: ep93xx: Switch to SPDX license tag
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

The subject says it all. Cut down on boilerplate.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 3bfd0e46f7ed..3822d11e90ac 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Generic EP93xx GPIO handling
  *
@@ -6,10 +7,6 @@
  *
  * Based on code originally from:
  *  linux/arch/arm/mach-ep93xx/core.c
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
  */
 
 #include <linux/init.h>
-- 
2.17.1

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

* [PATCH 03/11] gpio: ep93xx: Switch to SPDX license tag
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

The subject says it all. Cut down on boilerplate.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 3bfd0e46f7ed..3822d11e90ac 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Generic EP93xx GPIO handling
  *
@@ -6,10 +7,6 @@
  *
  * Based on code originally from:
  *  linux/arch/arm/mach-ep93xx/core.c
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
  */
 
 #include <linux/init.h>
-- 
2.17.1

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

* [PATCH 04/11] gpio: ep93xx: Pass around struct gpio_chip
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

Instead of using a global variable, pass around the
struct gpio_chip * pointer and dereference to the state
container struct ep93xx_gpio as needed, like all other
drivers do.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 111 ++++++++++++++++++++++++-------------
 1 file changed, 73 insertions(+), 38 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 3822d11e90ac..379f2573f794 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -21,11 +21,9 @@
 
 #define irq_to_gpio(irq)	((irq) - gpio_to_irq(0))
 
-void __iomem *ep93xx_gpio_base; /* FIXME: put this into irq_data */
-#define EP93XX_GPIO_REG(x) (ep93xx_gpio_base + (x))
-#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
-#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0)
-#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
+#define EP93XX_GPIO_F_INT_STATUS 0x5c
+#define EP93XX_GPIO_A_INT_STATUS 0xa0
+#define EP93XX_GPIO_B_INT_STATUS 0xbc
 
 /* Maximum value for gpio line identifiers */
 #define EP93XX_GPIO_LINE_MAX 63
@@ -54,23 +52,24 @@ static const u8 eoi_register_offset[3]		= { 0x98, 0xb4, 0x54 };
 static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x58 };
 static const u8 int_debounce_register_offset[3]	= { 0xa8, 0xc4, 0x64 };
 
-static void ep93xx_gpio_update_int_params(unsigned port)
+static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, unsigned port)
 {
 	BUG_ON(port > 2);
 
-	writeb_relaxed(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
+	writeb_relaxed(0, epg->base + int_en_register_offset[port]);
 
 	writeb_relaxed(gpio_int_type2[port],
-		EP93XX_GPIO_REG(int_type2_register_offset[port]));
+		       epg->base + int_type2_register_offset[port]);
 
 	writeb_relaxed(gpio_int_type1[port],
-		EP93XX_GPIO_REG(int_type1_register_offset[port]));
+		       epg->base + int_type1_register_offset[port]);
 
 	writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
-		EP93XX_GPIO_REG(int_en_register_offset[port]));
+	       epg->base + int_en_register_offset[port]);
 }
 
-static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
+static void ep93xx_gpio_int_debounce(struct ep93xx_gpio *epg,
+				     unsigned int irq, bool enable)
 {
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
@@ -82,15 +81,17 @@ static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
 		gpio_int_debounce[port] &= ~port_mask;
 
 	writeb(gpio_int_debounce[port],
-		EP93XX_GPIO_REG(int_debounce_register_offset[port]));
+	       epg->base + int_debounce_register_offset[port]);
 }
 
 static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 {
+	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	unsigned char status;
 	int i;
 
-	status = readb(EP93XX_GPIO_A_INT_STATUS);
+	status = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
 			int gpio_irq = gpio_to_irq(0) + i;
@@ -98,7 +99,7 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 		}
 	}
 
-	status = readb(EP93XX_GPIO_B_INT_STATUS);
+	status = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
 			int gpio_irq = gpio_to_irq(8) + i;
@@ -123,20 +124,24 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 
 static void ep93xx_gpio_irq_ack(struct irq_data *d)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	int line = irq_to_gpio(d->irq);
 	int port = line >> 3;
 	int port_mask = 1 << (line & 7);
 
 	if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
-		ep93xx_gpio_update_int_params(port);
+		ep93xx_gpio_update_int_params(epg, port);
 	}
 
-	writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+	writeb(port_mask, epg->base + eoi_register_offset[port]);
 }
 
 static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	int line = irq_to_gpio(d->irq);
 	int port = line >> 3;
 	int port_mask = 1 << (line & 7);
@@ -145,27 +150,31 @@ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
 
 	gpio_int_unmasked[port] &= ~port_mask;
-	ep93xx_gpio_update_int_params(port);
+	ep93xx_gpio_update_int_params(epg, port);
 
-	writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+	writeb(port_mask, epg->base + eoi_register_offset[port]);
 }
 
 static void ep93xx_gpio_irq_mask(struct irq_data *d)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	int line = irq_to_gpio(d->irq);
 	int port = line >> 3;
 
 	gpio_int_unmasked[port] &= ~(1 << (line & 7));
-	ep93xx_gpio_update_int_params(port);
+	ep93xx_gpio_update_int_params(epg, port);
 }
 
 static void ep93xx_gpio_irq_unmask(struct irq_data *d)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	int line = irq_to_gpio(d->irq);
 	int port = line >> 3;
 
 	gpio_int_unmasked[port] |= 1 << (line & 7);
-	ep93xx_gpio_update_int_params(port);
+	ep93xx_gpio_update_int_params(epg, port);
 }
 
 /*
@@ -175,6 +184,8 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d)
  */
 static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	const int gpio = irq_to_gpio(d->irq);
 	const int port = gpio >> 3;
 	const int port_mask = 1 << (gpio & 7);
@@ -220,7 +231,7 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 
 	gpio_int_enabled[port] |= port_mask;
 
-	ep93xx_gpio_update_int_params(port);
+	ep93xx_gpio_update_int_params(epg, port);
 
 	return 0;
 }
@@ -234,23 +245,47 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
 	.irq_set_type	= ep93xx_gpio_irq_type,
 };
 
-static void ep93xx_gpio_init_irq(struct platform_device *pdev)
+static void ep93xx_gpio_init_irq(struct platform_device *pdev,
+				 struct ep93xx_gpio *epg)
 {
 	int gpio_irq;
 	int i;
 
+	/* The A bank */
 	for (gpio_irq = gpio_to_irq(0);
-	     gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
+	     gpio_irq < gpio_to_irq(8);
+	     gpio_irq++) {
+		irq_set_chip_data(gpio_irq, &epg->gc[0]);
+		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
+					 handle_level_irq);
+		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+	}
+	/* The B bank */
+	for (gpio_irq = gpio_to_irq(8);
+	     gpio_irq < gpio_to_irq(16);
+	     gpio_irq++) {
+		irq_set_chip_data(gpio_irq, &epg->gc[1]);
+		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
+					 handle_level_irq);
+		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+	}
+	/* The F bank */
+	for (gpio_irq = gpio_to_irq(16);
+	     gpio_irq < gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ);
+	     gpio_irq++) {
+		irq_set_chip_data(gpio_irq, &epg->gc[5]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 
-	irq_set_chained_handler(platform_get_irq(pdev, 0),
-				ep93xx_gpio_ab_irq_handler);
+	irq_set_chained_handler_and_data(platform_get_irq(pdev, 0),
+					 ep93xx_gpio_ab_irq_handler,
+					 &epg->gc[0]);
 	for (i = 1; i <= 8; i++)
-		irq_set_chained_handler(platform_get_irq(pdev, i),
-					ep93xx_gpio_f_irq_handler);
+		irq_set_chained_handler_and_data(platform_get_irq(pdev, i),
+						 ep93xx_gpio_f_irq_handler,
+						 &epg->gc[i]);
 }
 
 
@@ -285,10 +320,11 @@ static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
 	EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false),
 };
 
-static int ep93xx_gpio_set_config(struct gpio_chip *chip, unsigned offset,
+static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 				  unsigned long config)
 {
-	int gpio = chip->base + offset;
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+	int gpio = gc->base + offset;
 	int irq = gpio_to_irq(gpio);
 	u32 debounce;
 
@@ -299,7 +335,7 @@ static int ep93xx_gpio_set_config(struct gpio_chip *chip, unsigned offset,
 		return -EINVAL;
 
 	debounce = pinconf_to_config_argument(config);
-	ep93xx_gpio_int_debounce(irq, debounce ? true : false);
+	ep93xx_gpio_int_debounce(epg, irq, debounce ? true : false);
 
 	return 0;
 }
@@ -320,10 +356,11 @@ static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 }
 
 static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
-	void __iomem *base, struct ep93xx_gpio_bank *bank)
+				struct ep93xx_gpio *epg,
+				struct ep93xx_gpio_bank *bank)
 {
-	void __iomem *data = base + bank->data;
-	void __iomem *dir =  base + bank->dir;
+	void __iomem *data = epg->base + bank->data;
+	void __iomem *dir = epg->base + bank->dir;
 	int err;
 
 	err = bgpio_init(gc, dev, 1, data, NULL, NULL, dir, NULL, 0);
@@ -338,7 +375,7 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
 		gc->to_irq = ep93xx_gpio_to_irq;
 	}
 
-	return devm_gpiochip_add_data(dev, gc, NULL);
+	return devm_gpiochip_add_data(dev, gc, epg);
 }
 
 static int ep93xx_gpio_probe(struct platform_device *pdev)
@@ -356,19 +393,17 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
 	epg->base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(epg->base))
 		return PTR_ERR(epg->base);
-	ep93xx_gpio_base = epg->base;
 
 	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
 		struct gpio_chip *gc = &epg->gc[i];
 		struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
 
-		if (ep93xx_gpio_add_bank(gc, &pdev->dev,
-					 epg->base, bank))
+		if (ep93xx_gpio_add_bank(gc, &pdev->dev, epg, bank))
 			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
 				bank->label);
 	}
 
-	ep93xx_gpio_init_irq(pdev);
+	ep93xx_gpio_init_irq(pdev, epg);
 
 	return 0;
 }
-- 
2.17.1

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

* [PATCH 04/11] gpio: ep93xx: Pass around struct gpio_chip
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of using a global variable, pass around the
struct gpio_chip * pointer and dereference to the state
container struct ep93xx_gpio as needed, like all other
drivers do.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 111 ++++++++++++++++++++++++-------------
 1 file changed, 73 insertions(+), 38 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 3822d11e90ac..379f2573f794 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -21,11 +21,9 @@
 
 #define irq_to_gpio(irq)	((irq) - gpio_to_irq(0))
 
-void __iomem *ep93xx_gpio_base; /* FIXME: put this into irq_data */
-#define EP93XX_GPIO_REG(x) (ep93xx_gpio_base + (x))
-#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
-#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0)
-#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
+#define EP93XX_GPIO_F_INT_STATUS 0x5c
+#define EP93XX_GPIO_A_INT_STATUS 0xa0
+#define EP93XX_GPIO_B_INT_STATUS 0xbc
 
 /* Maximum value for gpio line identifiers */
 #define EP93XX_GPIO_LINE_MAX 63
@@ -54,23 +52,24 @@ static const u8 eoi_register_offset[3]		= { 0x98, 0xb4, 0x54 };
 static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x58 };
 static const u8 int_debounce_register_offset[3]	= { 0xa8, 0xc4, 0x64 };
 
-static void ep93xx_gpio_update_int_params(unsigned port)
+static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, unsigned port)
 {
 	BUG_ON(port > 2);
 
-	writeb_relaxed(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
+	writeb_relaxed(0, epg->base + int_en_register_offset[port]);
 
 	writeb_relaxed(gpio_int_type2[port],
-		EP93XX_GPIO_REG(int_type2_register_offset[port]));
+		       epg->base + int_type2_register_offset[port]);
 
 	writeb_relaxed(gpio_int_type1[port],
-		EP93XX_GPIO_REG(int_type1_register_offset[port]));
+		       epg->base + int_type1_register_offset[port]);
 
 	writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
-		EP93XX_GPIO_REG(int_en_register_offset[port]));
+	       epg->base + int_en_register_offset[port]);
 }
 
-static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
+static void ep93xx_gpio_int_debounce(struct ep93xx_gpio *epg,
+				     unsigned int irq, bool enable)
 {
 	int line = irq_to_gpio(irq);
 	int port = line >> 3;
@@ -82,15 +81,17 @@ static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
 		gpio_int_debounce[port] &= ~port_mask;
 
 	writeb(gpio_int_debounce[port],
-		EP93XX_GPIO_REG(int_debounce_register_offset[port]));
+	       epg->base + int_debounce_register_offset[port]);
 }
 
 static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 {
+	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	unsigned char status;
 	int i;
 
-	status = readb(EP93XX_GPIO_A_INT_STATUS);
+	status = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
 			int gpio_irq = gpio_to_irq(0) + i;
@@ -98,7 +99,7 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 		}
 	}
 
-	status = readb(EP93XX_GPIO_B_INT_STATUS);
+	status = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
 			int gpio_irq = gpio_to_irq(8) + i;
@@ -123,20 +124,24 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 
 static void ep93xx_gpio_irq_ack(struct irq_data *d)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	int line = irq_to_gpio(d->irq);
 	int port = line >> 3;
 	int port_mask = 1 << (line & 7);
 
 	if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
-		ep93xx_gpio_update_int_params(port);
+		ep93xx_gpio_update_int_params(epg, port);
 	}
 
-	writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+	writeb(port_mask, epg->base + eoi_register_offset[port]);
 }
 
 static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	int line = irq_to_gpio(d->irq);
 	int port = line >> 3;
 	int port_mask = 1 << (line & 7);
@@ -145,27 +150,31 @@ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
 
 	gpio_int_unmasked[port] &= ~port_mask;
-	ep93xx_gpio_update_int_params(port);
+	ep93xx_gpio_update_int_params(epg, port);
 
-	writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+	writeb(port_mask, epg->base + eoi_register_offset[port]);
 }
 
 static void ep93xx_gpio_irq_mask(struct irq_data *d)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	int line = irq_to_gpio(d->irq);
 	int port = line >> 3;
 
 	gpio_int_unmasked[port] &= ~(1 << (line & 7));
-	ep93xx_gpio_update_int_params(port);
+	ep93xx_gpio_update_int_params(epg, port);
 }
 
 static void ep93xx_gpio_irq_unmask(struct irq_data *d)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	int line = irq_to_gpio(d->irq);
 	int port = line >> 3;
 
 	gpio_int_unmasked[port] |= 1 << (line & 7);
-	ep93xx_gpio_update_int_params(port);
+	ep93xx_gpio_update_int_params(epg, port);
 }
 
 /*
@@ -175,6 +184,8 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d)
  */
 static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	const int gpio = irq_to_gpio(d->irq);
 	const int port = gpio >> 3;
 	const int port_mask = 1 << (gpio & 7);
@@ -220,7 +231,7 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 
 	gpio_int_enabled[port] |= port_mask;
 
-	ep93xx_gpio_update_int_params(port);
+	ep93xx_gpio_update_int_params(epg, port);
 
 	return 0;
 }
@@ -234,23 +245,47 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
 	.irq_set_type	= ep93xx_gpio_irq_type,
 };
 
-static void ep93xx_gpio_init_irq(struct platform_device *pdev)
+static void ep93xx_gpio_init_irq(struct platform_device *pdev,
+				 struct ep93xx_gpio *epg)
 {
 	int gpio_irq;
 	int i;
 
+	/* The A bank */
 	for (gpio_irq = gpio_to_irq(0);
-	     gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
+	     gpio_irq < gpio_to_irq(8);
+	     gpio_irq++) {
+		irq_set_chip_data(gpio_irq, &epg->gc[0]);
+		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
+					 handle_level_irq);
+		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+	}
+	/* The B bank */
+	for (gpio_irq = gpio_to_irq(8);
+	     gpio_irq < gpio_to_irq(16);
+	     gpio_irq++) {
+		irq_set_chip_data(gpio_irq, &epg->gc[1]);
+		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
+					 handle_level_irq);
+		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+	}
+	/* The F bank */
+	for (gpio_irq = gpio_to_irq(16);
+	     gpio_irq < gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ);
+	     gpio_irq++) {
+		irq_set_chip_data(gpio_irq, &epg->gc[5]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 
-	irq_set_chained_handler(platform_get_irq(pdev, 0),
-				ep93xx_gpio_ab_irq_handler);
+	irq_set_chained_handler_and_data(platform_get_irq(pdev, 0),
+					 ep93xx_gpio_ab_irq_handler,
+					 &epg->gc[0]);
 	for (i = 1; i <= 8; i++)
-		irq_set_chained_handler(platform_get_irq(pdev, i),
-					ep93xx_gpio_f_irq_handler);
+		irq_set_chained_handler_and_data(platform_get_irq(pdev, i),
+						 ep93xx_gpio_f_irq_handler,
+						 &epg->gc[i]);
 }
 
 
@@ -285,10 +320,11 @@ static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
 	EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false),
 };
 
-static int ep93xx_gpio_set_config(struct gpio_chip *chip, unsigned offset,
+static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 				  unsigned long config)
 {
-	int gpio = chip->base + offset;
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+	int gpio = gc->base + offset;
 	int irq = gpio_to_irq(gpio);
 	u32 debounce;
 
@@ -299,7 +335,7 @@ static int ep93xx_gpio_set_config(struct gpio_chip *chip, unsigned offset,
 		return -EINVAL;
 
 	debounce = pinconf_to_config_argument(config);
-	ep93xx_gpio_int_debounce(irq, debounce ? true : false);
+	ep93xx_gpio_int_debounce(epg, irq, debounce ? true : false);
 
 	return 0;
 }
@@ -320,10 +356,11 @@ static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 }
 
 static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
-	void __iomem *base, struct ep93xx_gpio_bank *bank)
+				struct ep93xx_gpio *epg,
+				struct ep93xx_gpio_bank *bank)
 {
-	void __iomem *data = base + bank->data;
-	void __iomem *dir =  base + bank->dir;
+	void __iomem *data = epg->base + bank->data;
+	void __iomem *dir = epg->base + bank->dir;
 	int err;
 
 	err = bgpio_init(gc, dev, 1, data, NULL, NULL, dir, NULL, 0);
@@ -338,7 +375,7 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
 		gc->to_irq = ep93xx_gpio_to_irq;
 	}
 
-	return devm_gpiochip_add_data(dev, gc, NULL);
+	return devm_gpiochip_add_data(dev, gc, epg);
 }
 
 static int ep93xx_gpio_probe(struct platform_device *pdev)
@@ -356,19 +393,17 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
 	epg->base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(epg->base))
 		return PTR_ERR(epg->base);
-	ep93xx_gpio_base = epg->base;
 
 	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
 		struct gpio_chip *gc = &epg->gc[i];
 		struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
 
-		if (ep93xx_gpio_add_bank(gc, &pdev->dev,
-					 epg->base, bank))
+		if (ep93xx_gpio_add_bank(gc, &pdev->dev, epg, bank))
 			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
 				bank->label);
 	}
 
-	ep93xx_gpio_init_irq(pdev);
+	ep93xx_gpio_init_irq(pdev, epg);
 
 	return 0;
 }
-- 
2.17.1

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

* [PATCH 05/11] gpio: ep93xx: Rename has_debounce to has_irq
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

This is closer to what the variable (per bank) actually
means. We have the .gpio_to_irq() hook registered only
when this is true.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 379f2573f794..a81d1e796912 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -297,25 +297,25 @@ struct ep93xx_gpio_bank {
 	int		data;
 	int		dir;
 	int		base;
-	bool		has_debounce;
+	bool		has_irq;
 };
 
-#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _debounce)	\
+#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _has_irq)	\
 	{							\
 		.label		= _label,			\
 		.data		= _data,			\
 		.dir		= _dir,				\
 		.base		= _base,			\
-		.has_debounce	= _debounce,			\
+		.has_irq	= _has_irq,			\
 	}
 
 static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
-	EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true),
-	EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true),
+	EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true), /* Bank A has 8 IRQs */
+	EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true), /* Bank B has 8 IRQs */
 	EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false),
 	EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false),
 	EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false),
-	EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true),
+	EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true), /* Bank F has 8 IRQs */
 	EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false),
 	EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false),
 };
@@ -370,7 +370,7 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
 	gc->label = bank->label;
 	gc->base = bank->base;
 
-	if (bank->has_debounce) {
+	if (bank->has_irq) {
 		gc->set_config = ep93xx_gpio_set_config;
 		gc->to_irq = ep93xx_gpio_to_irq;
 	}
-- 
2.17.1

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

* [PATCH 05/11] gpio: ep93xx: Rename has_debounce to has_irq
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

This is closer to what the variable (per bank) actually
means. We have the .gpio_to_irq() hook registered only
when this is true.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 379f2573f794..a81d1e796912 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -297,25 +297,25 @@ struct ep93xx_gpio_bank {
 	int		data;
 	int		dir;
 	int		base;
-	bool		has_debounce;
+	bool		has_irq;
 };
 
-#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _debounce)	\
+#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _has_irq)	\
 	{							\
 		.label		= _label,			\
 		.data		= _data,			\
 		.dir		= _dir,				\
 		.base		= _base,			\
-		.has_debounce	= _debounce,			\
+		.has_irq	= _has_irq,			\
 	}
 
 static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
-	EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true),
-	EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true),
+	EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true), /* Bank A has 8 IRQs */
+	EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true), /* Bank B has 8 IRQs */
 	EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false),
 	EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false),
 	EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false),
-	EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true),
+	EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true), /* Bank F has 8 IRQs */
 	EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false),
 	EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false),
 };
@@ -370,7 +370,7 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
 	gc->label = bank->label;
 	gc->base = bank->base;
 
-	if (bank->has_debounce) {
+	if (bank->has_irq) {
 		gc->set_config = ep93xx_gpio_set_config;
 		gc->to_irq = ep93xx_gpio_to_irq;
 	}
-- 
2.17.1

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

* [PATCH 06/11] gpio: ep93xx: Properly call the chained IRQ handler
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

The chained irq handler should call chained_irq_enter()
and chained_irq_exit() before/after handling the chained
IRQ.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index a81d1e796912..ce7e88df9cc5 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -88,9 +88,12 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 {
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned char status;
 	int i;
 
+	chained_irq_enter(irqchip, desc);
+
 	status = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
@@ -106,6 +109,8 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 			generic_handle_irq(gpio_irq);
 		}
 	}
+
+	chained_irq_exit(irqchip, desc);
 }
 
 static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
@@ -115,11 +120,14 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 	 *
 	 *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
 	 */
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned int irq = irq_desc_get_irq(desc);
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
 	int gpio_irq = gpio_to_irq(16) + port_f_idx;
 
+	chained_irq_enter(irqchip, desc);
 	generic_handle_irq(gpio_irq);
+	chained_irq_exit(irqchip, desc);
 }
 
 static void ep93xx_gpio_irq_ack(struct irq_data *d)
-- 
2.17.1

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

* [PATCH 06/11] gpio: ep93xx: Properly call the chained IRQ handler
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

The chained irq handler should call chained_irq_enter()
and chained_irq_exit() before/after handling the chained
IRQ.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index a81d1e796912..ce7e88df9cc5 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -88,9 +88,12 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 {
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned char status;
 	int i;
 
+	chained_irq_enter(irqchip, desc);
+
 	status = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
@@ -106,6 +109,8 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 			generic_handle_irq(gpio_irq);
 		}
 	}
+
+	chained_irq_exit(irqchip, desc);
 }
 
 static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
@@ -115,11 +120,14 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 	 *
 	 *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
 	 */
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned int irq = irq_desc_get_irq(desc);
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
 	int gpio_irq = gpio_to_irq(16) + port_f_idx;
 
+	chained_irq_enter(irqchip, desc);
 	generic_handle_irq(gpio_irq);
+	chained_irq_exit(irqchip, desc);
 }
 
 static void ep93xx_gpio_irq_ack(struct irq_data *d)
-- 
2.17.1

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

* [PATCH 07/11] gpio: ep93xx: Do not pingpong irq numbers
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

For setting debounce config we want to write an offset in
a per-gpiochip register, and we know which gpiochip we are
on. Instead of a roundtrip over the IRQ number, figure out
what port we are on for this GPIO chip, then index to the
right register and write the value.

This adds the ep93xx_gpio_port() that finds the port index
from a struct gpio_chip * that we can later exploit to
simplify more code.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index ce7e88df9cc5..3b235b25c028 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -68,12 +68,29 @@ static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, unsigned port
 	       epg->base + int_en_register_offset[port]);
 }
 
-static void ep93xx_gpio_int_debounce(struct ep93xx_gpio *epg,
-				     unsigned int irq, bool enable)
+static int ep93xx_gpio_port(struct gpio_chip *gc)
 {
-	int line = irq_to_gpio(irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+	int port = 0;
+
+	while (gc != &epg->gc[port] && port < sizeof(epg->gc))
+		port++;
+
+	/* This should not happen but is there as a last safeguard */
+	if (gc != &epg->gc[port]) {
+		pr_crit("can't find the GPIO port\n");
+		return 0;
+	}
+
+	return port;
+}
+
+static void ep93xx_gpio_int_debounce(struct gpio_chip *gc,
+				     unsigned int offset, bool enable)
+{
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+	int port = ep93xx_gpio_port(gc);
+	int port_mask = BIT(offset);
 
 	if (enable)
 		gpio_int_debounce[port] |= port_mask;
@@ -331,19 +348,13 @@ static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
 static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 				  unsigned long config)
 {
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int gpio = gc->base + offset;
-	int irq = gpio_to_irq(gpio);
 	u32 debounce;
 
 	if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
 		return -ENOTSUPP;
 
-	if (irq < 0)
-		return -EINVAL;
-
 	debounce = pinconf_to_config_argument(config);
-	ep93xx_gpio_int_debounce(epg, irq, debounce ? true : false);
+	ep93xx_gpio_int_debounce(gc, offset, debounce ? true : false);
 
 	return 0;
 }
-- 
2.17.1

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

* [PATCH 07/11] gpio: ep93xx: Do not pingpong irq numbers
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

For setting debounce config we want to write an offset in
a per-gpiochip register, and we know which gpiochip we are
on. Instead of a roundtrip over the IRQ number, figure out
what port we are on for this GPIO chip, then index to the
right register and write the value.

This adds the ep93xx_gpio_port() that finds the port index
from a struct gpio_chip * that we can later exploit to
simplify more code.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index ce7e88df9cc5..3b235b25c028 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -68,12 +68,29 @@ static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, unsigned port
 	       epg->base + int_en_register_offset[port]);
 }
 
-static void ep93xx_gpio_int_debounce(struct ep93xx_gpio *epg,
-				     unsigned int irq, bool enable)
+static int ep93xx_gpio_port(struct gpio_chip *gc)
 {
-	int line = irq_to_gpio(irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+	int port = 0;
+
+	while (gc != &epg->gc[port] && port < sizeof(epg->gc))
+		port++;
+
+	/* This should not happen but is there as a last safeguard */
+	if (gc != &epg->gc[port]) {
+		pr_crit("can't find the GPIO port\n");
+		return 0;
+	}
+
+	return port;
+}
+
+static void ep93xx_gpio_int_debounce(struct gpio_chip *gc,
+				     unsigned int offset, bool enable)
+{
+	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
+	int port = ep93xx_gpio_port(gc);
+	int port_mask = BIT(offset);
 
 	if (enable)
 		gpio_int_debounce[port] |= port_mask;
@@ -331,19 +348,13 @@ static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
 static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 				  unsigned long config)
 {
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int gpio = gc->base + offset;
-	int irq = gpio_to_irq(gpio);
 	u32 debounce;
 
 	if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
 		return -ENOTSUPP;
 
-	if (irq < 0)
-		return -EINVAL;
-
 	debounce = pinconf_to_config_argument(config);
-	ep93xx_gpio_int_debounce(epg, irq, debounce ? true : false);
+	ep93xx_gpio_int_debounce(gc, offset, debounce ? true : false);
 
 	return 0;
 }
-- 
2.17.1

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

* [PATCH 08/11] gpio: ep93xx: Use the hwirq and port
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

In the IRQ-related functions, switch to using the hwirq
and port number found from the current struct gpio_chip *

As the lower 3 bits of the IRQ number is identical to the
lower 3 bits of the GPIO number we can cut some corners.

Call directly into the gpiochip to set up the direction
and read the input instead of using the consumer API.

This enabled us to cut the confusing irq_to_gpio() macro
that is a remnant of the old generic GPIO API as well.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 3b235b25c028..b2139ec43ce2 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -16,11 +16,10 @@
 #include <linux/irq.h>
 #include <linux/slab.h>
 #include <linux/gpio/driver.h>
+#include <linux/bitops.h>
 /* FIXME: this is here for gpio_to_irq() - get rid of this! */
 #include <linux/gpio.h>
 
-#define irq_to_gpio(irq)	((irq) - gpio_to_irq(0))
-
 #define EP93XX_GPIO_F_INT_STATUS 0x5c
 #define EP93XX_GPIO_A_INT_STATUS 0xa0
 #define EP93XX_GPIO_B_INT_STATUS 0xbc
@@ -151,9 +150,8 @@ static void ep93xx_gpio_irq_ack(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int line = irq_to_gpio(d->irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
+	int port = ep93xx_gpio_port(gc);
+	int port_mask = BIT(d->irq & 7);
 
 	if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
@@ -167,9 +165,8 @@ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int line = irq_to_gpio(d->irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
+	int port = ep93xx_gpio_port(gc);
+	int port_mask = BIT(d->irq & 7);
 
 	if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH)
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
@@ -184,10 +181,9 @@ static void ep93xx_gpio_irq_mask(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int line = irq_to_gpio(d->irq);
-	int port = line >> 3;
+	int port = ep93xx_gpio_port(gc);
 
-	gpio_int_unmasked[port] &= ~(1 << (line & 7));
+	gpio_int_unmasked[port] &= ~BIT(d->irq & 7);
 	ep93xx_gpio_update_int_params(epg, port);
 }
 
@@ -195,10 +191,9 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int line = irq_to_gpio(d->irq);
-	int port = line >> 3;
+	int port = ep93xx_gpio_port(gc);
 
-	gpio_int_unmasked[port] |= 1 << (line & 7);
+	gpio_int_unmasked[port] |= BIT(d->irq & 7);
 	ep93xx_gpio_update_int_params(epg, port);
 }
 
@@ -211,12 +206,12 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	const int gpio = irq_to_gpio(d->irq);
-	const int port = gpio >> 3;
-	const int port_mask = 1 << (gpio & 7);
+	int port = ep93xx_gpio_port(gc);
+	int offset = d->irq & 7;
+	int port_mask = BIT(offset);
 	irq_flow_handler_t handler;
 
-	gpio_direction_input(gpio);
+	gc->direction_input(gc, offset);
 
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -242,7 +237,7 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 	case IRQ_TYPE_EDGE_BOTH:
 		gpio_int_type1[port] |= port_mask;
 		/* set initial polarity based on current input level */
-		if (gpio_get_value(gpio))
+		if (gc->get(gc, offset))
 			gpio_int_type2[port] &= ~port_mask; /* falling */
 		else
 			gpio_int_type2[port] |= port_mask; /* rising */
-- 
2.17.1

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

* [PATCH 08/11] gpio: ep93xx: Use the hwirq and port
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

In the IRQ-related functions, switch to using the hwirq
and port number found from the current struct gpio_chip *

As the lower 3 bits of the IRQ number is identical to the
lower 3 bits of the GPIO number we can cut some corners.

Call directly into the gpiochip to set up the direction
and read the input instead of using the consumer API.

This enabled us to cut the confusing irq_to_gpio() macro
that is a remnant of the old generic GPIO API as well.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 3b235b25c028..b2139ec43ce2 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -16,11 +16,10 @@
 #include <linux/irq.h>
 #include <linux/slab.h>
 #include <linux/gpio/driver.h>
+#include <linux/bitops.h>
 /* FIXME: this is here for gpio_to_irq() - get rid of this! */
 #include <linux/gpio.h>
 
-#define irq_to_gpio(irq)	((irq) - gpio_to_irq(0))
-
 #define EP93XX_GPIO_F_INT_STATUS 0x5c
 #define EP93XX_GPIO_A_INT_STATUS 0xa0
 #define EP93XX_GPIO_B_INT_STATUS 0xbc
@@ -151,9 +150,8 @@ static void ep93xx_gpio_irq_ack(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int line = irq_to_gpio(d->irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
+	int port = ep93xx_gpio_port(gc);
+	int port_mask = BIT(d->irq & 7);
 
 	if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
@@ -167,9 +165,8 @@ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int line = irq_to_gpio(d->irq);
-	int port = line >> 3;
-	int port_mask = 1 << (line & 7);
+	int port = ep93xx_gpio_port(gc);
+	int port_mask = BIT(d->irq & 7);
 
 	if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH)
 		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
@@ -184,10 +181,9 @@ static void ep93xx_gpio_irq_mask(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int line = irq_to_gpio(d->irq);
-	int port = line >> 3;
+	int port = ep93xx_gpio_port(gc);
 
-	gpio_int_unmasked[port] &= ~(1 << (line & 7));
+	gpio_int_unmasked[port] &= ~BIT(d->irq & 7);
 	ep93xx_gpio_update_int_params(epg, port);
 }
 
@@ -195,10 +191,9 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int line = irq_to_gpio(d->irq);
-	int port = line >> 3;
+	int port = ep93xx_gpio_port(gc);
 
-	gpio_int_unmasked[port] |= 1 << (line & 7);
+	gpio_int_unmasked[port] |= BIT(d->irq & 7);
 	ep93xx_gpio_update_int_params(epg, port);
 }
 
@@ -211,12 +206,12 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	const int gpio = irq_to_gpio(d->irq);
-	const int port = gpio >> 3;
-	const int port_mask = 1 << (gpio & 7);
+	int port = ep93xx_gpio_port(gc);
+	int offset = d->irq & 7;
+	int port_mask = BIT(offset);
 	irq_flow_handler_t handler;
 
-	gpio_direction_input(gpio);
+	gc->direction_input(gc, offset);
 
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -242,7 +237,7 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 	case IRQ_TYPE_EDGE_BOTH:
 		gpio_int_type1[port] |= port_mask;
 		/* set initial polarity based on current input level */
-		if (gpio_get_value(gpio))
+		if (gc->get(gc, offset))
 			gpio_int_type2[port] &= ~port_mask; /* falling */
 		else
 			gpio_int_type2[port] |= port_mask; /* rising */
-- 
2.17.1

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

* [PATCH 09/11] gpio: ep93xx: Use for_each_set_bit() in IRQ handler
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

This simplifies and standardizes the AB IRQ handler by using
the for_each_set_bit() library function.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index b2139ec43ce2..1248d83f860b 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -105,25 +105,21 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
-	unsigned char status;
-	int i;
+	unsigned long stat;
+	int offset;
 
 	chained_irq_enter(irqchip, desc);
 
-	status = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
-	for (i = 0; i < 8; i++) {
-		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(0) + i;
-			generic_handle_irq(gpio_irq);
-		}
+	stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
+	for_each_set_bit(offset, &stat, 8) {
+		int gpio_irq = gpio_to_irq(0) + offset;
+		generic_handle_irq(gpio_irq);
 	}
 
-	status = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
-	for (i = 0; i < 8; i++) {
-		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(8) + i;
-			generic_handle_irq(gpio_irq);
-		}
+	stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
+	for_each_set_bit(offset, &stat, 8) {
+		int gpio_irq = gpio_to_irq(8) + offset;
+		generic_handle_irq(gpio_irq);
 	}
 
 	chained_irq_exit(irqchip, desc);
-- 
2.17.1

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

* [PATCH 09/11] gpio: ep93xx: Use for_each_set_bit() in IRQ handler
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

This simplifies and standardizes the AB IRQ handler by using
the for_each_set_bit() library function.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index b2139ec43ce2..1248d83f860b 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -105,25 +105,21 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
-	unsigned char status;
-	int i;
+	unsigned long stat;
+	int offset;
 
 	chained_irq_enter(irqchip, desc);
 
-	status = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
-	for (i = 0; i < 8; i++) {
-		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(0) + i;
-			generic_handle_irq(gpio_irq);
-		}
+	stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
+	for_each_set_bit(offset, &stat, 8) {
+		int gpio_irq = gpio_to_irq(0) + offset;
+		generic_handle_irq(gpio_irq);
 	}
 
-	status = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
-	for (i = 0; i < 8; i++) {
-		if (status & (1 << i)) {
-			int gpio_irq = gpio_to_irq(8) + i;
-			generic_handle_irq(gpio_irq);
-		}
+	stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
+	for_each_set_bit(offset, &stat, 8) {
+		int gpio_irq = gpio_to_irq(8) + offset;
+		generic_handle_irq(gpio_irq);
 	}
 
 	chained_irq_exit(irqchip, desc);
-- 
2.17.1

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

* [PATCH 10/11] gpio: ep93xx: Cut gpio_to_irq() usage
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

This removes the callback into the gpiolib creating a
circular call to convert between GPIO numbers and IRQs
and pushes the whole business into the driver, just
using an array of IRQ bases for the three IRQ capable
ports.

This way we get rid of including <linux/gpio.h> that
no driver should include.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 48 +++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 1248d83f860b..d45d8ac3b525 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -17,8 +17,6 @@
 #include <linux/slab.h>
 #include <linux/gpio/driver.h>
 #include <linux/bitops.h>
-/* FIXME: this is here for gpio_to_irq() - get rid of this! */
-#include <linux/gpio.h>
 
 #define EP93XX_GPIO_F_INT_STATUS 0x5c
 #define EP93XX_GPIO_A_INT_STATUS 0xa0
@@ -30,6 +28,15 @@
 /* Maximum value for irq capable line identifiers */
 #define EP93XX_GPIO_LINE_MAX_IRQ 23
 
+/*
+ * IRQ numbers used by this driver is 64 ..87
+ *
+ * Map GPIO A0..A7  (0..7)  to irq 64..71,
+ *          B0..B7  (7..15) to irq 72..79, and
+ *          F0..F7 (16..24) to irq 80..87.
+ */
+static unsigned int ep93xx_gpio_irq_base[3] = { 64, 72, 80 };
+
 struct ep93xx_gpio {
 	void __iomem		*base;
 	struct gpio_chip	gc[8];
@@ -112,13 +119,13 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 
 	stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
 	for_each_set_bit(offset, &stat, 8) {
-		int gpio_irq = gpio_to_irq(0) + offset;
+		int gpio_irq = ep93xx_gpio_irq_base[0] + offset;
 		generic_handle_irq(gpio_irq);
 	}
 
 	stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
 	for_each_set_bit(offset, &stat, 8) {
-		int gpio_irq = gpio_to_irq(8) + offset;
+		int gpio_irq = ep93xx_gpio_irq_base[1] + offset;
 		generic_handle_irq(gpio_irq);
 	}
 
@@ -130,12 +137,12 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 	/*
 	 * map discontiguous hw irq range to continuous sw irq range:
 	 *
-	 *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
+	 *  IRQ_EP93XX_GPIO{0..7}MUX -> EP93XX_GPIO_LINE_F{0..7}
 	 */
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned int irq = irq_desc_get_irq(desc);
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
-	int gpio_irq = gpio_to_irq(16) + port_f_idx;
+	int gpio_irq = ep93xx_gpio_irq_base[2] + port_f_idx;
 
 	chained_irq_enter(irqchip, desc);
 	generic_handle_irq(gpio_irq);
@@ -268,27 +275,24 @@ static void ep93xx_gpio_init_irq(struct platform_device *pdev,
 	int i;
 
 	/* The A bank */
-	for (gpio_irq = gpio_to_irq(0);
-	     gpio_irq < gpio_to_irq(8);
-	     gpio_irq++) {
+	for (i = 0; i < 8; i++) {
+		gpio_irq = ep93xx_gpio_irq_base[0] + i;
 		irq_set_chip_data(gpio_irq, &epg->gc[0]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 	/* The B bank */
-	for (gpio_irq = gpio_to_irq(8);
-	     gpio_irq < gpio_to_irq(16);
-	     gpio_irq++) {
+	for (i = 0; i < 8; i++) {
+		gpio_irq = ep93xx_gpio_irq_base[1] + i;
 		irq_set_chip_data(gpio_irq, &epg->gc[1]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 	/* The F bank */
-	for (gpio_irq = gpio_to_irq(16);
-	     gpio_irq < gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ);
-	     gpio_irq++) {
+	for (i = 0; i < 8; i++) {
+		gpio_irq = ep93xx_gpio_irq_base[2] + i;
 		irq_set_chip_data(gpio_irq, &epg->gc[5]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
@@ -350,19 +354,15 @@ static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 	return 0;
 }
 
-/*
- * Map GPIO A0..A7  (0..7)  to irq 64..71,
- *          B0..B7  (7..15) to irq 72..79, and
- *          F0..F7 (16..24) to irq 80..87.
- */
-static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+static int ep93xx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 {
-	int gpio = chip->base + offset;
+	int port = ep93xx_gpio_port(gc);
 
-	if (gpio > EP93XX_GPIO_LINE_MAX_IRQ)
+	/* Those are the ports supporting IRQ */
+	if (port != 0 && port != 1 && port != 5)
 		return -EINVAL;
 
-	return 64 + gpio;
+	return ep93xx_gpio_irq_base[port] + offset;
 }
 
 static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
-- 
2.17.1

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

* [PATCH 10/11] gpio: ep93xx: Cut gpio_to_irq() usage
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

This removes the callback into the gpiolib creating a
circular call to convert between GPIO numbers and IRQs
and pushes the whole business into the driver, just
using an array of IRQ bases for the three IRQ capable
ports.

This way we get rid of including <linux/gpio.h> that
no driver should include.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-ep93xx.c | 48 +++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 1248d83f860b..d45d8ac3b525 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -17,8 +17,6 @@
 #include <linux/slab.h>
 #include <linux/gpio/driver.h>
 #include <linux/bitops.h>
-/* FIXME: this is here for gpio_to_irq() - get rid of this! */
-#include <linux/gpio.h>
 
 #define EP93XX_GPIO_F_INT_STATUS 0x5c
 #define EP93XX_GPIO_A_INT_STATUS 0xa0
@@ -30,6 +28,15 @@
 /* Maximum value for irq capable line identifiers */
 #define EP93XX_GPIO_LINE_MAX_IRQ 23
 
+/*
+ * IRQ numbers used by this driver is 64 ..87
+ *
+ * Map GPIO A0..A7  (0..7)  to irq 64..71,
+ *          B0..B7  (7..15) to irq 72..79, and
+ *          F0..F7 (16..24) to irq 80..87.
+ */
+static unsigned int ep93xx_gpio_irq_base[3] = { 64, 72, 80 };
+
 struct ep93xx_gpio {
 	void __iomem		*base;
 	struct gpio_chip	gc[8];
@@ -112,13 +119,13 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 
 	stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
 	for_each_set_bit(offset, &stat, 8) {
-		int gpio_irq = gpio_to_irq(0) + offset;
+		int gpio_irq = ep93xx_gpio_irq_base[0] + offset;
 		generic_handle_irq(gpio_irq);
 	}
 
 	stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
 	for_each_set_bit(offset, &stat, 8) {
-		int gpio_irq = gpio_to_irq(8) + offset;
+		int gpio_irq = ep93xx_gpio_irq_base[1] + offset;
 		generic_handle_irq(gpio_irq);
 	}
 
@@ -130,12 +137,12 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 	/*
 	 * map discontiguous hw irq range to continuous sw irq range:
 	 *
-	 *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
+	 *  IRQ_EP93XX_GPIO{0..7}MUX -> EP93XX_GPIO_LINE_F{0..7}
 	 */
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned int irq = irq_desc_get_irq(desc);
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
-	int gpio_irq = gpio_to_irq(16) + port_f_idx;
+	int gpio_irq = ep93xx_gpio_irq_base[2] + port_f_idx;
 
 	chained_irq_enter(irqchip, desc);
 	generic_handle_irq(gpio_irq);
@@ -268,27 +275,24 @@ static void ep93xx_gpio_init_irq(struct platform_device *pdev,
 	int i;
 
 	/* The A bank */
-	for (gpio_irq = gpio_to_irq(0);
-	     gpio_irq < gpio_to_irq(8);
-	     gpio_irq++) {
+	for (i = 0; i < 8; i++) {
+		gpio_irq = ep93xx_gpio_irq_base[0] + i;
 		irq_set_chip_data(gpio_irq, &epg->gc[0]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 	/* The B bank */
-	for (gpio_irq = gpio_to_irq(8);
-	     gpio_irq < gpio_to_irq(16);
-	     gpio_irq++) {
+	for (i = 0; i < 8; i++) {
+		gpio_irq = ep93xx_gpio_irq_base[1] + i;
 		irq_set_chip_data(gpio_irq, &epg->gc[1]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 	/* The F bank */
-	for (gpio_irq = gpio_to_irq(16);
-	     gpio_irq < gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ);
-	     gpio_irq++) {
+	for (i = 0; i < 8; i++) {
+		gpio_irq = ep93xx_gpio_irq_base[2] + i;
 		irq_set_chip_data(gpio_irq, &epg->gc[5]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
@@ -350,19 +354,15 @@ static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 	return 0;
 }
 
-/*
- * Map GPIO A0..A7  (0..7)  to irq 64..71,
- *          B0..B7  (7..15) to irq 72..79, and
- *          F0..F7 (16..24) to irq 80..87.
- */
-static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+static int ep93xx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 {
-	int gpio = chip->base + offset;
+	int port = ep93xx_gpio_port(gc);
 
-	if (gpio > EP93XX_GPIO_LINE_MAX_IRQ)
+	/* Those are the ports supporting IRQ */
+	if (port != 0 && port != 1 && port != 5)
 		return -EINVAL;
 
-	return 64 + gpio;
+	return ep93xx_gpio_irq_base[port] + offset;
 }
 
 static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
-- 
2.17.1

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

* [PATCH 11/11] gpio: ep93xx: Switch A and B to use GPIOLIB_IRQCHIP
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-22 20:41   ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: H Hartley Sweeten, Alexander Sverdlin
  Cc: linux-gpio, Linus Walleij, linux-arm-kernel

We can quite easily switch banks/ports A and B to use
GPIOLIB_IRQCHIP which is code that will be more careful
about handling interrupt descriptors and use a proper
irqdomain for translating the IRQs. This cuts down some
code in favor of using the implementation inside
gpiolib.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/Kconfig       |  1 +
 drivers/gpio/gpio-ep93xx.c | 95 ++++++++++++++++++++------------------
 2 files changed, 51 insertions(+), 45 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 71c0ab46f216..afcd94613017 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -200,6 +200,7 @@ config GPIO_EP93XX
 	def_bool y
 	depends on ARCH_EP93XX
 	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
 
 config GPIO_EXAR
 	tristate "Support for GPIO pins on XR17V352/354/358"
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index d45d8ac3b525..68a416fc3141 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -29,13 +29,10 @@
 #define EP93XX_GPIO_LINE_MAX_IRQ 23
 
 /*
- * IRQ numbers used by this driver is 64 ..87
- *
- * Map GPIO A0..A7  (0..7)  to irq 64..71,
- *          B0..B7  (7..15) to irq 72..79, and
- *          F0..F7 (16..24) to irq 80..87.
+ * Static mapping of GPIO bank F IRQS:
+ * F0..F7 (16..24) to irq 80..87.
  */
-static unsigned int ep93xx_gpio_irq_base[3] = { 64, 72, 80 };
+#define EP93XX_GPIO_F_IRQ_BASE 80
 
 struct ep93xx_gpio {
 	void __iomem		*base;
@@ -117,17 +114,21 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 
 	chained_irq_enter(irqchip, desc);
 
+	/*
+	 * Dispatch the IRQs to the irqdomain of each A and B
+	 * gpiochip irqdomains depending on what has fired.
+	 * The tricky part is that the IRQ line is shared
+	 * between bank A and B and each has their own gpiochip.
+	 */
 	stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
-	for_each_set_bit(offset, &stat, 8) {
-		int gpio_irq = ep93xx_gpio_irq_base[0] + offset;
-		generic_handle_irq(gpio_irq);
-	}
+	for_each_set_bit(offset, &stat, 8)
+		generic_handle_irq(irq_find_mapping(epg->gc[0].irq.domain,
+						    offset));
 
 	stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
-	for_each_set_bit(offset, &stat, 8) {
-		int gpio_irq = ep93xx_gpio_irq_base[1] + offset;
-		generic_handle_irq(gpio_irq);
-	}
+	for_each_set_bit(offset, &stat, 8)
+		generic_handle_irq(irq_find_mapping(epg->gc[1].irq.domain,
+						    offset));
 
 	chained_irq_exit(irqchip, desc);
 }
@@ -142,7 +143,7 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned int irq = irq_desc_get_irq(desc);
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
-	int gpio_irq = ep93xx_gpio_irq_base[2] + port_f_idx;
+	int gpio_irq = EP93XX_GPIO_F_IRQ_BASE + port_f_idx;
 
 	chained_irq_enter(irqchip, desc);
 	generic_handle_irq(gpio_irq);
@@ -268,44 +269,53 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
 	.irq_set_type	= ep93xx_gpio_irq_type,
 };
 
-static void ep93xx_gpio_init_irq(struct platform_device *pdev,
-				 struct ep93xx_gpio *epg)
+static int ep93xx_gpio_init_irq(struct platform_device *pdev,
+				struct ep93xx_gpio *epg)
 {
+	int ab_parent_irq = platform_get_irq(pdev, 0);
+	struct device *dev = &pdev->dev;
 	int gpio_irq;
+	int ret;
 	int i;
 
 	/* The A bank */
-	for (i = 0; i < 8; i++) {
-		gpio_irq = ep93xx_gpio_irq_base[0] + i;
-		irq_set_chip_data(gpio_irq, &epg->gc[0]);
-		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
-					 handle_level_irq);
-		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+	ret = gpiochip_irqchip_add(&epg->gc[0], &ep93xx_gpio_irq_chip,
+                                   64, handle_level_irq,
+                                   IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(dev, "Could not add irqchip 0\n");
+		return ret;
 	}
+	gpiochip_set_chained_irqchip(&epg->gc[0], &ep93xx_gpio_irq_chip,
+				     ab_parent_irq,
+				     ep93xx_gpio_ab_irq_handler);
+
 	/* The B bank */
-	for (i = 0; i < 8; i++) {
-		gpio_irq = ep93xx_gpio_irq_base[1] + i;
-		irq_set_chip_data(gpio_irq, &epg->gc[1]);
-		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
-					 handle_level_irq);
-		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+	ret = gpiochip_irqchip_add(&epg->gc[1], &ep93xx_gpio_irq_chip,
+                                   72, handle_level_irq,
+                                   IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(dev, "Could not add irqchip 1\n");
+		return ret;
 	}
+	gpiochip_set_chained_irqchip(&epg->gc[1], &ep93xx_gpio_irq_chip,
+				     ab_parent_irq,
+				     ep93xx_gpio_ab_irq_handler);
+
 	/* The F bank */
 	for (i = 0; i < 8; i++) {
-		gpio_irq = ep93xx_gpio_irq_base[2] + i;
+		gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i;
 		irq_set_chip_data(gpio_irq, &epg->gc[5]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 
-	irq_set_chained_handler_and_data(platform_get_irq(pdev, 0),
-					 ep93xx_gpio_ab_irq_handler,
-					 &epg->gc[0]);
 	for (i = 1; i <= 8; i++)
 		irq_set_chained_handler_and_data(platform_get_irq(pdev, i),
 						 ep93xx_gpio_f_irq_handler,
 						 &epg->gc[i]);
+	return 0;
 }
 
 
@@ -354,15 +364,9 @@ static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 	return 0;
 }
 
-static int ep93xx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+static int ep93xx_gpio_f_to_irq(struct gpio_chip *gc, unsigned offset)
 {
-	int port = ep93xx_gpio_port(gc);
-
-	/* Those are the ports supporting IRQ */
-	if (port != 0 && port != 1 && port != 5)
-		return -EINVAL;
-
-	return ep93xx_gpio_irq_base[port] + offset;
+	return EP93XX_GPIO_F_IRQ_BASE + offset;
 }
 
 static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
@@ -380,10 +384,8 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
 	gc->label = bank->label;
 	gc->base = bank->base;
 
-	if (bank->has_irq) {
+	if (bank->has_irq)
 		gc->set_config = ep93xx_gpio_set_config;
-		gc->to_irq = ep93xx_gpio_to_irq;
-	}
 
 	return devm_gpiochip_add_data(dev, gc, epg);
 }
@@ -410,7 +412,10 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
 
 		if (ep93xx_gpio_add_bank(gc, &pdev->dev, epg, bank))
 			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
-				bank->label);
+				 bank->label);
+		/* Only bank F has especially funky IRQ handling */
+		if (i == 5)
+			gc->to_irq = ep93xx_gpio_f_to_irq;
 	}
 
 	ep93xx_gpio_init_irq(pdev, epg);
-- 
2.17.1

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

* [PATCH 11/11] gpio: ep93xx: Switch A and B to use GPIOLIB_IRQCHIP
@ 2018-08-22 20:41   ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-22 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

We can quite easily switch banks/ports A and B to use
GPIOLIB_IRQCHIP which is code that will be more careful
about handling interrupt descriptors and use a proper
irqdomain for translating the IRQs. This cuts down some
code in favor of using the implementation inside
gpiolib.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/Kconfig       |  1 +
 drivers/gpio/gpio-ep93xx.c | 95 ++++++++++++++++++++------------------
 2 files changed, 51 insertions(+), 45 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 71c0ab46f216..afcd94613017 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -200,6 +200,7 @@ config GPIO_EP93XX
 	def_bool y
 	depends on ARCH_EP93XX
 	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
 
 config GPIO_EXAR
 	tristate "Support for GPIO pins on XR17V352/354/358"
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index d45d8ac3b525..68a416fc3141 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -29,13 +29,10 @@
 #define EP93XX_GPIO_LINE_MAX_IRQ 23
 
 /*
- * IRQ numbers used by this driver is 64 ..87
- *
- * Map GPIO A0..A7  (0..7)  to irq 64..71,
- *          B0..B7  (7..15) to irq 72..79, and
- *          F0..F7 (16..24) to irq 80..87.
+ * Static mapping of GPIO bank F IRQS:
+ * F0..F7 (16..24) to irq 80..87.
  */
-static unsigned int ep93xx_gpio_irq_base[3] = { 64, 72, 80 };
+#define EP93XX_GPIO_F_IRQ_BASE 80
 
 struct ep93xx_gpio {
 	void __iomem		*base;
@@ -117,17 +114,21 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 
 	chained_irq_enter(irqchip, desc);
 
+	/*
+	 * Dispatch the IRQs to the irqdomain of each A and B
+	 * gpiochip irqdomains depending on what has fired.
+	 * The tricky part is that the IRQ line is shared
+	 * between bank A and B and each has their own gpiochip.
+	 */
 	stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
-	for_each_set_bit(offset, &stat, 8) {
-		int gpio_irq = ep93xx_gpio_irq_base[0] + offset;
-		generic_handle_irq(gpio_irq);
-	}
+	for_each_set_bit(offset, &stat, 8)
+		generic_handle_irq(irq_find_mapping(epg->gc[0].irq.domain,
+						    offset));
 
 	stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
-	for_each_set_bit(offset, &stat, 8) {
-		int gpio_irq = ep93xx_gpio_irq_base[1] + offset;
-		generic_handle_irq(gpio_irq);
-	}
+	for_each_set_bit(offset, &stat, 8)
+		generic_handle_irq(irq_find_mapping(epg->gc[1].irq.domain,
+						    offset));
 
 	chained_irq_exit(irqchip, desc);
 }
@@ -142,7 +143,7 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned int irq = irq_desc_get_irq(desc);
 	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
-	int gpio_irq = ep93xx_gpio_irq_base[2] + port_f_idx;
+	int gpio_irq = EP93XX_GPIO_F_IRQ_BASE + port_f_idx;
 
 	chained_irq_enter(irqchip, desc);
 	generic_handle_irq(gpio_irq);
@@ -268,44 +269,53 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
 	.irq_set_type	= ep93xx_gpio_irq_type,
 };
 
-static void ep93xx_gpio_init_irq(struct platform_device *pdev,
-				 struct ep93xx_gpio *epg)
+static int ep93xx_gpio_init_irq(struct platform_device *pdev,
+				struct ep93xx_gpio *epg)
 {
+	int ab_parent_irq = platform_get_irq(pdev, 0);
+	struct device *dev = &pdev->dev;
 	int gpio_irq;
+	int ret;
 	int i;
 
 	/* The A bank */
-	for (i = 0; i < 8; i++) {
-		gpio_irq = ep93xx_gpio_irq_base[0] + i;
-		irq_set_chip_data(gpio_irq, &epg->gc[0]);
-		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
-					 handle_level_irq);
-		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+	ret = gpiochip_irqchip_add(&epg->gc[0], &ep93xx_gpio_irq_chip,
+                                   64, handle_level_irq,
+                                   IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(dev, "Could not add irqchip 0\n");
+		return ret;
 	}
+	gpiochip_set_chained_irqchip(&epg->gc[0], &ep93xx_gpio_irq_chip,
+				     ab_parent_irq,
+				     ep93xx_gpio_ab_irq_handler);
+
 	/* The B bank */
-	for (i = 0; i < 8; i++) {
-		gpio_irq = ep93xx_gpio_irq_base[1] + i;
-		irq_set_chip_data(gpio_irq, &epg->gc[1]);
-		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
-					 handle_level_irq);
-		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+	ret = gpiochip_irqchip_add(&epg->gc[1], &ep93xx_gpio_irq_chip,
+                                   72, handle_level_irq,
+                                   IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(dev, "Could not add irqchip 1\n");
+		return ret;
 	}
+	gpiochip_set_chained_irqchip(&epg->gc[1], &ep93xx_gpio_irq_chip,
+				     ab_parent_irq,
+				     ep93xx_gpio_ab_irq_handler);
+
 	/* The F bank */
 	for (i = 0; i < 8; i++) {
-		gpio_irq = ep93xx_gpio_irq_base[2] + i;
+		gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i;
 		irq_set_chip_data(gpio_irq, &epg->gc[5]);
 		irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
 					 handle_level_irq);
 		irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
 	}
 
-	irq_set_chained_handler_and_data(platform_get_irq(pdev, 0),
-					 ep93xx_gpio_ab_irq_handler,
-					 &epg->gc[0]);
 	for (i = 1; i <= 8; i++)
 		irq_set_chained_handler_and_data(platform_get_irq(pdev, i),
 						 ep93xx_gpio_f_irq_handler,
 						 &epg->gc[i]);
+	return 0;
 }
 
 
@@ -354,15 +364,9 @@ static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 	return 0;
 }
 
-static int ep93xx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+static int ep93xx_gpio_f_to_irq(struct gpio_chip *gc, unsigned offset)
 {
-	int port = ep93xx_gpio_port(gc);
-
-	/* Those are the ports supporting IRQ */
-	if (port != 0 && port != 1 && port != 5)
-		return -EINVAL;
-
-	return ep93xx_gpio_irq_base[port] + offset;
+	return EP93XX_GPIO_F_IRQ_BASE + offset;
 }
 
 static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
@@ -380,10 +384,8 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
 	gc->label = bank->label;
 	gc->base = bank->base;
 
-	if (bank->has_irq) {
+	if (bank->has_irq)
 		gc->set_config = ep93xx_gpio_set_config;
-		gc->to_irq = ep93xx_gpio_to_irq;
-	}
 
 	return devm_gpiochip_add_data(dev, gc, epg);
 }
@@ -410,7 +412,10 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
 
 		if (ep93xx_gpio_add_bank(gc, &pdev->dev, epg, bank))
 			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
-				bank->label);
+				 bank->label);
+		/* Only bank F has especially funky IRQ handling */
+		if (i == 5)
+			gc->to_irq = ep93xx_gpio_f_to_irq;
 	}
 
 	ep93xx_gpio_init_irq(pdev, epg);
-- 
2.17.1

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

* Re: [PATCH 01/11] ARM/gpio: ep93xx: build standalone
  2018-08-22 20:41   ` Linus Walleij
@ 2018-08-23  7:36     ` Arnd Bergmann
  -1 siblings, 0 replies; 34+ messages in thread
From: Arnd Bergmann @ 2018-08-23  7:36 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Hartley Sweeten, arm-soc, Alexander Sverdlin, Linux ARM,
	open list:GPIO SUBSYSTEM

On Wed, Aug 22, 2018 at 10:41 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> From: Arnd Bergmann <arnd@arndb.de>
>
> As a preparation for multiplatform support, this ensures
> that the ep93xx gpio driver can be built without any of
> the platform specific header files. We pass the IRQ numbers
> as a resource now, and use the virtual mmio base from the
> already existing resource, rather than relying on the
> hardwired virtual address from the header file.
>
> Some numbers are now hardcoded that came from macros
> in the past, but for all I can tell, the driver already
> relied on the specific values.
>
> Cc: arm@kernel.org
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Arnd/other ARM SoC person:
> Please provide an ACK for this patch so I can merge it
> with the rest of the refactorings into the GPIO tree.

Acked-by: Arnd Bergmann <arnd@arndb.de>

Did I send the patch to you, or did you find it in old archives?

Normally I'd assume that my authorship implies the Ack,
but I guess it's ok to also explictly say that I'm ok with this
going through your tree.

       Arnd

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

* [PATCH 01/11] ARM/gpio: ep93xx: build standalone
@ 2018-08-23  7:36     ` Arnd Bergmann
  0 siblings, 0 replies; 34+ messages in thread
From: Arnd Bergmann @ 2018-08-23  7:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 22, 2018 at 10:41 PM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> From: Arnd Bergmann <arnd@arndb.de>
>
> As a preparation for multiplatform support, this ensures
> that the ep93xx gpio driver can be built without any of
> the platform specific header files. We pass the IRQ numbers
> as a resource now, and use the virtual mmio base from the
> already existing resource, rather than relying on the
> hardwired virtual address from the header file.
>
> Some numbers are now hardcoded that came from macros
> in the past, but for all I can tell, the driver already
> relied on the specific values.
>
> Cc: arm at kernel.org
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Arnd/other ARM SoC person:
> Please provide an ACK for this patch so I can merge it
> with the rest of the refactorings into the GPIO tree.

Acked-by: Arnd Bergmann <arnd@arndb.de>

Did I send the patch to you, or did you find it in old archives?

Normally I'd assume that my authorship implies the Ack,
but I guess it's ok to also explictly say that I'm ok with this
going through your tree.

       Arnd

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

* Re: [PATCH 01/11] ARM/gpio: ep93xx: build standalone
  2018-08-22 20:41   ` Linus Walleij
@ 2018-08-24 15:51     ` Olof Johansson
  -1 siblings, 0 replies; 34+ messages in thread
From: Olof Johansson @ 2018-08-24 15:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Arnd Bergmann, linux-gpio, H Hartley Sweeten, arm,
	Alexander Sverdlin, linux-arm-kernel

On Wed, Aug 22, 2018 at 10:41:01PM +0200, Linus Walleij wrote:
> From: Arnd Bergmann <arnd@arndb.de>
> 
> As a preparation for multiplatform support, this ensures
> that the ep93xx gpio driver can be built without any of
> the platform specific header files. We pass the IRQ numbers
> as a resource now, and use the virtual mmio base from the
> already existing resource, rather than relying on the
> hardwired virtual address from the header file.
> 
> Some numbers are now hardcoded that came from macros
> in the past, but for all I can tell, the driver already
> relied on the specific values.
> 
> Cc: arm@kernel.org
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Arnd/other ARM SoC person:
> Please provide an ACK for this patch so I can merge it
> with the rest of the refactorings into the GPIO tree.

Acked-by: Olof Johansson <olof@lixom.net>

(As Arnd said, isn't really needed but here's a redundant one anyway. :)


-Olof

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

* [PATCH 01/11] ARM/gpio: ep93xx: build standalone
@ 2018-08-24 15:51     ` Olof Johansson
  0 siblings, 0 replies; 34+ messages in thread
From: Olof Johansson @ 2018-08-24 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 22, 2018 at 10:41:01PM +0200, Linus Walleij wrote:
> From: Arnd Bergmann <arnd@arndb.de>
> 
> As a preparation for multiplatform support, this ensures
> that the ep93xx gpio driver can be built without any of
> the platform specific header files. We pass the IRQ numbers
> as a resource now, and use the virtual mmio base from the
> already existing resource, rather than relying on the
> hardwired virtual address from the header file.
> 
> Some numbers are now hardcoded that came from macros
> in the past, but for all I can tell, the driver already
> relied on the specific values.
> 
> Cc: arm at kernel.org
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Arnd/other ARM SoC person:
> Please provide an ACK for this patch so I can merge it
> with the rest of the refactorings into the GPIO tree.

Acked-by: Olof Johansson <olof@lixom.net>

(As Arnd said, isn't really needed but here's a redundant one anyway. :)


-Olof

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

* Re: [PATCH 02/11] gpio: ep93xx: Cut down variable names
  2018-08-22 20:41   ` Linus Walleij
@ 2018-08-29  5:56     ` Alexander Sverdlin
  -1 siblings, 0 replies; 34+ messages in thread
From: Alexander Sverdlin @ 2018-08-29  5:56 UTC (permalink / raw)
  To: Linus Walleij; +Cc: H Hartley Sweeten, linux-arm-kernel, linux-gpio

Hi!

On Wed, 22 Aug 2018 22:41:02 +0200
Linus Walleij <linus.walleij@linaro.org> wrote:

> In order to clean up the driver I need to cut a few trees,
> sorry, variable names, so I can see the forest, sorry driver
> properly.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>

> ---
>  drivers/gpio/gpio-ep93xx.c | 26 +++++++++++++-------------
>  1 file changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
> index 654525d6a9f1..3bfd0e46f7ed 100644
> --- a/drivers/gpio/gpio-ep93xx.c
> +++ b/drivers/gpio/gpio-ep93xx.c
> @@ -37,7 +37,7 @@ void __iomem *ep93xx_gpio_base; /* FIXME: put this into irq_data */
>  #define EP93XX_GPIO_LINE_MAX_IRQ 23
>  
>  struct ep93xx_gpio {
> -	void __iomem		*mmio_base;
> +	void __iomem		*base;
>  	struct gpio_chip	gc[8];
>  };
>  
> @@ -323,10 +323,10 @@ static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
>  }
>  
>  static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
> -	void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
> +	void __iomem *base, struct ep93xx_gpio_bank *bank)
>  {
> -	void __iomem *data = mmio_base + bank->data;
> -	void __iomem *dir =  mmio_base + bank->dir;
> +	void __iomem *data = base + bank->data;
> +	void __iomem *dir =  base + bank->dir;
>  	int err;
>  
>  	err = bgpio_init(gc, dev, 1, data, NULL, NULL, dir, NULL, 0);
> @@ -346,27 +346,27 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
>  
>  static int ep93xx_gpio_probe(struct platform_device *pdev)
>  {
> -	struct ep93xx_gpio *ep93xx_gpio;
> +	struct ep93xx_gpio *epg;
>  	struct resource *res;
>  	int i;
>  	struct device *dev = &pdev->dev;
>  
> -	ep93xx_gpio = devm_kzalloc(dev, sizeof(struct ep93xx_gpio), GFP_KERNEL);
> -	if (!ep93xx_gpio)
> +	epg = devm_kzalloc(dev, sizeof(*epg), GFP_KERNEL);
> +	if (!epg)
>  		return -ENOMEM;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	ep93xx_gpio->mmio_base = devm_ioremap_resource(dev, res);
> -	if (IS_ERR(ep93xx_gpio->mmio_base))
> -		return PTR_ERR(ep93xx_gpio->mmio_base);
> -	ep93xx_gpio_base = ep93xx_gpio->mmio_base;
> +	epg->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(epg->base))
> +		return PTR_ERR(epg->base);
> +	ep93xx_gpio_base = epg->base;
>  
>  	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
> -		struct gpio_chip *gc = &ep93xx_gpio->gc[i];
> +		struct gpio_chip *gc = &epg->gc[i];
>  		struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
>  
>  		if (ep93xx_gpio_add_bank(gc, &pdev->dev,
> -					 ep93xx_gpio->mmio_base, bank))
> +					 epg->base, bank))
>  			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
>  				bank->label);
>  	}


-- 
Alexander Sverdlin.

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

* [PATCH 02/11] gpio: ep93xx: Cut down variable names
@ 2018-08-29  5:56     ` Alexander Sverdlin
  0 siblings, 0 replies; 34+ messages in thread
From: Alexander Sverdlin @ 2018-08-29  5:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

On Wed, 22 Aug 2018 22:41:02 +0200
Linus Walleij <linus.walleij@linaro.org> wrote:

> In order to clean up the driver I need to cut a few trees,
> sorry, variable names, so I can see the forest, sorry driver
> properly.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>

> ---
>  drivers/gpio/gpio-ep93xx.c | 26 +++++++++++++-------------
>  1 file changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
> index 654525d6a9f1..3bfd0e46f7ed 100644
> --- a/drivers/gpio/gpio-ep93xx.c
> +++ b/drivers/gpio/gpio-ep93xx.c
> @@ -37,7 +37,7 @@ void __iomem *ep93xx_gpio_base; /* FIXME: put this into irq_data */
>  #define EP93XX_GPIO_LINE_MAX_IRQ 23
>  
>  struct ep93xx_gpio {
> -	void __iomem		*mmio_base;
> +	void __iomem		*base;
>  	struct gpio_chip	gc[8];
>  };
>  
> @@ -323,10 +323,10 @@ static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
>  }
>  
>  static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
> -	void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
> +	void __iomem *base, struct ep93xx_gpio_bank *bank)
>  {
> -	void __iomem *data = mmio_base + bank->data;
> -	void __iomem *dir =  mmio_base + bank->dir;
> +	void __iomem *data = base + bank->data;
> +	void __iomem *dir =  base + bank->dir;
>  	int err;
>  
>  	err = bgpio_init(gc, dev, 1, data, NULL, NULL, dir, NULL, 0);
> @@ -346,27 +346,27 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
>  
>  static int ep93xx_gpio_probe(struct platform_device *pdev)
>  {
> -	struct ep93xx_gpio *ep93xx_gpio;
> +	struct ep93xx_gpio *epg;
>  	struct resource *res;
>  	int i;
>  	struct device *dev = &pdev->dev;
>  
> -	ep93xx_gpio = devm_kzalloc(dev, sizeof(struct ep93xx_gpio), GFP_KERNEL);
> -	if (!ep93xx_gpio)
> +	epg = devm_kzalloc(dev, sizeof(*epg), GFP_KERNEL);
> +	if (!epg)
>  		return -ENOMEM;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	ep93xx_gpio->mmio_base = devm_ioremap_resource(dev, res);
> -	if (IS_ERR(ep93xx_gpio->mmio_base))
> -		return PTR_ERR(ep93xx_gpio->mmio_base);
> -	ep93xx_gpio_base = ep93xx_gpio->mmio_base;
> +	epg->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(epg->base))
> +		return PTR_ERR(epg->base);
> +	ep93xx_gpio_base = epg->base;
>  
>  	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
> -		struct gpio_chip *gc = &ep93xx_gpio->gc[i];
> +		struct gpio_chip *gc = &epg->gc[i];
>  		struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
>  
>  		if (ep93xx_gpio_add_bank(gc, &pdev->dev,
> -					 ep93xx_gpio->mmio_base, bank))
> +					 epg->base, bank))
>  			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
>  				bank->label);
>  	}


-- 
Alexander Sverdlin.

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

* Re: [PATCH 00/11] Reform EP93xx GPIO
  2018-08-22 20:41 ` Linus Walleij
@ 2018-08-29  6:18   ` Alexander Sverdlin
  -1 siblings, 0 replies; 34+ messages in thread
From: Alexander Sverdlin @ 2018-08-29  6:18 UTC (permalink / raw)
  To: Linus Walleij; +Cc: H Hartley Sweeten, linux-arm-kernel, linux-gpio

Hello Linus,

On Wed, 22 Aug 2018 22:41:00 +0200
Linus Walleij <linus.walleij@linaro.org> wrote:

> This series is a spin-off of a patch from Arnd that started to
> decouple the EP93xx GPIO driver from the code inside
> arch/arm.
> 
> The driver needed some modernization and in the end I managed
> to convert two of the banks to use GPIOLIB_IRQCHIP and use
> a proper irqdomain.
> 
> The F bank presents a special problem that I need to think
> about, because since there is one IRQ per GPIO line it is
> essentially a hierarchical irqdomain.
> 
> This was tested on the SIM.ONE where I rigged lines on some
> of the GPIOs on a board connector. It's crude but gives
> interrupts and behave as expected before and after these
> changes, the main visible change being that the hardware
> IRQ line on each port appears in /proc/interrupts.
> 
> It would be great if some EP93xx users could test this
> (especially something using bank F) so I can get it into
> shape and merge as a baseline for further refactorings.

I've tested only the basic GPIO functionality (as my
applications do not use IRQs as of now), but the whole
series looks good to me:

Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>

> Arnd Bergmann (1):
>   ARM/gpio: ep93xx: build standalone
> 
> Linus Walleij (10):
>   gpio: ep93xx: Cut down variable names
>   gpio: ep93xx: Switch to SPDX license tag
>   gpio: ep93xx: Pass around struct gpio_chip
>   gpio: ep93xx: Rename has_debounce to has_irq
>   gpio: ep93xx: Properly call the chained IRQ handler
>   gpio: ep93xx: Do not pingpong irq numbers
>   gpio: ep93xx: Use the hwirq and port
>   gpio: ep93xx: Use for_each_set_bit() in IRQ handler
>   gpio: ep93xx: Cut gpio_to_irq() usage
>   gpio: ep93xx: Switch A and B to use GPIOLIB_IRQCHIP
> 
>  arch/arm/mach-ep93xx/core.c |   9 ++
>  drivers/gpio/Kconfig        |   1 +
>  drivers/gpio/gpio-ep93xx.c  | 297 +++++++++++++++++++++---------------
>  3 files changed, 181 insertions(+), 126 deletions(-)

-- 
Alexander Sverdlin.

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

* [PATCH 00/11] Reform EP93xx GPIO
@ 2018-08-29  6:18   ` Alexander Sverdlin
  0 siblings, 0 replies; 34+ messages in thread
From: Alexander Sverdlin @ 2018-08-29  6:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Linus,

On Wed, 22 Aug 2018 22:41:00 +0200
Linus Walleij <linus.walleij@linaro.org> wrote:

> This series is a spin-off of a patch from Arnd that started to
> decouple the EP93xx GPIO driver from the code inside
> arch/arm.
> 
> The driver needed some modernization and in the end I managed
> to convert two of the banks to use GPIOLIB_IRQCHIP and use
> a proper irqdomain.
> 
> The F bank presents a special problem that I need to think
> about, because since there is one IRQ per GPIO line it is
> essentially a hierarchical irqdomain.
> 
> This was tested on the SIM.ONE where I rigged lines on some
> of the GPIOs on a board connector. It's crude but gives
> interrupts and behave as expected before and after these
> changes, the main visible change being that the hardware
> IRQ line on each port appears in /proc/interrupts.
> 
> It would be great if some EP93xx users could test this
> (especially something using bank F) so I can get it into
> shape and merge as a baseline for further refactorings.

I've tested only the basic GPIO functionality (as my
applications do not use IRQs as of now), but the whole
series looks good to me:

Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>

> Arnd Bergmann (1):
>   ARM/gpio: ep93xx: build standalone
> 
> Linus Walleij (10):
>   gpio: ep93xx: Cut down variable names
>   gpio: ep93xx: Switch to SPDX license tag
>   gpio: ep93xx: Pass around struct gpio_chip
>   gpio: ep93xx: Rename has_debounce to has_irq
>   gpio: ep93xx: Properly call the chained IRQ handler
>   gpio: ep93xx: Do not pingpong irq numbers
>   gpio: ep93xx: Use the hwirq and port
>   gpio: ep93xx: Use for_each_set_bit() in IRQ handler
>   gpio: ep93xx: Cut gpio_to_irq() usage
>   gpio: ep93xx: Switch A and B to use GPIOLIB_IRQCHIP
> 
>  arch/arm/mach-ep93xx/core.c |   9 ++
>  drivers/gpio/Kconfig        |   1 +
>  drivers/gpio/gpio-ep93xx.c  | 297 +++++++++++++++++++++---------------
>  3 files changed, 181 insertions(+), 126 deletions(-)

-- 
Alexander Sverdlin.

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

* Re: [PATCH 01/11] ARM/gpio: ep93xx: build standalone
  2018-08-23  7:36     ` Arnd Bergmann
@ 2018-08-29  7:03       ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-29  7:03 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hartley Sweeten, arm-soc, Alexander Sverdlin, Linux ARM,
	open list:GPIO SUBSYSTEM

On Thu, Aug 23, 2018 at 9:37 AM Arnd Bergmann <arnd@arndb.de> wrote:
> On Wed, Aug 22, 2018 at 10:41 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> >
> > From: Arnd Bergmann <arnd@arndb.de>
> >
> > As a preparation for multiplatform support, this ensures
> > that the ep93xx gpio driver can be built without any of
> > the platform specific header files. We pass the IRQ numbers
> > as a resource now, and use the virtual mmio base from the
> > already existing resource, rather than relying on the
> > hardwired virtual address from the header file.
> >
> > Some numbers are now hardcoded that came from macros
> > in the past, but for all I can tell, the driver already
> > relied on the specific values.
> >
> > Cc: arm@kernel.org
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> > ---
> > Arnd/other ARM SoC person:
> > Please provide an ACK for this patch so I can merge it
> > with the rest of the refactorings into the GPIO tree.
>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
>
> Did I send the patch to you, or did you find it in old archives?

You sent it at one point as we discussed modernizing EP93xx :)

I seem to finally start to get somewhere with that. Ground-up...

> Normally I'd assume that my authorship implies the Ack,
> but I guess it's ok to also explictly say that I'm ok with this
> going through your tree.

It's more of a handshake with ARM SoC so you folks know
this is going on.

Thanks!
Linus Walleij

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

* [PATCH 01/11] ARM/gpio: ep93xx: build standalone
@ 2018-08-29  7:03       ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2018-08-29  7:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Aug 23, 2018 at 9:37 AM Arnd Bergmann <arnd@arndb.de> wrote:
> On Wed, Aug 22, 2018 at 10:41 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> >
> > From: Arnd Bergmann <arnd@arndb.de>
> >
> > As a preparation for multiplatform support, this ensures
> > that the ep93xx gpio driver can be built without any of
> > the platform specific header files. We pass the IRQ numbers
> > as a resource now, and use the virtual mmio base from the
> > already existing resource, rather than relying on the
> > hardwired virtual address from the header file.
> >
> > Some numbers are now hardcoded that came from macros
> > in the past, but for all I can tell, the driver already
> > relied on the specific values.
> >
> > Cc: arm at kernel.org
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> > ---
> > Arnd/other ARM SoC person:
> > Please provide an ACK for this patch so I can merge it
> > with the rest of the refactorings into the GPIO tree.
>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
>
> Did I send the patch to you, or did you find it in old archives?

You sent it at one point as we discussed modernizing EP93xx :)

I seem to finally start to get somewhere with that. Ground-up...

> Normally I'd assume that my authorship implies the Ack,
> but I guess it's ok to also explictly say that I'm ok with this
> going through your tree.

It's more of a handshake with ARM SoC so you folks know
this is going on.

Thanks!
Linus Walleij

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

end of thread, other threads:[~2018-08-29  7:03 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-22 20:41 [PATCH 00/11] Reform EP93xx GPIO Linus Walleij
2018-08-22 20:41 ` Linus Walleij
2018-08-22 20:41 ` [PATCH 01/11] ARM/gpio: ep93xx: build standalone Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-23  7:36   ` Arnd Bergmann
2018-08-23  7:36     ` Arnd Bergmann
2018-08-29  7:03     ` Linus Walleij
2018-08-29  7:03       ` Linus Walleij
2018-08-24 15:51   ` Olof Johansson
2018-08-24 15:51     ` Olof Johansson
2018-08-22 20:41 ` [PATCH 02/11] gpio: ep93xx: Cut down variable names Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-29  5:56   ` Alexander Sverdlin
2018-08-29  5:56     ` Alexander Sverdlin
2018-08-22 20:41 ` [PATCH 03/11] gpio: ep93xx: Switch to SPDX license tag Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-22 20:41 ` [PATCH 04/11] gpio: ep93xx: Pass around struct gpio_chip Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-22 20:41 ` [PATCH 05/11] gpio: ep93xx: Rename has_debounce to has_irq Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-22 20:41 ` [PATCH 06/11] gpio: ep93xx: Properly call the chained IRQ handler Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-22 20:41 ` [PATCH 07/11] gpio: ep93xx: Do not pingpong irq numbers Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-22 20:41 ` [PATCH 08/11] gpio: ep93xx: Use the hwirq and port Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-22 20:41 ` [PATCH 09/11] gpio: ep93xx: Use for_each_set_bit() in IRQ handler Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-22 20:41 ` [PATCH 10/11] gpio: ep93xx: Cut gpio_to_irq() usage Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-22 20:41 ` [PATCH 11/11] gpio: ep93xx: Switch A and B to use GPIOLIB_IRQCHIP Linus Walleij
2018-08-22 20:41   ` Linus Walleij
2018-08-29  6:18 ` [PATCH 00/11] Reform EP93xx GPIO Alexander Sverdlin
2018-08-29  6:18   ` Alexander Sverdlin

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.