aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-at91/board-dt.c11
-rw-r--r--arch/arm/mach-at91/generic.h6
-rw-r--r--arch/arm/mach-at91/gpio.c122
-rw-r--r--arch/arm/mach-at91/irq.c90
4 files changed, 168 insertions, 61 deletions
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index 96d9a21dab68..acbe23c5b260 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -15,6 +15,8 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/gpio.h> 17#include <linux/gpio.h>
18#include <linux/of.h>
19#include <linux/of_irq.h>
18#include <linux/of_platform.h> 20#include <linux/of_platform.h>
19 21
20#include <mach/hardware.h> 22#include <mach/hardware.h>
@@ -80,9 +82,16 @@ static void __init ek_add_device_nand(void)
80 at91_add_device_nand(&ek_nand_data); 82 at91_add_device_nand(&ek_nand_data);
81} 83}
82 84
85static const struct of_device_id irq_of_match[] __initconst = {
86
87 { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
88 { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup },
89 { /*sentinel*/ }
90};
91
83static void __init at91_dt_init_irq(void) 92static void __init at91_dt_init_irq(void)
84{ 93{
85 at91_init_irq_default(); 94 of_irq_init(irq_of_match);
86} 95}
87 96
88static void __init at91_dt_device_init(void) 97static void __init at91_dt_device_init(void)
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 4cad85e57470..459f01a4a546 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/clkdev.h> 11#include <linux/clkdev.h>
12#include <linux/of.h>
12 13
13 /* Map io */ 14 /* Map io */
14extern void __init at91_map_io(void); 15extern void __init at91_map_io(void);
@@ -25,6 +26,9 @@ extern void __init at91_init_irq_default(void);
25extern void __init at91_init_interrupts(unsigned int priority[]); 26extern void __init at91_init_interrupts(unsigned int priority[]);
26extern void __init at91x40_init_interrupts(unsigned int priority[]); 27extern void __init at91x40_init_interrupts(unsigned int priority[]);
27extern void __init at91_aic_init(unsigned int priority[]); 28extern void __init at91_aic_init(unsigned int priority[]);
29extern int __init at91_aic_of_init(struct device_node *node,
30 struct device_node *parent);
31
28 32
29 /* Timer */ 33 /* Timer */
30struct sys_timer; 34struct sys_timer;
@@ -84,5 +88,7 @@ struct at91_gpio_bank {
84}; 88};
85extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); 89extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
86extern void __init at91_gpio_irq_setup(void); 90extern void __init at91_gpio_irq_setup(void);
91extern int __init at91_gpio_of_irq_setup(struct device_node *node,
92 struct device_node *parent);
87 93
88extern int at91_extern_irq; 94extern int at91_extern_irq;
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index ecf6bbb9103a..567df654a2e1 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -24,6 +24,7 @@
24#include <linux/irqdomain.h> 24#include <linux/irqdomain.h>
25#include <linux/of_address.h> 25#include <linux/of_address.h>
26#include <linux/of_irq.h> 26#include <linux/of_irq.h>
27#include <linux/of_gpio.h>
27 28
28#include <mach/hardware.h> 29#include <mach/hardware.h>
29#include <mach/at91_pio.h> 30#include <mach/at91_pio.h>
@@ -34,6 +35,7 @@ struct at91_gpio_chip {
34 struct gpio_chip chip; 35 struct gpio_chip chip;
35 struct at91_gpio_chip *next; /* Bank sharing same clock */ 36 struct at91_gpio_chip *next; /* Bank sharing same clock */
36 int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ 37 int pioc_hwirq; /* PIO bank interrupt identifier on AIC */
38 int pioc_virq; /* PIO bank Linux virtual interrupt */
37 int pioc_idx; /* PIO bank index */ 39 int pioc_idx; /* PIO bank index */
38 void __iomem *regbase; /* PIO bank virtual address */ 40 void __iomem *regbase; /* PIO bank virtual address */
39 struct clk *clock; /* associated clock */ 41 struct clk *clock; /* associated clock */
@@ -292,7 +294,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
292 else 294 else
293 wakeups[bank] &= ~mask; 295 wakeups[bank] &= ~mask;
294 296
295 irq_set_irq_wake(gpio_chip[bank].pioc_hwirq, state); 297 irq_set_irq_wake(at91_gpio->pioc_virq, state);
296 298
297 return 0; 299 return 0;
298} 300}
@@ -394,12 +396,12 @@ static struct irq_chip gpio_irqchip = {
394 396
395static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) 397static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
396{ 398{
397 unsigned virq;
398 struct irq_data *idata = irq_desc_get_irq_data(desc); 399 struct irq_data *idata = irq_desc_get_irq_data(desc);
399 struct irq_chip *chip = irq_data_get_irq_chip(idata); 400 struct irq_chip *chip = irq_data_get_irq_chip(idata);
400 struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); 401 struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata);
401 void __iomem *pio = at91_gpio->regbase; 402 void __iomem *pio = at91_gpio->regbase;
402 u32 isr; 403 unsigned long isr;
404 int n;
403 405
404 /* temporarily mask (level sensitive) parent IRQ */ 406 /* temporarily mask (level sensitive) parent IRQ */
405 chip->irq_ack(idata); 407 chip->irq_ack(idata);
@@ -417,13 +419,10 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
417 continue; 419 continue;
418 } 420 }
419 421
420 virq = gpio_to_irq(at91_gpio->chip.base); 422 n = find_first_bit(&isr, BITS_PER_LONG);
421 423 while (n < BITS_PER_LONG) {
422 while (isr) { 424 generic_handle_irq(irq_find_mapping(at91_gpio->domain, n));
423 if (isr & 1) 425 n = find_next_bit(&isr, BITS_PER_LONG, n + 1);
424 generic_handle_irq(virq);
425 virq++;
426 isr >>= 1;
427 } 426 }
428 } 427 }
429 chip->irq_unmask(idata); 428 chip->irq_unmask(idata);
@@ -493,23 +492,91 @@ postcore_initcall(at91_gpio_debugfs_init);
493/*--------------------------------------------------------------------------*/ 492/*--------------------------------------------------------------------------*/
494 493
495/* 494/*
495 * This lock class tells lockdep that GPIO irqs are in a different
496 * category than their parents, so it won't report false recursion.
497 */
498static struct lock_class_key gpio_lock_class;
499
500#if defined(CONFIG_OF)
501static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq,
502 irq_hw_number_t hw)
503{
504 struct at91_gpio_chip *at91_gpio = h->host_data;
505
506 irq_set_lockdep_class(virq, &gpio_lock_class);
507
508 /*
509 * Can use the "simple" and not "edge" handler since it's
510 * shorter, and the AIC handles interrupts sanely.
511 */
512 irq_set_chip_and_handler(virq, &gpio_irqchip,
513 handle_simple_irq);
514 set_irq_flags(virq, IRQF_VALID);
515 irq_set_chip_data(virq, at91_gpio);
516
517 return 0;
518}
519
520static struct irq_domain_ops at91_gpio_ops = {
521 .map = at91_gpio_irq_map,
522 .xlate = irq_domain_xlate_twocell,
523};
524
525int __init at91_gpio_of_irq_setup(struct device_node *node,
526 struct device_node *parent)
527{
528 struct at91_gpio_chip *prev = NULL;
529 int alias_idx = of_alias_get_id(node, "gpio");
530 struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx];
531
532 /* Disable irqs of this PIO controller */
533 __raw_writel(~0, at91_gpio->regbase + PIO_IDR);
534
535 /* Setup irq domain */
536 at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio,
537 &at91_gpio_ops, at91_gpio);
538 if (!at91_gpio->domain)
539 panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n",
540 at91_gpio->pioc_idx);
541
542 /* Setup chained handler */
543 if (at91_gpio->pioc_idx)
544 prev = &gpio_chip[at91_gpio->pioc_idx - 1];
545
546 /* The toplevel handler handles one bank of GPIOs, except
547 * on some SoC it can handles up to three...
548 * We only set up the handler for the first of the list.
549 */
550 if (prev && prev->next == at91_gpio)
551 return 0;
552
553 at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent),
554 at91_gpio->pioc_hwirq);
555 irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio);
556 irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler);
557
558 return 0;
559}
560#else
561int __init at91_gpio_of_irq_setup(struct device_node *node,
562 struct device_node *parent)
563{
564 return -EINVAL;
565}
566#endif
567
568/*
496 * irqdomain initialization: pile up irqdomains on top of AIC range 569 * irqdomain initialization: pile up irqdomains on top of AIC range
497 */ 570 */
498static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio) 571static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio)
499{ 572{
500 int irq_base; 573 int irq_base;
501#if defined(CONFIG_OF)
502 struct device_node *of_node = at91_gpio->chip.of_node;
503#else
504 struct device_node *of_node = NULL;
505#endif
506 574
507 irq_base = irq_alloc_descs(-1, 0, at91_gpio->chip.ngpio, 0); 575 irq_base = irq_alloc_descs(-1, 0, at91_gpio->chip.ngpio, 0);
508 if (irq_base < 0) 576 if (irq_base < 0)
509 panic("at91_gpio.%d: error %d: couldn't allocate IRQ numbers.\n", 577 panic("at91_gpio.%d: error %d: couldn't allocate IRQ numbers.\n",
510 at91_gpio->pioc_idx, irq_base); 578 at91_gpio->pioc_idx, irq_base);
511 at91_gpio->domain = irq_domain_add_legacy(of_node, 579 at91_gpio->domain = irq_domain_add_legacy(NULL, at91_gpio->chip.ngpio,
512 at91_gpio->chip.ngpio,
513 irq_base, 0, 580 irq_base, 0,
514 &irq_domain_simple_ops, NULL); 581 &irq_domain_simple_ops, NULL);
515 if (!at91_gpio->domain) 582 if (!at91_gpio->domain)
@@ -518,12 +585,6 @@ static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio)
518} 585}
519 586
520/* 587/*
521 * This lock class tells lockdep that GPIO irqs are in a different
522 * category than their parents, so it won't report false recursion.
523 */
524static struct lock_class_key gpio_lock_class;
525
526/*
527 * Called from the processor-specific init to enable GPIO interrupt support. 588 * Called from the processor-specific init to enable GPIO interrupt support.
528 */ 589 */
529void __init at91_gpio_irq_setup(void) 590void __init at91_gpio_irq_setup(void)
@@ -535,8 +596,7 @@ void __init at91_gpio_irq_setup(void)
535 for (pioc = 0, this = gpio_chip, prev = NULL; 596 for (pioc = 0, this = gpio_chip, prev = NULL;
536 pioc++ < gpio_banks; 597 pioc++ < gpio_banks;
537 prev = this, this++) { 598 prev = this, this++) {
538 unsigned pioc_hwirq = this->pioc_hwirq; 599 int offset;
539 int offset;
540 600
541 __raw_writel(~0, this->regbase + PIO_IDR); 601 __raw_writel(~0, this->regbase + PIO_IDR);
542 602
@@ -566,8 +626,9 @@ void __init at91_gpio_irq_setup(void)
566 if (prev && prev->next == this) 626 if (prev && prev->next == this)
567 continue; 627 continue;
568 628
569 irq_set_chip_data(pioc_hwirq, this); 629 this->pioc_virq = irq_create_mapping(NULL, this->pioc_hwirq);
570 irq_set_chained_handler(pioc_hwirq, gpio_irq_handler); 630 irq_set_chip_data(this->pioc_virq, this);
631 irq_set_chained_handler(this->pioc_virq, gpio_irq_handler);
571 } 632 }
572 pr_info("AT91: %d gpio irqs in %d banks\n", gpio_irqnbr, gpio_banks); 633 pr_info("AT91: %d gpio irqs in %d banks\n", gpio_irqnbr, gpio_banks);
573} 634}
@@ -645,7 +706,12 @@ static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
645static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset) 706static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset)
646{ 707{
647 struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); 708 struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
648 int virq = irq_find_mapping(at91_gpio->domain, offset); 709 int virq;
710
711 if (offset < chip->ngpio)
712 virq = irq_create_mapping(at91_gpio->domain, offset);
713 else
714 virq = -ENXIO;
649 715
650 dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", 716 dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
651 chip->label, offset + chip->base, virq); 717 chip->label, offset + chip->base, virq);
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index 46682fafa96f..cfcfcbe36269 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -135,27 +135,70 @@ static struct irq_chip at91_aic_chip = {
135 .irq_set_wake = at91_aic_set_wake, 135 .irq_set_wake = at91_aic_set_wake,
136}; 136};
137 137
138static void __init at91_aic_hw_init(unsigned int spu_vector)
139{
140 int i;
141
142 /*
143 * Perform 8 End Of Interrupt Command to make sure AIC
144 * will not Lock out nIRQ
145 */
146 for (i = 0; i < 8; i++)
147 at91_aic_write(AT91_AIC_EOICR, 0);
148
149 /*
150 * Spurious Interrupt ID in Spurious Vector Register.
151 * When there is no current interrupt, the IRQ Vector Register
152 * reads the value stored in AIC_SPU
153 */
154 at91_aic_write(AT91_AIC_SPU, spu_vector);
155
156 /* No debugging in AIC: Debug (Protect) Control Register */
157 at91_aic_write(AT91_AIC_DCR, 0);
158
159 /* Disable and clear all interrupts initially */
160 at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
161 at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
162}
163
138#if defined(CONFIG_OF) 164#if defined(CONFIG_OF)
139static int __init __at91_aic_of_init(struct device_node *node, 165static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq,
140 struct device_node *parent) 166 irq_hw_number_t hw)
141{ 167{
142 at91_aic_base = of_iomap(node, 0); 168 /* Put virq number in Source Vector Register */
143 at91_aic_np = node; 169 at91_aic_write(AT91_AIC_SVR(hw), virq);
170
171 /* Active Low interrupt, without priority */
172 at91_aic_write(AT91_AIC_SMR(hw), AT91_AIC_SRCTYPE_LOW);
173
174 irq_set_chip_and_handler(virq, &at91_aic_chip, handle_level_irq);
175 set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
144 176
145 return 0; 177 return 0;
146} 178}
147 179
148static const struct of_device_id aic_ids[] __initconst = { 180static struct irq_domain_ops at91_aic_irq_ops = {
149 { .compatible = "atmel,at91rm9200-aic", .data = __at91_aic_of_init }, 181 .map = at91_aic_irq_map,
150 { /*sentinel*/ } 182 .xlate = irq_domain_xlate_twocell,
151}; 183};
152 184
153static void __init at91_aic_of_init(void) 185int __init at91_aic_of_init(struct device_node *node,
186 struct device_node *parent)
154{ 187{
155 of_irq_init(aic_ids); 188 at91_aic_base = of_iomap(node, 0);
189 at91_aic_np = node;
190
191 at91_aic_domain = irq_domain_add_linear(at91_aic_np, NR_AIC_IRQS,
192 &at91_aic_irq_ops, NULL);
193 if (!at91_aic_domain)
194 panic("Unable to add AIC irq domain (DT)\n");
195
196 irq_set_default_host(at91_aic_domain);
197
198 at91_aic_hw_init(NR_AIC_IRQS);
199
200 return 0;
156} 201}
157#else
158static void __init at91_aic_of_init(void) {}
159#endif 202#endif
160 203
161/* 204/*
@@ -166,11 +209,7 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
166 unsigned int i; 209 unsigned int i;
167 int irq_base; 210 int irq_base;
168 211
169 if (of_have_populated_dt()) 212 at91_aic_base = ioremap(AT91_AIC, 512);
170 at91_aic_of_init();
171 else
172 at91_aic_base = ioremap(AT91_AIC, 512);
173
174 if (!at91_aic_base) 213 if (!at91_aic_base)
175 panic("Unable to ioremap AIC registers\n"); 214 panic("Unable to ioremap AIC registers\n");
176 215
@@ -187,6 +226,8 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
187 if (!at91_aic_domain) 226 if (!at91_aic_domain)
188 panic("Unable to add AIC irq domain\n"); 227 panic("Unable to add AIC irq domain\n");
189 228
229 irq_set_default_host(at91_aic_domain);
230
190 /* 231 /*
191 * The IVR is used by macro get_irqnr_and_base to read and verify. 232 * The IVR is used by macro get_irqnr_and_base to read and verify.
192 * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. 233 * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
@@ -199,22 +240,7 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
199 240
200 irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); 241 irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq);
201 set_irq_flags(i, IRQF_VALID | IRQF_PROBE); 242 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
202
203 /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
204 if (i < 8)
205 at91_aic_write(AT91_AIC_EOICR, 0);
206 } 243 }
207 244
208 /* 245 at91_aic_hw_init(NR_AIC_IRQS);
209 * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS
210 * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
211 */
212 at91_aic_write(AT91_AIC_SPU, NR_AIC_IRQS);
213
214 /* No debugging in AIC: Debug (Protect) Control Register */
215 at91_aic_write(AT91_AIC_DCR, 0);
216
217 /* Disable and clear all interrupts initially */
218 at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
219 at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
220} 246}