Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/common/gic.c
10819 views
1
/*
2
* linux/arch/arm/common/gic.c
3
*
4
* Copyright (C) 2002 ARM Limited, All Rights Reserved.
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
9
*
10
* Interrupt architecture for the GIC:
11
*
12
* o There is one Interrupt Distributor, which receives interrupts
13
* from system devices and sends them to the Interrupt Controllers.
14
*
15
* o There is one CPU Interface per CPU, which sends interrupts sent
16
* by the Distributor, and interrupts generated locally, to the
17
* associated CPU. The base address of the CPU interface is usually
18
* aliased so that the same address points to different chips depending
19
* on the CPU it is accessed from.
20
*
21
* Note that IRQs 0-31 are special - they are local to each CPU.
22
* As such, the enable set/clear, pending set/clear and active bit
23
* registers are banked per-cpu for these sources.
24
*/
25
#include <linux/init.h>
26
#include <linux/kernel.h>
27
#include <linux/list.h>
28
#include <linux/smp.h>
29
#include <linux/cpumask.h>
30
#include <linux/io.h>
31
32
#include <asm/irq.h>
33
#include <asm/mach/irq.h>
34
#include <asm/hardware/gic.h>
35
36
static DEFINE_SPINLOCK(irq_controller_lock);
37
38
/* Address of GIC 0 CPU interface */
39
void __iomem *gic_cpu_base_addr __read_mostly;
40
41
struct gic_chip_data {
42
unsigned int irq_offset;
43
void __iomem *dist_base;
44
void __iomem *cpu_base;
45
};
46
47
/*
48
* Supported arch specific GIC irq extension.
49
* Default make them NULL.
50
*/
51
struct irq_chip gic_arch_extn = {
52
.irq_eoi = NULL,
53
.irq_mask = NULL,
54
.irq_unmask = NULL,
55
.irq_retrigger = NULL,
56
.irq_set_type = NULL,
57
.irq_set_wake = NULL,
58
};
59
60
#ifndef MAX_GIC_NR
61
#define MAX_GIC_NR 1
62
#endif
63
64
static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
65
66
static inline void __iomem *gic_dist_base(struct irq_data *d)
67
{
68
struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
69
return gic_data->dist_base;
70
}
71
72
static inline void __iomem *gic_cpu_base(struct irq_data *d)
73
{
74
struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
75
return gic_data->cpu_base;
76
}
77
78
static inline unsigned int gic_irq(struct irq_data *d)
79
{
80
struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
81
return d->irq - gic_data->irq_offset;
82
}
83
84
/*
85
* Routines to acknowledge, disable and enable interrupts
86
*/
87
static void gic_mask_irq(struct irq_data *d)
88
{
89
u32 mask = 1 << (d->irq % 32);
90
91
spin_lock(&irq_controller_lock);
92
writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
93
if (gic_arch_extn.irq_mask)
94
gic_arch_extn.irq_mask(d);
95
spin_unlock(&irq_controller_lock);
96
}
97
98
static void gic_unmask_irq(struct irq_data *d)
99
{
100
u32 mask = 1 << (d->irq % 32);
101
102
spin_lock(&irq_controller_lock);
103
if (gic_arch_extn.irq_unmask)
104
gic_arch_extn.irq_unmask(d);
105
writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
106
spin_unlock(&irq_controller_lock);
107
}
108
109
static void gic_eoi_irq(struct irq_data *d)
110
{
111
if (gic_arch_extn.irq_eoi) {
112
spin_lock(&irq_controller_lock);
113
gic_arch_extn.irq_eoi(d);
114
spin_unlock(&irq_controller_lock);
115
}
116
117
writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
118
}
119
120
static int gic_set_type(struct irq_data *d, unsigned int type)
121
{
122
void __iomem *base = gic_dist_base(d);
123
unsigned int gicirq = gic_irq(d);
124
u32 enablemask = 1 << (gicirq % 32);
125
u32 enableoff = (gicirq / 32) * 4;
126
u32 confmask = 0x2 << ((gicirq % 16) * 2);
127
u32 confoff = (gicirq / 16) * 4;
128
bool enabled = false;
129
u32 val;
130
131
/* Interrupt configuration for SGIs can't be changed */
132
if (gicirq < 16)
133
return -EINVAL;
134
135
if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
136
return -EINVAL;
137
138
spin_lock(&irq_controller_lock);
139
140
if (gic_arch_extn.irq_set_type)
141
gic_arch_extn.irq_set_type(d, type);
142
143
val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
144
if (type == IRQ_TYPE_LEVEL_HIGH)
145
val &= ~confmask;
146
else if (type == IRQ_TYPE_EDGE_RISING)
147
val |= confmask;
148
149
/*
150
* As recommended by the spec, disable the interrupt before changing
151
* the configuration
152
*/
153
if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
154
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
155
enabled = true;
156
}
157
158
writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
159
160
if (enabled)
161
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
162
163
spin_unlock(&irq_controller_lock);
164
165
return 0;
166
}
167
168
static int gic_retrigger(struct irq_data *d)
169
{
170
if (gic_arch_extn.irq_retrigger)
171
return gic_arch_extn.irq_retrigger(d);
172
173
return -ENXIO;
174
}
175
176
#ifdef CONFIG_SMP
177
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
178
bool force)
179
{
180
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
181
unsigned int shift = (d->irq % 4) * 8;
182
unsigned int cpu = cpumask_first(mask_val);
183
u32 val, mask, bit;
184
185
if (cpu >= 8)
186
return -EINVAL;
187
188
mask = 0xff << shift;
189
bit = 1 << (cpu + shift);
190
191
spin_lock(&irq_controller_lock);
192
d->node = cpu;
193
val = readl_relaxed(reg) & ~mask;
194
writel_relaxed(val | bit, reg);
195
spin_unlock(&irq_controller_lock);
196
197
return 0;
198
}
199
#endif
200
201
#ifdef CONFIG_PM
202
static int gic_set_wake(struct irq_data *d, unsigned int on)
203
{
204
int ret = -ENXIO;
205
206
if (gic_arch_extn.irq_set_wake)
207
ret = gic_arch_extn.irq_set_wake(d, on);
208
209
return ret;
210
}
211
212
#else
213
#define gic_set_wake NULL
214
#endif
215
216
static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
217
{
218
struct gic_chip_data *chip_data = irq_get_handler_data(irq);
219
struct irq_chip *chip = irq_get_chip(irq);
220
unsigned int cascade_irq, gic_irq;
221
unsigned long status;
222
223
chained_irq_enter(chip, desc);
224
225
spin_lock(&irq_controller_lock);
226
status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK);
227
spin_unlock(&irq_controller_lock);
228
229
gic_irq = (status & 0x3ff);
230
if (gic_irq == 1023)
231
goto out;
232
233
cascade_irq = gic_irq + chip_data->irq_offset;
234
if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
235
do_bad_IRQ(cascade_irq, desc);
236
else
237
generic_handle_irq(cascade_irq);
238
239
out:
240
chained_irq_exit(chip, desc);
241
}
242
243
static struct irq_chip gic_chip = {
244
.name = "GIC",
245
.irq_mask = gic_mask_irq,
246
.irq_unmask = gic_unmask_irq,
247
.irq_eoi = gic_eoi_irq,
248
.irq_set_type = gic_set_type,
249
.irq_retrigger = gic_retrigger,
250
#ifdef CONFIG_SMP
251
.irq_set_affinity = gic_set_affinity,
252
#endif
253
.irq_set_wake = gic_set_wake,
254
};
255
256
void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
257
{
258
if (gic_nr >= MAX_GIC_NR)
259
BUG();
260
if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0)
261
BUG();
262
irq_set_chained_handler(irq, gic_handle_cascade_irq);
263
}
264
265
static void __init gic_dist_init(struct gic_chip_data *gic,
266
unsigned int irq_start)
267
{
268
unsigned int gic_irqs, irq_limit, i;
269
void __iomem *base = gic->dist_base;
270
u32 cpumask = 1 << smp_processor_id();
271
272
cpumask |= cpumask << 8;
273
cpumask |= cpumask << 16;
274
275
writel_relaxed(0, base + GIC_DIST_CTRL);
276
277
/*
278
* Find out how many interrupts are supported.
279
* The GIC only supports up to 1020 interrupt sources.
280
*/
281
gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f;
282
gic_irqs = (gic_irqs + 1) * 32;
283
if (gic_irqs > 1020)
284
gic_irqs = 1020;
285
286
/*
287
* Set all global interrupts to be level triggered, active low.
288
*/
289
for (i = 32; i < gic_irqs; i += 16)
290
writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16);
291
292
/*
293
* Set all global interrupts to this CPU only.
294
*/
295
for (i = 32; i < gic_irqs; i += 4)
296
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
297
298
/*
299
* Set priority on all global interrupts.
300
*/
301
for (i = 32; i < gic_irqs; i += 4)
302
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
303
304
/*
305
* Disable all interrupts. Leave the PPI and SGIs alone
306
* as these enables are banked registers.
307
*/
308
for (i = 32; i < gic_irqs; i += 32)
309
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
310
311
/*
312
* Limit number of interrupts registered to the platform maximum
313
*/
314
irq_limit = gic->irq_offset + gic_irqs;
315
if (WARN_ON(irq_limit > NR_IRQS))
316
irq_limit = NR_IRQS;
317
318
/*
319
* Setup the Linux IRQ subsystem.
320
*/
321
for (i = irq_start; i < irq_limit; i++) {
322
irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
323
irq_set_chip_data(i, gic);
324
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
325
}
326
327
writel_relaxed(1, base + GIC_DIST_CTRL);
328
}
329
330
static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
331
{
332
void __iomem *dist_base = gic->dist_base;
333
void __iomem *base = gic->cpu_base;
334
int i;
335
336
/*
337
* Deal with the banked PPI and SGI interrupts - disable all
338
* PPI interrupts, ensure all SGI interrupts are enabled.
339
*/
340
writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
341
writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
342
343
/*
344
* Set priority on PPI and SGI interrupts
345
*/
346
for (i = 0; i < 32; i += 4)
347
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
348
349
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
350
writel_relaxed(1, base + GIC_CPU_CTRL);
351
}
352
353
void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
354
void __iomem *dist_base, void __iomem *cpu_base)
355
{
356
struct gic_chip_data *gic;
357
358
BUG_ON(gic_nr >= MAX_GIC_NR);
359
360
gic = &gic_data[gic_nr];
361
gic->dist_base = dist_base;
362
gic->cpu_base = cpu_base;
363
gic->irq_offset = (irq_start - 1) & ~31;
364
365
if (gic_nr == 0)
366
gic_cpu_base_addr = cpu_base;
367
368
gic_dist_init(gic, irq_start);
369
gic_cpu_init(gic);
370
}
371
372
void __cpuinit gic_secondary_init(unsigned int gic_nr)
373
{
374
BUG_ON(gic_nr >= MAX_GIC_NR);
375
376
gic_cpu_init(&gic_data[gic_nr]);
377
}
378
379
void __cpuinit gic_enable_ppi(unsigned int irq)
380
{
381
unsigned long flags;
382
383
local_irq_save(flags);
384
irq_set_status_flags(irq, IRQ_NOPROBE);
385
gic_unmask_irq(irq_get_irq_data(irq));
386
local_irq_restore(flags);
387
}
388
389
#ifdef CONFIG_SMP
390
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
391
{
392
unsigned long map = *cpus_addr(*mask);
393
394
/*
395
* Ensure that stores to Normal memory are visible to the
396
* other CPUs before issuing the IPI.
397
*/
398
dsb();
399
400
/* this always happens on GIC0 */
401
writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
402
}
403
#endif
404
405