irq.c (946e0f6ffcaa614012d646f4cf84efdd62628c8b) irq.c (f0bbe4dc5ce2dd610e1ec7dd3f428bb5670f9878)
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <john@phrozen.org>
7 * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
8 */

--- 52 unchanged lines hidden (view full) ---

61/* we have a cascade of 8 irqs */
62#define MIPS_CPU_IRQ_CASCADE 8
63
64#ifdef CONFIG_MIPS_MT_SMP
65int gic_present;
66#endif
67
68static int exin_avail;
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <john@phrozen.org>
7 * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
8 */

--- 52 unchanged lines hidden (view full) ---

61/* we have a cascade of 8 irqs */
62#define MIPS_CPU_IRQ_CASCADE 8
63
64#ifdef CONFIG_MIPS_MT_SMP
65int gic_present;
66#endif
67
68static int exin_avail;
69static struct resource ltq_eiu_irq[MAX_EIU];
69static u32 ltq_eiu_irq[MAX_EIU];
70static void __iomem *ltq_icu_membase[MAX_IM];
71static void __iomem *ltq_eiu_membase;
72static struct irq_domain *ltq_domain;
73static int ltq_perfcount_irq;
74
75int ltq_eiu_get_irq(int exin)
76{
77 if (exin < exin_avail)
70static void __iomem *ltq_icu_membase[MAX_IM];
71static void __iomem *ltq_eiu_membase;
72static struct irq_domain *ltq_domain;
73static int ltq_perfcount_irq;
74
75int ltq_eiu_get_irq(int exin)
76{
77 if (exin < exin_avail)
78 return ltq_eiu_irq[exin].start;
78 return ltq_eiu_irq[exin];
79 return -1;
80}
81
82void ltq_disable_irq(struct irq_data *d)
83{
84 u32 ier = LTQ_ICU_IM0_IER;
85 int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
86 int im = offset / INT_NUM_IM_OFFSET;

--- 34 unchanged lines hidden (view full) ---

121 ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier);
122}
123
124static int ltq_eiu_settype(struct irq_data *d, unsigned int type)
125{
126 int i;
127
128 for (i = 0; i < MAX_EIU; i++) {
79 return -1;
80}
81
82void ltq_disable_irq(struct irq_data *d)
83{
84 u32 ier = LTQ_ICU_IM0_IER;
85 int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
86 int im = offset / INT_NUM_IM_OFFSET;

--- 34 unchanged lines hidden (view full) ---

121 ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier);
122}
123
124static int ltq_eiu_settype(struct irq_data *d, unsigned int type)
125{
126 int i;
127
128 for (i = 0; i < MAX_EIU; i++) {
129 if (d->hwirq == ltq_eiu_irq[i].start) {
129 if (d->hwirq == ltq_eiu_irq[i]) {
130 int val = 0;
131 int edge = 0;
132
133 switch (type) {
134 case IRQF_TRIGGER_NONE:
135 break;
136 case IRQF_TRIGGER_RISING:
137 val = 1;

--- 31 unchanged lines hidden (view full) ---

169}
170
171static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
172{
173 int i;
174
175 ltq_enable_irq(d);
176 for (i = 0; i < MAX_EIU; i++) {
130 int val = 0;
131 int edge = 0;
132
133 switch (type) {
134 case IRQF_TRIGGER_NONE:
135 break;
136 case IRQF_TRIGGER_RISING:
137 val = 1;

--- 31 unchanged lines hidden (view full) ---

169}
170
171static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
172{
173 int i;
174
175 ltq_enable_irq(d);
176 for (i = 0; i < MAX_EIU; i++) {
177 if (d->hwirq == ltq_eiu_irq[i].start) {
177 if (d->hwirq == ltq_eiu_irq[i]) {
178 /* by default we are low level triggered */
179 ltq_eiu_settype(d, IRQF_TRIGGER_LOW);
180 /* clear all pending */
181 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INC) & ~BIT(i),
182 LTQ_EIU_EXIN_INC);
183 /* enable */
184 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i),
185 LTQ_EIU_EXIN_INEN);

--- 5 unchanged lines hidden (view full) ---

191}
192
193static void ltq_shutdown_eiu_irq(struct irq_data *d)
194{
195 int i;
196
197 ltq_disable_irq(d);
198 for (i = 0; i < MAX_EIU; i++) {
178 /* by default we are low level triggered */
179 ltq_eiu_settype(d, IRQF_TRIGGER_LOW);
180 /* clear all pending */
181 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INC) & ~BIT(i),
182 LTQ_EIU_EXIN_INC);
183 /* enable */
184 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i),
185 LTQ_EIU_EXIN_INEN);

--- 5 unchanged lines hidden (view full) ---

191}
192
193static void ltq_shutdown_eiu_irq(struct irq_data *d)
194{
195 int i;
196
197 ltq_disable_irq(d);
198 for (i = 0; i < MAX_EIU; i++) {
199 if (d->hwirq == ltq_eiu_irq[i].start) {
199 if (d->hwirq == ltq_eiu_irq[i]) {
200 /* disable */
201 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i),
202 LTQ_EIU_EXIN_INEN);
203 break;
204 }
205 }
206}
207

--- 128 unchanged lines hidden (view full) ---

336{
337 struct irq_chip *chip = &ltq_irq_type;
338 int i;
339
340 if (hw < MIPS_CPU_IRQ_CASCADE)
341 return 0;
342
343 for (i = 0; i < exin_avail; i++)
200 /* disable */
201 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i),
202 LTQ_EIU_EXIN_INEN);
203 break;
204 }
205 }
206}
207

--- 128 unchanged lines hidden (view full) ---

336{
337 struct irq_chip *chip = &ltq_irq_type;
338 int i;
339
340 if (hw < MIPS_CPU_IRQ_CASCADE)
341 return 0;
342
343 for (i = 0; i < exin_avail; i++)
344 if (hw == ltq_eiu_irq[i].start)
344 if (hw == ltq_eiu_irq[i])
345 chip = &ltq_eiu_type;
346
347 irq_set_chip_and_handler(hw, chip, handle_level_irq);
348
349 return 0;
350}
351
352static const struct irq_domain_ops irq_domain_ops = {

--- 81 unchanged lines hidden (view full) ---

434 */
435 if (MIPS_CPU_TIMER_IRQ != 7)
436 irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);
437
438 /* the external interrupts are optional and xway only */
439 eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
440 if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
441 /* find out how many external irq sources we have */
345 chip = &ltq_eiu_type;
346
347 irq_set_chip_and_handler(hw, chip, handle_level_irq);
348
349 return 0;
350}
351
352static const struct irq_domain_ops irq_domain_ops = {

--- 81 unchanged lines hidden (view full) ---

434 */
435 if (MIPS_CPU_TIMER_IRQ != 7)
436 irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);
437
438 /* the external interrupts are optional and xway only */
439 eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
440 if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
441 /* find out how many external irq sources we have */
442 exin_avail = of_irq_count(eiu_node);
442 exin_avail = of_property_count_u32_elems(eiu_node,
443 "lantiq,eiu-irqs");
443
444 if (exin_avail > MAX_EIU)
445 exin_avail = MAX_EIU;
446
444
445 if (exin_avail > MAX_EIU)
446 exin_avail = MAX_EIU;
447
447 ret = of_irq_to_resource_table(eiu_node,
448 ret = of_property_read_u32_array(eiu_node, "lantiq,eiu-irqs",
448 ltq_eiu_irq, exin_avail);
449 ltq_eiu_irq, exin_avail);
449 if (ret != exin_avail)
450 if (ret)
450 panic("failed to load external irq resources");
451
452 if (!request_mem_region(res.start, resource_size(&res),
453 res.name))
454 pr_err("Failed to request eiu memory");
455
456 ltq_eiu_membase = ioremap_nocache(res.start,
457 resource_size(&res));

--- 27 unchanged lines hidden ---
451 panic("failed to load external irq resources");
452
453 if (!request_mem_region(res.start, resource_size(&res),
454 res.name))
455 pr_err("Failed to request eiu memory");
456
457 ltq_eiu_membase = ioremap_nocache(res.start,
458 resource_size(&res));

--- 27 unchanged lines hidden ---