@@ -40,7 +40,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
--- /dev/null
+++ b/drivers/gpio/gpio-bcm63xx.c
-@@ -0,0 +1,122 @@
+@@ -0,0 +1,178 @@
+/*
+ * Driver for BCM63XX memory-mapped GPIO controllers, based on
+ * Generic driver for memory-mapped GPIO controllers.
@@ -75,6 +75,58 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+
++#include <bcm63xx_irq.h>
++
++static int bcm63xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++ unsigned int i;
++ int irq2gpio[6] = { -1, -1, -1, -1, -1, -1 };
++
++ switch (bcm63xx_get_cpu_id()) {
++ case BCM6328_CPU_ID:
++ irq2gpio[0] = 23;
++ irq2gpio[1] = 24;
++ irq2gpio[2] = 15;
++ irq2gpio[3] = 12;
++ break;
++ case BCM6348_CPU_ID:
++ case BCM63268_CPU_ID:
++ if (chip->ngpio < 32)
++ {
++ irq2gpio[0] = 0;
++ irq2gpio[1] = 1;
++ irq2gpio[2] = 2;
++ irq2gpio[3] = 3;
++ }
++ else
++ return -EINVAL;
++ break;
++ case BCM6358_CPU_ID:
++ case BCM6368_CPU_ID:
++ if (chip->ngpio < 32)
++ {
++ irq2gpio[0] = 2;
++ irq2gpio[1] = 3;
++ irq2gpio[2] = 4;
++ irq2gpio[3] = 5;
++ irq2gpio[4] = 0;
++ irq2gpio[5] = 1;
++ }
++ else
++ return -EINVAL;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ for (i = 0; i < 6; i++) {
++ if (irq2gpio[i] == gpio)
++ return i + IRQ_EXTERNAL_BASE;
++ }
++
++ return -EINVAL;
++}
++
+static int bcm63xx_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
@@ -85,6 +137,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ int err;
+ struct bgpio_chip *bgc;
+ struct bgpio_pdata *pdata = dev_get_platdata(dev);
++ struct gpio_chip *chip;
+
+ dirout_r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dat_r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -131,8 +184,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (pdata->ngpio > 0)
+ bgc->gc.ngpio = pdata->ngpio;
+ }
++
++ chip = &bgc->gc;
++ chip->to_irq = bcm63xx_gpio_to_irq;
+
-+ return gpiochip_add(&bgc->gc);
++ return gpiochip_add(chip);
+}
+
+static int bcm63xx_gpio_remove(struct platform_device *pdev)
@@ -163,3 +219,14 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+MODULE_DESCRIPTION("Driver for BCM63XX memory-mapped GPIO controllers");
+MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>");
+MODULE_LICENSE("GPL");
+--- a/arch/mips/include/asm/mach-bcm63xx/gpio.h
++++ b/arch/mips/include/asm/mach-bcm63xx/gpio.h
+@@ -3,7 +3,7 @@
+
+ #include <bcm63xx_gpio.h>
+
+-#define gpio_to_irq(gpio) -1
++#define gpio_to_irq __gpio_to_irq
+
+ #define gpio_get_value __gpio_get_value
+ #define gpio_set_value __gpio_set_value
@@ -40,7 +40,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
--- /dev/null
+++ b/drivers/gpio/gpio-bcm63xx.c
-@@ -0,0 +1,122 @@
+@@ -0,0 +1,178 @@
+/*
+ * Driver for BCM63XX memory-mapped GPIO controllers, based on
+ * Generic driver for memory-mapped GPIO controllers.
@@ -75,6 +75,58 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+
++#include <bcm63xx_irq.h>
++
++static int bcm63xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++ unsigned int i;
++ int irq2gpio[6] = { -1, -1, -1, -1, -1, -1 };
++
++ switch (bcm63xx_get_cpu_id()) {
++ case BCM6328_CPU_ID:
++ irq2gpio[0] = 23;
++ irq2gpio[1] = 24;
++ irq2gpio[2] = 15;
++ irq2gpio[3] = 12;
++ break;
++ case BCM6348_CPU_ID:
++ case BCM63268_CPU_ID:
++ if (chip->ngpio < 32)
++ {
++ irq2gpio[0] = 0;
++ irq2gpio[1] = 1;
++ irq2gpio[2] = 2;
++ irq2gpio[3] = 3;
++ }
++ else
++ return -EINVAL;
++ break;
++ case BCM6358_CPU_ID:
++ case BCM6368_CPU_ID:
++ if (chip->ngpio < 32)
++ {
++ irq2gpio[0] = 2;
++ irq2gpio[1] = 3;
++ irq2gpio[2] = 4;
++ irq2gpio[3] = 5;
++ irq2gpio[4] = 0;
++ irq2gpio[5] = 1;
++ }
++ else
++ return -EINVAL;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ for (i = 0; i < 6; i++) {
++ if (irq2gpio[i] == gpio)
++ return i + IRQ_EXTERNAL_BASE;
++ }
++
++ return -EINVAL;
++}
++
+static int bcm63xx_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
@@ -85,6 +137,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ int err;
+ struct bgpio_chip *bgc;
+ struct bgpio_pdata *pdata = dev_get_platdata(dev);
++ struct gpio_chip *chip;
+
+ dirout_r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dat_r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -131,8 +184,11 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+ if (pdata->ngpio > 0)
+ bgc->gc.ngpio = pdata->ngpio;
+ }
++
++ chip = &bgc->gc;
++ chip->to_irq = bcm63xx_gpio_to_irq;
+
-+ return gpiochip_add(&bgc->gc);
++ return gpiochip_add(chip);
+}
+
+static int bcm63xx_gpio_remove(struct platform_device *pdev)
@@ -163,3 +219,14 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+MODULE_DESCRIPTION("Driver for BCM63XX memory-mapped GPIO controllers");
+MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>");
+MODULE_LICENSE("GPL");
+--- a/arch/mips/include/asm/mach-bcm63xx/gpio.h
++++ b/arch/mips/include/asm/mach-bcm63xx/gpio.h
+@@ -3,7 +3,7 @@
+
+ #include <bcm63xx_gpio.h>
+
+-#define gpio_to_irq(gpio) -1
++#define gpio_to_irq __gpio_to_irq
+
+ #define gpio_get_value __gpio_get_value
+ #define gpio_set_value __gpio_set_value
Implement "to_irq" in the GPIO driver. Some GPIOs in bcm63xx have IRQs. They are known in this target as external IRQs. This patch just adds the function "to_irq" for allowing to use the generic GPIO lib function gpio_to_irq(). This function just returns the IRQ number at the GPIO line. Signed-off-by: Daniel Gonzalez <dgcbueu@gmail.com> --- change in v2: Use a reverse table to get the IRQs later with a loop. Use ngpios instead label to know if we are in the 2nd gpio chip There wasn't anything wrong with the v1 patch. This one is a bit more sophisticated, and it might help if we wanted to integrate DTS stuff. ---