15edb1b3fSPeter Maydell /* 25edb1b3fSPeter Maydell * IRQ splitter device. 35edb1b3fSPeter Maydell * 45edb1b3fSPeter Maydell * Copyright (c) 2018 Linaro Limited. 55edb1b3fSPeter Maydell * Written by Peter Maydell 65edb1b3fSPeter Maydell * 75edb1b3fSPeter Maydell * Permission is hereby granted, free of charge, to any person obtaining a copy 85edb1b3fSPeter Maydell * of this software and associated documentation files (the "Software"), to deal 95edb1b3fSPeter Maydell * in the Software without restriction, including without limitation the rights 105edb1b3fSPeter Maydell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 115edb1b3fSPeter Maydell * copies of the Software, and to permit persons to whom the Software is 125edb1b3fSPeter Maydell * furnished to do so, subject to the following conditions: 135edb1b3fSPeter Maydell * 145edb1b3fSPeter Maydell * The above copyright notice and this permission notice shall be included in 155edb1b3fSPeter Maydell * all copies or substantial portions of the Software. 165edb1b3fSPeter Maydell * 175edb1b3fSPeter Maydell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 185edb1b3fSPeter Maydell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 195edb1b3fSPeter Maydell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 205edb1b3fSPeter Maydell * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 215edb1b3fSPeter Maydell * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 225edb1b3fSPeter Maydell * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 235edb1b3fSPeter Maydell * THE SOFTWARE. 245edb1b3fSPeter Maydell */ 255edb1b3fSPeter Maydell 265edb1b3fSPeter Maydell #include "qemu/osdep.h" 275edb1b3fSPeter Maydell #include "hw/core/split-irq.h" 2864552b6bSMarkus Armbruster #include "hw/irq.h" 29*a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h" 305edb1b3fSPeter Maydell #include "qapi/error.h" 310b8fa32fSMarkus Armbruster #include "qemu/module.h" 325edb1b3fSPeter Maydell 335edb1b3fSPeter Maydell static void split_irq_handler(void *opaque, int n, int level) 345edb1b3fSPeter Maydell { 355edb1b3fSPeter Maydell SplitIRQ *s = SPLIT_IRQ(opaque); 365edb1b3fSPeter Maydell int i; 375edb1b3fSPeter Maydell 385edb1b3fSPeter Maydell for (i = 0; i < s->num_lines; i++) { 395edb1b3fSPeter Maydell qemu_set_irq(s->out_irq[i], level); 405edb1b3fSPeter Maydell } 415edb1b3fSPeter Maydell } 425edb1b3fSPeter Maydell 435edb1b3fSPeter Maydell static void split_irq_init(Object *obj) 445edb1b3fSPeter Maydell { 455edb1b3fSPeter Maydell qdev_init_gpio_in(DEVICE(obj), split_irq_handler, 1); 465edb1b3fSPeter Maydell } 475edb1b3fSPeter Maydell 485edb1b3fSPeter Maydell static void split_irq_realize(DeviceState *dev, Error **errp) 495edb1b3fSPeter Maydell { 505edb1b3fSPeter Maydell SplitIRQ *s = SPLIT_IRQ(dev); 515edb1b3fSPeter Maydell 525edb1b3fSPeter Maydell if (s->num_lines < 1 || s->num_lines >= MAX_SPLIT_LINES) { 535edb1b3fSPeter Maydell error_setg(errp, 545edb1b3fSPeter Maydell "IRQ splitter number of lines %d is not between 1 and %d", 555edb1b3fSPeter Maydell s->num_lines, MAX_SPLIT_LINES); 565edb1b3fSPeter Maydell return; 575edb1b3fSPeter Maydell } 585edb1b3fSPeter Maydell 595edb1b3fSPeter Maydell qdev_init_gpio_out(dev, s->out_irq, s->num_lines); 605edb1b3fSPeter Maydell } 615edb1b3fSPeter Maydell 625edb1b3fSPeter Maydell static Property split_irq_properties[] = { 635edb1b3fSPeter Maydell DEFINE_PROP_UINT16("num-lines", SplitIRQ, num_lines, 1), 645edb1b3fSPeter Maydell DEFINE_PROP_END_OF_LIST(), 655edb1b3fSPeter Maydell }; 665edb1b3fSPeter Maydell 675edb1b3fSPeter Maydell static void split_irq_class_init(ObjectClass *klass, void *data) 685edb1b3fSPeter Maydell { 695edb1b3fSPeter Maydell DeviceClass *dc = DEVICE_CLASS(klass); 705edb1b3fSPeter Maydell 715edb1b3fSPeter Maydell /* No state to reset or migrate */ 725edb1b3fSPeter Maydell dc->props = split_irq_properties; 735edb1b3fSPeter Maydell dc->realize = split_irq_realize; 745edb1b3fSPeter Maydell 755edb1b3fSPeter Maydell /* Reason: Needs to be wired up to work */ 765edb1b3fSPeter Maydell dc->user_creatable = false; 775edb1b3fSPeter Maydell } 785edb1b3fSPeter Maydell 795edb1b3fSPeter Maydell static const TypeInfo split_irq_type_info = { 805edb1b3fSPeter Maydell .name = TYPE_SPLIT_IRQ, 815edb1b3fSPeter Maydell .parent = TYPE_DEVICE, 825edb1b3fSPeter Maydell .instance_size = sizeof(SplitIRQ), 835edb1b3fSPeter Maydell .instance_init = split_irq_init, 845edb1b3fSPeter Maydell .class_init = split_irq_class_init, 855edb1b3fSPeter Maydell }; 865edb1b3fSPeter Maydell 875edb1b3fSPeter Maydell static void split_irq_register_types(void) 885edb1b3fSPeter Maydell { 895edb1b3fSPeter Maydell type_register_static(&split_irq_type_info); 905edb1b3fSPeter Maydell } 915edb1b3fSPeter Maydell 925edb1b3fSPeter Maydell type_init(split_irq_register_types) 93