brcm47xx: add new led and button support
[openwrt.git] / target / linux / brcm47xx / patches-3.10 / 102-ssb-gpio-add-own-IRQ-domain.patch
1 From 5668cb19fea423cb6681f1efa8b130a26be2562e Mon Sep 17 00:00:00 2001
2 From: Rafa? Mi?ecki <zajec5@gmail.com>
3 Date: Fri, 3 Jan 2014 09:55:29 +0100
4 Subject: [PATCH] ssb: gpio: add own IRQ domain
5
6 Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
7 Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
8 ---
9  drivers/ssb/Kconfig       |    1 +
10  drivers/ssb/driver_gpio.c |  304 ++++++++++++++++++++++++++++++++++++++++++---
11  drivers/ssb/main.c        |   12 +-
12  include/linux/ssb/ssb.h   |    1 +
13  4 files changed, 297 insertions(+), 21 deletions(-)
14
15 --- a/drivers/ssb/Kconfig
16 +++ b/drivers/ssb/Kconfig
17 @@ -169,6 +169,7 @@ config SSB_DRIVER_GIGE
18  config SSB_DRIVER_GPIO
19         bool "SSB GPIO driver"
20         depends on SSB && GPIOLIB
21 +       select IRQ_DOMAIN if SSB_EMBEDDED
22         help
23           Driver to provide access to the GPIO pins on the bus.
24  
25 --- a/drivers/ssb/driver_gpio.c
26 +++ b/drivers/ssb/driver_gpio.c
27 @@ -9,16 +9,40 @@
28   */
29  
30  #include <linux/gpio.h>
31 +#include <linux/irq.h>
32 +#include <linux/interrupt.h>
33 +#include <linux/irqdomain.h>
34  #include <linux/export.h>
35  #include <linux/ssb/ssb.h>
36  
37  #include "ssb_private.h"
38  
39 +
40 +/**************************************************
41 + * Shared
42 + **************************************************/
43 +
44  static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)
45  {
46         return container_of(chip, struct ssb_bus, gpio);
47  }
48  
49 +#if IS_BUILTIN(CONFIG_SSB_EMBEDDED)
50 +static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
51 +{
52 +       struct ssb_bus *bus = ssb_gpio_get_bus(chip);
53 +
54 +       if (bus->bustype == SSB_BUSTYPE_SSB)
55 +               return irq_find_mapping(bus->irq_domain, gpio);
56 +       else
57 +               return -EINVAL;
58 +}
59 +#endif
60 +
61 +/**************************************************
62 + * ChipCommon
63 + **************************************************/
64 +
65  static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)
66  {
67         struct ssb_bus *bus = ssb_gpio_get_bus(chip);
68 @@ -74,19 +98,129 @@ static void ssb_gpio_chipco_free(struct
69         ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
70  }
71  
72 -static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio)
73 +#if IS_BUILTIN(CONFIG_SSB_EMBEDDED)
74 +static void ssb_gpio_irq_chipco_mask(struct irq_data *d)
75  {
76 -       struct ssb_bus *bus = ssb_gpio_get_bus(chip);
77 +       struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
78 +       int gpio = irqd_to_hwirq(d);
79  
80 -       if (bus->bustype == SSB_BUSTYPE_SSB)
81 -               return ssb_mips_irq(bus->chipco.dev) + 2;
82 -       else
83 -               return -EINVAL;
84 +       ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), 0);
85 +}
86 +
87 +static void ssb_gpio_irq_chipco_unmask(struct irq_data *d)
88 +{
89 +       struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
90 +       int gpio = irqd_to_hwirq(d);
91 +       u32 val = ssb_chipco_gpio_in(&bus->chipco, BIT(gpio));
92 +
93 +       ssb_chipco_gpio_polarity(&bus->chipco, BIT(gpio), val);
94 +       ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), BIT(gpio));
95 +}
96 +
97 +static struct irq_chip ssb_gpio_irq_chipco_chip = {
98 +       .name           = "SSB-GPIO-CC",
99 +       .irq_mask       = ssb_gpio_irq_chipco_mask,
100 +       .irq_unmask     = ssb_gpio_irq_chipco_unmask,
101 +};
102 +
103 +static irqreturn_t ssb_gpio_irq_chipco_handler(int irq, void *dev_id)
104 +{
105 +       struct ssb_bus *bus = dev_id;
106 +       struct ssb_chipcommon *chipco = &bus->chipco;
107 +       u32 val = chipco_read32(chipco, SSB_CHIPCO_GPIOIN);
108 +       u32 mask = chipco_read32(chipco, SSB_CHIPCO_GPIOIRQ);
109 +       u32 pol = chipco_read32(chipco, SSB_CHIPCO_GPIOPOL);
110 +       u32 irqs = (val ^ pol) & mask;
111 +       int gpio;
112 +
113 +       if (!irqs)
114 +               return IRQ_NONE;
115 +
116 +       for_each_set_bit(gpio, (unsigned long *)&irqs, bus->gpio.ngpio)
117 +               generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
118 +       ssb_chipco_gpio_polarity(chipco, irqs, val & irqs);
119 +
120 +       return IRQ_HANDLED;
121 +}
122 +
123 +static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
124 +{
125 +       struct ssb_chipcommon *chipco = &bus->chipco;
126 +       struct gpio_chip *chip = &bus->gpio;
127 +       int gpio, hwirq, err;
128 +
129 +       if (bus->bustype != SSB_BUSTYPE_SSB)
130 +               return 0;
131 +
132 +       bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
133 +                                               &irq_domain_simple_ops, chipco);
134 +       if (!bus->irq_domain) {
135 +               err = -ENODEV;
136 +               goto err_irq_domain;
137 +       }
138 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
139 +               int irq = irq_create_mapping(bus->irq_domain, gpio);
140 +
141 +               irq_set_chip_data(irq, bus);
142 +               irq_set_chip_and_handler(irq, &ssb_gpio_irq_chipco_chip,
143 +                                        handle_simple_irq);
144 +       }
145 +
146 +       hwirq = ssb_mips_irq(bus->chipco.dev) + 2;
147 +       err = request_irq(hwirq, ssb_gpio_irq_chipco_handler, IRQF_SHARED,
148 +                         "gpio", bus);
149 +       if (err)
150 +               goto err_req_irq;
151 +
152 +       ssb_chipco_gpio_intmask(&bus->chipco, ~0, 0);
153 +       chipco_set32(chipco, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO);
154 +
155 +       return 0;
156 +
157 +err_req_irq:
158 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
159 +               int irq = irq_find_mapping(bus->irq_domain, gpio);
160 +
161 +               irq_dispose_mapping(irq);
162 +       }
163 +       irq_domain_remove(bus->irq_domain);
164 +err_irq_domain:
165 +       return err;
166 +}
167 +
168 +static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
169 +{
170 +       struct ssb_chipcommon *chipco = &bus->chipco;
171 +       struct gpio_chip *chip = &bus->gpio;
172 +       int gpio;
173 +
174 +       if (bus->bustype != SSB_BUSTYPE_SSB)
175 +               return;
176 +
177 +       chipco_mask32(chipco, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO);
178 +       free_irq(ssb_mips_irq(bus->chipco.dev) + 2, chipco);
179 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
180 +               int irq = irq_find_mapping(bus->irq_domain, gpio);
181 +
182 +               irq_dispose_mapping(irq);
183 +       }
184 +       irq_domain_remove(bus->irq_domain);
185 +}
186 +#else
187 +static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
188 +{
189 +       return 0;
190 +}
191 +
192 +static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
193 +{
194  }
195 +#endif
196  
197  static int ssb_gpio_chipco_init(struct ssb_bus *bus)
198  {
199         struct gpio_chip *chip = &bus->gpio;
200 +       int err;
201  
202         chip->label             = "ssb_chipco_gpio";
203         chip->owner             = THIS_MODULE;
204 @@ -96,7 +230,8 @@ static int ssb_gpio_chipco_init(struct s
205         chip->set               = ssb_gpio_chipco_set_value;
206         chip->direction_input   = ssb_gpio_chipco_direction_input;
207         chip->direction_output  = ssb_gpio_chipco_direction_output;
208 -       chip->to_irq            = ssb_gpio_chipco_to_irq;
209 +       if (IS_BUILTIN(CONFIG_SSB_EMBEDDED))
210 +               chip->to_irq    = ssb_gpio_to_irq;
211         chip->ngpio             = 16;
212         /* There is just one SoC in one device and its GPIO addresses should be
213          * deterministic to address them more easily. The other buses could get
214 @@ -106,9 +241,23 @@ static int ssb_gpio_chipco_init(struct s
215         else
216                 chip->base              = -1;
217  
218 -       return gpiochip_add(chip);
219 +       err = ssb_gpio_irq_chipco_domain_init(bus);
220 +       if (err)
221 +               return err;
222 +
223 +       err = gpiochip_add(chip);
224 +       if (err) {
225 +               ssb_gpio_irq_chipco_domain_exit(bus);
226 +               return err;
227 +       }
228 +
229 +       return 0;
230  }
231  
232 +/**************************************************
233 + * EXTIF
234 + **************************************************/
235 +
236  #ifdef CONFIG_SSB_DRIVER_EXTIF
237  
238  static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)
239 @@ -145,19 +294,127 @@ static int ssb_gpio_extif_direction_outp
240         return 0;
241  }
242  
243 -static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio)
244 +#if IS_BUILTIN(CONFIG_SSB_EMBEDDED)
245 +static void ssb_gpio_irq_extif_mask(struct irq_data *d)
246  {
247 -       struct ssb_bus *bus = ssb_gpio_get_bus(chip);
248 +       struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
249 +       int gpio = irqd_to_hwirq(d);
250  
251 -       if (bus->bustype == SSB_BUSTYPE_SSB)
252 -               return ssb_mips_irq(bus->extif.dev) + 2;
253 -       else
254 -               return -EINVAL;
255 +       ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), 0);
256  }
257  
258 +static void ssb_gpio_irq_extif_unmask(struct irq_data *d)
259 +{
260 +       struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
261 +       int gpio = irqd_to_hwirq(d);
262 +       u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio));
263 +
264 +       ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val);
265 +       ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio));
266 +}
267 +
268 +static struct irq_chip ssb_gpio_irq_extif_chip = {
269 +       .name           = "SSB-GPIO-EXTIF",
270 +       .irq_mask       = ssb_gpio_irq_extif_mask,
271 +       .irq_unmask     = ssb_gpio_irq_extif_unmask,
272 +};
273 +
274 +static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id)
275 +{
276 +       struct ssb_bus *bus = dev_id;
277 +       struct ssb_extif *extif = &bus->extif;
278 +       u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN);
279 +       u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK);
280 +       u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL);
281 +       u32 irqs = (val ^ pol) & mask;
282 +       int gpio;
283 +
284 +       if (!irqs)
285 +               return IRQ_NONE;
286 +
287 +       for_each_set_bit(gpio, (unsigned long *)&irqs, bus->gpio.ngpio)
288 +               generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
289 +       ssb_extif_gpio_polarity(extif, irqs, val & irqs);
290 +
291 +       return IRQ_HANDLED;
292 +}
293 +
294 +static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
295 +{
296 +       struct ssb_extif *extif = &bus->extif;
297 +       struct gpio_chip *chip = &bus->gpio;
298 +       int gpio, hwirq, err;
299 +
300 +       if (bus->bustype != SSB_BUSTYPE_SSB)
301 +               return 0;
302 +
303 +       bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
304 +                                               &irq_domain_simple_ops, extif);
305 +       if (!bus->irq_domain) {
306 +               err = -ENODEV;
307 +               goto err_irq_domain;
308 +       }
309 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
310 +               int irq = irq_create_mapping(bus->irq_domain, gpio);
311 +
312 +               irq_set_chip_data(irq, bus);
313 +               irq_set_chip_and_handler(irq, &ssb_gpio_irq_extif_chip,
314 +                                        handle_simple_irq);
315 +       }
316 +
317 +       hwirq = ssb_mips_irq(bus->extif.dev) + 2;
318 +       err = request_irq(hwirq, ssb_gpio_irq_extif_handler, IRQF_SHARED,
319 +                         "gpio", bus);
320 +       if (err)
321 +               goto err_req_irq;
322 +
323 +       ssb_extif_gpio_intmask(&bus->extif, ~0, 0);
324 +
325 +       return 0;
326 +
327 +err_req_irq:
328 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
329 +               int irq = irq_find_mapping(bus->irq_domain, gpio);
330 +
331 +               irq_dispose_mapping(irq);
332 +       }
333 +       irq_domain_remove(bus->irq_domain);
334 +err_irq_domain:
335 +       return err;
336 +}
337 +
338 +static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
339 +{
340 +       struct ssb_extif *extif = &bus->extif;
341 +       struct gpio_chip *chip = &bus->gpio;
342 +       int gpio;
343 +
344 +       if (bus->bustype != SSB_BUSTYPE_SSB)
345 +               return;
346 +
347 +       free_irq(ssb_mips_irq(bus->extif.dev) + 2, extif);
348 +       for (gpio = 0; gpio < chip->ngpio; gpio++) {
349 +               int irq = irq_find_mapping(bus->irq_domain, gpio);
350 +
351 +               irq_dispose_mapping(irq);
352 +       }
353 +       irq_domain_remove(bus->irq_domain);
354 +}
355 +#else
356 +static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
357 +{
358 +       return 0;
359 +}
360 +
361 +static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
362 +{
363 +}
364 +#endif
365 +
366  static int ssb_gpio_extif_init(struct ssb_bus *bus)
367  {
368         struct gpio_chip *chip = &bus->gpio;
369 +       int err;
370  
371         chip->label             = "ssb_extif_gpio";
372         chip->owner             = THIS_MODULE;
373 @@ -165,7 +422,8 @@ static int ssb_gpio_extif_init(struct ss
374         chip->set               = ssb_gpio_extif_set_value;
375         chip->direction_input   = ssb_gpio_extif_direction_input;
376         chip->direction_output  = ssb_gpio_extif_direction_output;
377 -       chip->to_irq            = ssb_gpio_extif_to_irq;
378 +       if (IS_BUILTIN(CONFIG_SSB_EMBEDDED))
379 +               chip->to_irq    = ssb_gpio_to_irq;
380         chip->ngpio             = 5;
381         /* There is just one SoC in one device and its GPIO addresses should be
382          * deterministic to address them more easily. The other buses could get
383 @@ -175,7 +433,17 @@ static int ssb_gpio_extif_init(struct ss
384         else
385                 chip->base              = -1;
386  
387 -       return gpiochip_add(chip);
388 +       err = ssb_gpio_irq_extif_domain_init(bus);
389 +       if (err)
390 +               return err;
391 +
392 +       err = gpiochip_add(chip);
393 +       if (err) {
394 +               ssb_gpio_irq_extif_domain_exit(bus);
395 +               return err;
396 +       }
397 +
398 +       return 0;
399  }
400  
401  #else
402 @@ -185,6 +453,10 @@ static int ssb_gpio_extif_init(struct ss
403  }
404  #endif
405  
406 +/**************************************************
407 + * Init
408 + **************************************************/
409 +
410  int ssb_gpio_init(struct ssb_bus *bus)
411  {
412         if (ssb_chipco_available(&bus->chipco))
413 --- a/drivers/ssb/main.c
414 +++ b/drivers/ssb/main.c
415 @@ -590,6 +590,13 @@ static int ssb_attach_queued_buses(void)
416                 ssb_pcicore_init(&bus->pcicore);
417                 if (bus->bustype == SSB_BUSTYPE_SSB)
418                         ssb_watchdog_register(bus);
419 +
420 +               err = ssb_gpio_init(bus);
421 +               if (err == -ENOTSUPP)
422 +                       ssb_dbg("GPIO driver not activated\n");
423 +               else if (err)
424 +                       ssb_dbg("Error registering GPIO driver: %i\n", err);
425 +
426                 ssb_bus_may_powerdown(bus);
427  
428                 err = ssb_devices_register(bus);
429 @@ -827,11 +834,6 @@ static int ssb_bus_register(struct ssb_b
430         ssb_chipcommon_init(&bus->chipco);
431         ssb_extif_init(&bus->extif);
432         ssb_mipscore_init(&bus->mipscore);
433 -       err = ssb_gpio_init(bus);
434 -       if (err == -ENOTSUPP)
435 -               ssb_dbg("GPIO driver not activated\n");
436 -       else if (err)
437 -               ssb_dbg("Error registering GPIO driver: %i\n", err);
438         err = ssb_fetch_invariants(bus, get_invariants);
439         if (err) {
440                 ssb_bus_may_powerdown(bus);
441 --- a/include/linux/ssb/ssb.h
442 +++ b/include/linux/ssb/ssb.h
443 @@ -486,6 +486,7 @@ struct ssb_bus {
444  #endif /* EMBEDDED */
445  #ifdef CONFIG_SSB_DRIVER_GPIO
446         struct gpio_chip gpio;
447 +       struct irq_domain *irq_domain;
448  #endif /* DRIVER_GPIO */
449  
450         /* Internal-only stuff follows. Do not touch. */