Reviewed-by: Glenn Miles <[email protected]> Thanks,
Glenn On Mon, 2026-10-12 at 16:32 +0200, Emmanuel Blot via qemu development wrote: > Verify what releases a latched alert and what can bring it back: a > Mask/Enable read and a Configuration write both clear it, and only a > conversion that re-samples the fault on a channel it converted asserts > it again. > > Signed-off-by: Emmanuel Blot <[email protected]> > --- > tests/qtest/ina230-test.c | 89 > +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 89 insertions(+) > > diff --git a/tests/qtest/ina230-test.c b/tests/qtest/ina230-test.c > index f8b982686a..591927e551 100644 > --- a/tests/qtest/ina230-test.c > +++ b/tests/qtest/ina230-test.c > @@ -364,6 +364,88 @@ static void test_alert_latch(void *obj, void *data, > QGuestAllocator *alloc) > } > > /* Bus over-limit alert */ > +static void test_alert_latch_persist(void *obj, void *data, > + QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_ALERT_LIMIT, 0x1000); > + i2c_set16(dev, REG_MASK_ENABLE, ME_SOL | ME_LEN); > + > + qmp_ina230_set("shunt-voltage", 20000000); > + > + /* First read shows the latched AFF and clears the latch */ > + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE) & ME_AFF, ==, ME_AFF); > + > + /* Fault still present but no new conversion: AFF stays cleared */ > + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE) & ME_AFF, ==, 0); > + > + qmp_ina230_set("shunt-voltage", 20000000); > + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE) & ME_AFF, ==, ME_AFF); > +} > + > +/* A Configuration write releases the latch as a Mask/Enable read does. */ > +static void test_alert_latch_config(void *obj, void *data, > + QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_ALERT_LIMIT, 0x1000); > + i2c_set16(dev, REG_MASK_ENABLE, ME_SOL | ME_LEN); > + > + /* Latch a fault, then bring the input back below the limit */ > + qmp_ina230_set("shunt-voltage", 20000000); > + qmp_ina230_set("shunt-voltage", 2500000); > + > + i2c_set16(dev, REG_CONFIG, CONFIG_POR); > + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE) & ME_AFF, ==, 0); > + > + /* With the fault present, the reconversion latches it again */ > + qmp_ina230_set("shunt-voltage", 20000000); > + i2c_set16(dev, REG_CONFIG, CONFIG_POR); > + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE) & ME_AFF, ==, ME_AFF); > +} > + > +/* The releasing write need not reconvert: a power-down leaves it clear. */ > +static void test_alert_latch_shutdown(void *obj, void *data, > + QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_ALERT_LIMIT, 0x1000); > + i2c_set16(dev, REG_MASK_ENABLE, ME_SOL | ME_LEN); > + > + qmp_ina230_set("shunt-voltage", 20000000); > + > + i2c_set16(dev, REG_CONFIG, 0x0000); /* power-down */ > + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE) & ME_AFF, ==, 0); > +} > + > +/* > + * A conversion only re-samples the alert of a channel it converted: the bus > + * register a shunt-only conversion left stale must not re-latch. > + */ > +static void test_alert_channel(void *obj, void *data, QGuestAllocator *alloc) > +{ > + QI2CDevice *dev = (QI2CDevice *)obj; > + > + i2c_set16(dev, REG_CONFIG, CONFIG_RST); > + i2c_set16(dev, REG_ALERT_LIMIT, 0x2000); > + i2c_set16(dev, REG_MASK_ENABLE, ME_BOL | ME_LEN); > + > + qmp_ina230_set("bus-voltage", 12000000); > + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE) & ME_AFF, ==, ME_AFF); > + > + /* Shunt-only mode: the bus register keeps its over-limit value */ > + i2c_set16(dev, REG_CONFIG, 0x0005); > + qmp_ina230_set("shunt-voltage", 20000000); > + g_assert_cmphex(i2c_get16(dev, REG_BUS), ==, 0x2580); > + g_assert_cmphex(i2c_get16(dev, REG_MASK_ENABLE) & ME_AFF, ==, 0); > +} > + > static void test_alert_bus(void *obj, void *data, QGuestAllocator *alloc) > { > QI2CDevice *dev = (QI2CDevice *)obj; > @@ -481,6 +563,13 @@ static void ina230_register_nodes(void) > qos_add_test("edges-overflow", "ina230", test_edges_overflow, NULL); > qos_add_test("alert-shunt-over", "ina230", test_alert_shunt_over, NULL); > qos_add_test("alert-latch", "ina230", test_alert_latch, NULL); > + qos_add_test("alert-latch-persist", "ina230", test_alert_latch_persist, > + NULL); > + qos_add_test("alert-latch-config", "ina230", test_alert_latch_config, > + NULL); > + qos_add_test("alert-latch-shutdown", "ina230", test_alert_latch_shutdown, > + NULL); > + qos_add_test("alert-channel", "ina230", test_alert_channel, NULL); > qos_add_test("alert-bus", "ina230", test_alert_bus, NULL); > qos_add_test("alert-power", "ina230", test_alert_power, NULL); > qos_add_test("cvrf", "ina230", test_cvrf, NULL); >
