qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

split-irq.c (2851B)


      1 /*
      2  * IRQ splitter device.
      3  *
      4  * Copyright (c) 2018 Linaro Limited.
      5  * Written by Peter Maydell
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a copy
      8  * of this software and associated documentation files (the "Software"), to deal
      9  * in the Software without restriction, including without limitation the rights
     10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11  * copies of the Software, and to permit persons to whom the Software is
     12  * furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     23  * THE SOFTWARE.
     24  */
     25 
     26 #include "qemu/osdep.h"
     27 #include "hw/core/split-irq.h"
     28 #include "hw/irq.h"
     29 #include "hw/qdev-properties.h"
     30 #include "qapi/error.h"
     31 #include "qemu/module.h"
     32 
     33 static void split_irq_handler(void *opaque, int n, int level)
     34 {
     35     SplitIRQ *s = SPLIT_IRQ(opaque);
     36     int i;
     37 
     38     for (i = 0; i < s->num_lines; i++) {
     39         qemu_set_irq(s->out_irq[i], level);
     40     }
     41 }
     42 
     43 static void split_irq_init(Object *obj)
     44 {
     45     qdev_init_gpio_in(DEVICE(obj), split_irq_handler, 1);
     46 }
     47 
     48 static void split_irq_realize(DeviceState *dev, Error **errp)
     49 {
     50     SplitIRQ *s = SPLIT_IRQ(dev);
     51 
     52     if (s->num_lines < 1 || s->num_lines >= MAX_SPLIT_LINES) {
     53         error_setg(errp,
     54                    "IRQ splitter number of lines %d is not between 1 and %d",
     55                    s->num_lines, MAX_SPLIT_LINES);
     56         return;
     57     }
     58 
     59     qdev_init_gpio_out(dev, s->out_irq, s->num_lines);
     60 }
     61 
     62 static Property split_irq_properties[] = {
     63     DEFINE_PROP_UINT16("num-lines", SplitIRQ, num_lines, 1),
     64     DEFINE_PROP_END_OF_LIST(),
     65 };
     66 
     67 static void split_irq_class_init(ObjectClass *klass, void *data)
     68 {
     69     DeviceClass *dc = DEVICE_CLASS(klass);
     70 
     71     /* No state to reset or migrate */
     72     device_class_set_props(dc, split_irq_properties);
     73     dc->realize = split_irq_realize;
     74 
     75     /* Reason: Needs to be wired up to work */
     76     dc->user_creatable = false;
     77 }
     78 
     79 static const TypeInfo split_irq_type_info = {
     80    .name = TYPE_SPLIT_IRQ,
     81    .parent = TYPE_DEVICE,
     82    .instance_size = sizeof(SplitIRQ),
     83    .instance_init = split_irq_init,
     84    .class_init = split_irq_class_init,
     85 };
     86 
     87 static void split_irq_register_types(void)
     88 {
     89     type_register_static(&split_irq_type_info);
     90 }
     91 
     92 type_init(split_irq_register_types)