diff options
-rw-r--r-- | arch/mips/include/asm/gic.h | 29 | ||||
-rw-r--r-- | arch/mips/include/asm/mips-boards/maltaint.h | 55 | ||||
-rw-r--r-- | arch/mips/kernel/irq-gic.c | 35 | ||||
-rw-r--r-- | arch/mips/mti-malta/malta-int.c | 34 |
4 files changed, 81 insertions, 72 deletions
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 991b659e2548..77207fa459a5 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h | |||
@@ -341,15 +341,44 @@ struct gic_shared_intr_map { | |||
341 | unsigned int local_intr_mask; | 341 | unsigned int local_intr_mask; |
342 | }; | 342 | }; |
343 | 343 | ||
344 | /* GIC nomenclature for Core Interrupt Pins. */ | ||
345 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ | ||
346 | #define GIC_CPU_INT1 1 /* . */ | ||
347 | #define GIC_CPU_INT2 2 /* . */ | ||
348 | #define GIC_CPU_INT3 3 /* . */ | ||
349 | #define GIC_CPU_INT4 4 /* . */ | ||
350 | #define GIC_CPU_INT5 5 /* Core Interrupt 5 */ | ||
351 | |||
352 | /* Local GIC interrupts. */ | ||
353 | #define GIC_INT_TMR (GIC_CPU_INT5) | ||
354 | #define GIC_INT_PERFCTR (GIC_CPU_INT5) | ||
355 | |||
356 | /* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */ | ||
357 | #define GIC_CPU_TO_VEC_OFFSET (2) | ||
358 | |||
359 | /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ | ||
360 | #define GIC_PIN_TO_VEC_OFFSET (1) | ||
361 | |||
362 | extern unsigned long _gic_base; | ||
363 | extern unsigned int gic_irq_base; | ||
364 | extern unsigned int gic_irq_flags[]; | ||
365 | extern struct gic_shared_intr_map gic_shared_intr_map[]; | ||
366 | |||
344 | extern void gic_init(unsigned long gic_base_addr, | 367 | extern void gic_init(unsigned long gic_base_addr, |
345 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, | 368 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, |
346 | unsigned int intrmap_size, unsigned int irqbase); | 369 | unsigned int intrmap_size, unsigned int irqbase); |
347 | 370 | ||
371 | extern void gic_clocksource_init(unsigned int); | ||
348 | extern unsigned int gic_get_int(void); | 372 | extern unsigned int gic_get_int(void); |
349 | extern void gic_send_ipi(unsigned int intr); | 373 | extern void gic_send_ipi(unsigned int intr); |
350 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); | 374 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); |
351 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); | 375 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); |
352 | extern void gic_bind_eic_interrupt(int irq, int set); | 376 | extern void gic_bind_eic_interrupt(int irq, int set); |
353 | extern unsigned int gic_get_timer_pending(void); | 377 | extern unsigned int gic_get_timer_pending(void); |
378 | extern void gic_enable_interrupt(int irq_vec); | ||
379 | extern void gic_disable_interrupt(int irq_vec); | ||
380 | extern void gic_irq_ack(struct irq_data *d); | ||
381 | extern void gic_finish_irq(struct irq_data *d); | ||
382 | extern void gic_platform_init(int irqs, struct irq_chip *irq_controller); | ||
354 | 383 | ||
355 | #endif /* _ASM_GICREGS_H */ | 384 | #endif /* _ASM_GICREGS_H */ |
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index 5447d9fc4219..669244815753 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h | |||
@@ -1,31 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | 2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * | 4 | * for more details. |
5 | * ######################################################################## | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * ######################################################################## | ||
21 | * | ||
22 | * Defines for the Malta interrupt controller. | ||
23 | * | 5 | * |
6 | * Copyright (C) 2000,2012 MIPS Technologies, Inc. All rights reserved. | ||
7 | * Carsten Langgaard <carstenl@mips.com> | ||
8 | * Steven J. Hill <sjhill@mips.com> | ||
24 | */ | 9 | */ |
25 | #ifndef _MIPS_MALTAINT_H | 10 | #ifndef _MIPS_MALTAINT_H |
26 | #define _MIPS_MALTAINT_H | 11 | #define _MIPS_MALTAINT_H |
27 | 12 | ||
28 | #include <irq.h> | 13 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) |
29 | 14 | ||
30 | /* | 15 | /* |
31 | * Interrupts 0..15 are used for Malta ISA compatible interrupts | 16 | * Interrupts 0..15 are used for Malta ISA compatible interrupts |
@@ -78,26 +63,6 @@ | |||
78 | #define MSC01E_INT_PERFCTR 10 | 63 | #define MSC01E_INT_PERFCTR 10 |
79 | #define MSC01E_INT_CPUCTR 11 | 64 | #define MSC01E_INT_CPUCTR 11 |
80 | 65 | ||
81 | /* GIC's Nomenclature for Core Interrupt Pins on the Malta */ | ||
82 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ | ||
83 | #define GIC_CPU_INT1 1 /* . */ | ||
84 | #define GIC_CPU_INT2 2 /* . */ | ||
85 | #define GIC_CPU_INT3 3 /* . */ | ||
86 | #define GIC_CPU_INT4 4 /* . */ | ||
87 | #define GIC_CPU_INT5 5 /* Core Interrupt 5 */ | ||
88 | |||
89 | /* MALTA GIC local interrupts */ | ||
90 | #define GIC_INT_TMR (GIC_CPU_INT5) | ||
91 | #define GIC_INT_PERFCTR (GIC_CPU_INT5) | ||
92 | |||
93 | /* GIC constants */ | ||
94 | /* Add 2 to convert non-eic hw int # to eic vector # */ | ||
95 | #define GIC_CPU_TO_VEC_OFFSET (2) | ||
96 | /* If we map an intr to pin X, GIC will actually generate vector X+1 */ | ||
97 | #define GIC_PIN_TO_VEC_OFFSET (1) | ||
98 | |||
99 | #define GIC_EXT_INTR(x) x | ||
100 | |||
101 | /* External Interrupts used for IPI */ | 66 | /* External Interrupts used for IPI */ |
102 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 | 67 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 |
103 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 | 68 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 |
@@ -108,10 +73,4 @@ | |||
108 | #define GIC_IPI_EXT_INTR_RESCHED_VPE3 22 | 73 | #define GIC_IPI_EXT_INTR_RESCHED_VPE3 22 |
109 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23 | 74 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23 |
110 | 75 | ||
111 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
112 | |||
113 | #ifndef __ASSEMBLY__ | ||
114 | extern void maltaint_init(void); | ||
115 | #endif | ||
116 | |||
117 | #endif /* !(_MIPS_MALTAINT_H) */ | 76 | #endif /* !(_MIPS_MALTAINT_H) */ |
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index 0c527f652196..18124c3bda2f 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c | |||
@@ -12,12 +12,11 @@ | |||
12 | #include <asm-generic/bitops/find.h> | 12 | #include <asm-generic/bitops/find.h> |
13 | 13 | ||
14 | 14 | ||
15 | static unsigned long _gic_base; | 15 | unsigned long _gic_base; |
16 | static unsigned int _irqbase; | 16 | unsigned int gic_irq_base; |
17 | static unsigned int gic_irq_flags[GIC_NUM_INTRS]; | 17 | unsigned int gic_irq_flags[GIC_NUM_INTRS]; |
18 | #define GIC_IRQ_FLAG_EDGE 0x0001 | ||
19 | 18 | ||
20 | struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | 19 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; |
21 | static struct gic_pending_regs pending_regs[NR_CPUS]; | 20 | static struct gic_pending_regs pending_regs[NR_CPUS]; |
22 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; | 21 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; |
23 | 22 | ||
@@ -87,27 +86,16 @@ unsigned int gic_get_int(void) | |||
87 | return i; | 86 | return i; |
88 | } | 87 | } |
89 | 88 | ||
90 | static void gic_irq_ack(struct irq_data *d) | ||
91 | { | ||
92 | unsigned int irq = d->irq - _irqbase; | ||
93 | |||
94 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | ||
95 | GIC_CLR_INTR_MASK(irq); | ||
96 | |||
97 | if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE) | ||
98 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); | ||
99 | } | ||
100 | |||
101 | static void gic_mask_irq(struct irq_data *d) | 89 | static void gic_mask_irq(struct irq_data *d) |
102 | { | 90 | { |
103 | unsigned int irq = d->irq - _irqbase; | 91 | unsigned int irq = d->irq - gic_irq_base; |
104 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 92 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
105 | GIC_CLR_INTR_MASK(irq); | 93 | GIC_CLR_INTR_MASK(irq); |
106 | } | 94 | } |
107 | 95 | ||
108 | static void gic_unmask_irq(struct irq_data *d) | 96 | static void gic_unmask_irq(struct irq_data *d) |
109 | { | 97 | { |
110 | unsigned int irq = d->irq - _irqbase; | 98 | unsigned int irq = d->irq - gic_irq_base; |
111 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 99 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
112 | GIC_SET_INTR_MASK(irq); | 100 | GIC_SET_INTR_MASK(irq); |
113 | } | 101 | } |
@@ -119,7 +107,7 @@ static DEFINE_SPINLOCK(gic_lock); | |||
119 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, | 107 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, |
120 | bool force) | 108 | bool force) |
121 | { | 109 | { |
122 | unsigned int irq = d->irq - _irqbase; | 110 | unsigned int irq = d->irq - gic_irq_base; |
123 | cpumask_t tmp = CPU_MASK_NONE; | 111 | cpumask_t tmp = CPU_MASK_NONE; |
124 | unsigned long flags; | 112 | unsigned long flags; |
125 | int i; | 113 | int i; |
@@ -194,7 +182,7 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, | |||
194 | if (flags & GIC_FLAG_TRANSPARENT) | 182 | if (flags & GIC_FLAG_TRANSPARENT) |
195 | GIC_SET_INTR_MASK(intr); | 183 | GIC_SET_INTR_MASK(intr); |
196 | if (trigtype == GIC_TRIG_EDGE) | 184 | if (trigtype == GIC_TRIG_EDGE) |
197 | gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE; | 185 | gic_irq_flags[intr] |= GIC_TRIG_EDGE; |
198 | } | 186 | } |
199 | 187 | ||
200 | static void __init gic_basic_init(int numintrs, int numvpes, | 188 | static void __init gic_basic_init(int numintrs, int numvpes, |
@@ -227,9 +215,6 @@ static void __init gic_basic_init(int numintrs, int numvpes, | |||
227 | } | 215 | } |
228 | 216 | ||
229 | vpe_local_setup(numvpes); | 217 | vpe_local_setup(numvpes); |
230 | |||
231 | for (i = _irqbase; i < (_irqbase + numintrs); i++) | ||
232 | irq_set_chip(i, &gic_irq_controller); | ||
233 | } | 218 | } |
234 | 219 | ||
235 | void __init gic_init(unsigned long gic_base_addr, | 220 | void __init gic_init(unsigned long gic_base_addr, |
@@ -242,7 +227,7 @@ void __init gic_init(unsigned long gic_base_addr, | |||
242 | 227 | ||
243 | _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, | 228 | _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, |
244 | gic_addrspace_size); | 229 | gic_addrspace_size); |
245 | _irqbase = irqbase; | 230 | gic_irq_base = irqbase; |
246 | 231 | ||
247 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); | 232 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); |
248 | numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> | 233 | numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> |
@@ -255,4 +240,6 @@ void __init gic_init(unsigned long gic_base_addr, | |||
255 | pr_debug("%s called\n", __func__); | 240 | pr_debug("%s called\n", __func__); |
256 | 241 | ||
257 | gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); | 242 | gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); |
243 | |||
244 | gic_platform_init(numintrs, &gic_irq_controller); | ||
258 | } | 245 | } |
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 7b13a4caeea4..5222a7cc41e4 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
@@ -747,3 +747,37 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup) | |||
747 | 747 | ||
748 | return retval; | 748 | return retval; |
749 | } | 749 | } |
750 | |||
751 | void gic_enable_interrupt(int irq_vec) | ||
752 | { | ||
753 | GIC_SET_INTR_MASK(irq_vec); | ||
754 | } | ||
755 | |||
756 | void gic_disable_interrupt(int irq_vec) | ||
757 | { | ||
758 | GIC_CLR_INTR_MASK(irq_vec); | ||
759 | } | ||
760 | |||
761 | void gic_irq_ack(struct irq_data *d) | ||
762 | { | ||
763 | int irq = (d->irq - gic_irq_base); | ||
764 | |||
765 | GIC_CLR_INTR_MASK(irq); | ||
766 | |||
767 | if (gic_irq_flags[irq] & GIC_TRIG_EDGE) | ||
768 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); | ||
769 | } | ||
770 | |||
771 | void gic_finish_irq(struct irq_data *d) | ||
772 | { | ||
773 | /* Enable interrupts. */ | ||
774 | GIC_SET_INTR_MASK(d->irq - gic_irq_base); | ||
775 | } | ||
776 | |||
777 | void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) | ||
778 | { | ||
779 | int i; | ||
780 | |||
781 | for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) | ||
782 | irq_set_chip(i, irq_controller); | ||
783 | } | ||