aboutsummaryrefslogtreecommitdiff
path: root/hw/i2c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-03-03 17:11:22 +0000
committerPeter Maydell <peter.maydell@linaro.org>2023-03-03 17:11:22 +0000
commitcad8db986560668afbaed972e162e3e7a2d3a34c (patch)
tree862e6366a2aa282d12a702467d5e64a7a37c8898 /hw/i2c
parentbfbcaae9636260d3b2d997cd958df983298d149d (diff)
parentb22a2d409b1acfdf0d63d1bb3595194ceb3d94da (diff)
downloadqemu-cad8db986560668afbaed972e162e3e7a2d3a34c.zip
qemu-cad8db986560668afbaed972e162e3e7a2d3a34c.tar.gz
qemu-cad8db986560668afbaed972e162e3e7a2d3a34c.tar.bz2
Merge tag 'pull-aspeed-20230302' of https://github.com/legoater/qemu into staging
aspeed queue: * fix for the Aspeed I2C slave mode * a new I2C echo device from Klaus and its associated test in avocado. * initial SoC cleanups to allow the use of block devices instead of drives on the command line. * new facebook machines and eeprom fixes for the Fuji * readline fix # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmQAnrQACgkQUaNDx8/7 # 7KGIvQ//Te2eSxlZNxAXHb3HSVFRaBW+2EkJzNlalX75olFSzCLe8BnAHK5xPlYv # JjU0aPjWaPohPLdbNbAsJY2B8AwMGbUTjSv+ORRWF6s97LTVD9WcAYHgOTCz6d2X # ZrArJ5msEQAFEySOLmBqTcuyW3t4w8XeII+B09HZIS8Gn3F9kX5+4JCw9E4sX8fS # n9ayclMmrXCPbkGA4bfwJp3KI1Tc/WXNRyG0AmPEmepid7ECr5tVvQoXRMF1Sy/D # 10qbHEcmQXvZDy85M2ED1niOac4oU+EY8Wvjzkgc36uXcjqf0jIUfw56cwGSNVkW # MhPXSMiH4tEjgxmtzld3LeA6TGfrFcCvRXYiCuYWHjBS3gptlqY6Q0580vxoQVXL # lTYui57LB1YStNLcLG9toP0d4/fRfeqEx7ddCQKlopnW/K392eoJo0aYoVGVJhIC # 3QhN525EFUwMm4FDpdSW29Gfbk/ytpf0u4hQ6JPeBl8psirRKqCGuwr5NOnPYTaN # yErlsq2eL83t9kLo+2YIqgWic85wNP3kqAjIaE6lminqX7sWFH3V1g9HqUQZVG1g # msatZMiCCvwSFuz3DPkSfnuhqwaHuhvCATZloCtguCmnbUK9qUVVzvodKw62sZrd # GdS2XvRNyoOwezz0tDEvPipyZ7RpcaatryHNuzGwRsE5Lvr73dg= # =ExnJ # -----END PGP SIGNATURE----- # gpg: Signature made Thu 02 Mar 2023 13:03:48 GMT # gpg: using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1 # gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: A0F6 6548 F048 95EB FE6B 0B60 51A3 43C7 CFFB ECA1 * tag 'pull-aspeed-20230302' of https://github.com/legoater/qemu: aspeed/smc: Replace SysBus IRQs with GPIO lines aspeed: Add a boot_rom overlap region in the SoC spi_boot container aspeed: Introduce a spi_boot region under the SoC aspeed/fuji : correct the eeprom size hw/at24c : modify at24c to support 1 byte address mode hw/arm/aspeed: Adding new machine Tiogapass in QEMU hw/arm/aspeed: Adding new machine Yosemitev2 in QEMU tests/avocado/machine_aspeed.py: Add an I2C slave test hw/misc: add a toy i2c echo device hw/i2c: only schedule pending master when bus is idle readline: fix hmp completion issue Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i2c')
-rw-r--r--hw/i2c/aspeed_i2c.c2
-rw-r--r--hw/i2c/core.c37
2 files changed, 24 insertions, 15 deletions
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index c166fd2..1f071a3 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -550,6 +550,8 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
}
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_STOP_CMD, 0);
aspeed_i2c_set_state(bus, I2CD_IDLE);
+
+ i2c_schedule_pending_master(bus->bus);
}
if (aspeed_i2c_bus_pkt_mode_en(bus)) {
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index d4ba814..bed594f 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -185,22 +185,39 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, bool is_recv)
void i2c_bus_master(I2CBus *bus, QEMUBH *bh)
{
- if (i2c_bus_busy(bus)) {
- I2CPendingMaster *node = g_new(struct I2CPendingMaster, 1);
- node->bh = bh;
+ I2CPendingMaster *node = g_new(struct I2CPendingMaster, 1);
+ node->bh = bh;
+
+ QSIMPLEQ_INSERT_TAIL(&bus->pending_masters, node, entry);
+}
+
+void i2c_schedule_pending_master(I2CBus *bus)
+{
+ I2CPendingMaster *node;
- QSIMPLEQ_INSERT_TAIL(&bus->pending_masters, node, entry);
+ if (i2c_bus_busy(bus)) {
+ /* someone is already controlling the bus; wait for it to release it */
+ return;
+ }
+ if (QSIMPLEQ_EMPTY(&bus->pending_masters)) {
return;
}
- bus->bh = bh;
+ node = QSIMPLEQ_FIRST(&bus->pending_masters);
+ bus->bh = node->bh;
+
+ QSIMPLEQ_REMOVE_HEAD(&bus->pending_masters, entry);
+ g_free(node);
+
qemu_bh_schedule(bus->bh);
}
void i2c_bus_release(I2CBus *bus)
{
bus->bh = NULL;
+
+ i2c_schedule_pending_master(bus);
}
int i2c_start_recv(I2CBus *bus, uint8_t address)
@@ -234,16 +251,6 @@ void i2c_end_transfer(I2CBus *bus)
g_free(node);
}
bus->broadcast = false;
-
- if (!QSIMPLEQ_EMPTY(&bus->pending_masters)) {
- I2CPendingMaster *node = QSIMPLEQ_FIRST(&bus->pending_masters);
- bus->bh = node->bh;
-
- QSIMPLEQ_REMOVE_HEAD(&bus->pending_masters, entry);
- g_free(node);
-
- qemu_bh_schedule(bus->bh);
- }
}
int i2c_send(I2CBus *bus, uint8_t data)