diff options
author | Patrick Venture <venture@google.com> | 2021-04-12 12:45:21 -0700 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2021-04-15 07:10:30 -0500 |
commit | 3f9b32595e785c79720ed174198472c3d4d32c03 (patch) | |
tree | e37aadf2f77131ec20a77655d62a7de73af594d9 | |
parent | 513ca82d8982463aca98aa01dcf584e0b4fc0982 (diff) |
hw/i2c: move search to i2c_scan_bus method
Moves the search for matching devices on an i2c bus into a separate
method. This allows for an object that owns an I2CBus can avoid
duplicating this method.
Tested: A BMC firmware was booted to userspace and i2c devices were
detected.
Signed-off-by: Patrick Venture <venture@google.com>
Reviewed-by: Hao Wu <wuhaotsh@google.com>
Message-Id: <20210412194522.664594-4-venture@google.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
-rw-r--r-- | hw/i2c/core.c | 38 | ||||
-rw-r--r-- | include/hw/i2c/i2c.h | 2 |
2 files changed, 28 insertions, 12 deletions
diff --git a/hw/i2c/core.c b/hw/i2c/core.c index d03b0eea5c..3a7bae311d 100644 --- a/hw/i2c/core.c +++ b/hw/i2c/core.c @@ -77,6 +77,30 @@ int i2c_bus_busy(I2CBus *bus) return !QLIST_EMPTY(&bus->current_devs); } +bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast, + I2CNodeList *current_devs) +{ + BusChild *kid; + + QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { + DeviceState *qdev = kid->child; + I2CSlave *candidate = I2C_SLAVE(qdev); + I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(candidate); + + if (sc->match_and_add(candidate, address, broadcast, current_devs)) { + if (!broadcast) { + return true; + } + } + } + + /* + * If broadcast was true, and the list was full or empty, return true. If + * broadcast was false, return false. + */ + return broadcast; +} + /* TODO: Make this handle multiple masters. */ /* * Start or continue an i2c transaction. When this is called for the @@ -93,7 +117,6 @@ int i2c_bus_busy(I2CBus *bus) */ int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv) { - BusChild *kid; I2CSlaveClass *sc; I2CNode *node; bool bus_scanned = false; @@ -115,17 +138,8 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv) * terminating the previous transaction. */ if (QLIST_EMPTY(&bus->current_devs)) { - QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { - DeviceState *qdev = kid->child; - I2CSlave *candidate = I2C_SLAVE(qdev); - sc = I2C_SLAVE_GET_CLASS(candidate); - if (sc->match_and_add(candidate, address, bus->broadcast, - &bus->current_devs)) { - if (!bus->broadcast) { - break; - } - } - } + /* Disregard whether devices were found. */ + (void)i2c_scan_bus(bus, address, bus->broadcast, &bus->current_devs); bus_scanned = true; } diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index 9b8b95ff4a..ff4129ea70 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -87,6 +87,8 @@ void i2c_nack(I2CBus *bus); int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send); 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, + I2CNodeList *current_devs); /** * Create an I2C slave device on the heap. |