aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorSteven J. Hill <sjhill@mips.com>2012-08-31 17:05:37 -0400
committerSteven J. Hill <sjhill@mips.com>2012-09-13 16:43:47 -0400
commit0b271f5600b5ae56d331a18da830e33f9fb0acdc (patch)
treed49f4e86e0563aa212545587adacb15170978082 /arch/mips
parentec47b27434eff8ad41e7389efca1e5a6ca8b519a (diff)
MIPS: Make GIC code platform independent.
The GIC interrupt code is used by multiple platforms and the current code was half Malta dependent code. These changes abstract away the platform specific differences. Signed-off-by: Steven J. Hill <sjhill@mips.com>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/gic.h29
-rw-r--r--arch/mips/include/asm/mips-boards/maltaint.h55
-rw-r--r--arch/mips/kernel/irq-gic.c35
-rw-r--r--arch/mips/mti-malta/malta-int.c34
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
362extern unsigned long _gic_base;
363extern unsigned int gic_irq_base;
364extern unsigned int gic_irq_flags[];
365extern struct gic_shared_intr_map gic_shared_intr_map[];
366
344extern void gic_init(unsigned long gic_base_addr, 367extern 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
371extern void gic_clocksource_init(unsigned int);
348extern unsigned int gic_get_int(void); 372extern unsigned int gic_get_int(void);
349extern void gic_send_ipi(unsigned int intr); 373extern void gic_send_ipi(unsigned int intr);
350extern unsigned int plat_ipi_call_int_xlate(unsigned int); 374extern unsigned int plat_ipi_call_int_xlate(unsigned int);
351extern unsigned int plat_ipi_resched_int_xlate(unsigned int); 375extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
352extern void gic_bind_eic_interrupt(int irq, int set); 376extern void gic_bind_eic_interrupt(int irq, int set);
353extern unsigned int gic_get_timer_pending(void); 377extern unsigned int gic_get_timer_pending(void);
378extern void gic_enable_interrupt(int irq_vec);
379extern void gic_disable_interrupt(int irq_vec);
380extern void gic_irq_ack(struct irq_data *d);
381extern void gic_finish_irq(struct irq_data *d);
382extern 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__
114extern 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
15static unsigned long _gic_base; 15unsigned long _gic_base;
16static unsigned int _irqbase; 16unsigned int gic_irq_base;
17static unsigned int gic_irq_flags[GIC_NUM_INTRS]; 17unsigned int gic_irq_flags[GIC_NUM_INTRS];
18#define GIC_IRQ_FLAG_EDGE 0x0001
19 18
20struct gic_pcpu_mask pcpu_masks[NR_CPUS]; 19static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
21static struct gic_pending_regs pending_regs[NR_CPUS]; 20static struct gic_pending_regs pending_regs[NR_CPUS];
22static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; 21static 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
90static 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
101static void gic_mask_irq(struct irq_data *d) 89static 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
108static void gic_unmask_irq(struct irq_data *d) 96static 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);
119static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, 107static 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
200static void __init gic_basic_init(int numintrs, int numvpes, 188static 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
235void __init gic_init(unsigned long gic_base_addr, 220void __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
751void gic_enable_interrupt(int irq_vec)
752{
753 GIC_SET_INTR_MASK(irq_vec);
754}
755
756void gic_disable_interrupt(int irq_vec)
757{
758 GIC_CLR_INTR_MASK(irq_vec);
759}
760
761void 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
771void gic_finish_irq(struct irq_data *d)
772{
773 /* Enable interrupts. */
774 GIC_SET_INTR_MASK(d->irq - gic_irq_base);
775}
776
777void __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}