[lantiq]
[openwrt.git] / target / linux / lantiq / patches-3.0 / 0012-MIPS-lantiq-adds-GPIO3-support-on-AR9.patch
1 From 6b5e2ee7c8f9722d59213f17d423b3f90d80f822 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Sat, 13 Aug 2011 13:59:50 +0200
4 Subject: [PATCH 12/24] MIPS: lantiq: adds GPIO3 support on AR9
5
6 There are 3 16bit and 1 8bit gpio ports on AR9. The gpio driver needs a hack
7 at 2 places to make the different register layout of the GPIO3 work properly
8 with the driver. Before only GPIO0-2 were supported. As the GPIO number scheme
9 clashes with the new size, we also move the other gpio chips to new offsets.
10
11 Signed-off-by: John Crispin <blogic@openwrt.org>
12 Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
13 ---
14  .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    2 +
15  arch/mips/lantiq/xway/devices.c                    |    3 +
16  arch/mips/lantiq/xway/gpio.c                       |   62 ++++++++++++++++----
17  arch/mips/lantiq/xway/gpio_ebu.c                   |    3 +-
18  arch/mips/lantiq/xway/gpio_stp.c                   |    3 +-
19  5 files changed, 57 insertions(+), 16 deletions(-)
20
21 diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
22 index da8ff95..421768e 100644
23 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
24 +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
25 @@ -113,7 +113,9 @@
26  #define LTQ_GPIO0_BASE_ADDR    0x1E100B10
27  #define LTQ_GPIO1_BASE_ADDR    0x1E100B40
28  #define LTQ_GPIO2_BASE_ADDR    0x1E100B70
29 +#define LTQ_GPIO3_BASE_ADDR    0x1E100BA0
30  #define LTQ_GPIO_SIZE          0x30
31 +#define LTQ_GPIO3_SIZE         0x10
32  
33  /* SSC */
34  #define LTQ_SSC_BASE_ADDR      0x1e100800
35 diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
36 index 9bacaa8..b7efac5 100644
37 --- a/arch/mips/lantiq/xway/devices.c
38 +++ b/arch/mips/lantiq/xway/devices.c
39 @@ -34,6 +34,7 @@ static struct resource ltq_gpio_resource[] = {
40         MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE),
41         MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE),
42         MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE),
43 +       MEM_RES("gpio3", LTQ_GPIO3_BASE_ADDR, LTQ_GPIO3_SIZE),
44  };
45  
46  void __init ltq_register_gpio(void)
47 @@ -47,6 +48,8 @@ void __init ltq_register_gpio(void)
48         if (ltq_is_ar9() || ltq_is_vr9()) {
49                 platform_device_register_simple("ltq_gpio", 2,
50                         &ltq_gpio_resource[2], 1);
51 +               platform_device_register_simple("ltq_gpio", 3,
52 +                       &ltq_gpio_resource[3], 1);
53         }
54  }
55  
56 diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
57 index a321451..2c48c17 100644
58 --- a/arch/mips/lantiq/xway/gpio.c
59 +++ b/arch/mips/lantiq/xway/gpio.c
60 @@ -21,9 +21,15 @@
61  #define LTQ_GPIO_ALTSEL0       0x0C
62  #define LTQ_GPIO_ALTSEL1       0x10
63  #define LTQ_GPIO_OD            0x14
64 +#define LTQ_GPIO3_OD           0x24
65 +#define LTQ_GPIO3_ALTSEL1      0x24
66  
67 +/* PORT3 only has 8 pins and its register layout
68 +   is slightly different */
69  #define PINS_PER_PORT          16
70 -#define MAX_PORTS              3
71 +#define PINS_PORT3             8
72 +#define MAX_PORTS              4
73 +#define MAX_PIN                        56
74  
75  #define ltq_gpio_getbit(m, r, p)       (!!(ltq_r32(m + r) & (1 << p)))
76  #define ltq_gpio_setbit(m, r, p)       ltq_w32_mask(0, (1 << p), m + r)
77 @@ -53,7 +59,7 @@ int ltq_gpio_request(unsigned int pin, unsigned int alt0,
78  {
79         int id = 0;
80  
81 -       if (pin >= (MAX_PORTS * PINS_PER_PORT))
82 +       if (pin >= MAX_PIN)
83                 return -EINVAL;
84         if (gpio_request(pin, name)) {
85                 pr_err("failed to setup lantiq gpio: %s\n", name);
86 @@ -73,12 +79,21 @@ int ltq_gpio_request(unsigned int pin, unsigned int alt0,
87         else
88                 ltq_gpio_clearbit(ltq_gpio_port[id].membase,
89                         LTQ_GPIO_ALTSEL0, pin);
90 -       if (alt1)
91 -               ltq_gpio_setbit(ltq_gpio_port[id].membase,
92 -                       LTQ_GPIO_ALTSEL1, pin);
93 -       else
94 -               ltq_gpio_clearbit(ltq_gpio_port[id].membase,
95 -                       LTQ_GPIO_ALTSEL1, pin);
96 +       if (id == 3) {
97 +               if (alt1)
98 +                       ltq_gpio_setbit(ltq_gpio_port[1].membase,
99 +                               LTQ_GPIO3_ALTSEL1, pin);
100 +               else
101 +                       ltq_gpio_clearbit(ltq_gpio_port[1].membase,
102 +                               LTQ_GPIO3_ALTSEL1, pin);
103 +       } else {
104 +               if (alt1)
105 +                       ltq_gpio_setbit(ltq_gpio_port[id].membase,
106 +                               LTQ_GPIO_ALTSEL1, pin);
107 +               else
108 +                       ltq_gpio_clearbit(ltq_gpio_port[id].membase,
109 +                               LTQ_GPIO_ALTSEL1, pin);
110 +       }
111         return 0;
112  }
113  EXPORT_SYMBOL(ltq_gpio_request);
114 @@ -104,7 +119,11 @@ static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
115  {
116         struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
117  
118 -       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
119 +       if (chip->ngpio == PINS_PORT3)
120 +               ltq_gpio_clearbit(ltq_gpio_port[0].membase,
121 +                               LTQ_GPIO3_OD, offset);
122 +       else
123 +               ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
124         ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
125  
126         return 0;
127 @@ -115,7 +134,10 @@ static int ltq_gpio_direction_output(struct gpio_chip *chip,
128  {
129         struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
130  
131 -       ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
132 +       if (chip->ngpio == PINS_PORT3)
133 +               ltq_gpio_setbit(ltq_gpio_port[0].membase, LTQ_GPIO3_OD, offset);
134 +       else
135 +               ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
136         ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
137         ltq_gpio_set(chip, offset, value);
138  
139 @@ -127,7 +149,11 @@ static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
140         struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
141  
142         ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
143 -       ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
144 +       if (chip->ngpio == PINS_PORT3)
145 +               ltq_gpio_clearbit(ltq_gpio_port[1].membase,
146 +                               LTQ_GPIO3_ALTSEL1, offset);
147 +       else
148 +               ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
149         return 0;
150  }
151  
152 @@ -140,6 +166,15 @@ static int ltq_gpio_probe(struct platform_device *pdev)
153                         pdev->id);
154                 return -EINVAL;
155         }
156 +
157 +       /* dirty hack - The registers of port3 are not mapped linearly.
158 +          Port 3 may only load if Port 1/2 are mapped */
159 +       if ((pdev->id == 3) && (!ltq_gpio_port[1].membase || !ltq_gpio_port[2].membase)) {
160 +               dev_err(&pdev->dev,
161 +                       "ports 1/2 need to be loaded before port 3 works\n");
162 +               return -ENOMEM;
163 +       }
164 +
165         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
166         if (!res) {
167                 dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
168 @@ -169,7 +204,10 @@ static int ltq_gpio_probe(struct platform_device *pdev)
169         ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
170         ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
171         ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
172 -       ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
173 +       if (pdev->id == 3)
174 +               ltq_gpio_port[pdev->id].chip.ngpio = PINS_PORT3;
175 +       else
176 +               ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
177         platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
178         return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
179  }
180 diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c
181 index a479355..729f8e3 100644
182 --- a/arch/mips/lantiq/xway/gpio_ebu.c
183 +++ b/arch/mips/lantiq/xway/gpio_ebu.c
184 @@ -61,9 +61,8 @@ static struct gpio_chip ltq_ebu_chip = {
185         .label = "ltq_ebu",
186         .direction_output = ltq_ebu_direction_output,
187         .set = ltq_ebu_set,
188 -       .base = 72,
189 +       .base = 100,
190         .ngpio = 16,
191 -       .can_sleep = 1,
192         .owner = THIS_MODULE,
193  };
194  
195 diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c
196 index 67d59d6..c01294e 100644
197 --- a/arch/mips/lantiq/xway/gpio_stp.c
198 +++ b/arch/mips/lantiq/xway/gpio_stp.c
199 @@ -70,9 +70,8 @@ static struct gpio_chip ltq_stp_chip = {
200         .label = "ltq_stp",
201         .direction_output = ltq_stp_direction_output,
202         .set = ltq_stp_set,
203 -       .base = 48,
204 +       .base = 200,
205         .ngpio = 24,
206 -       .can_sleep = 1,
207         .owner = THIS_MODULE,
208  };
209  
210 -- 
211 1.7.5.4
212