xref: /openbmc/qemu/hw/intc/omap_intc.c (revision 9b4b4e51)
17702e47cSPaolo Bonzini /*
27702e47cSPaolo Bonzini  * TI OMAP interrupt controller emulation.
37702e47cSPaolo Bonzini  *
47702e47cSPaolo Bonzini  * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
57702e47cSPaolo Bonzini  * Copyright (C) 2007-2008 Nokia Corporation
67702e47cSPaolo Bonzini  *
77702e47cSPaolo Bonzini  * This program is free software; you can redistribute it and/or
87702e47cSPaolo Bonzini  * modify it under the terms of the GNU General Public License as
97702e47cSPaolo Bonzini  * published by the Free Software Foundation; either version 2 or
107702e47cSPaolo Bonzini  * (at your option) version 3 of the License.
117702e47cSPaolo Bonzini  *
127702e47cSPaolo Bonzini  * This program is distributed in the hope that it will be useful,
137702e47cSPaolo Bonzini  * but WITHOUT ANY WARRANTY; without even the implied warranty of
147702e47cSPaolo Bonzini  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
157702e47cSPaolo Bonzini  * GNU General Public License for more details.
167702e47cSPaolo Bonzini  *
177702e47cSPaolo Bonzini  * You should have received a copy of the GNU General Public License along
187702e47cSPaolo Bonzini  * with this program; if not, see <http://www.gnu.org/licenses/>.
197702e47cSPaolo Bonzini  */
200b8fa32fSMarkus Armbruster 
2190191d07SPeter Maydell #include "qemu/osdep.h"
2264552b6bSMarkus Armbruster #include "hw/irq.h"
23a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
247702e47cSPaolo Bonzini #include "hw/arm/omap.h"
257702e47cSPaolo Bonzini #include "hw/sysbus.h"
2684a3a53cSMarkus Armbruster #include "qemu/error-report.h"
270b8fa32fSMarkus Armbruster #include "qemu/module.h"
280a750e2aSxiaoqiang zhao #include "qapi/error.h"
297702e47cSPaolo Bonzini 
307702e47cSPaolo Bonzini /* Interrupt Handlers */
317702e47cSPaolo Bonzini struct omap_intr_handler_bank_s {
327702e47cSPaolo Bonzini     uint32_t irqs;
337702e47cSPaolo Bonzini     uint32_t inputs;
347702e47cSPaolo Bonzini     uint32_t mask;
357702e47cSPaolo Bonzini     uint32_t fiq;
367702e47cSPaolo Bonzini     uint32_t sens_edge;
377702e47cSPaolo Bonzini     uint32_t swi;
387702e47cSPaolo Bonzini     unsigned char priority[32];
397702e47cSPaolo Bonzini };
407702e47cSPaolo Bonzini 
41bded15c9SPhilippe Mathieu-Daudé struct OMAPIntcState {
4247edc5a4SAndreas Färber     SysBusDevice parent_obj;
4347edc5a4SAndreas Färber 
447702e47cSPaolo Bonzini     qemu_irq *pins;
457702e47cSPaolo Bonzini     qemu_irq parent_intr[2];
467702e47cSPaolo Bonzini     MemoryRegion mmio;
477702e47cSPaolo Bonzini     void *iclk;
487702e47cSPaolo Bonzini     void *fclk;
497702e47cSPaolo Bonzini     unsigned char nbanks;
507702e47cSPaolo Bonzini     int level_only;
517702e47cSPaolo Bonzini     uint32_t size;
527702e47cSPaolo Bonzini 
537702e47cSPaolo Bonzini     uint8_t revision;
547702e47cSPaolo Bonzini 
557702e47cSPaolo Bonzini     /* state */
567702e47cSPaolo Bonzini     uint32_t new_agr[2];
577702e47cSPaolo Bonzini     int sir_intr[2];
587702e47cSPaolo Bonzini     int autoidle;
597702e47cSPaolo Bonzini     uint32_t mask;
607702e47cSPaolo Bonzini     struct omap_intr_handler_bank_s bank[3];
617702e47cSPaolo Bonzini };
627702e47cSPaolo Bonzini 
omap_inth_sir_update(OMAPIntcState * s,int is_fiq)63bded15c9SPhilippe Mathieu-Daudé static void omap_inth_sir_update(OMAPIntcState *s, int is_fiq)
647702e47cSPaolo Bonzini {
6541074f3dSPaolo Bonzini     int i, j, sir_intr, p_intr, p;
667702e47cSPaolo Bonzini     uint32_t level;
677702e47cSPaolo Bonzini     sir_intr = 0;
687702e47cSPaolo Bonzini     p_intr = 255;
697702e47cSPaolo Bonzini 
707702e47cSPaolo Bonzini     /* Find the interrupt line with the highest dynamic priority.
71*9b4b4e51SMichael Tokarev      * Note: 0 denotes the highest priority.
727702e47cSPaolo Bonzini      * If all interrupts have the same priority, the default order is IRQ_N,
737702e47cSPaolo Bonzini      * IRQ_N-1,...,IRQ_0. */
747702e47cSPaolo Bonzini     for (j = 0; j < s->nbanks; ++j) {
757702e47cSPaolo Bonzini         level = s->bank[j].irqs & ~s->bank[j].mask &
767702e47cSPaolo Bonzini                 (is_fiq ? s->bank[j].fiq : ~s->bank[j].fiq);
7741074f3dSPaolo Bonzini 
7841074f3dSPaolo Bonzini         while (level != 0) {
7941074f3dSPaolo Bonzini             i = ctz32(level);
807702e47cSPaolo Bonzini             p = s->bank[j].priority[i];
817702e47cSPaolo Bonzini             if (p <= p_intr) {
827702e47cSPaolo Bonzini                 p_intr = p;
837702e47cSPaolo Bonzini                 sir_intr = 32 * j + i;
847702e47cSPaolo Bonzini             }
8541074f3dSPaolo Bonzini             level &= level - 1;
867702e47cSPaolo Bonzini         }
877702e47cSPaolo Bonzini     }
887702e47cSPaolo Bonzini     s->sir_intr[is_fiq] = sir_intr;
897702e47cSPaolo Bonzini }
907702e47cSPaolo Bonzini 
omap_inth_update(OMAPIntcState * s,int is_fiq)91bded15c9SPhilippe Mathieu-Daudé static inline void omap_inth_update(OMAPIntcState *s, int is_fiq)
927702e47cSPaolo Bonzini {
937702e47cSPaolo Bonzini     int i;
947702e47cSPaolo Bonzini     uint32_t has_intr = 0;
957702e47cSPaolo Bonzini 
967702e47cSPaolo Bonzini     for (i = 0; i < s->nbanks; ++i)
977702e47cSPaolo Bonzini         has_intr |= s->bank[i].irqs & ~s->bank[i].mask &
987702e47cSPaolo Bonzini                 (is_fiq ? s->bank[i].fiq : ~s->bank[i].fiq);
997702e47cSPaolo Bonzini 
1007702e47cSPaolo Bonzini     if (s->new_agr[is_fiq] & has_intr & s->mask) {
1017702e47cSPaolo Bonzini         s->new_agr[is_fiq] = 0;
1027702e47cSPaolo Bonzini         omap_inth_sir_update(s, is_fiq);
1037702e47cSPaolo Bonzini         qemu_set_irq(s->parent_intr[is_fiq], 1);
1047702e47cSPaolo Bonzini     }
1057702e47cSPaolo Bonzini }
1067702e47cSPaolo Bonzini 
1077702e47cSPaolo Bonzini #define INT_FALLING_EDGE	0
1087702e47cSPaolo Bonzini #define INT_LOW_LEVEL		1
1097702e47cSPaolo Bonzini 
omap_set_intr(void * opaque,int irq,int req)1107702e47cSPaolo Bonzini static void omap_set_intr(void *opaque, int irq, int req)
1117702e47cSPaolo Bonzini {
112bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *ih = opaque;
1137702e47cSPaolo Bonzini     uint32_t rise;
1147702e47cSPaolo Bonzini 
1157702e47cSPaolo Bonzini     struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
1167702e47cSPaolo Bonzini     int n = irq & 31;
1177702e47cSPaolo Bonzini 
1187702e47cSPaolo Bonzini     if (req) {
1197702e47cSPaolo Bonzini         rise = ~bank->irqs & (1 << n);
1207702e47cSPaolo Bonzini         if (~bank->sens_edge & (1 << n))
1217702e47cSPaolo Bonzini             rise &= ~bank->inputs;
1227702e47cSPaolo Bonzini 
1237702e47cSPaolo Bonzini         bank->inputs |= (1 << n);
1247702e47cSPaolo Bonzini         if (rise) {
1257702e47cSPaolo Bonzini             bank->irqs |= rise;
1267702e47cSPaolo Bonzini             omap_inth_update(ih, 0);
1277702e47cSPaolo Bonzini             omap_inth_update(ih, 1);
1287702e47cSPaolo Bonzini         }
1297702e47cSPaolo Bonzini     } else {
1307702e47cSPaolo Bonzini         rise = bank->sens_edge & bank->irqs & (1 << n);
1317702e47cSPaolo Bonzini         bank->irqs &= ~rise;
1327702e47cSPaolo Bonzini         bank->inputs &= ~(1 << n);
1337702e47cSPaolo Bonzini     }
1347702e47cSPaolo Bonzini }
1357702e47cSPaolo Bonzini 
1367702e47cSPaolo Bonzini /* Simplified version with no edge detection */
omap_set_intr_noedge(void * opaque,int irq,int req)1377702e47cSPaolo Bonzini static void omap_set_intr_noedge(void *opaque, int irq, int req)
1387702e47cSPaolo Bonzini {
139bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *ih = opaque;
1407702e47cSPaolo Bonzini     uint32_t rise;
1417702e47cSPaolo Bonzini 
1427702e47cSPaolo Bonzini     struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
1437702e47cSPaolo Bonzini     int n = irq & 31;
1447702e47cSPaolo Bonzini 
1457702e47cSPaolo Bonzini     if (req) {
1467702e47cSPaolo Bonzini         rise = ~bank->inputs & (1 << n);
1477702e47cSPaolo Bonzini         if (rise) {
1487702e47cSPaolo Bonzini             bank->irqs |= bank->inputs |= rise;
1497702e47cSPaolo Bonzini             omap_inth_update(ih, 0);
1507702e47cSPaolo Bonzini             omap_inth_update(ih, 1);
1517702e47cSPaolo Bonzini         }
1527702e47cSPaolo Bonzini     } else
1537702e47cSPaolo Bonzini         bank->irqs = (bank->inputs &= ~(1 << n)) | bank->swi;
1547702e47cSPaolo Bonzini }
1557702e47cSPaolo Bonzini 
omap_inth_read(void * opaque,hwaddr addr,unsigned size)1567702e47cSPaolo Bonzini static uint64_t omap_inth_read(void *opaque, hwaddr addr,
1577702e47cSPaolo Bonzini                                unsigned size)
1587702e47cSPaolo Bonzini {
159bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = opaque;
1607702e47cSPaolo Bonzini     int i, offset = addr;
1617702e47cSPaolo Bonzini     int bank_no = offset >> 8;
1627702e47cSPaolo Bonzini     int line_no;
1637702e47cSPaolo Bonzini     struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
1647702e47cSPaolo Bonzini     offset &= 0xff;
1657702e47cSPaolo Bonzini 
1667702e47cSPaolo Bonzini     switch (offset) {
1677702e47cSPaolo Bonzini     case 0x00:	/* ITR */
1687702e47cSPaolo Bonzini         return bank->irqs;
1697702e47cSPaolo Bonzini 
1707702e47cSPaolo Bonzini     case 0x04:	/* MIR */
1717702e47cSPaolo Bonzini         return bank->mask;
1727702e47cSPaolo Bonzini 
1737702e47cSPaolo Bonzini     case 0x10:	/* SIR_IRQ_CODE */
1747702e47cSPaolo Bonzini     case 0x14:  /* SIR_FIQ_CODE */
1757702e47cSPaolo Bonzini         if (bank_no != 0)
1767702e47cSPaolo Bonzini             break;
1777702e47cSPaolo Bonzini         line_no = s->sir_intr[(offset - 0x10) >> 2];
1787702e47cSPaolo Bonzini         bank = &s->bank[line_no >> 5];
1797702e47cSPaolo Bonzini         i = line_no & 31;
1807702e47cSPaolo Bonzini         if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
1817702e47cSPaolo Bonzini             bank->irqs &= ~(1 << i);
1827702e47cSPaolo Bonzini         return line_no;
1837702e47cSPaolo Bonzini 
1847702e47cSPaolo Bonzini     case 0x18:	/* CONTROL_REG */
1857702e47cSPaolo Bonzini         if (bank_no != 0)
1867702e47cSPaolo Bonzini             break;
1877702e47cSPaolo Bonzini         return 0;
1887702e47cSPaolo Bonzini 
1897702e47cSPaolo Bonzini     case 0x1c:	/* ILR0 */
1907702e47cSPaolo Bonzini     case 0x20:	/* ILR1 */
1917702e47cSPaolo Bonzini     case 0x24:	/* ILR2 */
1927702e47cSPaolo Bonzini     case 0x28:	/* ILR3 */
1937702e47cSPaolo Bonzini     case 0x2c:	/* ILR4 */
1947702e47cSPaolo Bonzini     case 0x30:	/* ILR5 */
1957702e47cSPaolo Bonzini     case 0x34:	/* ILR6 */
1967702e47cSPaolo Bonzini     case 0x38:	/* ILR7 */
1977702e47cSPaolo Bonzini     case 0x3c:	/* ILR8 */
1987702e47cSPaolo Bonzini     case 0x40:	/* ILR9 */
1997702e47cSPaolo Bonzini     case 0x44:	/* ILR10 */
2007702e47cSPaolo Bonzini     case 0x48:	/* ILR11 */
2017702e47cSPaolo Bonzini     case 0x4c:	/* ILR12 */
2027702e47cSPaolo Bonzini     case 0x50:	/* ILR13 */
2037702e47cSPaolo Bonzini     case 0x54:	/* ILR14 */
2047702e47cSPaolo Bonzini     case 0x58:	/* ILR15 */
2057702e47cSPaolo Bonzini     case 0x5c:	/* ILR16 */
2067702e47cSPaolo Bonzini     case 0x60:	/* ILR17 */
2077702e47cSPaolo Bonzini     case 0x64:	/* ILR18 */
2087702e47cSPaolo Bonzini     case 0x68:	/* ILR19 */
2097702e47cSPaolo Bonzini     case 0x6c:	/* ILR20 */
2107702e47cSPaolo Bonzini     case 0x70:	/* ILR21 */
2117702e47cSPaolo Bonzini     case 0x74:	/* ILR22 */
2127702e47cSPaolo Bonzini     case 0x78:	/* ILR23 */
2137702e47cSPaolo Bonzini     case 0x7c:	/* ILR24 */
2147702e47cSPaolo Bonzini     case 0x80:	/* ILR25 */
2157702e47cSPaolo Bonzini     case 0x84:	/* ILR26 */
2167702e47cSPaolo Bonzini     case 0x88:	/* ILR27 */
2177702e47cSPaolo Bonzini     case 0x8c:	/* ILR28 */
2187702e47cSPaolo Bonzini     case 0x90:	/* ILR29 */
2197702e47cSPaolo Bonzini     case 0x94:	/* ILR30 */
2207702e47cSPaolo Bonzini     case 0x98:	/* ILR31 */
2217702e47cSPaolo Bonzini         i = (offset - 0x1c) >> 2;
2227702e47cSPaolo Bonzini         return (bank->priority[i] << 2) |
2237702e47cSPaolo Bonzini                 (((bank->sens_edge >> i) & 1) << 1) |
2247702e47cSPaolo Bonzini                 ((bank->fiq >> i) & 1);
2257702e47cSPaolo Bonzini 
2267702e47cSPaolo Bonzini     case 0x9c:	/* ISR */
2277702e47cSPaolo Bonzini         return 0x00000000;
2287702e47cSPaolo Bonzini 
2297702e47cSPaolo Bonzini     }
2307702e47cSPaolo Bonzini     OMAP_BAD_REG(addr);
2317702e47cSPaolo Bonzini     return 0;
2327702e47cSPaolo Bonzini }
2337702e47cSPaolo Bonzini 
omap_inth_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)2347702e47cSPaolo Bonzini static void omap_inth_write(void *opaque, hwaddr addr,
2357702e47cSPaolo Bonzini                             uint64_t value, unsigned size)
2367702e47cSPaolo Bonzini {
237bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = opaque;
2387702e47cSPaolo Bonzini     int i, offset = addr;
2397702e47cSPaolo Bonzini     int bank_no = offset >> 8;
2407702e47cSPaolo Bonzini     struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
2417702e47cSPaolo Bonzini     offset &= 0xff;
2427702e47cSPaolo Bonzini 
2437702e47cSPaolo Bonzini     switch (offset) {
2447702e47cSPaolo Bonzini     case 0x00:	/* ITR */
2457702e47cSPaolo Bonzini         /* Important: ignore the clearing if the IRQ is level-triggered and
2467702e47cSPaolo Bonzini            the input bit is 1 */
2477702e47cSPaolo Bonzini         bank->irqs &= value | (bank->inputs & bank->sens_edge);
2487702e47cSPaolo Bonzini         return;
2497702e47cSPaolo Bonzini 
2507702e47cSPaolo Bonzini     case 0x04:	/* MIR */
2517702e47cSPaolo Bonzini         bank->mask = value;
2527702e47cSPaolo Bonzini         omap_inth_update(s, 0);
2537702e47cSPaolo Bonzini         omap_inth_update(s, 1);
2547702e47cSPaolo Bonzini         return;
2557702e47cSPaolo Bonzini 
2567702e47cSPaolo Bonzini     case 0x10:	/* SIR_IRQ_CODE */
2577702e47cSPaolo Bonzini     case 0x14:	/* SIR_FIQ_CODE */
2587702e47cSPaolo Bonzini         OMAP_RO_REG(addr);
2597702e47cSPaolo Bonzini         break;
2607702e47cSPaolo Bonzini 
2617702e47cSPaolo Bonzini     case 0x18:	/* CONTROL_REG */
2627702e47cSPaolo Bonzini         if (bank_no != 0)
2637702e47cSPaolo Bonzini             break;
2647702e47cSPaolo Bonzini         if (value & 2) {
2657702e47cSPaolo Bonzini             qemu_set_irq(s->parent_intr[1], 0);
2667702e47cSPaolo Bonzini             s->new_agr[1] = ~0;
2677702e47cSPaolo Bonzini             omap_inth_update(s, 1);
2687702e47cSPaolo Bonzini         }
2697702e47cSPaolo Bonzini         if (value & 1) {
2707702e47cSPaolo Bonzini             qemu_set_irq(s->parent_intr[0], 0);
2717702e47cSPaolo Bonzini             s->new_agr[0] = ~0;
2727702e47cSPaolo Bonzini             omap_inth_update(s, 0);
2737702e47cSPaolo Bonzini         }
2747702e47cSPaolo Bonzini         return;
2757702e47cSPaolo Bonzini 
2767702e47cSPaolo Bonzini     case 0x1c:	/* ILR0 */
2777702e47cSPaolo Bonzini     case 0x20:	/* ILR1 */
2787702e47cSPaolo Bonzini     case 0x24:	/* ILR2 */
2797702e47cSPaolo Bonzini     case 0x28:	/* ILR3 */
2807702e47cSPaolo Bonzini     case 0x2c:	/* ILR4 */
2817702e47cSPaolo Bonzini     case 0x30:	/* ILR5 */
2827702e47cSPaolo Bonzini     case 0x34:	/* ILR6 */
2837702e47cSPaolo Bonzini     case 0x38:	/* ILR7 */
2847702e47cSPaolo Bonzini     case 0x3c:	/* ILR8 */
2857702e47cSPaolo Bonzini     case 0x40:	/* ILR9 */
2867702e47cSPaolo Bonzini     case 0x44:	/* ILR10 */
2877702e47cSPaolo Bonzini     case 0x48:	/* ILR11 */
2887702e47cSPaolo Bonzini     case 0x4c:	/* ILR12 */
2897702e47cSPaolo Bonzini     case 0x50:	/* ILR13 */
2907702e47cSPaolo Bonzini     case 0x54:	/* ILR14 */
2917702e47cSPaolo Bonzini     case 0x58:	/* ILR15 */
2927702e47cSPaolo Bonzini     case 0x5c:	/* ILR16 */
2937702e47cSPaolo Bonzini     case 0x60:	/* ILR17 */
2947702e47cSPaolo Bonzini     case 0x64:	/* ILR18 */
2957702e47cSPaolo Bonzini     case 0x68:	/* ILR19 */
2967702e47cSPaolo Bonzini     case 0x6c:	/* ILR20 */
2977702e47cSPaolo Bonzini     case 0x70:	/* ILR21 */
2987702e47cSPaolo Bonzini     case 0x74:	/* ILR22 */
2997702e47cSPaolo Bonzini     case 0x78:	/* ILR23 */
3007702e47cSPaolo Bonzini     case 0x7c:	/* ILR24 */
3017702e47cSPaolo Bonzini     case 0x80:	/* ILR25 */
3027702e47cSPaolo Bonzini     case 0x84:	/* ILR26 */
3037702e47cSPaolo Bonzini     case 0x88:	/* ILR27 */
3047702e47cSPaolo Bonzini     case 0x8c:	/* ILR28 */
3057702e47cSPaolo Bonzini     case 0x90:	/* ILR29 */
3067702e47cSPaolo Bonzini     case 0x94:	/* ILR30 */
3077702e47cSPaolo Bonzini     case 0x98:	/* ILR31 */
3087702e47cSPaolo Bonzini         i = (offset - 0x1c) >> 2;
3097702e47cSPaolo Bonzini         bank->priority[i] = (value >> 2) & 0x1f;
3107702e47cSPaolo Bonzini         bank->sens_edge &= ~(1 << i);
3117702e47cSPaolo Bonzini         bank->sens_edge |= ((value >> 1) & 1) << i;
3127702e47cSPaolo Bonzini         bank->fiq &= ~(1 << i);
3137702e47cSPaolo Bonzini         bank->fiq |= (value & 1) << i;
3147702e47cSPaolo Bonzini         return;
3157702e47cSPaolo Bonzini 
3167702e47cSPaolo Bonzini     case 0x9c:	/* ISR */
3177702e47cSPaolo Bonzini         for (i = 0; i < 32; i ++)
3187702e47cSPaolo Bonzini             if (value & (1 << i)) {
3197702e47cSPaolo Bonzini                 omap_set_intr(s, 32 * bank_no + i, 1);
3207702e47cSPaolo Bonzini                 return;
3217702e47cSPaolo Bonzini             }
3227702e47cSPaolo Bonzini         return;
3237702e47cSPaolo Bonzini     }
3247702e47cSPaolo Bonzini     OMAP_BAD_REG(addr);
3257702e47cSPaolo Bonzini }
3267702e47cSPaolo Bonzini 
3277702e47cSPaolo Bonzini static const MemoryRegionOps omap_inth_mem_ops = {
3287702e47cSPaolo Bonzini     .read = omap_inth_read,
3297702e47cSPaolo Bonzini     .write = omap_inth_write,
3307702e47cSPaolo Bonzini     .endianness = DEVICE_NATIVE_ENDIAN,
3317702e47cSPaolo Bonzini     .valid = {
3327702e47cSPaolo Bonzini         .min_access_size = 4,
3337702e47cSPaolo Bonzini         .max_access_size = 4,
3347702e47cSPaolo Bonzini     },
3357702e47cSPaolo Bonzini };
3367702e47cSPaolo Bonzini 
omap_inth_reset(DeviceState * dev)3377702e47cSPaolo Bonzini static void omap_inth_reset(DeviceState *dev)
3387702e47cSPaolo Bonzini {
339bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = OMAP_INTC(dev);
3407702e47cSPaolo Bonzini     int i;
3417702e47cSPaolo Bonzini 
3427702e47cSPaolo Bonzini     for (i = 0; i < s->nbanks; ++i){
3437702e47cSPaolo Bonzini         s->bank[i].irqs = 0x00000000;
3447702e47cSPaolo Bonzini         s->bank[i].mask = 0xffffffff;
3457702e47cSPaolo Bonzini         s->bank[i].sens_edge = 0x00000000;
3467702e47cSPaolo Bonzini         s->bank[i].fiq = 0x00000000;
3477702e47cSPaolo Bonzini         s->bank[i].inputs = 0x00000000;
3487702e47cSPaolo Bonzini         s->bank[i].swi = 0x00000000;
3497702e47cSPaolo Bonzini         memset(s->bank[i].priority, 0, sizeof(s->bank[i].priority));
3507702e47cSPaolo Bonzini 
3517702e47cSPaolo Bonzini         if (s->level_only)
3527702e47cSPaolo Bonzini             s->bank[i].sens_edge = 0xffffffff;
3537702e47cSPaolo Bonzini     }
3547702e47cSPaolo Bonzini 
3557702e47cSPaolo Bonzini     s->new_agr[0] = ~0;
3567702e47cSPaolo Bonzini     s->new_agr[1] = ~0;
3577702e47cSPaolo Bonzini     s->sir_intr[0] = 0;
3587702e47cSPaolo Bonzini     s->sir_intr[1] = 0;
3597702e47cSPaolo Bonzini     s->autoidle = 0;
3607702e47cSPaolo Bonzini     s->mask = ~0;
3617702e47cSPaolo Bonzini 
3627702e47cSPaolo Bonzini     qemu_set_irq(s->parent_intr[0], 0);
3637702e47cSPaolo Bonzini     qemu_set_irq(s->parent_intr[1], 0);
3647702e47cSPaolo Bonzini }
3657702e47cSPaolo Bonzini 
omap_intc_init(Object * obj)3660a750e2aSxiaoqiang zhao static void omap_intc_init(Object *obj)
3677702e47cSPaolo Bonzini {
3680a750e2aSxiaoqiang zhao     DeviceState *dev = DEVICE(obj);
369bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = OMAP_INTC(obj);
3700a750e2aSxiaoqiang zhao     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
37147edc5a4SAndreas Färber 
3727702e47cSPaolo Bonzini     s->nbanks = 1;
37347edc5a4SAndreas Färber     sysbus_init_irq(sbd, &s->parent_intr[0]);
37447edc5a4SAndreas Färber     sysbus_init_irq(sbd, &s->parent_intr[1]);
37547edc5a4SAndreas Färber     qdev_init_gpio_in(dev, omap_set_intr, s->nbanks * 32);
3760a750e2aSxiaoqiang zhao     memory_region_init_io(&s->mmio, obj, &omap_inth_mem_ops, s,
3777702e47cSPaolo Bonzini                           "omap-intc", s->size);
37847edc5a4SAndreas Färber     sysbus_init_mmio(sbd, &s->mmio);
3790a750e2aSxiaoqiang zhao }
3800a750e2aSxiaoqiang zhao 
omap_intc_realize(DeviceState * dev,Error ** errp)3810a750e2aSxiaoqiang zhao static void omap_intc_realize(DeviceState *dev, Error **errp)
3820a750e2aSxiaoqiang zhao {
383bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = OMAP_INTC(dev);
3840a750e2aSxiaoqiang zhao 
3850a750e2aSxiaoqiang zhao     if (!s->iclk) {
3860a750e2aSxiaoqiang zhao         error_setg(errp, "omap-intc: clk not connected");
3870a750e2aSxiaoqiang zhao     }
3887702e47cSPaolo Bonzini }
3897702e47cSPaolo Bonzini 
omap_intc_set_iclk(OMAPIntcState * intc,omap_clk clk)390bded15c9SPhilippe Mathieu-Daudé void omap_intc_set_iclk(OMAPIntcState *intc, omap_clk clk)
391bab592a2SMarc-André Lureau {
392bab592a2SMarc-André Lureau     intc->iclk = clk;
393bab592a2SMarc-André Lureau }
394bab592a2SMarc-André Lureau 
omap_intc_set_fclk(OMAPIntcState * intc,omap_clk clk)395bded15c9SPhilippe Mathieu-Daudé void omap_intc_set_fclk(OMAPIntcState *intc, omap_clk clk)
396bab592a2SMarc-André Lureau {
397bab592a2SMarc-André Lureau     intc->fclk = clk;
398bab592a2SMarc-André Lureau }
399bab592a2SMarc-André Lureau 
4007702e47cSPaolo Bonzini static Property omap_intc_properties[] = {
401bded15c9SPhilippe Mathieu-Daudé     DEFINE_PROP_UINT32("size", OMAPIntcState, size, 0x100),
4027702e47cSPaolo Bonzini     DEFINE_PROP_END_OF_LIST(),
4037702e47cSPaolo Bonzini };
4047702e47cSPaolo Bonzini 
omap_intc_class_init(ObjectClass * klass,void * data)4057702e47cSPaolo Bonzini static void omap_intc_class_init(ObjectClass *klass, void *data)
4067702e47cSPaolo Bonzini {
4077702e47cSPaolo Bonzini     DeviceClass *dc = DEVICE_CLASS(klass);
4087702e47cSPaolo Bonzini 
4097702e47cSPaolo Bonzini     dc->reset = omap_inth_reset;
4104f67d30bSMarc-André Lureau     device_class_set_props(dc, omap_intc_properties);
4111b111dc1SMarkus Armbruster     /* Reason: pointer property "clk" */
412e90f2a8cSEduardo Habkost     dc->user_creatable = false;
4130a750e2aSxiaoqiang zhao     dc->realize = omap_intc_realize;
4147702e47cSPaolo Bonzini }
4157702e47cSPaolo Bonzini 
4167702e47cSPaolo Bonzini static const TypeInfo omap_intc_info = {
4177702e47cSPaolo Bonzini     .name          = "omap-intc",
41847edc5a4SAndreas Färber     .parent        = TYPE_OMAP_INTC,
4190a750e2aSxiaoqiang zhao     .instance_init = omap_intc_init,
4207702e47cSPaolo Bonzini     .class_init    = omap_intc_class_init,
4217702e47cSPaolo Bonzini };
4227702e47cSPaolo Bonzini 
omap2_inth_read(void * opaque,hwaddr addr,unsigned size)4237702e47cSPaolo Bonzini static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
4247702e47cSPaolo Bonzini                                 unsigned size)
4257702e47cSPaolo Bonzini {
426bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = opaque;
4277702e47cSPaolo Bonzini     int offset = addr;
4287702e47cSPaolo Bonzini     int bank_no, line_no;
4297702e47cSPaolo Bonzini     struct omap_intr_handler_bank_s *bank = NULL;
4307702e47cSPaolo Bonzini 
4317702e47cSPaolo Bonzini     if ((offset & 0xf80) == 0x80) {
4327702e47cSPaolo Bonzini         bank_no = (offset & 0x60) >> 5;
4337702e47cSPaolo Bonzini         if (bank_no < s->nbanks) {
4347702e47cSPaolo Bonzini             offset &= ~0x60;
4357702e47cSPaolo Bonzini             bank = &s->bank[bank_no];
4367702e47cSPaolo Bonzini         } else {
4377702e47cSPaolo Bonzini             OMAP_BAD_REG(addr);
4387702e47cSPaolo Bonzini             return 0;
4397702e47cSPaolo Bonzini         }
4407702e47cSPaolo Bonzini     }
4417702e47cSPaolo Bonzini 
4427702e47cSPaolo Bonzini     switch (offset) {
4437702e47cSPaolo Bonzini     case 0x00:	/* INTC_REVISION */
4447702e47cSPaolo Bonzini         return s->revision;
4457702e47cSPaolo Bonzini 
4467702e47cSPaolo Bonzini     case 0x10:	/* INTC_SYSCONFIG */
4477702e47cSPaolo Bonzini         return (s->autoidle >> 2) & 1;
4487702e47cSPaolo Bonzini 
4497702e47cSPaolo Bonzini     case 0x14:	/* INTC_SYSSTATUS */
4507702e47cSPaolo Bonzini         return 1;						/* RESETDONE */
4517702e47cSPaolo Bonzini 
4527702e47cSPaolo Bonzini     case 0x40:	/* INTC_SIR_IRQ */
4537702e47cSPaolo Bonzini         return s->sir_intr[0];
4547702e47cSPaolo Bonzini 
4557702e47cSPaolo Bonzini     case 0x44:	/* INTC_SIR_FIQ */
4567702e47cSPaolo Bonzini         return s->sir_intr[1];
4577702e47cSPaolo Bonzini 
4587702e47cSPaolo Bonzini     case 0x48:	/* INTC_CONTROL */
4597702e47cSPaolo Bonzini         return (!s->mask) << 2;					/* GLOBALMASK */
4607702e47cSPaolo Bonzini 
4617702e47cSPaolo Bonzini     case 0x4c:	/* INTC_PROTECTION */
4627702e47cSPaolo Bonzini         return 0;
4637702e47cSPaolo Bonzini 
4647702e47cSPaolo Bonzini     case 0x50:	/* INTC_IDLE */
4657702e47cSPaolo Bonzini         return s->autoidle & 3;
4667702e47cSPaolo Bonzini 
4677702e47cSPaolo Bonzini     /* Per-bank registers */
4687702e47cSPaolo Bonzini     case 0x80:	/* INTC_ITR */
4697702e47cSPaolo Bonzini         return bank->inputs;
4707702e47cSPaolo Bonzini 
4717702e47cSPaolo Bonzini     case 0x84:	/* INTC_MIR */
4727702e47cSPaolo Bonzini         return bank->mask;
4737702e47cSPaolo Bonzini 
4747702e47cSPaolo Bonzini     case 0x88:	/* INTC_MIR_CLEAR */
4757702e47cSPaolo Bonzini     case 0x8c:	/* INTC_MIR_SET */
4767702e47cSPaolo Bonzini         return 0;
4777702e47cSPaolo Bonzini 
4787702e47cSPaolo Bonzini     case 0x90:	/* INTC_ISR_SET */
4797702e47cSPaolo Bonzini         return bank->swi;
4807702e47cSPaolo Bonzini 
4817702e47cSPaolo Bonzini     case 0x94:	/* INTC_ISR_CLEAR */
4827702e47cSPaolo Bonzini         return 0;
4837702e47cSPaolo Bonzini 
4847702e47cSPaolo Bonzini     case 0x98:	/* INTC_PENDING_IRQ */
4857702e47cSPaolo Bonzini         return bank->irqs & ~bank->mask & ~bank->fiq;
4867702e47cSPaolo Bonzini 
4877702e47cSPaolo Bonzini     case 0x9c:	/* INTC_PENDING_FIQ */
4887702e47cSPaolo Bonzini         return bank->irqs & ~bank->mask & bank->fiq;
4897702e47cSPaolo Bonzini 
4907702e47cSPaolo Bonzini     /* Per-line registers */
4917702e47cSPaolo Bonzini     case 0x100 ... 0x300:	/* INTC_ILR */
4927702e47cSPaolo Bonzini         bank_no = (offset - 0x100) >> 7;
4937702e47cSPaolo Bonzini         if (bank_no > s->nbanks)
4947702e47cSPaolo Bonzini             break;
4957702e47cSPaolo Bonzini         bank = &s->bank[bank_no];
4967702e47cSPaolo Bonzini         line_no = (offset & 0x7f) >> 2;
4977702e47cSPaolo Bonzini         return (bank->priority[line_no] << 2) |
4987702e47cSPaolo Bonzini                 ((bank->fiq >> line_no) & 1);
4997702e47cSPaolo Bonzini     }
5007702e47cSPaolo Bonzini     OMAP_BAD_REG(addr);
5017702e47cSPaolo Bonzini     return 0;
5027702e47cSPaolo Bonzini }
5037702e47cSPaolo Bonzini 
omap2_inth_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)5047702e47cSPaolo Bonzini static void omap2_inth_write(void *opaque, hwaddr addr,
5057702e47cSPaolo Bonzini                              uint64_t value, unsigned size)
5067702e47cSPaolo Bonzini {
507bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = opaque;
5087702e47cSPaolo Bonzini     int offset = addr;
5097702e47cSPaolo Bonzini     int bank_no, line_no;
5107702e47cSPaolo Bonzini     struct omap_intr_handler_bank_s *bank = NULL;
5117702e47cSPaolo Bonzini 
5127702e47cSPaolo Bonzini     if ((offset & 0xf80) == 0x80) {
5137702e47cSPaolo Bonzini         bank_no = (offset & 0x60) >> 5;
5147702e47cSPaolo Bonzini         if (bank_no < s->nbanks) {
5157702e47cSPaolo Bonzini             offset &= ~0x60;
5167702e47cSPaolo Bonzini             bank = &s->bank[bank_no];
5177702e47cSPaolo Bonzini         } else {
5187702e47cSPaolo Bonzini             OMAP_BAD_REG(addr);
5197702e47cSPaolo Bonzini             return;
5207702e47cSPaolo Bonzini         }
5217702e47cSPaolo Bonzini     }
5227702e47cSPaolo Bonzini 
5237702e47cSPaolo Bonzini     switch (offset) {
5247702e47cSPaolo Bonzini     case 0x10:	/* INTC_SYSCONFIG */
5257702e47cSPaolo Bonzini         s->autoidle &= 4;
5267702e47cSPaolo Bonzini         s->autoidle |= (value & 1) << 2;
52747edc5a4SAndreas Färber         if (value & 2) {                                        /* SOFTRESET */
52847edc5a4SAndreas Färber             omap_inth_reset(DEVICE(s));
52947edc5a4SAndreas Färber         }
5307702e47cSPaolo Bonzini         return;
5317702e47cSPaolo Bonzini 
5327702e47cSPaolo Bonzini     case 0x48:	/* INTC_CONTROL */
5337702e47cSPaolo Bonzini         s->mask = (value & 4) ? 0 : ~0;				/* GLOBALMASK */
5347702e47cSPaolo Bonzini         if (value & 2) {					/* NEWFIQAGR */
5357702e47cSPaolo Bonzini             qemu_set_irq(s->parent_intr[1], 0);
5367702e47cSPaolo Bonzini             s->new_agr[1] = ~0;
5377702e47cSPaolo Bonzini             omap_inth_update(s, 1);
5387702e47cSPaolo Bonzini         }
5397702e47cSPaolo Bonzini         if (value & 1) {					/* NEWIRQAGR */
5407702e47cSPaolo Bonzini             qemu_set_irq(s->parent_intr[0], 0);
5417702e47cSPaolo Bonzini             s->new_agr[0] = ~0;
5427702e47cSPaolo Bonzini             omap_inth_update(s, 0);
5437702e47cSPaolo Bonzini         }
5447702e47cSPaolo Bonzini         return;
5457702e47cSPaolo Bonzini 
5467702e47cSPaolo Bonzini     case 0x4c:	/* INTC_PROTECTION */
5477702e47cSPaolo Bonzini         /* TODO: Make a bitmap (or sizeof(char)map) of access privileges
5487702e47cSPaolo Bonzini          * for every register, see Chapter 3 and 4 for privileged mode.  */
5497702e47cSPaolo Bonzini         if (value & 1)
5507702e47cSPaolo Bonzini             fprintf(stderr, "%s: protection mode enable attempt\n",
551a89f364aSAlistair Francis                             __func__);
5527702e47cSPaolo Bonzini         return;
5537702e47cSPaolo Bonzini 
5547702e47cSPaolo Bonzini     case 0x50:	/* INTC_IDLE */
5557702e47cSPaolo Bonzini         s->autoidle &= ~3;
5567702e47cSPaolo Bonzini         s->autoidle |= value & 3;
5577702e47cSPaolo Bonzini         return;
5587702e47cSPaolo Bonzini 
5597702e47cSPaolo Bonzini     /* Per-bank registers */
5607702e47cSPaolo Bonzini     case 0x84:	/* INTC_MIR */
5617702e47cSPaolo Bonzini         bank->mask = value;
5627702e47cSPaolo Bonzini         omap_inth_update(s, 0);
5637702e47cSPaolo Bonzini         omap_inth_update(s, 1);
5647702e47cSPaolo Bonzini         return;
5657702e47cSPaolo Bonzini 
5667702e47cSPaolo Bonzini     case 0x88:	/* INTC_MIR_CLEAR */
5677702e47cSPaolo Bonzini         bank->mask &= ~value;
5687702e47cSPaolo Bonzini         omap_inth_update(s, 0);
5697702e47cSPaolo Bonzini         omap_inth_update(s, 1);
5707702e47cSPaolo Bonzini         return;
5717702e47cSPaolo Bonzini 
5727702e47cSPaolo Bonzini     case 0x8c:	/* INTC_MIR_SET */
5737702e47cSPaolo Bonzini         bank->mask |= value;
5747702e47cSPaolo Bonzini         return;
5757702e47cSPaolo Bonzini 
5767702e47cSPaolo Bonzini     case 0x90:	/* INTC_ISR_SET */
5777702e47cSPaolo Bonzini         bank->irqs |= bank->swi |= value;
5787702e47cSPaolo Bonzini         omap_inth_update(s, 0);
5797702e47cSPaolo Bonzini         omap_inth_update(s, 1);
5807702e47cSPaolo Bonzini         return;
5817702e47cSPaolo Bonzini 
5827702e47cSPaolo Bonzini     case 0x94:	/* INTC_ISR_CLEAR */
5837702e47cSPaolo Bonzini         bank->swi &= ~value;
5847702e47cSPaolo Bonzini         bank->irqs = bank->swi & bank->inputs;
5857702e47cSPaolo Bonzini         return;
5867702e47cSPaolo Bonzini 
5877702e47cSPaolo Bonzini     /* Per-line registers */
5887702e47cSPaolo Bonzini     case 0x100 ... 0x300:	/* INTC_ILR */
5897702e47cSPaolo Bonzini         bank_no = (offset - 0x100) >> 7;
5907702e47cSPaolo Bonzini         if (bank_no > s->nbanks)
5917702e47cSPaolo Bonzini             break;
5927702e47cSPaolo Bonzini         bank = &s->bank[bank_no];
5937702e47cSPaolo Bonzini         line_no = (offset & 0x7f) >> 2;
5947702e47cSPaolo Bonzini         bank->priority[line_no] = (value >> 2) & 0x3f;
5957702e47cSPaolo Bonzini         bank->fiq &= ~(1 << line_no);
5967702e47cSPaolo Bonzini         bank->fiq |= (value & 1) << line_no;
5977702e47cSPaolo Bonzini         return;
5987702e47cSPaolo Bonzini 
5997702e47cSPaolo Bonzini     case 0x00:	/* INTC_REVISION */
6007702e47cSPaolo Bonzini     case 0x14:	/* INTC_SYSSTATUS */
6017702e47cSPaolo Bonzini     case 0x40:	/* INTC_SIR_IRQ */
6027702e47cSPaolo Bonzini     case 0x44:	/* INTC_SIR_FIQ */
6037702e47cSPaolo Bonzini     case 0x80:	/* INTC_ITR */
6047702e47cSPaolo Bonzini     case 0x98:	/* INTC_PENDING_IRQ */
6057702e47cSPaolo Bonzini     case 0x9c:	/* INTC_PENDING_FIQ */
6067702e47cSPaolo Bonzini         OMAP_RO_REG(addr);
6077702e47cSPaolo Bonzini         return;
6087702e47cSPaolo Bonzini     }
6097702e47cSPaolo Bonzini     OMAP_BAD_REG(addr);
6107702e47cSPaolo Bonzini }
6117702e47cSPaolo Bonzini 
6127702e47cSPaolo Bonzini static const MemoryRegionOps omap2_inth_mem_ops = {
6137702e47cSPaolo Bonzini     .read = omap2_inth_read,
6147702e47cSPaolo Bonzini     .write = omap2_inth_write,
6157702e47cSPaolo Bonzini     .endianness = DEVICE_NATIVE_ENDIAN,
6167702e47cSPaolo Bonzini     .valid = {
6177702e47cSPaolo Bonzini         .min_access_size = 4,
6187702e47cSPaolo Bonzini         .max_access_size = 4,
6197702e47cSPaolo Bonzini     },
6207702e47cSPaolo Bonzini };
6217702e47cSPaolo Bonzini 
omap2_intc_init(Object * obj)6220a750e2aSxiaoqiang zhao static void omap2_intc_init(Object *obj)
6237702e47cSPaolo Bonzini {
6240a750e2aSxiaoqiang zhao     DeviceState *dev = DEVICE(obj);
625bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = OMAP_INTC(obj);
6260a750e2aSxiaoqiang zhao     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
62747edc5a4SAndreas Färber 
6287702e47cSPaolo Bonzini     s->level_only = 1;
6297702e47cSPaolo Bonzini     s->nbanks = 3;
63047edc5a4SAndreas Färber     sysbus_init_irq(sbd, &s->parent_intr[0]);
63147edc5a4SAndreas Färber     sysbus_init_irq(sbd, &s->parent_intr[1]);
63247edc5a4SAndreas Färber     qdev_init_gpio_in(dev, omap_set_intr_noedge, s->nbanks * 32);
6330a750e2aSxiaoqiang zhao     memory_region_init_io(&s->mmio, obj, &omap2_inth_mem_ops, s,
6347702e47cSPaolo Bonzini                           "omap2-intc", 0x1000);
63547edc5a4SAndreas Färber     sysbus_init_mmio(sbd, &s->mmio);
6360a750e2aSxiaoqiang zhao }
6370a750e2aSxiaoqiang zhao 
omap2_intc_realize(DeviceState * dev,Error ** errp)6380a750e2aSxiaoqiang zhao static void omap2_intc_realize(DeviceState *dev, Error **errp)
6390a750e2aSxiaoqiang zhao {
640bded15c9SPhilippe Mathieu-Daudé     OMAPIntcState *s = OMAP_INTC(dev);
6410a750e2aSxiaoqiang zhao 
6420a750e2aSxiaoqiang zhao     if (!s->iclk) {
6430a750e2aSxiaoqiang zhao         error_setg(errp, "omap2-intc: iclk not connected");
6440a750e2aSxiaoqiang zhao         return;
6450a750e2aSxiaoqiang zhao     }
6460a750e2aSxiaoqiang zhao     if (!s->fclk) {
6470a750e2aSxiaoqiang zhao         error_setg(errp, "omap2-intc: fclk not connected");
6480a750e2aSxiaoqiang zhao         return;
6490a750e2aSxiaoqiang zhao     }
6507702e47cSPaolo Bonzini }
6517702e47cSPaolo Bonzini 
6527702e47cSPaolo Bonzini static Property omap2_intc_properties[] = {
653bded15c9SPhilippe Mathieu-Daudé     DEFINE_PROP_UINT8("revision", OMAPIntcState,
6547702e47cSPaolo Bonzini     revision, 0x21),
6557702e47cSPaolo Bonzini     DEFINE_PROP_END_OF_LIST(),
6567702e47cSPaolo Bonzini };
6577702e47cSPaolo Bonzini 
omap2_intc_class_init(ObjectClass * klass,void * data)6587702e47cSPaolo Bonzini static void omap2_intc_class_init(ObjectClass *klass, void *data)
6597702e47cSPaolo Bonzini {
6607702e47cSPaolo Bonzini     DeviceClass *dc = DEVICE_CLASS(klass);
6617702e47cSPaolo Bonzini 
6627702e47cSPaolo Bonzini     dc->reset = omap_inth_reset;
6634f67d30bSMarc-André Lureau     device_class_set_props(dc, omap2_intc_properties);
6641b111dc1SMarkus Armbruster     /* Reason: pointer property "iclk", "fclk" */
665e90f2a8cSEduardo Habkost     dc->user_creatable = false;
6660a750e2aSxiaoqiang zhao     dc->realize = omap2_intc_realize;
6677702e47cSPaolo Bonzini }
6687702e47cSPaolo Bonzini 
6697702e47cSPaolo Bonzini static const TypeInfo omap2_intc_info = {
6707702e47cSPaolo Bonzini     .name          = "omap2-intc",
67147edc5a4SAndreas Färber     .parent        = TYPE_OMAP_INTC,
6720a750e2aSxiaoqiang zhao     .instance_init = omap2_intc_init,
67347edc5a4SAndreas Färber     .class_init    = omap2_intc_class_init,
67447edc5a4SAndreas Färber };
67547edc5a4SAndreas Färber 
67647edc5a4SAndreas Färber static const TypeInfo omap_intc_type_info = {
67747edc5a4SAndreas Färber     .name          = TYPE_OMAP_INTC,
6787702e47cSPaolo Bonzini     .parent        = TYPE_SYS_BUS_DEVICE,
679bded15c9SPhilippe Mathieu-Daudé     .instance_size = sizeof(OMAPIntcState),
68047edc5a4SAndreas Färber     .abstract      = true,
6817702e47cSPaolo Bonzini };
6827702e47cSPaolo Bonzini 
omap_intc_register_types(void)6837702e47cSPaolo Bonzini static void omap_intc_register_types(void)
6847702e47cSPaolo Bonzini {
68547edc5a4SAndreas Färber     type_register_static(&omap_intc_type_info);
6867702e47cSPaolo Bonzini     type_register_static(&omap_intc_info);
6877702e47cSPaolo Bonzini     type_register_static(&omap2_intc_info);
6887702e47cSPaolo Bonzini }
6897702e47cSPaolo Bonzini 
6907702e47cSPaolo Bonzini type_init(omap_intc_register_types)
691