From 7582d930dad3331bfdd7a4e1fe5d2080051d10d9 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 4 Apr 2022 16:46:52 +0100 Subject: [PATCH] hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs() In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device instead of qemu_irq_split(). Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20220404154658.565020-13-peter.maydell@linaro.org --- hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++-------- include/hw/arm/exynos4210.h | 9 ++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 86a9a0dae1..919821833b 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -263,6 +263,8 @@ static void exynos4210_init_board_irqs(Exynos4210State *s) uint32_t grp, bit, irq_id, n; Exynos4210Irq *is = &s->irqs; DeviceState *extgicdev = DEVICE(&s->ext_gic); + int splitcount = 0; + DeviceState *splitter; for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) { irq_id = 0; @@ -276,13 +278,19 @@ static void exynos4210_init_board_irqs(Exynos4210State *s) /* MCT_G1 is passed to External and GIC */ irq_id = EXT_GIC_ID_MCT_G1; } + + assert(splitcount < EXYNOS4210_NUM_SPLITTERS); + splitter = DEVICE(&s->splitter[splitcount]); + qdev_prop_set_uint16(splitter, "num-lines", 2); + qdev_realize(splitter, NULL, &error_abort); + splitcount++; + s->irq_table[n] = qdev_get_gpio_in(splitter, 0); + qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]); if (irq_id) { - s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n], - qdev_get_gpio_in(extgicdev, - irq_id - 32)); + qdev_connect_gpio_out(splitter, 1, + qdev_get_gpio_in(extgicdev, irq_id - 32)); } else { - s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n], - is->ext_combiner_irq[n]); + qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]); } } for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) { @@ -293,11 +301,23 @@ static void exynos4210_init_board_irqs(Exynos4210State *s) EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit]; if (irq_id) { - s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n], - qdev_get_gpio_in(extgicdev, - irq_id - 32)); + assert(splitcount < EXYNOS4210_NUM_SPLITTERS); + splitter = DEVICE(&s->splitter[splitcount]); + qdev_prop_set_uint16(splitter, "num-lines", 2); + qdev_realize(splitter, NULL, &error_abort); + splitcount++; + s->irq_table[n] = qdev_get_gpio_in(splitter, 0); + qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]); + qdev_connect_gpio_out(splitter, 1, + qdev_get_gpio_in(extgicdev, irq_id - 32)); } } + /* + * We check this here to avoid a more obscure assert later when + * qdev_assert_realized_properly() checks that we realized every + * child object we initialized. + */ + assert(splitcount == EXYNOS4210_NUM_SPLITTERS); } /* @@ -766,6 +786,11 @@ static void exynos4210_init(Object *obj) object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ); } + for (i = 0; i < ARRAY_SIZE(s->splitter); i++) { + g_autofree char *name = g_strdup_printf("irq-splitter%d", i); + object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ); + } + object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV); object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC); } diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index f0769a4045..f58ee0f268 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -28,6 +28,7 @@ #include "hw/sysbus.h" #include "hw/cpu/a9mpcore.h" #include "hw/intc/exynos4210_gic.h" +#include "hw/core/split-irq.h" #include "target/arm/cpu-qom.h" #include "qom/object.h" @@ -71,6 +72,13 @@ #define EXYNOS4210_NUM_DMA 3 +/* + * We need one splitter for every external combiner input, plus + * one for every non-zero entry in combiner_grp_to_gic_id[]. + * We'll assert in exynos4210_init_board_irqs() if this is wrong. + */ +#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60) + typedef struct Exynos4210Irq { qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ]; @@ -95,6 +103,7 @@ struct Exynos4210State { qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS]; A9MPPrivState a9mpcore; Exynos4210GicState ext_gic; + SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS]; }; #define TYPE_EXYNOS4210_SOC "exynos4210"