aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/common/irq.c
diff options
context:
space:
mode:
authorJayachandran C <jayachandranc@netlogicmicro.com>2011-11-11 06:38:29 -0500
committerRalf Baechle <ralf@linux-mips.org>2011-12-07 17:04:55 -0500
commit0c9654072a6e15aa3da9b314f0c5c01e90938268 (patch)
tree865bbcf93aac081b15bf38604384e4bf7620024b /arch/mips/netlogic/common/irq.c
parent99fb2f7984726ba03d5634df8e6d26eb891f1ec3 (diff)
MIPS: Netlogic: Move code common with XLP to common/
- Move code that can be shared with XLP (irq.c, smp.c, time.c and xlr_console.c) to arch/mips/netlogic/common - Add asm/netlogic/haldefs.h and asm/netlogic/common.h for common and io functions shared with XLP - remove type 'nlm_reg_t *' and use uint64_t for mmio offsets - Move XLR specific code in smp.c to xlr/wakeup.c - Move XLR specific PCI code from irq.c to mips/pci/pci-xlr.c - Provide API for pic functions called from common/irq.c Signed-off-by: Jayachandran C <jayachandranc@netlogicmicro.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2964/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/netlogic/common/irq.c')
-rw-r--r--arch/mips/netlogic/common/irq.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
new file mode 100644
index 000000000000..dd0dd626cc8f
--- /dev/null
+++ b/arch/mips/netlogic/common/irq.c
@@ -0,0 +1,230 @@
1/*
2 * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
3 * reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the NetLogic
9 * license below:
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
32 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <linux/kernel.h>
36#include <linux/init.h>
37#include <linux/linkage.h>
38#include <linux/interrupt.h>
39#include <linux/spinlock.h>
40#include <linux/mm.h>
41#include <linux/slab.h>
42#include <linux/irq.h>
43
44#include <asm/errno.h>
45#include <asm/signal.h>
46#include <asm/system.h>
47#include <asm/ptrace.h>
48#include <asm/mipsregs.h>
49#include <asm/thread_info.h>
50
51#include <asm/netlogic/mips-extns.h>
52#include <asm/netlogic/interrupt.h>
53#include <asm/netlogic/haldefs.h>
54#include <asm/netlogic/common.h>
55
56#include <asm/netlogic/xlr/iomap.h>
57#include <asm/netlogic/xlr/pic.h>
58/*
59 * These are the routines that handle all the low level interrupt stuff.
60 * Actions handled here are: initialization of the interrupt map, requesting of
61 * interrupt lines by handlers, dispatching if interrupts to handlers, probing
62 * for interrupt lines
63 */
64
65/* Globals */
66static uint64_t nlm_irq_mask;
67static DEFINE_SPINLOCK(nlm_pic_lock);
68
69static void xlp_pic_enable(struct irq_data *d)
70{
71 unsigned long flags;
72 int irt;
73
74 irt = nlm_irq_to_irt(d->irq);
75 if (irt == -1)
76 return;
77 spin_lock_irqsave(&nlm_pic_lock, flags);
78 nlm_pic_enable_irt(nlm_pic_base, irt);
79 spin_unlock_irqrestore(&nlm_pic_lock, flags);
80}
81
82static void xlp_pic_disable(struct irq_data *d)
83{
84 unsigned long flags;
85 int irt;
86
87 irt = nlm_irq_to_irt(d->irq);
88 if (irt == -1)
89 return;
90 spin_lock_irqsave(&nlm_pic_lock, flags);
91 nlm_pic_disable_irt(nlm_pic_base, irt);
92 spin_unlock_irqrestore(&nlm_pic_lock, flags);
93}
94
95static void xlp_pic_mask_ack(struct irq_data *d)
96{
97 uint64_t mask = 1ull << d->irq;
98
99 write_c0_eirr(mask); /* ack by writing EIRR */
100}
101
102static void xlp_pic_unmask(struct irq_data *d)
103{
104 void *hd = irq_data_get_irq_handler_data(d);
105 int irt;
106
107 irt = nlm_irq_to_irt(d->irq);
108 if (irt == -1)
109 return;
110
111 if (hd) {
112 void (*extra_ack)(void *) = hd;
113 extra_ack(d);
114 }
115 /* Ack is a single write, no need to lock */
116 nlm_pic_ack(nlm_pic_base, irt);
117}
118
119static struct irq_chip xlp_pic = {
120 .name = "XLP-PIC",
121 .irq_enable = xlp_pic_enable,
122 .irq_disable = xlp_pic_disable,
123 .irq_mask_ack = xlp_pic_mask_ack,
124 .irq_unmask = xlp_pic_unmask,
125};
126
127static void cpuintr_disable(struct irq_data *d)
128{
129 uint64_t eimr;
130 uint64_t mask = 1ull << d->irq;
131
132 eimr = read_c0_eimr();
133 write_c0_eimr(eimr & ~mask);
134}
135
136static void cpuintr_enable(struct irq_data *d)
137{
138 uint64_t eimr;
139 uint64_t mask = 1ull << d->irq;
140
141 eimr = read_c0_eimr();
142 write_c0_eimr(eimr | mask);
143}
144
145static void cpuintr_ack(struct irq_data *d)
146{
147 uint64_t mask = 1ull << d->irq;
148
149 write_c0_eirr(mask);
150}
151
152static void cpuintr_nop(struct irq_data *d)
153{
154 WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq);
155}
156
157/*
158 * Chip definition for CPU originated interrupts(timer, msg) and
159 * IPIs
160 */
161struct irq_chip nlm_cpu_intr = {
162 .name = "XLP-CPU-INTR",
163 .irq_enable = cpuintr_enable,
164 .irq_disable = cpuintr_disable,
165 .irq_mask = cpuintr_nop,
166 .irq_ack = cpuintr_nop,
167 .irq_eoi = cpuintr_ack,
168};
169
170void __init init_nlm_common_irqs(void)
171{
172 int i, irq, irt;
173
174 for (i = 0; i < PIC_IRT_FIRST_IRQ; i++)
175 irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq);
176
177 for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ ; i++)
178 irq_set_chip_and_handler(i, &xlp_pic, handle_level_irq);
179
180#ifdef CONFIG_SMP
181 irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr,
182 nlm_smp_function_ipi_handler);
183 irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,
184 nlm_smp_resched_ipi_handler);
185 nlm_irq_mask |=
186 ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));
187#endif
188
189 for (irq = PIC_IRT_FIRST_IRQ; irq <= PIC_IRT_LAST_IRQ; irq++) {
190 irt = nlm_irq_to_irt(irq);
191 if (irt == -1)
192 continue;
193 nlm_irq_mask |= (1ULL << irq);
194 nlm_pic_init_irt(nlm_pic_base, irt, irq, 0);
195 }
196
197 nlm_irq_mask |= (1ULL << IRQ_TIMER);
198}
199
200void __init arch_init_irq(void)
201{
202 /* Initialize the irq descriptors */
203 init_nlm_common_irqs();
204
205 write_c0_eimr(nlm_irq_mask);
206}
207
208void __cpuinit nlm_smp_irq_init(void)
209{
210 /* set interrupt mask for non-zero cpus */
211 write_c0_eimr(nlm_irq_mask);
212}
213
214asmlinkage void plat_irq_dispatch(void)
215{
216 uint64_t eirr;
217 int i;
218
219 eirr = read_c0_eirr() & read_c0_eimr();
220 if (eirr & (1 << IRQ_TIMER)) {
221 do_IRQ(IRQ_TIMER);
222 return;
223 }
224
225 i = __ilog2_u64(eirr);
226 if (i == -1)
227 return;
228
229 do_IRQ(i);
230}