[lantiq] bump kernel to 3.2.12
[openwrt.git] / target / linux / lantiq / patches-3.2 / 0056-MIPS-lantiq-make-GPIO3-work-on-AR9.patch
diff --git a/target/linux/lantiq/patches-3.2/0056-MIPS-lantiq-make-GPIO3-work-on-AR9.patch b/target/linux/lantiq/patches-3.2/0056-MIPS-lantiq-make-GPIO3-work-on-AR9.patch
new file mode 100644 (file)
index 0000000..295e7ac
--- /dev/null
@@ -0,0 +1,236 @@
+From b11a96f2bdf1730fe3fd3be1d0667e20a4eb5bff Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sat, 13 Aug 2011 13:59:50 +0200
+Subject: [PATCH 56/70] MIPS: lantiq: make GPIO3 work on AR9
+
+There are 3 16bit and 1 8bit gpio ports on AR9. The gpio driver needs a hack
+at 2 places to make the different register layout of the GPIO3 work properly
+with the driver. Before only GPIO0-2 were supported. As the GPIO number scheme
+clashes with the new size, we also move the other gpio chips to new offsets.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
+---
+ .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    2 +
+ arch/mips/lantiq/xway/devices.c                    |    3 +
+ arch/mips/lantiq/xway/gpio.c                       |   84 ++++++++++++++++----
+ arch/mips/lantiq/xway/gpio_ebu.c                   |    3 +-
+ arch/mips/lantiq/xway/gpio_stp.c                   |    3 +-
+ 5 files changed, 75 insertions(+), 20 deletions(-)
+
+diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+index d1b8cc8..bfdeb16 100644
+--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+@@ -126,7 +126,9 @@
+ #define LTQ_GPIO0_BASE_ADDR   0x1E100B10
+ #define LTQ_GPIO1_BASE_ADDR   0x1E100B40
+ #define LTQ_GPIO2_BASE_ADDR   0x1E100B70
++#define LTQ_GPIO3_BASE_ADDR   0x1E100BA0
+ #define LTQ_GPIO_SIZE         0x30
++#define LTQ_GPIO3_SIZE                0x10
+ /* SSC */
+ #define LTQ_SSC_BASE_ADDR     0x1e100800
+diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
+index 5efa4f3..e6d45bc 100644
+--- a/arch/mips/lantiq/xway/devices.c
++++ b/arch/mips/lantiq/xway/devices.c
+@@ -34,6 +34,7 @@ static struct resource ltq_gpio_resource[] = {
+       MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE),
+       MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE),
+       MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE),
++      MEM_RES("gpio3", LTQ_GPIO3_BASE_ADDR, LTQ_GPIO3_SIZE),
+ };
+ void __init ltq_register_gpio(void)
+@@ -47,6 +48,8 @@ void __init ltq_register_gpio(void)
+       if (ltq_is_ar9() || ltq_is_vr9()) {
+               platform_device_register_simple("ltq_gpio", 2,
+                       &ltq_gpio_resource[2], 1);
++              platform_device_register_simple("ltq_gpio", 3,
++                      &ltq_gpio_resource[3], 1);
+       }
+ }
+diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
+index 54ec6c9..375329b 100644
+--- a/arch/mips/lantiq/xway/gpio.c
++++ b/arch/mips/lantiq/xway/gpio.c
+@@ -23,9 +23,17 @@
+ #define LTQ_GPIO_OD           0x14
+ #define LTQ_GPIO_PUDSEL               0x1C
+ #define LTQ_GPIO_PUDEN                0x20
++#define LTQ_GPIO3_OD          0x24
++#define LTQ_GPIO3_ALTSEL1     0x24
++#define LTQ_GPIO3_PUDSEL      0x28
++#define LTQ_GPIO3_PUDEN               0x2C
++/* PORT3 only has 8 pins and its register layout
++   is slightly different */
+ #define PINS_PER_PORT         16
+-#define MAX_PORTS             3
++#define PINS_PORT3            8
++#define MAX_PORTS             4
++#define MAX_PIN                       56
+ #define ltq_gpio_getbit(m, r, p)      (!!(ltq_r32(m + r) & (1 << p)))
+ #define ltq_gpio_setbit(m, r, p)      ltq_w32_mask(0, (1 << p), m + r)
+@@ -55,7 +63,7 @@ int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
+ {
+       int id = 0;
+-      if (pin >= (MAX_PORTS * PINS_PER_PORT))
++      if (pin >= MAX_PIN)
+               return -EINVAL;
+       if (devm_gpio_request(dev, pin, name)) {
+               pr_err("failed to setup lantiq gpio: %s\n", name);
+@@ -75,12 +83,21 @@ int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
+       else
+               ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+                       LTQ_GPIO_ALTSEL0, pin);
+-      if (mux & 0x1)
+-              ltq_gpio_setbit(ltq_gpio_port[id].membase,
+-                      LTQ_GPIO_ALTSEL1, pin);
+-      else
+-              ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+-                      LTQ_GPIO_ALTSEL1, pin);
++      if (id == 3) {
++              if (mux & 0x1)
++                      ltq_gpio_setbit(ltq_gpio_port[1].membase,
++                              LTQ_GPIO3_ALTSEL1, pin);
++              else
++                      ltq_gpio_clearbit(ltq_gpio_port[1].membase,
++                              LTQ_GPIO3_ALTSEL1, pin);
++      } else {
++              if (mux & 0x1)
++                      ltq_gpio_setbit(ltq_gpio_port[id].membase,
++                              LTQ_GPIO_ALTSEL1, pin);
++              else
++                      ltq_gpio_clearbit(ltq_gpio_port[id].membase,
++                              LTQ_GPIO_ALTSEL1, pin);
++      }
+       return 0;
+ }
+ EXPORT_SYMBOL(ltq_gpio_request);
+@@ -106,10 +123,19 @@ static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+ {
+       struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+-      ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
++      if (chip->ngpio == PINS_PORT3) {
++              ltq_gpio_clearbit(ltq_gpio_port[0].membase,
++                              LTQ_GPIO3_OD, offset);
++              ltq_gpio_setbit(ltq_gpio_port[0].membase,
++                              LTQ_GPIO3_PUDSEL, offset);
++              ltq_gpio_setbit(ltq_gpio_port[0].membase,
++                              LTQ_GPIO3_PUDEN, offset);
++      } else {
++              ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
++              ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
++              ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
++      }
+       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+-      ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
+-      ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
+       return 0;
+ }
+@@ -119,10 +145,19 @@ static int ltq_gpio_direction_output(struct gpio_chip *chip,
+ {
+       struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+-      ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
++      if (chip->ngpio == PINS_PORT3) {
++              ltq_gpio_setbit(ltq_gpio_port[0].membase,
++                              LTQ_GPIO3_OD, offset);
++              ltq_gpio_clearbit(ltq_gpio_port[0].membase,
++                              LTQ_GPIO3_PUDSEL, offset);
++              ltq_gpio_clearbit(ltq_gpio_port[0].membase,
++                              LTQ_GPIO3_PUDEN, offset);
++      } else {
++              ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
++              ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
++              ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
++      }
+       ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+-      ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset);
+-      ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset);
+       ltq_gpio_set(chip, offset, value);
+       return 0;
+@@ -133,7 +168,11 @@ static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
+       struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
+-      ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
++      if (chip->ngpio == PINS_PORT3)
++              ltq_gpio_clearbit(ltq_gpio_port[1].membase,
++                              LTQ_GPIO3_ALTSEL1, offset);
++      else
++              ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
+       return 0;
+ }
+@@ -146,6 +185,16 @@ static int ltq_gpio_probe(struct platform_device *pdev)
+                       pdev->id);
+               return -EINVAL;
+       }
++
++      /* dirty hack - The registers of port3 are not mapped linearly.
++         Port 3 may only load if Port 1/2 are mapped */
++      if ((pdev->id == 3) && (!ltq_gpio_port[1].membase
++                                      || !ltq_gpio_port[2].membase)) {
++              dev_err(&pdev->dev,
++                      "ports 1/2 need to be loaded before port 3 works\n");
++              return -ENOMEM;
++      }
++
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
+@@ -175,7 +224,10 @@ static int ltq_gpio_probe(struct platform_device *pdev)
+       ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
+       ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
+       ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
+-      ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
++      if (pdev->id == 3)
++              ltq_gpio_port[pdev->id].chip.ngpio = PINS_PORT3;
++      else
++              ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
+       platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
+       return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
+ }
+diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c
+index b91c7f1..bc5696b 100644
+--- a/arch/mips/lantiq/xway/gpio_ebu.c
++++ b/arch/mips/lantiq/xway/gpio_ebu.c
+@@ -61,9 +61,8 @@ static struct gpio_chip ltq_ebu_chip = {
+       .label = "ltq_ebu",
+       .direction_output = ltq_ebu_direction_output,
+       .set = ltq_ebu_set,
+-      .base = 72,
++      .base = 100,
+       .ngpio = 16,
+-      .can_sleep = 1,
+       .owner = THIS_MODULE,
+ };
+diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c
+index da91c5e..9610c10 100644
+--- a/arch/mips/lantiq/xway/gpio_stp.c
++++ b/arch/mips/lantiq/xway/gpio_stp.c
+@@ -74,9 +74,8 @@ static struct gpio_chip ltq_stp_chip = {
+       .label = "ltq_stp",
+       .direction_output = ltq_stp_direction_output,
+       .set = ltq_stp_set,
+-      .base = 48,
++      .base = 200,
+       .ngpio = 24,
+-      .can_sleep = 1,
+       .owner = THIS_MODULE,
+ };
+-- 
+1.7.7.1
+
This page took 0.038982 seconds and 4 git commands to generate.