17f132a21Scmchao /*
27f132a21Scmchao * TI OMAP interrupt controller emulation.
37f132a21Scmchao *
47f132a21Scmchao * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
57f132a21Scmchao * Copyright (C) 2007-2008 Nokia Corporation
67f132a21Scmchao *
77f132a21Scmchao * This program is free software; you can redistribute it and/or
87f132a21Scmchao * modify it under the terms of the GNU General Public License as
97f132a21Scmchao * published by the Free Software Foundation; either version 2 or
107f132a21Scmchao * (at your option) version 3 of the License.
117f132a21Scmchao *
127f132a21Scmchao * This program is distributed in the hope that it will be useful,
137f132a21Scmchao * but WITHOUT ANY WARRANTY; without even the implied warranty of
147f132a21Scmchao * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
157f132a21Scmchao * GNU General Public License for more details.
167f132a21Scmchao *
177f132a21Scmchao * You should have received a copy of the GNU General Public License along
187f132a21Scmchao * with this program; if not, see <http://www.gnu.org/licenses/>.
197f132a21Scmchao */
200b8fa32fSMarkus Armbruster
2190191d07SPeter Maydell #include "qemu/osdep.h"
2264552b6bSMarkus Armbruster #include "hw/irq.h"
23a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
240d09e41aSPaolo Bonzini #include "hw/arm/omap.h"
2583c9f4caSPaolo Bonzini #include "hw/sysbus.h"
2684a3a53cSMarkus Armbruster #include "qemu/error-report.h"
270b8fa32fSMarkus Armbruster #include "qemu/module.h"
280a750e2aSxiaoqiang zhao #include "qapi/error.h"
297f132a21Scmchao
307f132a21Scmchao /* Interrupt Handlers */
317f132a21Scmchao struct omap_intr_handler_bank_s {
327f132a21Scmchao uint32_t irqs;
337f132a21Scmchao uint32_t inputs;
347f132a21Scmchao uint32_t mask;
357f132a21Scmchao uint32_t fiq;
367f132a21Scmchao uint32_t sens_edge;
377f132a21Scmchao uint32_t swi;
387f132a21Scmchao unsigned char priority[32];
397f132a21Scmchao };
407f132a21Scmchao
41bded15c9SPhilippe Mathieu-Daudé struct OMAPIntcState {
4247edc5a4SAndreas Färber SysBusDevice parent_obj;
4347edc5a4SAndreas Färber
447f132a21Scmchao qemu_irq *pins;
457f132a21Scmchao qemu_irq parent_intr[2];
4653bb614eSPeter Maydell MemoryRegion mmio;
470919ac78SPeter Maydell void *iclk;
480919ac78SPeter Maydell void *fclk;
497f132a21Scmchao unsigned char nbanks;
507f132a21Scmchao int level_only;
510919ac78SPeter Maydell uint32_t size;
520919ac78SPeter Maydell
537f132a21Scmchao /* state */
547f132a21Scmchao uint32_t new_agr[2];
557f132a21Scmchao int sir_intr[2];
567f132a21Scmchao int autoidle;
577f132a21Scmchao uint32_t mask;
580919ac78SPeter Maydell struct omap_intr_handler_bank_s bank[3];
597f132a21Scmchao };
607f132a21Scmchao
omap_inth_sir_update(OMAPIntcState * s,int is_fiq)61bded15c9SPhilippe Mathieu-Daudé static void omap_inth_sir_update(OMAPIntcState *s, int is_fiq)
627f132a21Scmchao {
6341074f3dSPaolo Bonzini int i, j, sir_intr, p_intr, p;
647f132a21Scmchao uint32_t level;
657f132a21Scmchao sir_intr = 0;
667f132a21Scmchao p_intr = 255;
677f132a21Scmchao
687f132a21Scmchao /* Find the interrupt line with the highest dynamic priority.
699b4b4e51SMichael Tokarev * Note: 0 denotes the highest priority.
707f132a21Scmchao * If all interrupts have the same priority, the default order is IRQ_N,
717f132a21Scmchao * IRQ_N-1,...,IRQ_0. */
727f132a21Scmchao for (j = 0; j < s->nbanks; ++j) {
737f132a21Scmchao level = s->bank[j].irqs & ~s->bank[j].mask &
747f132a21Scmchao (is_fiq ? s->bank[j].fiq : ~s->bank[j].fiq);
7541074f3dSPaolo Bonzini
7641074f3dSPaolo Bonzini while (level != 0) {
7741074f3dSPaolo Bonzini i = ctz32(level);
787f132a21Scmchao p = s->bank[j].priority[i];
797f132a21Scmchao if (p <= p_intr) {
807f132a21Scmchao p_intr = p;
817f132a21Scmchao sir_intr = 32 * j + i;
827f132a21Scmchao }
8341074f3dSPaolo Bonzini level &= level - 1;
847f132a21Scmchao }
857f132a21Scmchao }
867f132a21Scmchao s->sir_intr[is_fiq] = sir_intr;
877f132a21Scmchao }
887f132a21Scmchao
omap_inth_update(OMAPIntcState * s,int is_fiq)89bded15c9SPhilippe Mathieu-Daudé static inline void omap_inth_update(OMAPIntcState *s, int is_fiq)
907f132a21Scmchao {
917f132a21Scmchao int i;
927f132a21Scmchao uint32_t has_intr = 0;
937f132a21Scmchao
947f132a21Scmchao for (i = 0; i < s->nbanks; ++i)
957f132a21Scmchao has_intr |= s->bank[i].irqs & ~s->bank[i].mask &
967f132a21Scmchao (is_fiq ? s->bank[i].fiq : ~s->bank[i].fiq);
977f132a21Scmchao
987f132a21Scmchao if (s->new_agr[is_fiq] & has_intr & s->mask) {
997f132a21Scmchao s->new_agr[is_fiq] = 0;
1007f132a21Scmchao omap_inth_sir_update(s, is_fiq);
1017f132a21Scmchao qemu_set_irq(s->parent_intr[is_fiq], 1);
1027f132a21Scmchao }
1037f132a21Scmchao }
1047f132a21Scmchao
1057f132a21Scmchao #define INT_FALLING_EDGE 0
1067f132a21Scmchao #define INT_LOW_LEVEL 1
1077f132a21Scmchao
omap_set_intr(void * opaque,int irq,int req)1087f132a21Scmchao static void omap_set_intr(void *opaque, int irq, int req)
1097f132a21Scmchao {
110bded15c9SPhilippe Mathieu-Daudé OMAPIntcState *ih = opaque;
1117f132a21Scmchao uint32_t rise;
1127f132a21Scmchao
1137f132a21Scmchao struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
1147f132a21Scmchao int n = irq & 31;
1157f132a21Scmchao
1167f132a21Scmchao if (req) {
1177f132a21Scmchao rise = ~bank->irqs & (1 << n);
1187f132a21Scmchao if (~bank->sens_edge & (1 << n))
1197f132a21Scmchao rise &= ~bank->inputs;
1207f132a21Scmchao
1217f132a21Scmchao bank->inputs |= (1 << n);
1227f132a21Scmchao if (rise) {
1237f132a21Scmchao bank->irqs |= rise;
1247f132a21Scmchao omap_inth_update(ih, 0);
1257f132a21Scmchao omap_inth_update(ih, 1);
1267f132a21Scmchao }
1277f132a21Scmchao } else {
1287f132a21Scmchao rise = bank->sens_edge & bank->irqs & (1 << n);
1297f132a21Scmchao bank->irqs &= ~rise;
1307f132a21Scmchao bank->inputs &= ~(1 << n);
1317f132a21Scmchao }
1327f132a21Scmchao }
1337f132a21Scmchao
omap_inth_read(void * opaque,hwaddr addr,unsigned size)134a8170e5eSAvi Kivity static uint64_t omap_inth_read(void *opaque, hwaddr addr,
13553bb614eSPeter Maydell unsigned size)
1367f132a21Scmchao {
137bded15c9SPhilippe Mathieu-Daudé OMAPIntcState *s = opaque;
1387f132a21Scmchao int i, offset = addr;
1397f132a21Scmchao int bank_no = offset >> 8;
1407f132a21Scmchao int line_no;
1417f132a21Scmchao struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
1427f132a21Scmchao offset &= 0xff;
1437f132a21Scmchao
1447f132a21Scmchao switch (offset) {
1457f132a21Scmchao case 0x00: /* ITR */
1467f132a21Scmchao return bank->irqs;
1477f132a21Scmchao
1487f132a21Scmchao case 0x04: /* MIR */
1497f132a21Scmchao return bank->mask;
1507f132a21Scmchao
1517f132a21Scmchao case 0x10: /* SIR_IRQ_CODE */
1527f132a21Scmchao case 0x14: /* SIR_FIQ_CODE */
1537f132a21Scmchao if (bank_no != 0)
1547f132a21Scmchao break;
1557f132a21Scmchao line_no = s->sir_intr[(offset - 0x10) >> 2];
1567f132a21Scmchao bank = &s->bank[line_no >> 5];
1577f132a21Scmchao i = line_no & 31;
1587f132a21Scmchao if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
1597f132a21Scmchao bank->irqs &= ~(1 << i);
1607f132a21Scmchao return line_no;
1617f132a21Scmchao
1627f132a21Scmchao case 0x18: /* CONTROL_REG */
1637f132a21Scmchao if (bank_no != 0)
1647f132a21Scmchao break;
1657f132a21Scmchao return 0;
1667f132a21Scmchao
1677f132a21Scmchao case 0x1c: /* ILR0 */
1687f132a21Scmchao case 0x20: /* ILR1 */
1697f132a21Scmchao case 0x24: /* ILR2 */
1707f132a21Scmchao case 0x28: /* ILR3 */
1717f132a21Scmchao case 0x2c: /* ILR4 */
1727f132a21Scmchao case 0x30: /* ILR5 */
1737f132a21Scmchao case 0x34: /* ILR6 */
1747f132a21Scmchao case 0x38: /* ILR7 */
1757f132a21Scmchao case 0x3c: /* ILR8 */
1767f132a21Scmchao case 0x40: /* ILR9 */
1777f132a21Scmchao case 0x44: /* ILR10 */
1787f132a21Scmchao case 0x48: /* ILR11 */
1797f132a21Scmchao case 0x4c: /* ILR12 */
1807f132a21Scmchao case 0x50: /* ILR13 */
1817f132a21Scmchao case 0x54: /* ILR14 */
1827f132a21Scmchao case 0x58: /* ILR15 */
1837f132a21Scmchao case 0x5c: /* ILR16 */
1847f132a21Scmchao case 0x60: /* ILR17 */
1857f132a21Scmchao case 0x64: /* ILR18 */
1867f132a21Scmchao case 0x68: /* ILR19 */
1877f132a21Scmchao case 0x6c: /* ILR20 */
1887f132a21Scmchao case 0x70: /* ILR21 */
1897f132a21Scmchao case 0x74: /* ILR22 */
1907f132a21Scmchao case 0x78: /* ILR23 */
1917f132a21Scmchao case 0x7c: /* ILR24 */
1927f132a21Scmchao case 0x80: /* ILR25 */
1937f132a21Scmchao case 0x84: /* ILR26 */
1947f132a21Scmchao case 0x88: /* ILR27 */
1957f132a21Scmchao case 0x8c: /* ILR28 */
1967f132a21Scmchao case 0x90: /* ILR29 */
1977f132a21Scmchao case 0x94: /* ILR30 */
1987f132a21Scmchao case 0x98: /* ILR31 */
1997f132a21Scmchao i = (offset - 0x1c) >> 2;
2007f132a21Scmchao return (bank->priority[i] << 2) |
2017f132a21Scmchao (((bank->sens_edge >> i) & 1) << 1) |
2027f132a21Scmchao ((bank->fiq >> i) & 1);
2037f132a21Scmchao
2047f132a21Scmchao case 0x9c: /* ISR */
2057f132a21Scmchao return 0x00000000;
2067f132a21Scmchao
2077f132a21Scmchao }
2087f132a21Scmchao OMAP_BAD_REG(addr);
2097f132a21Scmchao return 0;
2107f132a21Scmchao }
2117f132a21Scmchao
omap_inth_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)212a8170e5eSAvi Kivity static void omap_inth_write(void *opaque, hwaddr addr,
21353bb614eSPeter Maydell uint64_t value, unsigned size)
2147f132a21Scmchao {
215bded15c9SPhilippe Mathieu-Daudé OMAPIntcState *s = opaque;
2167f132a21Scmchao int i, offset = addr;
2177f132a21Scmchao int bank_no = offset >> 8;
2187f132a21Scmchao struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
2197f132a21Scmchao offset &= 0xff;
2207f132a21Scmchao
2217f132a21Scmchao switch (offset) {
2227f132a21Scmchao case 0x00: /* ITR */
2237f132a21Scmchao /* Important: ignore the clearing if the IRQ is level-triggered and
2247f132a21Scmchao the input bit is 1 */
2257f132a21Scmchao bank->irqs &= value | (bank->inputs & bank->sens_edge);
2267f132a21Scmchao return;
2277f132a21Scmchao
2287f132a21Scmchao case 0x04: /* MIR */
2297f132a21Scmchao bank->mask = value;
2307f132a21Scmchao omap_inth_update(s, 0);
2317f132a21Scmchao omap_inth_update(s, 1);
2327f132a21Scmchao return;
2337f132a21Scmchao
2347f132a21Scmchao case 0x10: /* SIR_IRQ_CODE */
2357f132a21Scmchao case 0x14: /* SIR_FIQ_CODE */
2367f132a21Scmchao OMAP_RO_REG(addr);
2377f132a21Scmchao break;
2387f132a21Scmchao
2397f132a21Scmchao case 0x18: /* CONTROL_REG */
2407f132a21Scmchao if (bank_no != 0)
2417f132a21Scmchao break;
2427f132a21Scmchao if (value & 2) {
2437f132a21Scmchao qemu_set_irq(s->parent_intr[1], 0);
2447f132a21Scmchao s->new_agr[1] = ~0;
2457f132a21Scmchao omap_inth_update(s, 1);
2467f132a21Scmchao }
2477f132a21Scmchao if (value & 1) {
2487f132a21Scmchao qemu_set_irq(s->parent_intr[0], 0);
2497f132a21Scmchao s->new_agr[0] = ~0;
2507f132a21Scmchao omap_inth_update(s, 0);
2517f132a21Scmchao }
2527f132a21Scmchao return;
2537f132a21Scmchao
2547f132a21Scmchao case 0x1c: /* ILR0 */
2557f132a21Scmchao case 0x20: /* ILR1 */
2567f132a21Scmchao case 0x24: /* ILR2 */
2577f132a21Scmchao case 0x28: /* ILR3 */
2587f132a21Scmchao case 0x2c: /* ILR4 */
2597f132a21Scmchao case 0x30: /* ILR5 */
2607f132a21Scmchao case 0x34: /* ILR6 */
2617f132a21Scmchao case 0x38: /* ILR7 */
2627f132a21Scmchao case 0x3c: /* ILR8 */
2637f132a21Scmchao case 0x40: /* ILR9 */
2647f132a21Scmchao case 0x44: /* ILR10 */
2657f132a21Scmchao case 0x48: /* ILR11 */
2667f132a21Scmchao case 0x4c: /* ILR12 */
2677f132a21Scmchao case 0x50: /* ILR13 */
2687f132a21Scmchao case 0x54: /* ILR14 */
2697f132a21Scmchao case 0x58: /* ILR15 */
2707f132a21Scmchao case 0x5c: /* ILR16 */
2717f132a21Scmchao case 0x60: /* ILR17 */
2727f132a21Scmchao case 0x64: /* ILR18 */
2737f132a21Scmchao case 0x68: /* ILR19 */
2747f132a21Scmchao case 0x6c: /* ILR20 */
2757f132a21Scmchao case 0x70: /* ILR21 */
2767f132a21Scmchao case 0x74: /* ILR22 */
2777f132a21Scmchao case 0x78: /* ILR23 */
2787f132a21Scmchao case 0x7c: /* ILR24 */
2797f132a21Scmchao case 0x80: /* ILR25 */
2807f132a21Scmchao case 0x84: /* ILR26 */
2817f132a21Scmchao case 0x88: /* ILR27 */
2827f132a21Scmchao case 0x8c: /* ILR28 */
2837f132a21Scmchao case 0x90: /* ILR29 */
2847f132a21Scmchao case 0x94: /* ILR30 */
2857f132a21Scmchao case 0x98: /* ILR31 */
2867f132a21Scmchao i = (offset - 0x1c) >> 2;
2877f132a21Scmchao bank->priority[i] = (value >> 2) & 0x1f;
2887f132a21Scmchao bank->sens_edge &= ~(1 << i);
2897f132a21Scmchao bank->sens_edge |= ((value >> 1) & 1) << i;
2907f132a21Scmchao bank->fiq &= ~(1 << i);
2917f132a21Scmchao bank->fiq |= (value & 1) << i;
2927f132a21Scmchao return;
2937f132a21Scmchao
2947f132a21Scmchao case 0x9c: /* ISR */
2957f132a21Scmchao for (i = 0; i < 32; i ++)
2967f132a21Scmchao if (value & (1 << i)) {
2977f132a21Scmchao omap_set_intr(s, 32 * bank_no + i, 1);
2987f132a21Scmchao return;
2997f132a21Scmchao }
3007f132a21Scmchao return;
3017f132a21Scmchao }
3027f132a21Scmchao OMAP_BAD_REG(addr);
3037f132a21Scmchao }
3047f132a21Scmchao
30553bb614eSPeter Maydell static const MemoryRegionOps omap_inth_mem_ops = {
30653bb614eSPeter Maydell .read = omap_inth_read,
30753bb614eSPeter Maydell .write = omap_inth_write,
30853bb614eSPeter Maydell .endianness = DEVICE_NATIVE_ENDIAN,
30953bb614eSPeter Maydell .valid = {
31053bb614eSPeter Maydell .min_access_size = 4,
31153bb614eSPeter Maydell .max_access_size = 4,
31253bb614eSPeter Maydell },
3137f132a21Scmchao };
3147f132a21Scmchao
omap_inth_reset(DeviceState * dev)3150919ac78SPeter Maydell static void omap_inth_reset(DeviceState *dev)
3167f132a21Scmchao {
317bded15c9SPhilippe Mathieu-Daudé OMAPIntcState *s = OMAP_INTC(dev);
3187f132a21Scmchao int i;
3197f132a21Scmchao
3207f132a21Scmchao for (i = 0; i < s->nbanks; ++i){
3217f132a21Scmchao s->bank[i].irqs = 0x00000000;
3227f132a21Scmchao s->bank[i].mask = 0xffffffff;
3237f132a21Scmchao s->bank[i].sens_edge = 0x00000000;
3247f132a21Scmchao s->bank[i].fiq = 0x00000000;
3257f132a21Scmchao s->bank[i].inputs = 0x00000000;
3267f132a21Scmchao s->bank[i].swi = 0x00000000;
3277f132a21Scmchao memset(s->bank[i].priority, 0, sizeof(s->bank[i].priority));
3287f132a21Scmchao
3297f132a21Scmchao if (s->level_only)
3307f132a21Scmchao s->bank[i].sens_edge = 0xffffffff;
3317f132a21Scmchao }
3327f132a21Scmchao
3337f132a21Scmchao s->new_agr[0] = ~0;
3347f132a21Scmchao s->new_agr[1] = ~0;
3357f132a21Scmchao s->sir_intr[0] = 0;
3367f132a21Scmchao s->sir_intr[1] = 0;
3377f132a21Scmchao s->autoidle = 0;
3387f132a21Scmchao s->mask = ~0;
3397f132a21Scmchao
3407f132a21Scmchao qemu_set_irq(s->parent_intr[0], 0);
3417f132a21Scmchao qemu_set_irq(s->parent_intr[1], 0);
3427f132a21Scmchao }
3437f132a21Scmchao
omap_intc_init(Object * obj)3440a750e2aSxiaoqiang zhao static void omap_intc_init(Object *obj)
3457f132a21Scmchao {
3460a750e2aSxiaoqiang zhao DeviceState *dev = DEVICE(obj);
347bded15c9SPhilippe Mathieu-Daudé OMAPIntcState *s = OMAP_INTC(obj);
3480a750e2aSxiaoqiang zhao SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
34947edc5a4SAndreas Färber
3500919ac78SPeter Maydell s->nbanks = 1;
35147edc5a4SAndreas Färber sysbus_init_irq(sbd, &s->parent_intr[0]);
35247edc5a4SAndreas Färber sysbus_init_irq(sbd, &s->parent_intr[1]);
35347edc5a4SAndreas Färber qdev_init_gpio_in(dev, omap_set_intr, s->nbanks * 32);
3540a750e2aSxiaoqiang zhao memory_region_init_io(&s->mmio, obj, &omap_inth_mem_ops, s,
3550919ac78SPeter Maydell "omap-intc", s->size);
35647edc5a4SAndreas Färber sysbus_init_mmio(sbd, &s->mmio);
3570a750e2aSxiaoqiang zhao }
3580a750e2aSxiaoqiang zhao
omap_intc_realize(DeviceState * dev,Error ** errp)3590a750e2aSxiaoqiang zhao static void omap_intc_realize(DeviceState *dev, Error **errp)
3600a750e2aSxiaoqiang zhao {
361bded15c9SPhilippe Mathieu-Daudé OMAPIntcState *s = OMAP_INTC(dev);
3620a750e2aSxiaoqiang zhao
3630a750e2aSxiaoqiang zhao if (!s->iclk) {
3640a750e2aSxiaoqiang zhao error_setg(errp, "omap-intc: clk not connected");
3650a750e2aSxiaoqiang zhao }
3660919ac78SPeter Maydell }
3670919ac78SPeter Maydell
omap_intc_set_iclk(OMAPIntcState * intc,omap_clk clk)368bded15c9SPhilippe Mathieu-Daudé void omap_intc_set_iclk(OMAPIntcState *intc, omap_clk clk)
369bab592a2SMarc-André Lureau {
370bab592a2SMarc-André Lureau intc->iclk = clk;
371bab592a2SMarc-André Lureau }
372bab592a2SMarc-André Lureau
omap_intc_set_fclk(OMAPIntcState * intc,omap_clk clk)373bded15c9SPhilippe Mathieu-Daudé void omap_intc_set_fclk(OMAPIntcState *intc, omap_clk clk)
374bab592a2SMarc-André Lureau {
375bab592a2SMarc-André Lureau intc->fclk = clk;
376bab592a2SMarc-André Lureau }
377bab592a2SMarc-André Lureau
378783e3b21SRichard Henderson static const Property omap_intc_properties[] = {
379bded15c9SPhilippe Mathieu-Daudé DEFINE_PROP_UINT32("size", OMAPIntcState, size, 0x100),
380999e12bbSAnthony Liguori };
381999e12bbSAnthony Liguori
omap_intc_class_init(ObjectClass * klass,const void * data)382*12d1a768SPhilippe Mathieu-Daudé static void omap_intc_class_init(ObjectClass *klass, const void *data)
383999e12bbSAnthony Liguori {
38439bffca2SAnthony Liguori DeviceClass *dc = DEVICE_CLASS(klass);
385999e12bbSAnthony Liguori
386e3d08143SPeter Maydell device_class_set_legacy_reset(dc, omap_inth_reset);
3874f67d30bSMarc-André Lureau device_class_set_props(dc, omap_intc_properties);
3881b111dc1SMarkus Armbruster /* Reason: pointer property "clk" */
389e90f2a8cSEduardo Habkost dc->user_creatable = false;
3900a750e2aSxiaoqiang zhao dc->realize = omap_intc_realize;
3910919ac78SPeter Maydell }
392999e12bbSAnthony Liguori
3938c43a6f0SAndreas Färber static const TypeInfo omap_intc_info = {
39485a25670SPeter Maydell .name = TYPE_OMAP_INTC,
39585a25670SPeter Maydell .parent = TYPE_SYS_BUS_DEVICE,
39685a25670SPeter Maydell .instance_size = sizeof(OMAPIntcState),
3970a750e2aSxiaoqiang zhao .instance_init = omap_intc_init,
398999e12bbSAnthony Liguori .class_init = omap_intc_class_init,
3990919ac78SPeter Maydell };
4007f132a21Scmchao
omap_intc_register_types(void)40183f7d43aSAndreas Färber static void omap_intc_register_types(void)
4020919ac78SPeter Maydell {
40339bffca2SAnthony Liguori type_register_static(&omap_intc_info);
4040919ac78SPeter Maydell }
4050919ac78SPeter Maydell
40683f7d43aSAndreas Färber type_init(omap_intc_register_types)
407