From: Shubham Patil <shubhamsanjay.patil@amd.com>
To: <alexandre.belloni@bootlin.com>, <Frank.Li@kernel.org>,
<robh@kernel.org>, <krzk+dt@kernel.org>, <conor+dt@kernel.org>
Cc: <linux-i3c@lists.infradead.org>, <devicetree@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <git@amd.com>,
Shubham Patil <shubhamsanjay.patil@amd.com>
Subject: [PATCH v2 3/3] i3c: master: amd: Add hot-join support
Date: Mon, 24 Aug 2026 10:18:35 +0530 [thread overview]
Message-ID: <20260824044835.2924141-4-shubhamsanjay.patil@amd.com> (raw)
In-Reply-To: <20260824044835.2924141-1-shubhamsanjay.patil@amd.com>
Add hot-join support for the AMD AXI I3C master controller.
By default, the hot-join acknowledgment is disabled. Users can use the
sysfs entry to enable it. A hot-join event is handed to the i3c core
with i3c_master_queue_hotjoin(), which runs DAA from the core workqueue
so the new device is enumerated.
Signed-off-by: Shubham Patil <shubhamsanjay.patil@amd.com>
---
Changes in V2:
- Use the core's i3c_master_queue_hotjoin() instead of a private work
item, and only queue when hj_capable is set; the core owns the work
and cancels it on unregister.
- Update the commit description accordingly.
---
drivers/i3c/master/amd-i3c-master.c | 67 +++++++++++++++++++++++++----
1 file changed, 58 insertions(+), 9 deletions(-)
diff --git a/drivers/i3c/master/amd-i3c-master.c b/drivers/i3c/master/amd-i3c-master.c
index 92a9f43f8934..26ef2ba9f651 100644
--- a/drivers/i3c/master/amd-i3c-master.c
+++ b/drivers/i3c/master/amd-i3c-master.c
@@ -55,9 +55,11 @@
#define XI3C_CR_EN_MASK BIT(0) /* Core Enable */
#define XI3C_CR_RESUME_MASK BIT(2) /* Core Resume */
#define XI3C_CR_IBI_MASK BIT(3) /* IBI ACK enable */
+#define XI3C_CR_HJ_MASK BIT(4) /* Hot-Join ACK enable */
#define XI3C_SR_RESP_NOT_EMPTY_MASK BIT(4) /* Resp Fifo not empty status mask */
#define XI3C_RD_FIFO_NOT_EMPTY_MASK BIT(15) /* Read Fifo not empty status mask */
#define XI3C_INTR_IBI_MASK BIT(7) /* IBI event (INTR status/enable) */
+#define XI3C_INTR_HJ_MASK BIT(8) /* Hot-Join event */
#define XI3C_BCR_MASK GENMASK(23, 16)
#define XI3C_DCR_MASK GENMASK(31, 24)
@@ -191,11 +193,14 @@ struct xi3c_xfer {
* @xfer_resp_valid is set. Guarded by @lock.
* @xfer_resp_valid: True once the in-flight transfer's own response word has
* been taken from the shared response FIFO. Guarded by @lock.
- * @irq: Controller interrupt line, used for IBI events. Only valid when
- * @ibi_capable is set.
+ * @irq: Controller interrupt line, used for IBI/Hot-Join events. Only valid
+ * when @ibi_capable is set.
* @ibi_capable: True when the IP was synthesized with In-Band Interrupt
- * support ("xlnx,in-band-interrupt-capable"); also the
- * condition for the controller interrupt being present.
+ * support ("xlnx,in-band-interrupt-capable"). Since Hot-Join
+ * requests are ACKed by the IBI machinery, this is also the
+ * condition for the controller interrupt being present at all.
+ * @hj_capable: True when the IP was synthesized with Hot-Join support
+ * ("xlnx,hot-join-capable"); implies @ibi_capable.
* @ops: Controller ops handed to the framework, assembled at probe time from
* the base ops plus the callbacks the design actually supports.
* @ibi: In-Band Interrupt slot tracking.
@@ -224,6 +229,7 @@ struct xi3c_master {
bool xfer_resp_valid;
int irq;
bool ibi_capable;
+ bool hj_capable;
struct i3c_master_controller_ops ops;
struct {
spinlock_t lock; /* protects slots[] against the IBI handler */
@@ -1243,13 +1249,14 @@ static void xi3c_master_bus_cleanup(struct i3c_master_controller *m)
struct xi3c_master *master = to_xi3c_master(m);
/*
- * Disarm all interrupt sources and the IBI ACK so the controller can't
- * assert once disabled; reset the refcount that tracks them.
+ * Disarm the interrupts and the IBI/Hot-Join ACKs so nothing is left
+ * armed for a later bus_init(); reset the refcount that tracks them.
*/
scoped_guard(spinlock_irqsave, &master->reg_lock) {
iowrite32(0, master->membase + XI3C_INTR_RE_OFFSET);
iowrite32(ioread32(master->membase + XI3C_CR_OFFSET) &
- ~XI3C_CR_IBI_MASK, master->membase + XI3C_CR_OFFSET);
+ ~(XI3C_CR_IBI_MASK | XI3C_CR_HJ_MASK),
+ master->membase + XI3C_CR_OFFSET);
master->ibi.enabled_count = 0;
}
@@ -1550,6 +1557,32 @@ static void xi3c_master_process_ibi(struct xi3c_master *master, u32 resp, u8 da)
xi3c_master_drain_ibi_fifo(master, len);
}
+static int xi3c_master_enable_hotjoin(struct i3c_master_controller *m)
+{
+ struct xi3c_master *master = to_xi3c_master(m);
+
+ guard(spinlock_irqsave)(&master->reg_lock);
+ iowrite32(ioread32(master->membase + XI3C_CR_OFFSET) | XI3C_CR_HJ_MASK,
+ master->membase + XI3C_CR_OFFSET);
+ iowrite32(ioread32(master->membase + XI3C_INTR_RE_OFFSET) |
+ XI3C_INTR_HJ_MASK, master->membase + XI3C_INTR_RE_OFFSET);
+
+ return 0;
+}
+
+static int xi3c_master_disable_hotjoin(struct i3c_master_controller *m)
+{
+ struct xi3c_master *master = to_xi3c_master(m);
+
+ guard(spinlock_irqsave)(&master->reg_lock);
+ iowrite32(ioread32(master->membase + XI3C_INTR_RE_OFFSET) &
+ ~XI3C_INTR_HJ_MASK, master->membase + XI3C_INTR_RE_OFFSET);
+ iowrite32(ioread32(master->membase + XI3C_CR_OFFSET) & ~XI3C_CR_HJ_MASK,
+ master->membase + XI3C_CR_OFFSET);
+
+ return 0;
+}
+
static irqreturn_t xi3c_master_irq_handler(int irq, void *dev_id)
{
struct xi3c_master *master = dev_id;
@@ -1570,6 +1603,9 @@ static irqreturn_t xi3c_master_irq_handler(int irq, void *dev_id)
xi3c_master_handle_ibi(master);
}
+ if (master->hj_capable && (status & XI3C_INTR_HJ_MASK))
+ i3c_master_queue_hotjoin(&master->base);
+
return IRQ_HANDLED;
}
@@ -1590,6 +1626,11 @@ static void xi3c_master_init_ibi_ops(struct xi3c_master *master)
master->ops.enable_ibi = xi3c_master_enable_ibi;
master->ops.disable_ibi = xi3c_master_disable_ibi;
master->ops.recycle_ibi_slot = xi3c_master_recycle_ibi_slot;
+
+ if (master->hj_capable) {
+ master->ops.enable_hotjoin = xi3c_master_enable_hotjoin;
+ master->ops.disable_hotjoin = xi3c_master_disable_hotjoin;
+ }
}
static int xi3c_master_probe(struct platform_device *pdev)
@@ -1625,10 +1666,18 @@ static int xi3c_master_probe(struct platform_device *pdev)
master->ibi_capable =
device_property_read_bool(master->dev,
"xlnx,in-band-interrupt-capable");
+ master->hj_capable =
+ device_property_read_bool(master->dev,
+ "xlnx,hot-join-capable");
+
+ /* Hot-Join requests are ACKed by the IBI machinery. */
+ if (master->hj_capable && !master->ibi_capable)
+ return dev_err_probe(master->dev, -EINVAL,
+ "hot-join-capable requires in-band-interrupt-capable\n");
/*
- * The interrupt only carries IBI events, so it is only described for
- * designs synthesized with that feature.
+ * The interrupt only carries IBI and Hot-Join events, so it is only
+ * described for designs synthesized with those features.
*/
if (master->ibi_capable) {
xi3c_master_init_ibi_ops(master);
--
2.34.1
prev parent reply other threads:[~2026-08-24 4:49 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-24 4:48 [PATCH v2 0/3] i3c: master: amd: Add IBI and hot-join support Shubham Patil
2026-08-24 4:48 ` [PATCH v2 1/3] dt-bindings: i3c: xlnx: Add IBI and hot-join capability properties Shubham Patil
2026-08-24 15:06 ` Frank Li
2026-08-24 16:36 ` Conor Dooley
2026-08-24 4:48 ` [PATCH v2 2/3] i3c: master: amd: Add support for in-band interrupts Shubham Patil
2026-08-24 5:04 ` sashiko-bot
2026-08-24 4:48 ` Shubham Patil [this message]
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=20260824044835.2924141-4-shubhamsanjay.patil@amd.com \
--to=shubhamsanjay.patil@amd.com \
--cc=Frank.Li@kernel.org \
--cc=alexandre.belloni@bootlin.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=git@amd.com \
--cc=krzk+dt@kernel.org \
--cc=linux-i3c@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robh@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox