All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Cédric Le Goater" <clg@kaod.org>
To: qemu-arm@nongnu.org, qemu-devel@nongnu.org
Cc: "Peter Maydell" <peter.maydell@linaro.org>,
	"Joe Komlodi" <komlodi@google.com>,
	"Troy Lee" <troy_lee@aspeedtech.com>,
	"Jamin Lin" <jamin_lin@aspeedtech.com>,
	"Steven Lee" <steven_lee@aspeedtech.com>,
	"Klaus Jensen" <k.jensen@samsung.com>,
	"Peter Delevoryas" <pdel@fb.com>,
	"Corey Minyard" <cminyard@mvista.com>,
	"Jonathan Cameron" <Jonathan.Cameron@huawei.com>,
	"Damien Hedde" <damien.hedde@greensocs.com>,
	"Andrew Jeffery" <andrew@aj.id.au>,
	"Joel Stanley" <joel@jms.id.au>, "Cleber Rosa" <crosa@redhat.com>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	"Wainer dos Santos Moschetta" <wainersm@redhat.com>,
	"Beraldo Leal" <bleal@redhat.com>,
	"Cédric Le Goater" <clg@kaod.org>
Subject: [PATCH 16/21] hw/i2c: support multiple masters
Date: Mon,  6 Jun 2022 17:07:27 +0200	[thread overview]
Message-ID: <20220606150732.2282041-17-clg@kaod.org> (raw)
In-Reply-To: <20220606150732.2282041-1-clg@kaod.org>

From: Klaus Jensen <k.jensen@samsung.com>

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>
---
 include/hw/i2c/i2c.h | 14 ++++++++++++++
 hw/i2c/core.c        | 34 +++++++++++++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 5ca3b708c0be..be8bb8b78a60 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,
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index d0cb2d32fa44..145dce60782a 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -13,6 +13,7 @@
 #include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
+#include "qemu/main-loop.h"
 #include "trace.h"
 
 #define I2C_BROADCAST 0x00
@@ -62,6 +63,7 @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
 
     bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
     QLIST_INIT(&bus->current_devs);
+    QSIMPLEQ_INIT(&bus->pending_masters);
     vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus);
     return bus;
 }
@@ -74,7 +76,7 @@ void i2c_slave_set_address(I2CSlave *dev, uint8_t address)
 /* Return nonzero if bus is busy.  */
 int i2c_bus_busy(I2CBus *bus)
 {
-    return !QLIST_EMPTY(&bus->current_devs);
+    return !QLIST_EMPTY(&bus->current_devs) || bus->bh;
 }
 
 bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
@@ -180,6 +182,26 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, bool is_recv)
                                                : I2C_START_SEND);
 }
 
+void i2c_bus_master(I2CBus *bus, QEMUBH *bh)
+{
+    if (i2c_bus_busy(bus)) {
+        I2CPendingMaster *node = g_new(struct I2CPendingMaster, 1);
+        node->bh = bh;
+
+        QSIMPLEQ_INSERT_TAIL(&bus->pending_masters, node, entry);
+
+        return;
+    }
+
+    bus->bh = bh;
+    qemu_bh_schedule(bus->bh);
+}
+
+void i2c_bus_release(I2CBus *bus)
+{
+    bus->bh = NULL;
+}
+
 int i2c_start_recv(I2CBus *bus, uint8_t address)
 {
     return i2c_do_start_transfer(bus, address, I2C_START_RECV);
@@ -206,6 +228,16 @@ 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)
-- 
2.35.3



  parent reply	other threads:[~2022-06-06 15:27 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-06 15:07 [PATCH 00/21] aspeed: Extend ast2600 I2C model with new mode Cédric Le Goater
2022-06-06 15:07 ` [PATCH 01/21] hw/registerfields: Add shared fields macros Cédric Le Goater
2022-06-06 15:07 ` [PATCH 02/21] aspeed: i2c: Add ctrl_global_rsvd property Cédric Le Goater
2022-06-07  0:05   ` Joel Stanley
2022-06-07 17:32     ` Cédric Le Goater
2022-06-06 15:07 ` [PATCH 03/21] aspeed: i2c: Migrate to registerfields API Cédric Le Goater
2022-06-06 23:29   ` Joel Stanley
2022-06-06 15:07 ` [PATCH 04/21] aspeed: i2c: Use reg array instead of individual vars Cédric Le Goater
2022-06-06 23:49   ` Joel Stanley
2022-06-07  9:57     ` Cédric Le Goater
2022-06-07 10:50     ` Cédric Le Goater
2022-06-06 15:07 ` [PATCH 05/21] aspeed: i2c: Add new mode support Cédric Le Goater
2022-06-06 15:07 ` [PATCH 06/21] aspeed: i2c: Add PKT_DONE IRQ to trace Cédric Le Goater
2022-06-06 15:07 ` [PATCH 07/21] aspeed: i2c: Move regs and helpers to header file Cédric Le Goater
2022-06-06 15:07 ` [PATCH 08/21] test/avocado/machine_aspeed.py: Move OpenBMC tests Cédric Le Goater
2022-06-06 15:07 ` [PATCH 09/21] test/avocado/machine_aspeed.py: Add tests using buildroot images Cédric Le Goater
2022-06-06 15:07 ` [PATCH 10/21] test/avocado/machine_aspeed.py: Add I2C tests to ast2600-evb Cédric Le Goater
2022-06-06 15:07 ` [PATCH 11/21] test/avocado/machine_aspeed.py: Add an I2C RTC test Cédric Le Goater
2022-06-06 23:16   ` Joel Stanley
2022-06-07 10:17     ` Cédric Le Goater
2022-06-06 15:07 ` [PATCH 12/21] aspeed/i2c: Add ast1030 controller models Cédric Le Goater
2022-06-06 23:22   ` Joel Stanley
2022-06-06 15:07 ` [PATCH 13/21] aspeed: Add I2C buses to AST1030 model Cédric Le Goater
2022-06-06 23:18   ` Joel Stanley
2022-06-07 10:43     ` Cédric Le Goater
2022-06-06 15:07 ` [PATCH 14/21] hw/i2c/aspeed: rework raise interrupt trace event Cédric Le Goater
2022-06-06 15:07 ` [PATCH 15/21] hw/i2c/aspeed: add DEV_ADDR in old register mode Cédric Le Goater
2022-06-06 15:07 ` Cédric Le Goater [this message]
2022-06-06 15:07 ` [PATCH 17/21] hw/i2c: add asynchronous send Cédric Le Goater
2022-06-06 15:07 ` [PATCH 18/21] hw/i2c/aspeed: add slave device in old register mode Cédric Le Goater
2022-06-06 15:07 ` [PATCH 19/21] aspeed/i2c: Enable SLAVE_ADDR_RX_MATCH always Cédric Le Goater
2022-06-06 15:07 ` [PATCH 20/21] hw/misc: add a toy i2c echo device [DO NOT PULL] Cédric Le Goater
2022-06-06 15:07 ` [PATCH 21/21] test/avocado/machine_aspeed.py: Add I2C slave tests Cédric Le Goater
2022-06-19 14:50 ` [PATCH 00/21] aspeed: Extend ast2600 I2C model with new mode Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220606150732.2282041-17-clg@kaod.org \
    --to=clg@kaod.org \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=andrew@aj.id.au \
    --cc=bleal@redhat.com \
    --cc=cminyard@mvista.com \
    --cc=crosa@redhat.com \
    --cc=damien.hedde@greensocs.com \
    --cc=f4bug@amsat.org \
    --cc=jamin_lin@aspeedtech.com \
    --cc=joel@jms.id.au \
    --cc=k.jensen@samsung.com \
    --cc=komlodi@google.com \
    --cc=pdel@fb.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=steven_lee@aspeedtech.com \
    --cc=troy_lee@aspeedtech.com \
    --cc=wainersm@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.