]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/gic.c
Implement intr_isrc_init_on_cpu() and use it to replace very same
[FreeBSD/FreeBSD.git] / sys / arm / arm / gic.c
1 /*-
2  * Copyright (c) 2011 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * Developed by Damjan Marion <damjan.marion@gmail.com>
6  *
7  * Based on OMAP4 GIC code by Ben Gray
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the company nor the name of the author may be used to
18  *    endorse or promote products derived from this software without specific
19  *    prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "opt_platform.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/bus.h>
42 #include <sys/kernel.h>
43 #include <sys/ktr.h>
44 #include <sys/module.h>
45 #include <sys/malloc.h>
46 #include <sys/rman.h>
47 #include <sys/pcpu.h>
48 #include <sys/proc.h>
49 #include <sys/cpuset.h>
50 #include <sys/lock.h>
51 #include <sys/mutex.h>
52 #include <sys/smp.h>
53 #ifdef ARM_INTRNG
54 #include <sys/sched.h>
55 #endif
56 #include <machine/bus.h>
57 #include <machine/intr.h>
58 #include <machine/smp.h>
59
60 #include <dev/fdt/fdt_common.h>
61 #include <dev/ofw/openfirm.h>
62 #include <dev/ofw/ofw_bus.h>
63 #include <dev/ofw/ofw_bus_subr.h>
64
65 #ifdef ARM_INTRNG
66 #include "pic_if.h"
67 #endif
68
69 #define GIC_DEBUG_SPURIOUS
70
71 /* We are using GICv2 register naming */
72
73 /* Distributor Registers */
74 #define GICD_CTLR               0x000                   /* v1 ICDDCR */
75 #define GICD_TYPER              0x004                   /* v1 ICDICTR */
76 #define GICD_IIDR               0x008                   /* v1 ICDIIDR */
77 #define GICD_IGROUPR(n)         (0x0080 + ((n) * 4))    /* v1 ICDISER */
78 #define GICD_ISENABLER(n)       (0x0100 + ((n) * 4))    /* v1 ICDISER */
79 #define GICD_ICENABLER(n)       (0x0180 + ((n) * 4))    /* v1 ICDICER */
80 #define GICD_ISPENDR(n)         (0x0200 + ((n) * 4))    /* v1 ICDISPR */
81 #define GICD_ICPENDR(n)         (0x0280 + ((n) * 4))    /* v1 ICDICPR */
82 #define GICD_ICACTIVER(n)       (0x0380 + ((n) * 4))    /* v1 ICDABR */
83 #define GICD_IPRIORITYR(n)      (0x0400 + ((n) * 4))    /* v1 ICDIPR */
84 #define GICD_ITARGETSR(n)       (0x0800 + ((n) * 4))    /* v1 ICDIPTR */
85 #define GICD_ICFGR(n)           (0x0C00 + ((n) * 4))    /* v1 ICDICFR */
86 #define GICD_SGIR(n)            (0x0F00 + ((n) * 4))    /* v1 ICDSGIR */
87 #define  GICD_SGI_TARGET_SHIFT  16
88
89 /* CPU Registers */
90 #define GICC_CTLR               0x0000                  /* v1 ICCICR */
91 #define GICC_PMR                0x0004                  /* v1 ICCPMR */
92 #define GICC_BPR                0x0008                  /* v1 ICCBPR */
93 #define GICC_IAR                0x000C                  /* v1 ICCIAR */
94 #define GICC_EOIR               0x0010                  /* v1 ICCEOIR */
95 #define GICC_RPR                0x0014                  /* v1 ICCRPR */
96 #define GICC_HPPIR              0x0018                  /* v1 ICCHPIR */
97 #define GICC_ABPR               0x001C                  /* v1 ICCABPR */
98 #define GICC_IIDR               0x00FC                  /* v1 ICCIIDR*/
99
100 #define GIC_FIRST_SGI            0      /* Irqs 0-15 are SGIs/IPIs. */
101 #define GIC_LAST_SGI            15
102 #define GIC_FIRST_PPI           16      /* Irqs 16-31 are private (per */
103 #define GIC_LAST_PPI            31      /* core) peripheral interrupts. */
104 #define GIC_FIRST_SPI           32      /* Irqs 32+ are shared peripherals. */
105
106 /* First bit is a polarity bit (0 - low, 1 - high) */
107 #define GICD_ICFGR_POL_LOW      (0 << 0)
108 #define GICD_ICFGR_POL_HIGH     (1 << 0)
109 #define GICD_ICFGR_POL_MASK     0x1
110 /* Second bit is a trigger bit (0 - level, 1 - edge) */
111 #define GICD_ICFGR_TRIG_LVL     (0 << 1)
112 #define GICD_ICFGR_TRIG_EDGE    (1 << 1)
113 #define GICD_ICFGR_TRIG_MASK    0x2
114
115 #ifndef GIC_DEFAULT_ICFGR_INIT
116 #define GIC_DEFAULT_ICFGR_INIT  0x00000000
117 #endif
118
119 #ifdef ARM_INTRNG
120 struct gic_irqsrc {
121         struct intr_irqsrc      gi_isrc;
122         uint32_t                gi_irq;
123         enum intr_polarity      gi_pol;
124         enum intr_trigger       gi_trig;
125 };
126
127 static u_int gic_irq_cpu;
128 static int arm_gic_intr(void *);
129 static int arm_gic_bind_intr(device_t dev, struct intr_irqsrc *isrc);
130
131 #ifdef SMP
132 u_int sgi_to_ipi[GIC_LAST_SGI - GIC_FIRST_SGI + 1];
133 u_int sgi_first_unused = GIC_FIRST_SGI;
134 #endif
135 #endif
136
137 struct arm_gic_softc {
138         device_t                gic_dev;
139 #ifdef ARM_INTRNG
140         void *                  gic_intrhand;
141         struct gic_irqsrc *     gic_irqs;
142 #endif
143         struct resource *       gic_res[3];
144         bus_space_tag_t         gic_c_bst;
145         bus_space_tag_t         gic_d_bst;
146         bus_space_handle_t      gic_c_bsh;
147         bus_space_handle_t      gic_d_bsh;
148         uint8_t                 ver;
149         struct mtx              mutex;
150         uint32_t                nirqs;
151 #ifdef GIC_DEBUG_SPURIOUS
152         uint32_t                last_irq[MAXCPU];
153 #endif
154 };
155
156 #ifdef ARM_INTRNG
157 #define GIC_INTR_ISRC(sc, irq)  (&sc->gic_irqs[irq].gi_isrc)
158 #endif
159
160 static struct resource_spec arm_gic_spec[] = {
161         { SYS_RES_MEMORY,       0,      RF_ACTIVE },    /* Distributor registers */
162         { SYS_RES_MEMORY,       1,      RF_ACTIVE },    /* CPU Interrupt Intf. registers */
163 #ifdef ARM_INTRNG
164         { SYS_RES_IRQ,    0, RF_ACTIVE | RF_OPTIONAL }, /* Parent interrupt */
165 #endif
166         { -1, 0 }
167 };
168
169 static u_int arm_gic_map[MAXCPU];
170
171 static struct arm_gic_softc *gic_sc = NULL;
172
173 #define gic_c_read_4(_sc, _reg)         \
174     bus_space_read_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg))
175 #define gic_c_write_4(_sc, _reg, _val)          \
176     bus_space_write_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg), (_val))
177 #define gic_d_read_4(_sc, _reg)         \
178     bus_space_read_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg))
179 #define gic_d_write_1(_sc, _reg, _val)          \
180     bus_space_write_1((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val))
181 #define gic_d_write_4(_sc, _reg, _val)          \
182     bus_space_write_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val))
183
184 #ifndef ARM_INTRNG
185 static int gic_config_irq(int irq, enum intr_trigger trig,
186     enum intr_polarity pol);
187 static void gic_post_filter(void *);
188 #endif
189
190 static struct ofw_compat_data compat_data[] = {
191         {"arm,gic",             true},  /* Non-standard, used in FreeBSD dts. */
192         {"arm,gic-400",         true},
193         {"arm,cortex-a15-gic",  true},
194         {"arm,cortex-a9-gic",   true},
195         {"arm,cortex-a7-gic",   true},
196         {"arm,arm11mp-gic",     true},
197         {"brcm,brahma-b15-gic", true},
198         {NULL,                  false}
199 };
200
201 static int
202 arm_gic_probe(device_t dev)
203 {
204
205         if (!ofw_bus_status_okay(dev))
206                 return (ENXIO);
207
208         if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
209                 return (ENXIO);
210         device_set_desc(dev, "ARM Generic Interrupt Controller");
211         return (BUS_PROBE_DEFAULT);
212 }
213
214 #ifdef ARM_INTRNG
215 static inline void
216 gic_irq_unmask(struct arm_gic_softc *sc, u_int irq)
217 {
218
219         gic_d_write_4(sc, GICD_ISENABLER(irq >> 5), (1UL << (irq & 0x1F)));
220 }
221
222 static inline void
223 gic_irq_mask(struct arm_gic_softc *sc, u_int irq)
224 {
225
226         gic_d_write_4(sc, GICD_ICENABLER(irq >> 5), (1UL << (irq & 0x1F)));
227 }
228 #endif
229
230 static uint8_t
231 gic_cpu_mask(struct arm_gic_softc *sc)
232 {
233         uint32_t mask;
234         int i;
235
236         /* Read the current cpuid mask by reading ITARGETSR{0..7} */
237         for (i = 0; i < 8; i++) {
238                 mask = gic_d_read_4(sc, GICD_ITARGETSR(i));
239                 if (mask != 0)
240                         break;
241         }
242         /* No mask found, assume we are on CPU interface 0 */
243         if (mask == 0)
244                 return (1);
245
246         /* Collect the mask in the lower byte */
247         mask |= mask >> 16;
248         mask |= mask >> 8;
249
250         return (mask);
251 }
252
253 #ifdef SMP
254 #ifdef ARM_INTRNG
255 static void
256 arm_gic_init_secondary(device_t dev)
257 {
258         struct arm_gic_softc *sc = device_get_softc(dev);
259         u_int irq, cpu;
260
261         /* Set the mask so we can find this CPU to send it IPIs */
262         cpu = PCPU_GET(cpuid);
263         arm_gic_map[cpu] = gic_cpu_mask(sc);
264
265         for (irq = 0; irq < sc->nirqs; irq += 4)
266                 gic_d_write_4(sc, GICD_IPRIORITYR(irq >> 2), 0);
267
268         /* Set all the interrupts to be in Group 0 (secure) */
269         for (irq = 0; irq < sc->nirqs; irq += 32) {
270                 gic_d_write_4(sc, GICD_IGROUPR(irq >> 5), 0);
271         }
272
273         /* Enable CPU interface */
274         gic_c_write_4(sc, GICC_CTLR, 1);
275
276         /* Set priority mask register. */
277         gic_c_write_4(sc, GICC_PMR, 0xff);
278
279         /* Enable interrupt distribution */
280         gic_d_write_4(sc, GICD_CTLR, 0x01);
281
282         /* Unmask attached SGI interrupts. */
283         for (irq = GIC_FIRST_SGI; irq <= GIC_LAST_SGI; irq++)
284                 if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu))
285                         gic_irq_unmask(sc, irq);
286
287         /* Unmask attached PPI interrupts. */
288         for (irq = GIC_FIRST_PPI; irq <= GIC_LAST_PPI; irq++)
289                 if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu))
290                         gic_irq_unmask(sc, irq);
291 }
292 #else
293 static void
294 arm_gic_init_secondary(device_t dev)
295 {
296         struct arm_gic_softc *sc = device_get_softc(dev);
297         int i;
298
299         /* Set the mask so we can find this CPU to send it IPIs */
300         arm_gic_map[PCPU_GET(cpuid)] = gic_cpu_mask(sc);
301
302         for (i = 0; i < sc->nirqs; i += 4)
303                 gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
304
305         /* Set all the interrupts to be in Group 0 (secure) */
306         for (i = 0; i < sc->nirqs; i += 32) {
307                 gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
308         }
309
310         /* Enable CPU interface */
311         gic_c_write_4(sc, GICC_CTLR, 1);
312
313         /* Set priority mask register. */
314         gic_c_write_4(sc, GICC_PMR, 0xff);
315
316         /* Enable interrupt distribution */
317         gic_d_write_4(sc, GICD_CTLR, 0x01);
318
319         /*
320          * Activate the timer interrupts: virtual, secure, and non-secure.
321          */
322         gic_d_write_4(sc, GICD_ISENABLER(27 >> 5), (1UL << (27 & 0x1F)));
323         gic_d_write_4(sc, GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F)));
324         gic_d_write_4(sc, GICD_ISENABLER(30 >> 5), (1UL << (30 & 0x1F)));
325 }
326 #endif /* ARM_INTRNG */
327 #endif /* SMP */
328
329 #ifndef ARM_INTRNG
330 int
331 gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt,
332     int *trig, int *pol)
333 {
334         static u_int num_intr_cells;
335         static phandle_t self;
336         struct ofw_compat_data *ocd;
337
338         if (self == 0) {
339                 for (ocd = compat_data; ocd->ocd_str != NULL; ocd++) {
340                         if (fdt_is_compatible(iparent, ocd->ocd_str)) {
341                                 self = iparent;
342                                 break;
343                         }
344                 }
345         }
346         if (self != iparent)
347                 return (ENXIO);
348
349         if (num_intr_cells == 0) {
350                 if (OF_searchencprop(OF_node_from_xref(iparent),
351                     "#interrupt-cells", &num_intr_cells,
352                     sizeof(num_intr_cells)) == -1) {
353                         num_intr_cells = 1;
354                 }
355         }
356
357         if (num_intr_cells == 1) {
358                 *interrupt = fdt32_to_cpu(intr[0]);
359                 *trig = INTR_TRIGGER_CONFORM;
360                 *pol = INTR_POLARITY_CONFORM;
361         } else {
362                 if (fdt32_to_cpu(intr[0]) == 0)
363                         *interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_SPI;
364                 else
365                         *interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_PPI;
366                 /*
367                  * In intr[2], bits[3:0] are trigger type and level flags.
368                  *   1 = low-to-high edge triggered
369                  *   2 = high-to-low edge triggered
370                  *   4 = active high level-sensitive
371                  *   8 = active low level-sensitive
372                  * The hardware only supports active-high-level or rising-edge
373                  * for SPIs
374                  */
375                 if (*interrupt >= GIC_FIRST_SPI &&
376                     fdt32_to_cpu(intr[2]) & 0x0a) {
377                         printf("unsupported trigger/polarity configuration "
378                             "0x%02x\n", fdt32_to_cpu(intr[2]) & 0x0f);
379                 }
380                 *pol  = INTR_POLARITY_CONFORM;
381                 if (fdt32_to_cpu(intr[2]) & 0x03)
382                         *trig = INTR_TRIGGER_EDGE;
383                 else
384                         *trig = INTR_TRIGGER_LEVEL;
385         }
386         return (0);
387 }
388 #endif
389
390 #ifdef ARM_INTRNG
391 static inline intptr_t
392 gic_xref(device_t dev)
393 {
394 #ifdef FDT
395         return (OF_xref_from_node(ofw_bus_get_node(dev)));
396 #else
397         return (0);
398 #endif
399 }
400
401 static int
402 arm_gic_register_isrcs(struct arm_gic_softc *sc, uint32_t num)
403 {
404         int error;
405         uint32_t irq;
406         struct gic_irqsrc *irqs;
407         struct intr_irqsrc *isrc;
408         const char *name;
409
410         irqs = malloc(num * sizeof(struct gic_irqsrc), M_DEVBUF,
411             M_WAITOK | M_ZERO);
412
413         name = device_get_nameunit(sc->gic_dev);
414         for (irq = 0; irq < num; irq++) {
415                 irqs[irq].gi_irq = irq;
416                 irqs[irq].gi_pol = INTR_POLARITY_CONFORM;
417                 irqs[irq].gi_trig = INTR_TRIGGER_CONFORM;
418
419                 isrc = &irqs[irq].gi_isrc;
420                 if (irq <= GIC_LAST_SGI) {
421                         error = intr_isrc_register(isrc, sc->gic_dev,
422                             INTR_ISRCF_IPI, "%s,i%u", name, irq - GIC_FIRST_SGI);
423                 } else if (irq <= GIC_LAST_PPI) {
424                         error = intr_isrc_register(isrc, sc->gic_dev,
425                             INTR_ISRCF_PPI, "%s,p%u", name, irq - GIC_FIRST_PPI);
426                 } else {
427                         error = intr_isrc_register(isrc, sc->gic_dev, 0,
428                             "%s,s%u", name, irq - GIC_FIRST_SPI);
429                 }
430                 if (error != 0) {
431                         /* XXX call intr_isrc_deregister() */
432                         free(irqs, M_DEVBUF);
433                         return (error);
434                 }
435         }
436         sc->gic_irqs = irqs;
437         sc->nirqs = num;
438         return (0);
439 }
440 #endif
441
442 static int
443 arm_gic_attach(device_t dev)
444 {
445         struct          arm_gic_softc *sc;
446         int             i;
447         uint32_t        icciidr, mask, nirqs;
448 #ifdef ARM_INTRNG
449         phandle_t       pxref;
450         intptr_t        xref = gic_xref(dev);
451 #endif
452
453         if (gic_sc)
454                 return (ENXIO);
455
456         sc = device_get_softc(dev);
457
458         if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) {
459                 device_printf(dev, "could not allocate resources\n");
460                 return (ENXIO);
461         }
462
463         sc->gic_dev = dev;
464         gic_sc = sc;
465
466         /* Initialize mutex */
467         mtx_init(&sc->mutex, "GIC lock", "", MTX_SPIN);
468
469         /* Distributor Interface */
470         sc->gic_d_bst = rman_get_bustag(sc->gic_res[0]);
471         sc->gic_d_bsh = rman_get_bushandle(sc->gic_res[0]);
472
473         /* CPU Interface */
474         sc->gic_c_bst = rman_get_bustag(sc->gic_res[1]);
475         sc->gic_c_bsh = rman_get_bushandle(sc->gic_res[1]);
476
477         /* Disable interrupt forwarding to the CPU interface */
478         gic_d_write_4(sc, GICD_CTLR, 0x00);
479
480         /* Get the number of interrupts */
481         nirqs = gic_d_read_4(sc, GICD_TYPER);
482         nirqs = 32 * ((nirqs & 0x1f) + 1);
483
484 #ifdef ARM_INTRNG
485         if (arm_gic_register_isrcs(sc, nirqs)) {
486                 device_printf(dev, "could not register irqs\n");
487                 goto cleanup;
488         }
489 #else
490         sc->nirqs = nirqs;
491
492         /* Set up function pointers */
493         arm_post_filter = gic_post_filter;
494         arm_config_irq = gic_config_irq;
495 #endif
496
497         icciidr = gic_c_read_4(sc, GICC_IIDR);
498         device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n",
499                         icciidr>>20, (icciidr>>16) & 0xF, (icciidr>>12) & 0xf,
500                         (icciidr & 0xfff), sc->nirqs);
501
502         /* Set all global interrupts to be level triggered, active low. */
503         for (i = 32; i < sc->nirqs; i += 16) {
504                 gic_d_write_4(sc, GICD_ICFGR(i >> 4), GIC_DEFAULT_ICFGR_INIT);
505         }
506
507         /* Disable all interrupts. */
508         for (i = 32; i < sc->nirqs; i += 32) {
509                 gic_d_write_4(sc, GICD_ICENABLER(i >> 5), 0xFFFFFFFF);
510         }
511
512         /* Find the current cpu mask */
513         mask = gic_cpu_mask(sc);
514         /* Set the mask so we can find this CPU to send it IPIs */
515         arm_gic_map[PCPU_GET(cpuid)] = mask;
516         /* Set all four targets to this cpu */
517         mask |= mask << 8;
518         mask |= mask << 16;
519
520         for (i = 0; i < sc->nirqs; i += 4) {
521                 gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
522                 if (i > 32) {
523                         gic_d_write_4(sc, GICD_ITARGETSR(i >> 2), mask);
524                 }
525         }
526
527         /* Set all the interrupts to be in Group 0 (secure) */
528         for (i = 0; i < sc->nirqs; i += 32) {
529                 gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
530         }
531
532         /* Enable CPU interface */
533         gic_c_write_4(sc, GICC_CTLR, 1);
534
535         /* Set priority mask register. */
536         gic_c_write_4(sc, GICC_PMR, 0xff);
537
538         /* Enable interrupt distribution */
539         gic_d_write_4(sc, GICD_CTLR, 0x01);
540 #ifndef ARM_INTRNG
541         return (0);
542 #else
543         /*
544          * Now, when everything is initialized, it's right time to
545          * register interrupt controller to interrupt framefork.
546          */
547         if (intr_pic_register(dev, xref) != 0) {
548                 device_printf(dev, "could not register PIC\n");
549                 goto cleanup;
550         }
551
552         /*
553          * Controller is root if:
554          * - doesn't have interrupt parent
555          * - his interrupt parent is this controller
556          */
557         pxref = ofw_bus_find_iparent(ofw_bus_get_node(dev));
558         if (pxref == 0 || xref == pxref) {
559                 if (intr_pic_claim_root(dev, xref, arm_gic_intr, sc,
560                     GIC_LAST_SGI - GIC_FIRST_SGI + 1) != 0) {
561                         device_printf(dev, "could not set PIC as a root\n");
562                         intr_pic_deregister(dev, xref);
563                         goto cleanup;
564                 }
565         } else {
566                 if (sc->gic_res[2] == NULL) {
567                         device_printf(dev,
568                             "not root PIC must have defined interrupt\n");
569                         intr_pic_deregister(dev, xref);
570                         goto cleanup;
571                 }
572                 if (bus_setup_intr(dev, sc->gic_res[2], INTR_TYPE_CLK,
573                     arm_gic_intr, NULL, sc, &sc->gic_intrhand)) {
574                         device_printf(dev, "could not setup irq handler\n");
575                         intr_pic_deregister(dev, xref);
576                         goto cleanup;
577                 }
578         }
579
580         OF_device_register_xref(xref, dev);
581         return (0);
582
583 cleanup:
584         /*
585          * XXX - not implemented arm_gic_detach() should be called !
586          */
587         if (sc->gic_irqs != NULL)
588                 free(sc->gic_irqs, M_DEVBUF);
589         bus_release_resources(dev, arm_gic_spec, sc->gic_res);
590         return(ENXIO);
591 #endif
592 }
593
594 #ifdef ARM_INTRNG
595 static int
596 arm_gic_intr(void *arg)
597 {
598         struct arm_gic_softc *sc = arg;
599         struct gic_irqsrc *gi;
600         uint32_t irq_active_reg, irq;
601         struct trapframe *tf;
602
603         irq_active_reg = gic_c_read_4(sc, GICC_IAR);
604         irq = irq_active_reg & 0x3FF;
605
606         /*
607          * 1. We do EOI here because recent read value from active interrupt
608          *    register must be used for it. Another approach is to save this
609          *    value into associated interrupt source.
610          * 2. EOI must be done on same CPU where interrupt has fired. Thus
611          *    we must ensure that interrupted thread does not migrate to
612          *    another CPU.
613          * 3. EOI cannot be delayed by any preemption which could happen on
614          *    critical_exit() used in MI intr code, when interrupt thread is
615          *    scheduled. See next point.
616          * 4. IPI_RENDEZVOUS assumes that no preemption is permitted during
617          *    an action and any use of critical_exit() could break this
618          *    assumption. See comments within smp_rendezvous_action().
619          * 5. We always return FILTER_HANDLED as this is an interrupt
620          *    controller dispatch function. Otherwise, in cascaded interrupt
621          *    case, the whole interrupt subtree would be masked.
622          */
623
624         if (irq >= sc->nirqs) {
625 #ifdef GIC_DEBUG_SPURIOUS
626                 device_printf(sc->gic_dev,
627                     "Spurious interrupt detected: last irq: %d on CPU%d\n",
628                     sc->last_irq[PCPU_GET(cpuid)], PCPU_GET(cpuid));
629 #endif
630                 return (FILTER_HANDLED);
631         }
632
633         tf = curthread->td_intr_frame;
634 dispatch_irq:
635         gi = sc->gic_irqs + irq;
636         /*
637          * Note that GIC_FIRST_SGI is zero and is not used in 'if' statement
638          * as compiler complains that comparing u_int >= 0 is always true.
639          */
640         if (irq <= GIC_LAST_SGI) {
641 #ifdef SMP
642                 /* Call EOI for all IPI before dispatch. */
643                 gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
644                 intr_ipi_dispatch(sgi_to_ipi[gi->gi_irq], tf);
645                 goto next_irq;
646 #else
647                 device_printf(sc->gic_dev, "SGI %u on UP system detected\n",
648                     irq - GIC_FIRST_SGI);
649                 gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
650                 goto next_irq;
651 #endif
652         }
653
654 #ifdef GIC_DEBUG_SPURIOUS
655         sc->last_irq[PCPU_GET(cpuid)] = irq;
656 #endif
657         if (gi->gi_trig == INTR_TRIGGER_EDGE)
658                 gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
659
660         if (intr_isrc_dispatch(&gi->gi_isrc, tf) != 0) {
661                 gic_irq_mask(sc, irq);
662                 if (gi->gi_trig != INTR_TRIGGER_EDGE)
663                         gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
664                 device_printf(sc->gic_dev, "Stray irq %u disabled\n", irq);
665         }
666
667 next_irq:
668         arm_irq_memory_barrier(irq);
669         irq_active_reg = gic_c_read_4(sc, GICC_IAR);
670         irq = irq_active_reg & 0x3FF;
671         if (irq < sc->nirqs)
672                 goto dispatch_irq;
673
674         return (FILTER_HANDLED);
675 }
676
677 static void
678 gic_config(struct arm_gic_softc *sc, u_int irq, enum intr_trigger trig,
679     enum intr_polarity pol)
680 {
681         uint32_t reg;
682         uint32_t mask;
683
684         if (irq < GIC_FIRST_SPI)
685                 return;
686
687         mtx_lock_spin(&sc->mutex);
688
689         reg = gic_d_read_4(sc, GICD_ICFGR(irq >> 4));
690         mask = (reg >> 2*(irq % 16)) & 0x3;
691
692         if (pol == INTR_POLARITY_LOW) {
693                 mask &= ~GICD_ICFGR_POL_MASK;
694                 mask |= GICD_ICFGR_POL_LOW;
695         } else if (pol == INTR_POLARITY_HIGH) {
696                 mask &= ~GICD_ICFGR_POL_MASK;
697                 mask |= GICD_ICFGR_POL_HIGH;
698         }
699
700         if (trig == INTR_TRIGGER_LEVEL) {
701                 mask &= ~GICD_ICFGR_TRIG_MASK;
702                 mask |= GICD_ICFGR_TRIG_LVL;
703         } else if (trig == INTR_TRIGGER_EDGE) {
704                 mask &= ~GICD_ICFGR_TRIG_MASK;
705                 mask |= GICD_ICFGR_TRIG_EDGE;
706         }
707
708         /* Set mask */
709         reg = reg & ~(0x3 << 2*(irq % 16));
710         reg = reg | (mask << 2*(irq % 16));
711         gic_d_write_4(sc, GICD_ICFGR(irq >> 4), reg);
712
713         mtx_unlock_spin(&sc->mutex);
714 }
715
716 static int
717 gic_bind(struct arm_gic_softc *sc, u_int irq, cpuset_t *cpus)
718 {
719         uint32_t cpu, end, mask;
720
721         end = min(mp_ncpus, 8);
722         for (cpu = end; cpu < MAXCPU; cpu++)
723                 if (CPU_ISSET(cpu, cpus))
724                         return (EINVAL);
725
726         for (mask = 0, cpu = 0; cpu < end; cpu++)
727                 if (CPU_ISSET(cpu, cpus))
728                         mask |= 1 << cpu;
729
730         gic_d_write_1(sc, GICD_ITARGETSR(0) + irq, mask);
731         return (0);
732 }
733
734 #ifdef FDT
735 static int
736 gic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp,
737     enum intr_polarity *polp, enum intr_trigger *trigp)
738 {
739
740         if (ncells == 1) {
741                 *irqp = cells[0];
742                 *polp = INTR_POLARITY_CONFORM;
743                 *trigp = INTR_TRIGGER_CONFORM;
744                 return (0);
745         }
746         if (ncells == 3) {
747                 u_int irq, tripol;
748
749                 /*
750                  * The 1st cell is the interrupt type:
751                  *      0 = SPI
752                  *      1 = PPI
753                  * The 2nd cell contains the interrupt number:
754                  *      [0 - 987] for SPI
755                  *      [0 -  15] for PPI
756                  * The 3rd cell is the flags, encoded as follows:
757                  *   bits[3:0] trigger type and level flags
758                  *      1 = low-to-high edge triggered
759                  *      2 = high-to-low edge triggered
760                  *      4 = active high level-sensitive
761                  *      8 = active low level-sensitive
762                  *   bits[15:8] PPI interrupt cpu mask
763                  *      Each bit corresponds to each of the 8 possible cpus
764                  *      attached to the GIC.  A bit set to '1' indicated
765                  *      the interrupt is wired to that CPU.
766                  */
767                 switch (cells[0]) {
768                 case 0:
769                         irq = GIC_FIRST_SPI + cells[1];
770                         /* SPI irq is checked later. */
771                         break;
772                 case 1:
773                         irq = GIC_FIRST_PPI + cells[1];
774                         if (irq > GIC_LAST_PPI) {
775                                 device_printf(dev, "unsupported PPI interrupt "
776                                     "number %u\n", cells[1]);
777                                 return (EINVAL);
778                         }
779                         break;
780                 default:
781                         device_printf(dev, "unsupported interrupt type "
782                             "configuration %u\n", cells[0]);
783                         return (EINVAL);
784                 }
785
786                 tripol = cells[2] & 0xff;
787                 if (tripol & 0xf0 || (tripol & 0x0a && cells[0] == 0))
788                         device_printf(dev, "unsupported trigger/polarity "
789                             "configuration 0x%02x\n", tripol);
790
791                 *irqp = irq;
792                 *polp = INTR_POLARITY_CONFORM;
793                 *trigp = tripol & 0x03 ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL;
794                 return (0);
795         }
796         return (EINVAL);
797 }
798 #endif
799
800 static int
801 gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp,
802     enum intr_polarity *polp, enum intr_trigger *trigp)
803 {
804         u_int irq;
805         enum intr_polarity pol;
806         enum intr_trigger trig;
807         struct arm_gic_softc *sc;
808
809         sc = device_get_softc(dev);
810         switch (data->type) {
811 #ifdef FDT
812         case INTR_MAP_DATA_FDT:
813                 if (gic_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
814                     &pol, &trig) != 0)
815                         return (EINVAL);
816                 break;
817 #endif
818         default:
819                 return (EINVAL);
820         }
821
822         if (irq >= sc->nirqs)
823                 return (EINVAL);
824         if (pol != INTR_POLARITY_CONFORM && pol != INTR_POLARITY_LOW &&
825             pol != INTR_POLARITY_HIGH)
826                 return (EINVAL);
827         if (trig != INTR_TRIGGER_CONFORM && trig != INTR_TRIGGER_EDGE &&
828             trig != INTR_TRIGGER_LEVEL)
829                 return (EINVAL);
830
831         *irqp = irq;
832         if (polp != NULL)
833                 *polp = pol;
834         if (trigp != NULL)
835                 *trigp = trig;
836         return (0);
837 }
838
839 static int
840 arm_gic_map_intr(device_t dev, struct intr_map_data *data,
841     struct intr_irqsrc **isrcp)
842 {
843         int error;
844         u_int irq;
845         struct arm_gic_softc *sc;
846
847         error = gic_map_intr(dev, data, &irq, NULL, NULL);
848         if (error == 0) {
849                 sc = device_get_softc(dev);
850                 *isrcp = GIC_INTR_ISRC(sc, irq);
851         }
852         return (error);
853 }
854
855 static int
856 arm_gic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
857     struct resource *res, struct intr_map_data *data)
858 {
859         struct arm_gic_softc *sc = device_get_softc(dev);
860         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
861         u_int irq;
862         enum intr_trigger trig;
863         enum intr_polarity pol;
864
865         if (data == NULL)
866                 return (ENOTSUP);
867
868         /* Get config for resource. */
869         if (gic_map_intr(dev, data, &irq, &pol, &trig))
870                 return (EINVAL);
871
872         if (gi->gi_irq != irq)
873                 return (EINVAL);
874
875         /* Compare config if this is not first setup. */
876         if (isrc->isrc_handlers != 0) {
877                 if ((pol != INTR_POLARITY_CONFORM && pol != gi->gi_pol) ||
878                     (trig != INTR_TRIGGER_CONFORM && trig != gi->gi_trig))
879                         return (EINVAL);
880                 else
881                         return (0);
882         }
883
884         if (pol == INTR_POLARITY_CONFORM)
885                 pol = INTR_POLARITY_LOW;        /* just pick some */
886         if (trig == INTR_TRIGGER_CONFORM)
887                 trig = INTR_TRIGGER_EDGE;       /* just pick some */
888
889         gi->gi_pol = pol;
890         gi->gi_trig = trig;
891
892         /*
893          * XXX - In case that per CPU interrupt is going to be enabled in time
894          *       when SMP is already started, we need some IPI call which
895          *       enables it on others CPUs. Further, it's more complicated as
896          *       pic_enable_source() and pic_disable_source() should act on
897          *       per CPU basis only. Thus, it should be solved here somehow.
898          */
899         if (isrc->isrc_flags & INTR_ISRCF_PPI)
900                 CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
901
902         gic_config(sc, gi->gi_irq, trig, pol);
903         arm_gic_bind_intr(dev, isrc);
904         return (0);
905 }
906
907 static int
908 arm_gic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
909     struct resource *res, struct intr_map_data *data)
910 {
911         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
912
913         if (isrc->isrc_handlers == 0) {
914                 gi->gi_pol = INTR_POLARITY_CONFORM;
915                 gi->gi_trig = INTR_TRIGGER_CONFORM;
916         }
917         return (0);
918 }
919
920 static void
921 arm_gic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
922 {
923         struct arm_gic_softc *sc = device_get_softc(dev);
924         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
925
926         arm_irq_memory_barrier(gi->gi_irq);
927         gic_irq_unmask(sc, gi->gi_irq);
928 }
929
930 static void
931 arm_gic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
932 {
933         struct arm_gic_softc *sc = device_get_softc(dev);
934         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
935
936         gic_irq_mask(sc, gi->gi_irq);
937 }
938
939 static void
940 arm_gic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
941 {
942         struct arm_gic_softc *sc = device_get_softc(dev);
943         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
944
945         arm_gic_disable_intr(dev, isrc);
946         gic_c_write_4(sc, GICC_EOIR, gi->gi_irq);
947 }
948
949 static void
950 arm_gic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
951 {
952
953         arm_irq_memory_barrier(0);
954         arm_gic_enable_intr(dev, isrc);
955 }
956
957 static void
958 arm_gic_post_filter(device_t dev, struct intr_irqsrc *isrc)
959 {
960         struct arm_gic_softc *sc = device_get_softc(dev);
961         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
962
963         /* EOI for edge-triggered done earlier. */
964         if (gi->gi_trig == INTR_TRIGGER_EDGE)
965                 return;
966
967         arm_irq_memory_barrier(0);
968         gic_c_write_4(sc, GICC_EOIR, gi->gi_irq);
969 }
970
971 static int
972 arm_gic_bind_intr(device_t dev, struct intr_irqsrc *isrc)
973 {
974         struct arm_gic_softc *sc = device_get_softc(dev);
975         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
976
977         if (gi->gi_irq < GIC_FIRST_SPI)
978                 return (EINVAL);
979
980         if (CPU_EMPTY(&isrc->isrc_cpu)) {
981                 gic_irq_cpu = intr_irq_next_cpu(gic_irq_cpu, &all_cpus);
982                 CPU_SETOF(gic_irq_cpu, &isrc->isrc_cpu);
983         }
984         return (gic_bind(sc, gi->gi_irq, &isrc->isrc_cpu));
985 }
986
987 #ifdef SMP
988 static void
989 arm_gic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus,
990     u_int ipi)
991 {
992         struct arm_gic_softc *sc = device_get_softc(dev);
993         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
994         uint32_t val = 0, i;
995
996         for (i = 0; i < MAXCPU; i++)
997                 if (CPU_ISSET(i, &cpus))
998                         val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT;
999
1000         gic_d_write_4(sc, GICD_SGIR(0), val | gi->gi_irq);
1001 }
1002
1003 static int
1004 arm_gic_ipi_setup(device_t dev, u_int ipi, struct intr_irqsrc **isrcp)
1005 {
1006         struct arm_gic_softc *sc = device_get_softc(dev);
1007
1008         if (sgi_first_unused > GIC_LAST_SGI)
1009                 return (ENOSPC);
1010
1011         *isrcp = GIC_INTR_ISRC(sc, sgi_first_unused);
1012         sgi_to_ipi[sgi_first_unused++] = ipi;
1013         return (0);
1014 }
1015 #endif
1016 #else
1017 static int
1018 arm_gic_next_irq(struct arm_gic_softc *sc, int last_irq)
1019 {
1020         uint32_t active_irq;
1021
1022         active_irq = gic_c_read_4(sc, GICC_IAR);
1023
1024         /*
1025          * Immediatly EOIR the SGIs, because doing so requires the other
1026          * bits (ie CPU number), not just the IRQ number, and we do not
1027          * have this information later.
1028          */
1029         if ((active_irq & 0x3ff) <= GIC_LAST_SGI)
1030                 gic_c_write_4(sc, GICC_EOIR, active_irq);
1031         active_irq &= 0x3FF;
1032
1033         if (active_irq == 0x3FF) {
1034                 if (last_irq == -1)
1035                         device_printf(sc->gic_dev,
1036                             "Spurious interrupt detected\n");
1037                 return -1;
1038         }
1039
1040         return active_irq;
1041 }
1042
1043 static int
1044 arm_gic_config(device_t dev, int irq, enum intr_trigger trig,
1045     enum intr_polarity pol)
1046 {
1047         struct arm_gic_softc *sc = device_get_softc(dev);
1048         uint32_t reg;
1049         uint32_t mask;
1050
1051         /* Function is public-accessible, so validate input arguments */
1052         if ((irq < 0) || (irq >= sc->nirqs))
1053                 goto invalid_args;
1054         if ((trig != INTR_TRIGGER_EDGE) && (trig != INTR_TRIGGER_LEVEL) &&
1055             (trig != INTR_TRIGGER_CONFORM))
1056                 goto invalid_args;
1057         if ((pol != INTR_POLARITY_HIGH) && (pol != INTR_POLARITY_LOW) &&
1058             (pol != INTR_POLARITY_CONFORM))
1059                 goto invalid_args;
1060
1061         mtx_lock_spin(&sc->mutex);
1062
1063         reg = gic_d_read_4(sc, GICD_ICFGR(irq >> 4));
1064         mask = (reg >> 2*(irq % 16)) & 0x3;
1065
1066         if (pol == INTR_POLARITY_LOW) {
1067                 mask &= ~GICD_ICFGR_POL_MASK;
1068                 mask |= GICD_ICFGR_POL_LOW;
1069         } else if (pol == INTR_POLARITY_HIGH) {
1070                 mask &= ~GICD_ICFGR_POL_MASK;
1071                 mask |= GICD_ICFGR_POL_HIGH;
1072         }
1073
1074         if (trig == INTR_TRIGGER_LEVEL) {
1075                 mask &= ~GICD_ICFGR_TRIG_MASK;
1076                 mask |= GICD_ICFGR_TRIG_LVL;
1077         } else if (trig == INTR_TRIGGER_EDGE) {
1078                 mask &= ~GICD_ICFGR_TRIG_MASK;
1079                 mask |= GICD_ICFGR_TRIG_EDGE;
1080         }
1081
1082         /* Set mask */
1083         reg = reg & ~(0x3 << 2*(irq % 16));
1084         reg = reg | (mask << 2*(irq % 16));
1085         gic_d_write_4(sc, GICD_ICFGR(irq >> 4), reg);
1086
1087         mtx_unlock_spin(&sc->mutex);
1088
1089         return (0);
1090
1091 invalid_args:
1092         device_printf(dev, "gic_config_irg, invalid parameters\n");
1093         return (EINVAL);
1094 }
1095
1096
1097 static void
1098 arm_gic_mask(device_t dev, int irq)
1099 {
1100         struct arm_gic_softc *sc = device_get_softc(dev);
1101
1102         gic_d_write_4(sc, GICD_ICENABLER(irq >> 5), (1UL << (irq & 0x1F)));
1103         gic_c_write_4(sc, GICC_EOIR, irq); /* XXX - not allowed */
1104 }
1105
1106 static void
1107 arm_gic_unmask(device_t dev, int irq)
1108 {
1109         struct arm_gic_softc *sc = device_get_softc(dev);
1110
1111         if (irq > GIC_LAST_SGI)
1112                 arm_irq_memory_barrier(irq);
1113
1114         gic_d_write_4(sc, GICD_ISENABLER(irq >> 5), (1UL << (irq & 0x1F)));
1115 }
1116
1117 #ifdef SMP
1118 static void
1119 arm_gic_ipi_send(device_t dev, cpuset_t cpus, u_int ipi)
1120 {
1121         struct arm_gic_softc *sc = device_get_softc(dev);
1122         uint32_t val = 0, i;
1123
1124         for (i = 0; i < MAXCPU; i++)
1125                 if (CPU_ISSET(i, &cpus))
1126                         val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT;
1127
1128         gic_d_write_4(sc, GICD_SGIR(0), val | ipi);
1129 }
1130
1131 static int
1132 arm_gic_ipi_read(device_t dev, int i)
1133 {
1134
1135         if (i != -1) {
1136                 /*
1137                  * The intr code will automagically give the frame pointer
1138                  * if the interrupt argument is 0.
1139                  */
1140                 if ((unsigned int)i > 16)
1141                         return (0);
1142                 return (i);
1143         }
1144
1145         return (0x3ff);
1146 }
1147
1148 static void
1149 arm_gic_ipi_clear(device_t dev, int ipi)
1150 {
1151         /* no-op */
1152 }
1153 #endif
1154
1155 static void
1156 gic_post_filter(void *arg)
1157 {
1158         struct arm_gic_softc *sc = gic_sc;
1159         uintptr_t irq = (uintptr_t) arg;
1160
1161         if (irq > GIC_LAST_SGI)
1162                 arm_irq_memory_barrier(irq);
1163         gic_c_write_4(sc, GICC_EOIR, irq);
1164 }
1165
1166 static int
1167 gic_config_irq(int irq, enum intr_trigger trig, enum intr_polarity pol)
1168 {
1169
1170         return (arm_gic_config(gic_sc->gic_dev, irq, trig, pol));
1171 }
1172
1173 void
1174 arm_mask_irq(uintptr_t nb)
1175 {
1176
1177         arm_gic_mask(gic_sc->gic_dev, nb);
1178 }
1179
1180 void
1181 arm_unmask_irq(uintptr_t nb)
1182 {
1183
1184         arm_gic_unmask(gic_sc->gic_dev, nb);
1185 }
1186
1187 int
1188 arm_get_next_irq(int last_irq)
1189 {
1190
1191         return (arm_gic_next_irq(gic_sc, last_irq));
1192 }
1193
1194 #ifdef SMP
1195 void
1196 intr_pic_init_secondary(void)
1197 {
1198
1199         arm_gic_init_secondary(gic_sc->gic_dev);
1200 }
1201
1202 void
1203 pic_ipi_send(cpuset_t cpus, u_int ipi)
1204 {
1205
1206         arm_gic_ipi_send(gic_sc->gic_dev, cpus, ipi);
1207 }
1208
1209 int
1210 pic_ipi_read(int i)
1211 {
1212
1213         return (arm_gic_ipi_read(gic_sc->gic_dev, i));
1214 }
1215
1216 void
1217 pic_ipi_clear(int ipi)
1218 {
1219
1220         arm_gic_ipi_clear(gic_sc->gic_dev, ipi);
1221 }
1222 #endif
1223 #endif /* ARM_INTRNG */
1224
1225 static device_method_t arm_gic_methods[] = {
1226         /* Device interface */
1227         DEVMETHOD(device_probe,         arm_gic_probe),
1228         DEVMETHOD(device_attach,        arm_gic_attach),
1229 #ifdef ARM_INTRNG
1230         /* Interrupt controller interface */
1231         DEVMETHOD(pic_disable_intr,     arm_gic_disable_intr),
1232         DEVMETHOD(pic_enable_intr,      arm_gic_enable_intr),
1233         DEVMETHOD(pic_map_intr,         arm_gic_map_intr),
1234         DEVMETHOD(pic_setup_intr,       arm_gic_setup_intr),
1235         DEVMETHOD(pic_teardown_intr,    arm_gic_teardown_intr),
1236         DEVMETHOD(pic_post_filter,      arm_gic_post_filter),
1237         DEVMETHOD(pic_post_ithread,     arm_gic_post_ithread),
1238         DEVMETHOD(pic_pre_ithread,      arm_gic_pre_ithread),
1239 #ifdef SMP
1240         DEVMETHOD(pic_bind_intr,        arm_gic_bind_intr),
1241         DEVMETHOD(pic_init_secondary,   arm_gic_init_secondary),
1242         DEVMETHOD(pic_ipi_send,         arm_gic_ipi_send),
1243         DEVMETHOD(pic_ipi_setup,        arm_gic_ipi_setup),
1244 #endif
1245 #endif
1246         { 0, 0 }
1247 };
1248
1249 static driver_t arm_gic_driver = {
1250         "gic",
1251         arm_gic_methods,
1252         sizeof(struct arm_gic_softc),
1253 };
1254
1255 static devclass_t arm_gic_devclass;
1256
1257 EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0,
1258     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
1259 EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0,
1260     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);