Skip to content

Commit d4e1d8f

Browse files
committed
hw/arm/tosa: Encapsulate misc GPIO handling in a device
Currently we have a free-floating set of IRQs and a function tosa_out_switch() which handle the GPIO lines on the tosa board which connect to LEDs, and another free-floating IRQ and tosa_reset() function to handle the GPIO line that resets the system. Encapsulate this behaviour in a simple QOM device. This commit fixes Coverity issue CID 1421929 (which pointed out that the 'outsignals' in tosa_gpio_setup() were leaked), because it removes the use of the qemu_allocate_irqs() API from this code entirely. Signed-off-by: Peter Maydell <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Message-id: [email protected]
1 parent ad9d854 commit d4e1d8f

File tree

1 file changed

+64
-24
lines changed

1 file changed

+64
-24
lines changed

hw/arm/tosa.c

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,39 @@ static void tosa_microdrive_attach(PXA2xxState *cpu)
6565
pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
6666
}
6767

68-
static void tosa_out_switch(void *opaque, int line, int level)
68+
/*
69+
* Encapsulation of some GPIO line behaviour for the Tosa board
70+
*
71+
* QEMU interface:
72+
* + named GPIO inputs "leds[0..3]": assert to light LEDs
73+
* + named GPIO input "reset": when asserted, resets the system
74+
*/
75+
76+
#define TYPE_TOSA_MISC_GPIO "tosa-misc-gpio"
77+
#define TOSA_MISC_GPIO(obj) \
78+
OBJECT_CHECK(TosaMiscGPIOState, (obj), TYPE_TOSA_MISC_GPIO)
79+
80+
typedef struct TosaMiscGPIOState {
81+
SysBusDevice parent_obj;
82+
} TosaMiscGPIOState;
83+
84+
static void tosa_gpio_leds(void *opaque, int line, int level)
6985
{
7086
switch (line) {
71-
case 0:
72-
fprintf(stderr, "blue LED %s.\n", level ? "on" : "off");
73-
break;
74-
case 1:
75-
fprintf(stderr, "green LED %s.\n", level ? "on" : "off");
76-
break;
77-
case 2:
78-
fprintf(stderr, "amber LED %s.\n", level ? "on" : "off");
79-
break;
80-
case 3:
81-
fprintf(stderr, "wlan LED %s.\n", level ? "on" : "off");
82-
break;
83-
default:
84-
fprintf(stderr, "Uhandled out event: %d = %d\n", line, level);
85-
break;
87+
case 0:
88+
fprintf(stderr, "blue LED %s.\n", level ? "on" : "off");
89+
break;
90+
case 1:
91+
fprintf(stderr, "green LED %s.\n", level ? "on" : "off");
92+
break;
93+
case 2:
94+
fprintf(stderr, "amber LED %s.\n", level ? "on" : "off");
95+
break;
96+
case 3:
97+
fprintf(stderr, "wlan LED %s.\n", level ? "on" : "off");
98+
break;
99+
default:
100+
g_assert_not_reached();
86101
}
87102
}
88103

@@ -93,22 +108,31 @@ static void tosa_reset(void *opaque, int line, int level)
93108
}
94109
}
95110

111+
static void tosa_misc_gpio_init(Object *obj)
112+
{
113+
DeviceState *dev = DEVICE(obj);
114+
115+
qdev_init_gpio_in_named(dev, tosa_gpio_leds, "leds", 4);
116+
qdev_init_gpio_in_named(dev, tosa_reset, "reset", 1);
117+
}
118+
96119
static void tosa_gpio_setup(PXA2xxState *cpu,
97120
DeviceState *scp0,
98121
DeviceState *scp1,
99122
TC6393xbState *tmio)
100123
{
101-
qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4);
102-
qemu_irq reset;
124+
DeviceState *misc_gpio;
125+
126+
misc_gpio = sysbus_create_simple(TYPE_TOSA_MISC_GPIO, -1, NULL);
103127

104128
/* MMC/SD host */
105129
pxa2xx_mmci_handlers(cpu->mmc,
106130
qdev_get_gpio_in(scp0, TOSA_GPIO_SD_WP),
107131
qemu_irq_invert(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_nSD_DETECT)));
108132

109133
/* Handle reset */
110-
reset = qemu_allocate_irq(tosa_reset, cpu, 0);
111-
qdev_connect_gpio_out(cpu->gpio, TOSA_GPIO_ON_RESET, reset);
134+
qdev_connect_gpio_out(cpu->gpio, TOSA_GPIO_ON_RESET,
135+
qdev_get_gpio_in_named(misc_gpio, "reset", 0));
112136

113137
/* PCMCIA signals: card's IRQ and Card-Detect */
114138
pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
@@ -119,10 +143,14 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
119143
qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_JC_CF_IRQ),
120144
NULL);
121145

122-
qdev_connect_gpio_out(scp1, TOSA_GPIO_BT_LED, outsignals[0]);
123-
qdev_connect_gpio_out(scp1, TOSA_GPIO_NOTE_LED, outsignals[1]);
124-
qdev_connect_gpio_out(scp1, TOSA_GPIO_CHRG_ERR_LED, outsignals[2]);
125-
qdev_connect_gpio_out(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]);
146+
qdev_connect_gpio_out(scp1, TOSA_GPIO_BT_LED,
147+
qdev_get_gpio_in_named(misc_gpio, "leds", 0));
148+
qdev_connect_gpio_out(scp1, TOSA_GPIO_NOTE_LED,
149+
qdev_get_gpio_in_named(misc_gpio, "leds", 1));
150+
qdev_connect_gpio_out(scp1, TOSA_GPIO_CHRG_ERR_LED,
151+
qdev_get_gpio_in_named(misc_gpio, "leds", 2));
152+
qdev_connect_gpio_out(scp1, TOSA_GPIO_WLAN_LED,
153+
qdev_get_gpio_in_named(misc_gpio, "leds", 3));
126154

127155
qdev_connect_gpio_out(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio));
128156

@@ -287,10 +315,22 @@ static const TypeInfo tosa_ssp_info = {
287315
.class_init = tosa_ssp_class_init,
288316
};
289317

318+
static const TypeInfo tosa_misc_gpio_info = {
319+
.name = "tosa-misc-gpio",
320+
.parent = TYPE_SYS_BUS_DEVICE,
321+
.instance_size = sizeof(TosaMiscGPIOState),
322+
.instance_init = tosa_misc_gpio_init,
323+
/*
324+
* No class init required: device has no internal state so does not
325+
* need to set up reset or vmstate, and has no realize method.
326+
*/
327+
};
328+
290329
static void tosa_register_types(void)
291330
{
292331
type_register_static(&tosa_dac_info);
293332
type_register_static(&tosa_ssp_info);
333+
type_register_static(&tosa_misc_gpio_info);
294334
}
295335

296336
type_init(tosa_register_types)

0 commit comments

Comments
 (0)