1*1b255677SAlistair Francis /* 2*1b255677SAlistair Francis * QEMU IRQ/GPIO common code. 3*1b255677SAlistair Francis * 4*1b255677SAlistair Francis * Copyright (c) 2016 Alistair Francis <alistair@alistair23.me>. 5*1b255677SAlistair Francis * 6*1b255677SAlistair Francis * Permission is hereby granted, free of charge, to any person obtaining a copy 7*1b255677SAlistair Francis * of this software and associated documentation files (the "Software"), to deal 8*1b255677SAlistair Francis * in the Software without restriction, including without limitation the rights 9*1b255677SAlistair Francis * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10*1b255677SAlistair Francis * copies of the Software, and to permit persons to whom the Software is 11*1b255677SAlistair Francis * furnished to do so, subject to the following conditions: 12*1b255677SAlistair Francis * 13*1b255677SAlistair Francis * The above copyright notice and this permission notice shall be included in 14*1b255677SAlistair Francis * all copies or substantial portions of the Software. 15*1b255677SAlistair Francis * 16*1b255677SAlistair Francis * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*1b255677SAlistair Francis * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*1b255677SAlistair Francis * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*1b255677SAlistair Francis * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20*1b255677SAlistair Francis * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21*1b255677SAlistair Francis * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22*1b255677SAlistair Francis * THE SOFTWARE. 23*1b255677SAlistair Francis */ 24*1b255677SAlistair Francis 25*1b255677SAlistair Francis #include "qemu/osdep.h" 26*1b255677SAlistair Francis #include "hw/or-irq.h" 27*1b255677SAlistair Francis 28*1b255677SAlistair Francis static void or_irq_handler(void *opaque, int n, int level) 29*1b255677SAlistair Francis { 30*1b255677SAlistair Francis qemu_or_irq *s = OR_IRQ(opaque); 31*1b255677SAlistair Francis int or_level = 0; 32*1b255677SAlistair Francis int i; 33*1b255677SAlistair Francis 34*1b255677SAlistair Francis s->levels[n] = level; 35*1b255677SAlistair Francis 36*1b255677SAlistair Francis for (i = 0; i < s->num_lines; i++) { 37*1b255677SAlistair Francis or_level |= s->levels[i]; 38*1b255677SAlistair Francis } 39*1b255677SAlistair Francis 40*1b255677SAlistair Francis qemu_set_irq(s->out_irq, or_level); 41*1b255677SAlistair Francis } 42*1b255677SAlistair Francis 43*1b255677SAlistair Francis static void or_irq_reset(DeviceState *dev) 44*1b255677SAlistair Francis { 45*1b255677SAlistair Francis qemu_or_irq *s = OR_IRQ(dev); 46*1b255677SAlistair Francis int i; 47*1b255677SAlistair Francis 48*1b255677SAlistair Francis for (i = 0; i < MAX_OR_LINES; i++) { 49*1b255677SAlistair Francis s->levels[i] = false; 50*1b255677SAlistair Francis } 51*1b255677SAlistair Francis } 52*1b255677SAlistair Francis 53*1b255677SAlistair Francis static void or_irq_realize(DeviceState *dev, Error **errp) 54*1b255677SAlistair Francis { 55*1b255677SAlistair Francis qemu_or_irq *s = OR_IRQ(dev); 56*1b255677SAlistair Francis 57*1b255677SAlistair Francis assert(s->num_lines < MAX_OR_LINES); 58*1b255677SAlistair Francis 59*1b255677SAlistair Francis qdev_init_gpio_in(dev, or_irq_handler, s->num_lines); 60*1b255677SAlistair Francis } 61*1b255677SAlistair Francis 62*1b255677SAlistair Francis static void or_irq_init(Object *obj) 63*1b255677SAlistair Francis { 64*1b255677SAlistair Francis qemu_or_irq *s = OR_IRQ(obj); 65*1b255677SAlistair Francis 66*1b255677SAlistair Francis qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1); 67*1b255677SAlistair Francis } 68*1b255677SAlistair Francis 69*1b255677SAlistair Francis static const VMStateDescription vmstate_or_irq = { 70*1b255677SAlistair Francis .name = TYPE_OR_IRQ, 71*1b255677SAlistair Francis .version_id = 1, 72*1b255677SAlistair Francis .minimum_version_id = 1, 73*1b255677SAlistair Francis .fields = (VMStateField[]) { 74*1b255677SAlistair Francis VMSTATE_BOOL_ARRAY(levels, qemu_or_irq, MAX_OR_LINES), 75*1b255677SAlistair Francis VMSTATE_END_OF_LIST(), 76*1b255677SAlistair Francis } 77*1b255677SAlistair Francis }; 78*1b255677SAlistair Francis 79*1b255677SAlistair Francis static Property or_irq_properties[] = { 80*1b255677SAlistair Francis DEFINE_PROP_UINT16("num-lines", qemu_or_irq, num_lines, 1), 81*1b255677SAlistair Francis DEFINE_PROP_END_OF_LIST(), 82*1b255677SAlistair Francis }; 83*1b255677SAlistair Francis 84*1b255677SAlistair Francis static void or_irq_class_init(ObjectClass *klass, void *data) 85*1b255677SAlistair Francis { 86*1b255677SAlistair Francis DeviceClass *dc = DEVICE_CLASS(klass); 87*1b255677SAlistair Francis 88*1b255677SAlistair Francis dc->reset = or_irq_reset; 89*1b255677SAlistair Francis dc->props = or_irq_properties; 90*1b255677SAlistair Francis dc->realize = or_irq_realize; 91*1b255677SAlistair Francis dc->vmsd = &vmstate_or_irq; 92*1b255677SAlistair Francis } 93*1b255677SAlistair Francis 94*1b255677SAlistair Francis static const TypeInfo or_irq_type_info = { 95*1b255677SAlistair Francis .name = TYPE_OR_IRQ, 96*1b255677SAlistair Francis .parent = TYPE_DEVICE, 97*1b255677SAlistair Francis .instance_size = sizeof(qemu_or_irq), 98*1b255677SAlistair Francis .instance_init = or_irq_init, 99*1b255677SAlistair Francis .class_init = or_irq_class_init, 100*1b255677SAlistair Francis }; 101*1b255677SAlistair Francis 102*1b255677SAlistair Francis static void or_irq_register_types(void) 103*1b255677SAlistair Francis { 104*1b255677SAlistair Francis type_register_static(&or_irq_type_info); 105*1b255677SAlistair Francis } 106*1b255677SAlistair Francis 107*1b255677SAlistair Francis type_init(or_irq_register_types) 108