diff options
author | Klaus Jensen <k.jensen@samsung.com> | 2022-06-30 09:21:14 +0200 |
---|---|---|
committer | Cédric Le Goater <clg@kaod.org> | 2022-06-30 09:21:14 +0200 |
commit | 37fa5ca42623ef08ac99c8d927b6a3af0c76dc7b (patch) | |
tree | 153279675f9be4b055c20cb54d0b3416b893fa5f /include/hw/i2c/i2c.h | |
parent | 0c0f1bee6a24cf36a019aefa26d849480a31c746 (diff) | |
download | qemu-37fa5ca42623ef08ac99c8d927b6a3af0c76dc7b.zip qemu-37fa5ca42623ef08ac99c8d927b6a3af0c76dc7b.tar.gz qemu-37fa5ca42623ef08ac99c8d927b6a3af0c76dc7b.tar.bz2 |
hw/i2c: support multiple masters
Allow slaves to master the bus by registering a bottom halve. If the bus
is busy, the bottom half is queued up. When a slave has succesfully
mastered the bus, the bottom half is scheduled.
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
[ clg : - fixed typos in commit log ]
Message-Id: <20220601210831.67259-4-its@irrelevant.dk>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20220630045133.32251-5-me@pjd.dev>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'include/hw/i2c/i2c.h')
-rw-r--r-- | include/hw/i2c/i2c.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index 5ca3b70..be8bb8b 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -69,13 +69,25 @@ struct I2CNode { QLIST_ENTRY(I2CNode) next; }; +typedef struct I2CPendingMaster I2CPendingMaster; + +struct I2CPendingMaster { + QEMUBH *bh; + QSIMPLEQ_ENTRY(I2CPendingMaster) entry; +}; + typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList; +typedef QSIMPLEQ_HEAD(I2CPendingMasters, I2CPendingMaster) I2CPendingMasters; struct I2CBus { BusState qbus; I2CNodeList current_devs; + I2CPendingMasters pending_masters; uint8_t saved_address; bool broadcast; + + /* Set from slave currently mastering the bus. */ + QEMUBH *bh; }; I2CBus *i2c_init_bus(DeviceState *parent, const char *name); @@ -117,6 +129,8 @@ int i2c_start_send(I2CBus *bus, uint8_t address); void i2c_end_transfer(I2CBus *bus); void i2c_nack(I2CBus *bus); +void i2c_bus_master(I2CBus *bus, QEMUBH *bh); +void i2c_bus_release(I2CBus *bus); int i2c_send(I2CBus *bus, uint8_t data); uint8_t i2c_recv(I2CBus *bus); bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast, |