[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 28/34] hw/arm/spitz: Encapsulate misc GPIO handling in a device
From: |
Peter Maydell |
Subject: |
[PULL 28/34] hw/arm/spitz: Encapsulate misc GPIO handling in a device |
Date: |
Fri, 3 Jul 2020 17:53:59 +0100 |
Currently we have a free-floating set of IRQs and a function
spitz_out_switch() which handle some miscellaneous GPIO lines for the
spitz board. Encapsulate this behaviour in a simple QOM device.
At this point we can finally remove the 'max1111' global, because the
ADC battery-temperature value is now handled by the misc-gpio device
writing the value to its outbound "adc-temp" GPIO, which the board
code wires up to the appropriate inbound GPIO line on the max1111.
This commit also fixes Coverity issue CID 1421913 (which pointed out
that the 'outsignals' in spitz_scoop_gpio_setup() were leaked),
because it removes the use of the qemu_allocate_irqs() API from this
code entirely.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20200628142429.17111-13-peter.maydell@linaro.org
---
hw/arm/spitz.c | 129 +++++++++++++++++++++++++++++++++----------------
1 file changed, 87 insertions(+), 42 deletions(-)
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 1400a56729d..bab9968ccee 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -51,6 +51,7 @@ typedef struct {
DeviceState *max1111;
DeviceState *scp0;
DeviceState *scp1;
+ DeviceState *misc_gpio;
} SpitzMachineState;
#define TYPE_SPITZ_MACHINE "spitz-common"
@@ -658,8 +659,6 @@ static void spitz_lcdtg_realize(SSISlave *ssi, Error **errp)
#define SPITZ_GPIO_MAX1111_CS 20
#define SPITZ_GPIO_TP_INT 11
-static DeviceState *max1111;
-
/* "Demux" the signal based on current chipselect */
typedef struct {
SSISlave ssidev;
@@ -695,18 +694,6 @@ static void corgi_ssp_gpio_cs(void *opaque, int line, int
level)
#define SPITZ_BATTERY_VOLT 0xd0 /* About 4.0V */
#define SPITZ_CHARGEON_ACIN 0x80 /* About 5.0V */
-static void spitz_adc_temp_on(void *opaque, int line, int level)
-{
- int batt_temp;
-
- if (!max1111)
- return;
-
- batt_temp = level ? SPITZ_BATTERY_TEMP : 0;
-
- qemu_set_irq(qdev_get_gpio_in(max1111, MAX1111_BATT_TEMP), batt_temp);
-}
-
static void corgi_ssp_realize(SSISlave *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
@@ -734,7 +721,6 @@ static void spitz_ssp_attach(SpitzMachineState *sms)
bus = qdev_get_child_bus(sms->mux, "ssi2");
sms->max1111 = qdev_new(TYPE_MAX_1111);
- max1111 = sms->max1111;
qdev_prop_set_uint8(sms->max1111, "input1" /* BATT_VOLT */,
SPITZ_BATTERY_VOLT);
qdev_prop_set_uint8(sms->max1111, "input2" /* BATT_TEMP */, 0);
@@ -810,27 +796,66 @@ static void spitz_akita_i2c_setup(PXA2xxState *cpu)
/* Other peripherals */
-static void spitz_out_switch(void *opaque, int line, int level)
+/*
+ * Encapsulation of some miscellaneous GPIO line behaviour for the Spitz
boards.
+ *
+ * QEMU interface:
+ * + named GPIO inputs "green-led", "orange-led", "charging", "discharging":
+ * these currently just print messages that the line has been signalled
+ * + named GPIO input "adc-temp-on": set to cause the battery-temperature
+ * value to be passed to the max111x ADC
+ * + named GPIO output "adc-temp": the ADC value, to be wired up to the
max111x
+ */
+#define TYPE_SPITZ_MISC_GPIO "spitz-misc-gpio"
+#define SPITZ_MISC_GPIO(obj) \
+ OBJECT_CHECK(SpitzMiscGPIOState, (obj), TYPE_SPITZ_MISC_GPIO)
+
+typedef struct SpitzMiscGPIOState {
+ SysBusDevice parent_obj;
+
+ qemu_irq adc_value;
+} SpitzMiscGPIOState;
+
+static void spitz_misc_charging(void *opaque, int n, int level)
{
- switch (line) {
- case 0:
- zaurus_printf("Charging %s.\n", level ? "off" : "on");
- break;
- case 1:
- zaurus_printf("Discharging %s.\n", level ? "on" : "off");
- break;
- case 2:
- zaurus_printf("Green LED %s.\n", level ? "on" : "off");
- break;
- case 3:
- zaurus_printf("Orange LED %s.\n", level ? "on" : "off");
- break;
- case 6:
- spitz_adc_temp_on(opaque, line, level);
- break;
- default:
- g_assert_not_reached();
- }
+ zaurus_printf("Charging %s.\n", level ? "off" : "on");
+}
+
+static void spitz_misc_discharging(void *opaque, int n, int level)
+{
+ zaurus_printf("Discharging %s.\n", level ? "off" : "on");
+}
+
+static void spitz_misc_green_led(void *opaque, int n, int level)
+{
+ zaurus_printf("Green LED %s.\n", level ? "off" : "on");
+}
+
+static void spitz_misc_orange_led(void *opaque, int n, int level)
+{
+ zaurus_printf("Orange LED %s.\n", level ? "off" : "on");
+}
+
+static void spitz_misc_adc_temp(void *opaque, int n, int level)
+{
+ SpitzMiscGPIOState *s = SPITZ_MISC_GPIO(opaque);
+ int batt_temp = level ? SPITZ_BATTERY_TEMP : 0;
+
+ qemu_set_irq(s->adc_value, batt_temp);
+}
+
+static void spitz_misc_gpio_init(Object *obj)
+{
+ SpitzMiscGPIOState *s = SPITZ_MISC_GPIO(obj);
+ DeviceState *dev = DEVICE(obj);
+
+ qdev_init_gpio_in_named(dev, spitz_misc_charging, "charging", 1);
+ qdev_init_gpio_in_named(dev, spitz_misc_discharging, "discharging", 1);
+ qdev_init_gpio_in_named(dev, spitz_misc_green_led, "green-led", 1);
+ qdev_init_gpio_in_named(dev, spitz_misc_orange_led, "orange-led", 1);
+ qdev_init_gpio_in_named(dev, spitz_misc_adc_temp, "adc-temp-on", 1);
+
+ qdev_init_gpio_out_named(dev, &s->adc_value, "adc-temp", 1);
}
#define SPITZ_SCP_LED_GREEN 1
@@ -850,12 +875,22 @@ static void spitz_out_switch(void *opaque, int line, int
level)
static void spitz_scoop_gpio_setup(SpitzMachineState *sms)
{
- qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, sms->mpu, 8);
+ DeviceState *miscdev = sysbus_create_simple(TYPE_SPITZ_MISC_GPIO, -1,
NULL);
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_CHRG_ON, outsignals[0]);
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_JK_B, outsignals[1]);
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_LED_GREEN, outsignals[2]);
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_LED_ORANGE, outsignals[3]);
+ sms->misc_gpio = miscdev;
+
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_CHRG_ON,
+ qdev_get_gpio_in_named(miscdev, "charging", 0));
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_JK_B,
+ qdev_get_gpio_in_named(miscdev, "discharging", 0));
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_LED_GREEN,
+ qdev_get_gpio_in_named(miscdev, "green-led", 0));
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_LED_ORANGE,
+ qdev_get_gpio_in_named(miscdev, "orange-led", 0));
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_ADC_TEMP_ON,
+ qdev_get_gpio_in_named(miscdev, "adc-temp-on", 0));
+ qdev_connect_gpio_out_named(miscdev, "adc-temp", 0,
+ qdev_get_gpio_in(sms->max1111,
MAX1111_BATT_TEMP));
if (sms->scp1) {
qdev_connect_gpio_out(sms->scp1, SPITZ_SCP2_BACKLIGHT_CONT,
@@ -863,8 +898,6 @@ static void spitz_scoop_gpio_setup(SpitzMachineState *sms)
qdev_connect_gpio_out(sms->scp1, SPITZ_SCP2_BACKLIGHT_ON,
qdev_get_gpio_in_named(sms->lcdtg, "bl_power",
0));
}
-
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_ADC_TEMP_ON, outsignals[6]);
}
#define SPITZ_GPIO_HSYNC 22
@@ -1217,12 +1250,24 @@ static const TypeInfo spitz_lcdtg_info = {
.class_init = spitz_lcdtg_class_init,
};
+static const TypeInfo spitz_misc_gpio_info = {
+ .name = TYPE_SPITZ_MISC_GPIO,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(SpitzMiscGPIOState),
+ .instance_init = spitz_misc_gpio_init,
+ /*
+ * No class_init required: device has no internal state so does not
+ * need to set up reset or vmstate, and does not have a realize method.
+ */
+};
+
static void spitz_register_types(void)
{
type_register_static(&corgi_ssp_info);
type_register_static(&spitz_lcdtg_info);
type_register_static(&spitz_keyboard_info);
type_register_static(&sl_nand_info);
+ type_register_static(&spitz_misc_gpio_info);
}
type_init(spitz_register_types)
--
2.20.1
- [PULL 19/34] hw/arm/spitz: Keep pointers to MPU and SSI devices in SpitzMachineState, (continued)
- [PULL 19/34] hw/arm/spitz: Keep pointers to MPU and SSI devices in SpitzMachineState, Peter Maydell, 2020/07/03
- [PULL 18/34] hw/arm/spitz: Create SpitzMachineClass abstract base class, Peter Maydell, 2020/07/03
- [PULL 20/34] hw/arm/spitz: Keep pointers to scp0, scp1 in SpitzMachineState, Peter Maydell, 2020/07/03
- [PULL 21/34] hw/arm/spitz: Implement inbound GPIO lines for bit5 and power signals, Peter Maydell, 2020/07/03
- [PULL 22/34] hw/misc/max111x: provide QOM properties for setting initial values, Peter Maydell, 2020/07/03
- [PULL 23/34] hw/misc/max111x: Don't use vmstate_register(), Peter Maydell, 2020/07/03
- [PULL 24/34] ssi: Add ssi_realize_and_unref(), Peter Maydell, 2020/07/03
- [PULL 26/34] hw/misc/max111x: Use GPIO lines rather than max111x_set_input(), Peter Maydell, 2020/07/03
- [PULL 25/34] hw/arm/spitz: Use max111x properties to set initial values, Peter Maydell, 2020/07/03
- [PULL 27/34] hw/misc/max111x: Create header file for documentation, TYPE_ macros, Peter Maydell, 2020/07/03
- [PULL 28/34] hw/arm/spitz: Encapsulate misc GPIO handling in a device,
Peter Maydell <=
- [PULL 29/34] hw/gpio/zaurus.c: Use LOG_GUEST_ERROR for bad guest register accesses, Peter Maydell, 2020/07/03
- [PULL 30/34] hw/arm/spitz: Use LOG_GUEST_ERROR for bad guest register accesses, Peter Maydell, 2020/07/03
- [PULL 32/34] hw/arm/spitz: Provide usual QOM macros for corgi-ssp and spitz-lcdtg, Peter Maydell, 2020/07/03
- [PULL 33/34] Replace uses of FROM_SSI_SLAVE() macro with QOM casts, Peter Maydell, 2020/07/03
- [PULL 34/34] Deprecate TileGX port, Peter Maydell, 2020/07/03
- [PULL 31/34] hw/arm/pxa2xx_pic: Use LOG_GUEST_ERROR for bad guest register accesses, Peter Maydell, 2020/07/03
- Re: [PULL 00/34] target-arm queue, no-reply, 2020/07/03
- Re: [PULL 00/34] target-arm queue, Peter Maydell, 2020/07/04