Commit ad938fc1 authored by Peter Maydell's avatar Peter Maydell
Browse files

hw/arm/palm.c: Encapsulate misc GPIO handling in a device



Replace the free-floating set of IRQs and palmte_onoff_gpios()
function with a simple QOM device that encapsulates this
behaviour.

This fixes Coverity issue CID 1421944, which points out that
the memory returned by qemu_allocate_irqs() is leaked.

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarLi Qiang <liq3ea@gmail.com>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20200628214230.2592-3-peter.maydell@linaro.org
parent c1abd462
Loading
Loading
Loading
Loading
+52 −9
Original line number Diff line number Diff line
@@ -124,6 +124,21 @@ static void palmte_button_event(void *opaque, int keycode)
                        !(keycode & 0x80));
}

/*
 * Encapsulation of some GPIO line behaviour for the Palm board
 *
 * QEMU interface:
 *  + unnamed GPIO inputs 0..6: for the various miscellaneous input lines
 */

#define TYPE_PALM_MISC_GPIO "palm-misc-gpio"
#define PALM_MISC_GPIO(obj) \
    OBJECT_CHECK(PalmMiscGPIOState, (obj), TYPE_PALM_MISC_GPIO)

typedef struct PalmMiscGPIOState {
    SysBusDevice parent_obj;
} PalmMiscGPIOState;

static void palmte_onoff_gpios(void *opaque, int line, int level)
{
    switch (line) {
@@ -151,23 +166,44 @@ static void palmte_onoff_gpios(void *opaque, int line, int level)
    }
}

static void palm_misc_gpio_init(Object *obj)
{
    DeviceState *dev = DEVICE(obj);

    qdev_init_gpio_in(dev, palmte_onoff_gpios, 7);
}

static const TypeInfo palm_misc_gpio_info = {
    .name = TYPE_PALM_MISC_GPIO,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(PalmMiscGPIOState),
    .instance_init = palm_misc_gpio_init,
    /*
     * No class init required: device has no internal state so does not
     * need to set up reset or vmstate, and has no realize method.
     */
};

static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
{
    qemu_irq *misc_gpio;
    DeviceState *misc_gpio;

    misc_gpio = sysbus_create_simple(TYPE_PALM_MISC_GPIO, -1, NULL);

    omap_mmc_handlers(cpu->mmc,
                    qdev_get_gpio_in(cpu->gpio, PALMTE_MMC_WP_GPIO),
                    qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
                            [PALMTE_MMC_SWITCH_GPIO]));

    misc_gpio = qemu_allocate_irqs(palmte_onoff_gpios, cpu, 7);
    qdev_connect_gpio_out(cpu->gpio, PALMTE_MMC_POWER_GPIO,     misc_gpio[0]);
    qdev_connect_gpio_out(cpu->gpio, PALMTE_SPEAKER_GPIO,       misc_gpio[1]);
    qdev_connect_gpio_out(cpu->gpio, 11,                        misc_gpio[2]);
    qdev_connect_gpio_out(cpu->gpio, 12,                        misc_gpio[3]);
    qdev_connect_gpio_out(cpu->gpio, 13,                        misc_gpio[4]);
    omap_mpuio_out_set(cpu->mpuio, 1,                           misc_gpio[5]);
    omap_mpuio_out_set(cpu->mpuio, 3,                           misc_gpio[6]);
    qdev_connect_gpio_out(cpu->gpio, PALMTE_MMC_POWER_GPIO,
                          qdev_get_gpio_in(misc_gpio, 0));
    qdev_connect_gpio_out(cpu->gpio, PALMTE_SPEAKER_GPIO,
                          qdev_get_gpio_in(misc_gpio, 1));
    qdev_connect_gpio_out(cpu->gpio, 11, qdev_get_gpio_in(misc_gpio, 2));
    qdev_connect_gpio_out(cpu->gpio, 12, qdev_get_gpio_in(misc_gpio, 3));
    qdev_connect_gpio_out(cpu->gpio, 13, qdev_get_gpio_in(misc_gpio, 4));
    omap_mpuio_out_set(cpu->mpuio, 1, qdev_get_gpio_in(misc_gpio, 5));
    omap_mpuio_out_set(cpu->mpuio, 3, qdev_get_gpio_in(misc_gpio, 6));

    /* Reset some inputs to initial state.  */
    qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USBDETECT_GPIO));
@@ -276,3 +312,10 @@ static void palmte_machine_init(MachineClass *mc)
}

DEFINE_MACHINE("cheetah", palmte_machine_init)

static void palm_register_types(void)
{
    type_register_static(&palm_misc_gpio_info);
}

type_init(palm_register_types)