diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2012-02-11 09:41:40 -0500 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2012-03-01 07:29:01 -0500 |
commit | 21f81872788b8089ec4214afad8fc6a0a23f70c8 (patch) | |
tree | ab105f921cee41ed161e2a21d5ae0a470543572d | |
parent | 4340cde57d54db2078d0f1ef070664e21d32711d (diff) |
ARM: at91/gpio: add irqdomain and DT support
Add "legacy" type of irqdomain to preserve old-style numbering
and allow smooth transition for both DT and non-DT cases.
Original idea and code by Jean-Christophe Plagniol-Villard.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
-rw-r--r-- | Documentation/devicetree/bindings/gpio/gpio_atmel.txt | 20 | ||||
-rw-r--r-- | arch/arm/boot/dts/at91sam9g20.dtsi | 30 | ||||
-rw-r--r-- | arch/arm/boot/dts/at91sam9g45.dtsi | 50 | ||||
-rw-r--r-- | arch/arm/boot/dts/at91sam9x5.dtsi | 4 | ||||
-rw-r--r-- | arch/arm/mach-at91/gpio.c | 233 |
5 files changed, 291 insertions, 46 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt new file mode 100644 index 000000000000..a7bcaec913bf --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | * Atmel GPIO controller (PIO) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "atmel,at91rm9200-gpio" | ||
5 | - reg: Should contain GPIO controller registers location and length | ||
6 | - interrupts: Should be the port interrupt shared by all the pins. | ||
7 | - #gpio-cells: Should be two. The first cell is the pin number and | ||
8 | the second cell is used to specify optional parameters (currently | ||
9 | unused). | ||
10 | - gpio-controller: Marks the device node as a GPIO controller. | ||
11 | |||
12 | Example: | ||
13 | pioA: gpio@fffff200 { | ||
14 | compatible = "atmel,at91rm9200-gpio"; | ||
15 | reg = <0xfffff200 0x100>; | ||
16 | interrupts = <2 4>; | ||
17 | #gpio-cells = <2>; | ||
18 | gpio-controller; | ||
19 | }; | ||
20 | |||
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index 9a0aee791a40..325989a27a7a 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi | |||
@@ -23,6 +23,9 @@ | |||
23 | serial4 = &usart3; | 23 | serial4 = &usart3; |
24 | serial5 = &usart4; | 24 | serial5 = &usart4; |
25 | serial6 = &usart5; | 25 | serial6 = &usart5; |
26 | gpio0 = &pioA; | ||
27 | gpio1 = &pioB; | ||
28 | gpio2 = &pioC; | ||
26 | }; | 29 | }; |
27 | cpus { | 30 | cpus { |
28 | cpu@0 { | 31 | cpu@0 { |
@@ -54,6 +57,33 @@ | |||
54 | reg = <0xfffff000 0x200>; | 57 | reg = <0xfffff000 0x200>; |
55 | }; | 58 | }; |
56 | 59 | ||
60 | pioA: gpio@fffff400 { | ||
61 | compatible = "atmel,at91rm9200-gpio"; | ||
62 | reg = <0xfffff400 0x100>; | ||
63 | interrupts = <2 4>; | ||
64 | #gpio-cells = <2>; | ||
65 | gpio-controller; | ||
66 | interrupt-controller; | ||
67 | }; | ||
68 | |||
69 | pioB: gpio@fffff600 { | ||
70 | compatible = "atmel,at91rm9200-gpio"; | ||
71 | reg = <0xfffff600 0x100>; | ||
72 | interrupts = <3 4>; | ||
73 | #gpio-cells = <2>; | ||
74 | gpio-controller; | ||
75 | interrupt-controller; | ||
76 | }; | ||
77 | |||
78 | pioC: gpio@fffff800 { | ||
79 | compatible = "atmel,at91rm9200-gpio"; | ||
80 | reg = <0xfffff800 0x100>; | ||
81 | interrupts = <4 4>; | ||
82 | #gpio-cells = <2>; | ||
83 | gpio-controller; | ||
84 | interrupt-controller; | ||
85 | }; | ||
86 | |||
57 | dbgu: serial@fffff200 { | 87 | dbgu: serial@fffff200 { |
58 | compatible = "atmel,at91sam9260-usart"; | 88 | compatible = "atmel,at91sam9260-usart"; |
59 | reg = <0xfffff200 0x200>; | 89 | reg = <0xfffff200 0x200>; |
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 67f94d3698a2..a9dbbb5b86f5 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi | |||
@@ -22,6 +22,11 @@ | |||
22 | serial2 = &usart1; | 22 | serial2 = &usart1; |
23 | serial3 = &usart2; | 23 | serial3 = &usart2; |
24 | serial4 = &usart3; | 24 | serial4 = &usart3; |
25 | gpio0 = &pioA; | ||
26 | gpio1 = &pioB; | ||
27 | gpio2 = &pioC; | ||
28 | gpio3 = &pioD; | ||
29 | gpio4 = &pioE; | ||
25 | }; | 30 | }; |
26 | cpus { | 31 | cpus { |
27 | cpu@0 { | 32 | cpu@0 { |
@@ -59,6 +64,51 @@ | |||
59 | interrupts = <21 4>; | 64 | interrupts = <21 4>; |
60 | }; | 65 | }; |
61 | 66 | ||
67 | pioA: gpio@fffff200 { | ||
68 | compatible = "atmel,at91rm9200-gpio"; | ||
69 | reg = <0xfffff200 0x100>; | ||
70 | interrupts = <2 4>; | ||
71 | #gpio-cells = <2>; | ||
72 | gpio-controller; | ||
73 | interrupt-controller; | ||
74 | }; | ||
75 | |||
76 | pioB: gpio@fffff400 { | ||
77 | compatible = "atmel,at91rm9200-gpio"; | ||
78 | reg = <0xfffff400 0x100>; | ||
79 | interrupts = <3 4>; | ||
80 | #gpio-cells = <2>; | ||
81 | gpio-controller; | ||
82 | interrupt-controller; | ||
83 | }; | ||
84 | |||
85 | pioC: gpio@fffff600 { | ||
86 | compatible = "atmel,at91rm9200-gpio"; | ||
87 | reg = <0xfffff600 0x100>; | ||
88 | interrupts = <4 4>; | ||
89 | #gpio-cells = <2>; | ||
90 | gpio-controller; | ||
91 | interrupt-controller; | ||
92 | }; | ||
93 | |||
94 | pioD: gpio@fffff800 { | ||
95 | compatible = "atmel,at91rm9200-gpio"; | ||
96 | reg = <0xfffff800 0x100>; | ||
97 | interrupts = <5 4>; | ||
98 | #gpio-cells = <2>; | ||
99 | gpio-controller; | ||
100 | interrupt-controller; | ||
101 | }; | ||
102 | |||
103 | pioE: gpio@fffffa00 { | ||
104 | compatible = "atmel,at91rm9200-gpio"; | ||
105 | reg = <0xfffffa00 0x100>; | ||
106 | interrupts = <5 4>; | ||
107 | #gpio-cells = <2>; | ||
108 | gpio-controller; | ||
109 | interrupt-controller; | ||
110 | }; | ||
111 | |||
62 | dbgu: serial@ffffee00 { | 112 | dbgu: serial@ffffee00 { |
63 | compatible = "atmel,at91sam9260-usart"; | 113 | compatible = "atmel,at91sam9260-usart"; |
64 | reg = <0xffffee00 0x200>; | 114 | reg = <0xffffee00 0x200>; |
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index e91391f50730..bb0c676b3393 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi | |||
@@ -94,6 +94,7 @@ | |||
94 | interrupts = <2 4>; | 94 | interrupts = <2 4>; |
95 | #gpio-cells = <2>; | 95 | #gpio-cells = <2>; |
96 | gpio-controller; | 96 | gpio-controller; |
97 | interrupt-controller; | ||
97 | }; | 98 | }; |
98 | 99 | ||
99 | pioB: gpio@fffff600 { | 100 | pioB: gpio@fffff600 { |
@@ -102,6 +103,7 @@ | |||
102 | interrupts = <2 4>; | 103 | interrupts = <2 4>; |
103 | #gpio-cells = <2>; | 104 | #gpio-cells = <2>; |
104 | gpio-controller; | 105 | gpio-controller; |
106 | interrupt-controller; | ||
105 | }; | 107 | }; |
106 | 108 | ||
107 | pioC: gpio@fffff800 { | 109 | pioC: gpio@fffff800 { |
@@ -110,6 +112,7 @@ | |||
110 | interrupts = <3 4>; | 112 | interrupts = <3 4>; |
111 | #gpio-cells = <2>; | 113 | #gpio-cells = <2>; |
112 | gpio-controller; | 114 | gpio-controller; |
115 | interrupt-controller; | ||
113 | }; | 116 | }; |
114 | 117 | ||
115 | pioD: gpio@fffffa00 { | 118 | pioD: gpio@fffffa00 { |
@@ -118,6 +121,7 @@ | |||
118 | interrupts = <3 4>; | 121 | interrupts = <3 4>; |
119 | #gpio-cells = <2>; | 122 | #gpio-cells = <2>; |
120 | gpio-controller; | 123 | gpio-controller; |
124 | interrupt-controller; | ||
121 | }; | 125 | }; |
122 | 126 | ||
123 | dbgu: serial@fffff200 { | 127 | dbgu: serial@fffff200 { |
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index b762afc4ec17..89e683aaae6c 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/irqdomain.h> | ||
24 | #include <linux/of_address.h> | ||
25 | #include <linux/of_irq.h> | ||
23 | 26 | ||
24 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
25 | #include <mach/at91_pio.h> | 28 | #include <mach/at91_pio.h> |
@@ -30,8 +33,10 @@ struct at91_gpio_chip { | |||
30 | struct gpio_chip chip; | 33 | struct gpio_chip chip; |
31 | struct at91_gpio_chip *next; /* Bank sharing same clock */ | 34 | struct at91_gpio_chip *next; /* Bank sharing same clock */ |
32 | int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ | 35 | int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ |
36 | int pioc_idx; /* PIO bank index */ | ||
33 | void __iomem *regbase; /* PIO bank virtual address */ | 37 | void __iomem *regbase; /* PIO bank virtual address */ |
34 | struct clk *clock; /* associated clock */ | 38 | struct clk *clock; /* associated clock */ |
39 | struct irq_domain *domain; /* associated irq domain */ | ||
35 | }; | 40 | }; |
36 | 41 | ||
37 | #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) | 42 | #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) |
@@ -273,9 +278,9 @@ static u32 backups[MAX_GPIO_BANKS]; | |||
273 | 278 | ||
274 | static int gpio_irq_set_wake(struct irq_data *d, unsigned state) | 279 | static int gpio_irq_set_wake(struct irq_data *d, unsigned state) |
275 | { | 280 | { |
276 | unsigned pin = irq_to_gpio(d->irq); | 281 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); |
277 | unsigned mask = pin_to_mask(pin); | 282 | unsigned mask = 1 << d->hwirq; |
278 | unsigned bank = pin / 32; | 283 | unsigned bank = at91_gpio->pioc_idx; |
279 | 284 | ||
280 | if (unlikely(bank >= MAX_GPIO_BANKS)) | 285 | if (unlikely(bank >= MAX_GPIO_BANKS)) |
281 | return -EINVAL; | 286 | return -EINVAL; |
@@ -301,9 +306,10 @@ void at91_gpio_suspend(void) | |||
301 | __raw_writel(backups[i], pio + PIO_IDR); | 306 | __raw_writel(backups[i], pio + PIO_IDR); |
302 | __raw_writel(wakeups[i], pio + PIO_IER); | 307 | __raw_writel(wakeups[i], pio + PIO_IER); |
303 | 308 | ||
304 | if (!wakeups[i]) | 309 | if (!wakeups[i]) { |
310 | clk_unprepare(gpio_chip[i].clock); | ||
305 | clk_disable(gpio_chip[i].clock); | 311 | clk_disable(gpio_chip[i].clock); |
306 | else { | 312 | } else { |
307 | #ifdef CONFIG_PM_DEBUG | 313 | #ifdef CONFIG_PM_DEBUG |
308 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); | 314 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); |
309 | #endif | 315 | #endif |
@@ -318,8 +324,10 @@ void at91_gpio_resume(void) | |||
318 | for (i = 0; i < gpio_banks; i++) { | 324 | for (i = 0; i < gpio_banks; i++) { |
319 | void __iomem *pio = gpio_chip[i].regbase; | 325 | void __iomem *pio = gpio_chip[i].regbase; |
320 | 326 | ||
321 | if (!wakeups[i]) | 327 | if (!wakeups[i]) { |
322 | clk_enable(gpio_chip[i].clock); | 328 | if (clk_prepare(gpio_chip[i].clock) == 0) |
329 | clk_enable(gpio_chip[i].clock); | ||
330 | } | ||
323 | 331 | ||
324 | __raw_writel(wakeups[i], pio + PIO_IDR); | 332 | __raw_writel(wakeups[i], pio + PIO_IDR); |
325 | __raw_writel(backups[i], pio + PIO_IER); | 333 | __raw_writel(backups[i], pio + PIO_IER); |
@@ -344,9 +352,9 @@ void at91_gpio_resume(void) | |||
344 | 352 | ||
345 | static void gpio_irq_mask(struct irq_data *d) | 353 | static void gpio_irq_mask(struct irq_data *d) |
346 | { | 354 | { |
347 | unsigned pin = irq_to_gpio(d->irq); | 355 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); |
348 | void __iomem *pio = pin_to_controller(pin); | 356 | void __iomem *pio = at91_gpio->regbase; |
349 | unsigned mask = pin_to_mask(pin); | 357 | unsigned mask = 1 << d->hwirq; |
350 | 358 | ||
351 | if (pio) | 359 | if (pio) |
352 | __raw_writel(mask, pio + PIO_IDR); | 360 | __raw_writel(mask, pio + PIO_IDR); |
@@ -354,9 +362,9 @@ static void gpio_irq_mask(struct irq_data *d) | |||
354 | 362 | ||
355 | static void gpio_irq_unmask(struct irq_data *d) | 363 | static void gpio_irq_unmask(struct irq_data *d) |
356 | { | 364 | { |
357 | unsigned pin = irq_to_gpio(d->irq); | 365 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); |
358 | void __iomem *pio = pin_to_controller(pin); | 366 | void __iomem *pio = at91_gpio->regbase; |
359 | unsigned mask = pin_to_mask(pin); | 367 | unsigned mask = 1 << d->hwirq; |
360 | 368 | ||
361 | if (pio) | 369 | if (pio) |
362 | __raw_writel(mask, pio + PIO_IER); | 370 | __raw_writel(mask, pio + PIO_IER); |
@@ -384,7 +392,7 @@ static struct irq_chip gpio_irqchip = { | |||
384 | 392 | ||
385 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | 393 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) |
386 | { | 394 | { |
387 | unsigned irq_pin; | 395 | unsigned virq; |
388 | struct irq_data *idata = irq_desc_get_irq_data(desc); | 396 | struct irq_data *idata = irq_desc_get_irq_data(desc); |
389 | struct irq_chip *chip = irq_data_get_irq_chip(idata); | 397 | struct irq_chip *chip = irq_data_get_irq_chip(idata); |
390 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); | 398 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); |
@@ -407,12 +415,12 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
407 | continue; | 415 | continue; |
408 | } | 416 | } |
409 | 417 | ||
410 | irq_pin = gpio_to_irq(at91_gpio->chip.base); | 418 | virq = gpio_to_irq(at91_gpio->chip.base); |
411 | 419 | ||
412 | while (isr) { | 420 | while (isr) { |
413 | if (isr & 1) | 421 | if (isr & 1) |
414 | generic_handle_irq(irq_pin); | 422 | generic_handle_irq(virq); |
415 | irq_pin++; | 423 | virq++; |
416 | isr >>= 1; | 424 | isr >>= 1; |
417 | } | 425 | } |
418 | } | 426 | } |
@@ -483,6 +491,26 @@ postcore_initcall(at91_gpio_debugfs_init); | |||
483 | /*--------------------------------------------------------------------------*/ | 491 | /*--------------------------------------------------------------------------*/ |
484 | 492 | ||
485 | /* | 493 | /* |
494 | * irqdomain initialization: pile up irqdomains on top of AIC range | ||
495 | */ | ||
496 | static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio) | ||
497 | { | ||
498 | int irq_base; | ||
499 | |||
500 | irq_base = irq_alloc_descs(-1, 0, at91_gpio->chip.ngpio, 0); | ||
501 | if (irq_base < 0) | ||
502 | panic("at91_gpio.%d: error %d: couldn't allocate IRQ numbers.\n", | ||
503 | at91_gpio->pioc_idx, irq_base); | ||
504 | at91_gpio->domain = irq_domain_add_legacy(at91_gpio->chip.of_node, | ||
505 | at91_gpio->chip.ngpio, | ||
506 | irq_base, 0, | ||
507 | &irq_domain_simple_ops, NULL); | ||
508 | if (!at91_gpio->domain) | ||
509 | panic("at91_gpio.%d: couldn't allocate irq domain.\n", | ||
510 | at91_gpio->pioc_idx); | ||
511 | } | ||
512 | |||
513 | /* | ||
486 | * This lock class tells lockdep that GPIO irqs are in a different | 514 | * This lock class tells lockdep that GPIO irqs are in a different |
487 | * category than their parents, so it won't report false recursion. | 515 | * category than their parents, so it won't report false recursion. |
488 | */ | 516 | */ |
@@ -493,28 +521,35 @@ static struct lock_class_key gpio_lock_class; | |||
493 | */ | 521 | */ |
494 | void __init at91_gpio_irq_setup(void) | 522 | void __init at91_gpio_irq_setup(void) |
495 | { | 523 | { |
496 | unsigned pioc, irq = gpio_to_irq(0); | 524 | unsigned pioc; |
525 | int gpio_irqnbr = 0; | ||
497 | struct at91_gpio_chip *this, *prev; | 526 | struct at91_gpio_chip *this, *prev; |
498 | 527 | ||
499 | for (pioc = 0, this = gpio_chip, prev = NULL; | 528 | for (pioc = 0, this = gpio_chip, prev = NULL; |
500 | pioc++ < gpio_banks; | 529 | pioc++ < gpio_banks; |
501 | prev = this, this++) { | 530 | prev = this, this++) { |
502 | unsigned pioc_hwirq = this->pioc_hwirq; | 531 | unsigned pioc_hwirq = this->pioc_hwirq; |
503 | unsigned i; | 532 | int offset; |
504 | 533 | ||
505 | __raw_writel(~0, this->regbase + PIO_IDR); | 534 | __raw_writel(~0, this->regbase + PIO_IDR); |
506 | 535 | ||
507 | for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32; | 536 | /* setup irq domain for this GPIO controller */ |
508 | i++, irq++) { | 537 | at91_gpio_irqdomain(this); |
509 | irq_set_lockdep_class(irq, &gpio_lock_class); | 538 | |
539 | for (offset = 0; offset < this->chip.ngpio; offset++) { | ||
540 | unsigned int virq = irq_find_mapping(this->domain, offset); | ||
541 | irq_set_lockdep_class(virq, &gpio_lock_class); | ||
510 | 542 | ||
511 | /* | 543 | /* |
512 | * Can use the "simple" and not "edge" handler since it's | 544 | * Can use the "simple" and not "edge" handler since it's |
513 | * shorter, and the AIC handles interrupts sanely. | 545 | * shorter, and the AIC handles interrupts sanely. |
514 | */ | 546 | */ |
515 | irq_set_chip_and_handler(irq, &gpio_irqchip, | 547 | irq_set_chip_and_handler(virq, &gpio_irqchip, |
516 | handle_simple_irq); | 548 | handle_simple_irq); |
517 | set_irq_flags(irq, IRQF_VALID); | 549 | set_irq_flags(virq, IRQF_VALID); |
550 | irq_set_chip_data(virq, this); | ||
551 | |||
552 | gpio_irqnbr++; | ||
518 | } | 553 | } |
519 | 554 | ||
520 | /* The toplevel handler handles one bank of GPIOs, except | 555 | /* The toplevel handler handles one bank of GPIOs, except |
@@ -527,7 +562,7 @@ void __init at91_gpio_irq_setup(void) | |||
527 | irq_set_chip_data(pioc_hwirq, this); | 562 | irq_set_chip_data(pioc_hwirq, this); |
528 | irq_set_chained_handler(pioc_hwirq, gpio_irq_handler); | 563 | irq_set_chained_handler(pioc_hwirq, gpio_irq_handler); |
529 | } | 564 | } |
530 | pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks); | 565 | pr_info("AT91: %d gpio irqs in %d banks\n", gpio_irqnbr, gpio_banks); |
531 | } | 566 | } |
532 | 567 | ||
533 | /* gpiolib support */ | 568 | /* gpiolib support */ |
@@ -600,39 +635,145 @@ static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
600 | } | 635 | } |
601 | } | 636 | } |
602 | 637 | ||
638 | static int __init at91_gpio_setup_clk(int idx) | ||
639 | { | ||
640 | struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; | ||
641 | |||
642 | /* retreive PIO controller's clock */ | ||
643 | at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); | ||
644 | if (IS_ERR(at91_gpio->clock)) { | ||
645 | pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", idx); | ||
646 | goto err; | ||
647 | } | ||
648 | |||
649 | if (clk_prepare(at91_gpio->clock)) | ||
650 | goto clk_prep_err; | ||
651 | |||
652 | /* enable PIO controller's clock */ | ||
653 | if (clk_enable(at91_gpio->clock)) { | ||
654 | pr_err("at91_gpio.%d, failed to enable clock, ignoring.\n", idx); | ||
655 | goto clk_err; | ||
656 | } | ||
657 | |||
658 | return 0; | ||
659 | |||
660 | clk_err: | ||
661 | clk_unprepare(at91_gpio->clock); | ||
662 | clk_prep_err: | ||
663 | clk_put(at91_gpio->clock); | ||
664 | err: | ||
665 | return -EINVAL; | ||
666 | } | ||
667 | |||
668 | #ifdef CONFIG_OF_GPIO | ||
669 | static void __init of_at91_gpio_init_one(struct device_node *np) | ||
670 | { | ||
671 | int alias_idx; | ||
672 | struct at91_gpio_chip *at91_gpio; | ||
673 | |||
674 | if (!np) | ||
675 | return; | ||
676 | |||
677 | alias_idx = of_alias_get_id(np, "gpio"); | ||
678 | if (alias_idx >= MAX_GPIO_BANKS) { | ||
679 | pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n", | ||
680 | alias_idx, MAX_GPIO_BANKS); | ||
681 | return; | ||
682 | } | ||
683 | |||
684 | at91_gpio = &gpio_chip[alias_idx]; | ||
685 | at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio; | ||
686 | |||
687 | at91_gpio->regbase = of_iomap(np, 0); | ||
688 | if (!at91_gpio->regbase) { | ||
689 | pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", | ||
690 | alias_idx); | ||
691 | return; | ||
692 | } | ||
693 | |||
694 | /* Get the interrupts property */ | ||
695 | if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) { | ||
696 | pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n", | ||
697 | alias_idx); | ||
698 | goto ioremap_err; | ||
699 | } | ||
700 | |||
701 | /* Setup clock */ | ||
702 | if (at91_gpio_setup_clk(alias_idx)) | ||
703 | goto ioremap_err; | ||
704 | |||
705 | at91_gpio->chip.of_node = np; | ||
706 | gpio_banks = max(gpio_banks, alias_idx + 1); | ||
707 | at91_gpio->pioc_idx = alias_idx; | ||
708 | return; | ||
709 | |||
710 | ioremap_err: | ||
711 | iounmap(at91_gpio->regbase); | ||
712 | } | ||
713 | |||
714 | static int __init of_at91_gpio_init(void) | ||
715 | { | ||
716 | struct device_node *np = NULL; | ||
717 | |||
718 | /* | ||
719 | * This isn't ideal, but it gets things hooked up until this | ||
720 | * driver is converted into a platform_device | ||
721 | */ | ||
722 | for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio") | ||
723 | of_at91_gpio_init_one(np); | ||
724 | |||
725 | return gpio_banks > 0 ? 0 : -EINVAL; | ||
726 | } | ||
727 | #else | ||
728 | static int __init of_at91_gpio_init(void) | ||
729 | { | ||
730 | return -EINVAL; | ||
731 | } | ||
732 | #endif | ||
733 | |||
734 | static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) | ||
735 | { | ||
736 | struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; | ||
737 | |||
738 | at91_gpio->chip.base = idx * at91_gpio->chip.ngpio; | ||
739 | at91_gpio->pioc_hwirq = pioc_hwirq; | ||
740 | at91_gpio->pioc_idx = idx; | ||
741 | |||
742 | at91_gpio->regbase = ioremap(regbase, 512); | ||
743 | if (!at91_gpio->regbase) { | ||
744 | pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", idx); | ||
745 | return; | ||
746 | } | ||
747 | |||
748 | if (at91_gpio_setup_clk(idx)) | ||
749 | goto ioremap_err; | ||
750 | |||
751 | gpio_banks = max(gpio_banks, idx + 1); | ||
752 | return; | ||
753 | |||
754 | ioremap_err: | ||
755 | iounmap(at91_gpio->regbase); | ||
756 | } | ||
757 | |||
603 | /* | 758 | /* |
604 | * Called from the processor-specific init to enable GPIO pin support. | 759 | * Called from the processor-specific init to enable GPIO pin support. |
605 | */ | 760 | */ |
606 | void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) | 761 | void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) |
607 | { | 762 | { |
608 | unsigned i; | 763 | unsigned i; |
609 | struct at91_gpio_chip *at91_gpio, *last = NULL; | 764 | struct at91_gpio_chip *at91_gpio, *last = NULL; |
610 | 765 | ||
611 | BUG_ON(nr_banks > MAX_GPIO_BANKS); | 766 | BUG_ON(nr_banks > MAX_GPIO_BANKS); |
612 | 767 | ||
613 | gpio_banks = nr_banks; | 768 | if (of_at91_gpio_init() < 0) { |
769 | /* No GPIO controller found in device tree */ | ||
770 | for (i = 0; i < nr_banks; i++) | ||
771 | at91_gpio_init_one(i, data[i].regbase, data[i].id); | ||
772 | } | ||
614 | 773 | ||
615 | for (i = 0; i < nr_banks; i++) { | 774 | for (i = 0; i < gpio_banks; i++) { |
616 | at91_gpio = &gpio_chip[i]; | 775 | at91_gpio = &gpio_chip[i]; |
617 | 776 | ||
618 | at91_gpio->pioc_hwirq = data[i].pioc_hwirq; | ||
619 | at91_gpio->chip.base = i * 32; | ||
620 | |||
621 | at91_gpio->regbase = ioremap(data[i].regbase, 512); | ||
622 | if (!at91_gpio->regbase) { | ||
623 | pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i); | ||
624 | continue; | ||
625 | } | ||
626 | |||
627 | at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); | ||
628 | if (!at91_gpio->clock) { | ||
629 | pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", i); | ||
630 | continue; | ||
631 | } | ||
632 | |||
633 | /* enable PIO controller's clock */ | ||
634 | clk_enable(at91_gpio->clock); | ||
635 | |||
636 | /* | 777 | /* |
637 | * GPIO controller are grouped on some SoC: | 778 | * GPIO controller are grouped on some SoC: |
638 | * PIOC, PIOD and PIOE can share the same IRQ line | 779 | * PIOC, PIOD and PIOE can share the same IRQ line |