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 | } | ||
