public inbox for linux-i3c@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH v5 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix
@ 2025-12-02  8:26 adrianhoyin.ng
  2025-12-02  8:26 ` [PATCH v5 1/5] i3c: add sysfs entry for Device NACK Retry count adrianhoyin.ng
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: adrianhoyin.ng @ 2025-12-02  8:26 UTC (permalink / raw)
  To: alexandre.belloni, Frank.Li, linux-i3c, linux-kernel; +Cc: adrianhoyin.ng

From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>

This patch series adds a controller-wide sysfs attribute
dev_nack_retry_count for the DesignWare I3C controller, allowing runtime
control of the automatic retry mechanism when a device NACKs. Some I3C
slave devices may temporarily be busy and unable to respond immediately;
automatic retries improve robustness in such cases. Writes are clamped to
the hardware maximum of 3, and the value is applied to all active DAT
entries.

The series also fixes dw_i3c_master_restore_addrs() to preserve existing
DAT entry bits, preventing overwrites during runtime PM resume.
---
changelog:
v4->v5
* Revert changes that made bus_maintenance_lock and
  bus_maintenance_unlock helpers public.
* Move dev_nack_retry sysfs attribute to master.c; create it only if
  the master implements the dev_nack_retry callback.
* Add dev_nack_retry field to i3c_master_controller; updates are applied
  under bus maintenance lock.
* Add optional ops to configure dev_nack_retry in the DAT entry in
  dw-i3c-master.

v4 patch link:
https://lore.kernel.org/all/cover.1764571045.git.adrianhoyin.ng@altera.com/

v3->v4
* Make bus_maintenance_lock and bus_maintenance_unlock helpers public.
* Replace taking spinlock during DAT update with bus_maintenance_lock.
* Add macro for static and dynamic addr for device addr table.
* Replace GENMASK calls with the appropriate macros when updating addr
  table.

v3 patch link:
https://lore.kernel.org/all/cover.1763747151.git.adrianhoyin.ng@altera.com/

v2->v3
* Update commit message for better clarity
* Update function name to maintain consistency.
* Update store function to return error when retry value exceeds hw limit.
* Add lock to protect DAT to avoid concurrent during transfers.
* Clear the address field in the DAT entry before setting new values to
  ensure correct dynamic/static address configuration

v2 patch link:
https://lore.kernel.org/all/cover.1763703573.git.adrianhoyin.ng@altera.com/

v1->v2
* Drop dev_nack_retry_cnt binding and device tree changes.
* Update commit message for better clarity.
* Update to use controller wide sysfs attribute that configures
  dev_nack_retry_cnt during runtime.

v1 patch link:
https://lore.kernel.org/all/cover.1762245890.git.adrianhoyin.ng@altera.com/
---

Adrian Ng Ho Yin (5):
  i3c: add sysfs entry for Device NACK Retry count
  i3c: add sysfs attribute for device NACK retry
  i3c: dw: Add support for Device NACK Retry configuration
  i3c: dw: use FIELD_PREP for device address table macros
  i3c: dw: Preserve DAT entry bits when restoring addresses

 Documentation/ABI/testing/sysfs-bus-i3c | 12 ++++++
 drivers/i3c/master.c                    | 44 ++++++++++++++++++++
 drivers/i3c/master/dw-i3c-master.c      | 55 ++++++++++++++++++++++---
 include/linux/i3c/master.h              |  2 +
 4 files changed, 107 insertions(+), 6 deletions(-)

-- 
2.49.GIT


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v5 1/5] i3c: add sysfs entry for Device NACK Retry count
  2025-12-02  8:26 [PATCH v5 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix adrianhoyin.ng
@ 2025-12-02  8:26 ` adrianhoyin.ng
  2025-12-02  8:26 ` [PATCH v5 2/5] i3c: add sysfs attribute for device NACK retry adrianhoyin.ng
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: adrianhoyin.ng @ 2025-12-02  8:26 UTC (permalink / raw)
  To: alexandre.belloni, Frank.Li, linux-i3c, linux-kernel; +Cc: adrianhoyin.ng

From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>

Document sysfs attribute dev_nack_retry_cnt that controls the number of
automatic retries performed by the I3C controller when a target device
returns a NACK

Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 Documentation/ABI/testing/sysfs-bus-i3c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-i3c b/Documentation/ABI/testing/sysfs-bus-i3c
index c812ab180ff4..0b8a0c223f4a 100644
--- a/Documentation/ABI/testing/sysfs-bus-i3c
+++ b/Documentation/ABI/testing/sysfs-bus-i3c
@@ -161,3 +161,15 @@ Contact:	linux-i3c@vger.kernel.org
 Description:
 		These directories are just symbolic links to
 		/sys/bus/i3c/devices/i3c-<bus-id>/<bus-id>-<device-pid>.
+
+What:		/sys/bus/i3c/devices/i3c-<bus-id>/<bus-id>-<device-pid>/dev_nack_retry_count
+KernelVersion:  6.18
+Contact:	linux-i3c@vger.kernel.org
+Description:
+		Expose the dev_nak_retry_count which controls the number of
+		automatic retries that will be performed by the controller when
+		the target device returns a NACK response. A value of 0 disables
+		the automatic retries. A max value of 3 can be configured. Exist
+		only when I3C constroller supports this retry on nack feature.
+
+		Valid values: 0-3
-- 
2.49.GIT


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 2/5] i3c: add sysfs attribute for device NACK retry
  2025-12-02  8:26 [PATCH v5 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix adrianhoyin.ng
  2025-12-02  8:26 ` [PATCH v5 1/5] i3c: add sysfs entry for Device NACK Retry count adrianhoyin.ng
@ 2025-12-02  8:26 ` adrianhoyin.ng
  2025-12-02 21:12   ` Frank Li
  2025-12-02  8:26 ` [PATCH v5 3/5] i3c: dw: Add support for Device NACK Retry configuration adrianhoyin.ng
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: adrianhoyin.ng @ 2025-12-02  8:26 UTC (permalink / raw)
  To: alexandre.belloni, Frank.Li, linux-i3c, linux-kernel; +Cc: adrianhoyin.ng

From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>

Add a `dev_nack_retry` sysfs attribute to allow reading and updating the
device NACK retry count. A new `dev_nack_retry` field and an optional
`set_dev_nack_retry()` callback are added to i3c_master_controller.
The attribute is created only when the callback is implemented.

Updates are applied under the I3C bus maintenance lock to ensure safe
hardware reconfiguration.

Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
---
 drivers/i3c/master.c       | 44 ++++++++++++++++++++++++++++++++++++++
 include/linux/i3c/master.h |  2 ++
 2 files changed, 46 insertions(+)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index d946db75df70..ab630c77b3c2 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -685,6 +685,44 @@ static ssize_t hotjoin_show(struct device *dev, struct device_attribute *da, cha
 
 static DEVICE_ATTR_RW(hotjoin);
 
+static ssize_t dev_nack_retry_show(struct device *dev, struct device_attribute *attr,
+				   char *buf)
+{
+	struct i3c_bus *i3cbus = dev_to_i3cbus(dev);
+
+	return sysfs_emit(buf, "%u\n", i3cbus->cur_master->common.master->dev_nack_retry);
+}
+
+static ssize_t dev_nack_retry_store(struct device *dev, struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct i3c_bus *i3cbus = dev_to_i3cbus(dev);
+	struct i3c_master_controller *master;
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	master = i3cbus->cur_master->common.master;
+
+	if (i3cbus->cur_master->common.master->ops->set_dev_nack_retry) {
+		master->dev_nack_retry = val;
+
+		i3c_bus_maintenance_lock(i3cbus);
+		ret = master->ops->set_dev_nack_retry(master);
+		i3c_bus_maintenance_unlock(i3cbus);
+	}
+
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(dev_nack_retry);
+
 static struct attribute *i3c_masterdev_attrs[] = {
 	&dev_attr_mode.attr,
 	&dev_attr_current_master.attr,
@@ -2962,6 +3000,9 @@ int i3c_master_register(struct i3c_master_controller *master,
 	i3c_master_register_new_i3c_devs(master);
 	i3c_bus_normaluse_unlock(&master->bus);
 
+	if (master->ops->set_dev_nack_retry)
+		device_create_file(&master->dev, &dev_attr_dev_nack_retry);
+
 	return 0;
 
 err_del_dev:
@@ -2987,6 +3028,9 @@ void i3c_master_unregister(struct i3c_master_controller *master)
 {
 	i3c_bus_notify(&master->bus, I3C_NOTIFY_BUS_REMOVE);
 
+	if (master->ops->set_dev_nack_retry)
+		device_remove_file(&master->dev, &dev_attr_dev_nack_retry);
+
 	i3c_master_i2c_adapter_cleanup(master);
 	i3c_master_unregister_i3c_devs(master);
 	i3c_master_bus_cleanup(master);
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
index c52a82dd79a6..ccbc9a14bd6e 100644
--- a/include/linux/i3c/master.h
+++ b/include/linux/i3c/master.h
@@ -491,6 +491,7 @@ struct i3c_master_controller_ops {
 	int (*enable_hotjoin)(struct i3c_master_controller *master);
 	int (*disable_hotjoin)(struct i3c_master_controller *master);
 	int (*set_speed)(struct i3c_master_controller *master, enum i3c_open_drain_speed speed);
+	int (*set_dev_nack_retry)(struct i3c_master_controller *master);
 };
 
 /**
@@ -534,6 +535,7 @@ struct i3c_master_controller {
 	} boardinfo;
 	struct i3c_bus bus;
 	struct workqueue_struct *wq;
+	unsigned int dev_nack_retry;
 };
 
 /**
-- 
2.49.GIT


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 3/5] i3c: dw: Add support for Device NACK Retry configuration
  2025-12-02  8:26 [PATCH v5 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix adrianhoyin.ng
  2025-12-02  8:26 ` [PATCH v5 1/5] i3c: add sysfs entry for Device NACK Retry count adrianhoyin.ng
  2025-12-02  8:26 ` [PATCH v5 2/5] i3c: add sysfs attribute for device NACK retry adrianhoyin.ng
@ 2025-12-02  8:26 ` adrianhoyin.ng
  2025-12-02 21:15   ` Frank Li
  2025-12-02  8:26 ` [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros adrianhoyin.ng
  2025-12-02  8:26 ` [PATCH v5 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses adrianhoyin.ng
  4 siblings, 1 reply; 12+ messages in thread
From: adrianhoyin.ng @ 2025-12-02  8:26 UTC (permalink / raw)
  To: alexandre.belloni, Frank.Li, linux-i3c, linux-kernel; +Cc: adrianhoyin.ng

From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>

The DesignWare I3C controller supports automatically retrying transactions
when a device NACKs. This is useful for slave devices that may be
temporarily busy and not ready to respond immediately.

Add new ops to configure all active DAT entry with dev_nack_retry during
runtime. Returns error when value exceeds hw specified limit.

Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
---
 drivers/i3c/master/dw-i3c-master.c | 36 ++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 9ceedf09c3b6..8288888be591 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -204,8 +204,10 @@
 #define EXTENDED_CAPABILITY		0xe8
 #define SLAVE_CONFIG			0xec
 
+#define DW_I3C_DEV_NACK_RETRY_CNT_MAX	0x3
 #define DEV_ADDR_TABLE_IBI_MDB		BIT(12)
 #define DEV_ADDR_TABLE_SIR_REJECT	BIT(13)
+#define DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(x)	(((x) << 29) & GENMASK(30, 29))
 #define DEV_ADDR_TABLE_LEGACY_I2C_DEV	BIT(31)
 #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x)	(((x) << 16) & GENMASK(23, 16))
 #define DEV_ADDR_TABLE_STATIC_ADDR(x)	((x) & GENMASK(6, 0))
@@ -1484,6 +1486,39 @@ static irqreturn_t dw_i3c_master_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int dw_i3c_master_set_dev_nack_retry(struct i3c_master_controller *m)
+{
+	struct dw_i3c_master *master = to_dw_i3c_master(m);
+	u32 reg;
+	int i;
+
+	if (m->dev_nack_retry > DW_I3C_DEV_NACK_RETRY_CNT_MAX) {
+		dev_err(&master->base.dev,
+			"Value %x exceeds maximum %d\n",
+			m->dev_nack_retry, DW_I3C_DEV_NACK_RETRY_CNT_MAX);
+		return -ERANGE;
+	}
+
+	/*
+	 * Update DAT entries for all currently attached devices.
+	 * We directly iterate through the master's device array.
+	 */
+	for (i = 0; i < master->maxdevs; i++) {
+		/* Skip free/empty slots */
+		if (master->free_pos & BIT(i))
+			continue;
+
+		reg = readl(master->regs +
+				DEV_ADDR_TABLE_LOC(master->datstartaddr, i));
+		reg &= ~GENMASK(30, 29);
+		reg |= DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(m->dev_nack_retry);
+		writel(reg, master->regs +
+			DEV_ADDR_TABLE_LOC(master->datstartaddr, i));
+	}
+
+	return 0;
+}
+
 static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
 	.bus_init = dw_i3c_master_bus_init,
 	.bus_cleanup = dw_i3c_master_bus_cleanup,
@@ -1504,6 +1539,7 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
 	.recycle_ibi_slot = dw_i3c_master_recycle_ibi_slot,
 	.enable_hotjoin = dw_i3c_master_enable_hotjoin,
 	.disable_hotjoin = dw_i3c_master_disable_hotjoin,
+	.set_dev_nack_retry = dw_i3c_master_set_dev_nack_retry,
 };
 
 /* default platform ops implementations */
-- 
2.49.GIT


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros
  2025-12-02  8:26 [PATCH v5 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix adrianhoyin.ng
                   ` (2 preceding siblings ...)
  2025-12-02  8:26 ` [PATCH v5 3/5] i3c: dw: Add support for Device NACK Retry configuration adrianhoyin.ng
@ 2025-12-02  8:26 ` adrianhoyin.ng
  2025-12-02 21:16   ` Frank Li
                     ` (2 more replies)
  2025-12-02  8:26 ` [PATCH v5 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses adrianhoyin.ng
  4 siblings, 3 replies; 12+ messages in thread
From: adrianhoyin.ng @ 2025-12-02  8:26 UTC (permalink / raw)
  To: alexandre.belloni, Frank.Li, linux-i3c, linux-kernel; +Cc: adrianhoyin.ng

From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>

Add DEV_ADDR_TABLE_DYNAMIC_MASK / DEV_ADDR_TABLE_DYNAMIC_ADDR(x) for
dynamic device addresses and DEV_ADDR_TABLE_STATIC_MASK /
DEV_ADDR_TABLE_STATIC_ADDR(x) for static device addresses in the I3C
address table. Replace manual shift-and-mask with FIELD_PREP() for both
dynamic and static addresses for clarity and maintainability.

Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
---
 drivers/i3c/master/dw-i3c-master.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 8288888be591..1c1418d0a62a 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -205,12 +205,14 @@
 #define SLAVE_CONFIG			0xec
 
 #define DW_I3C_DEV_NACK_RETRY_CNT_MAX	0x3
+#define DEV_ADDR_TABLE_DYNAMIC_MASK		GENMASK(23, 16)
+#define DEV_ADDR_TABLE_STATIC_MASK		GENMASK(6, 0)
 #define DEV_ADDR_TABLE_IBI_MDB		BIT(12)
 #define DEV_ADDR_TABLE_SIR_REJECT	BIT(13)
 #define DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(x)	(((x) << 29) & GENMASK(30, 29))
 #define DEV_ADDR_TABLE_LEGACY_I2C_DEV	BIT(31)
-#define DEV_ADDR_TABLE_DYNAMIC_ADDR(x)	(((x) << 16) & GENMASK(23, 16))
-#define DEV_ADDR_TABLE_STATIC_ADDR(x)	((x) & GENMASK(6, 0))
+#define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_DYNAMIC_MASK, x)
+#define DEV_ADDR_TABLE_STATIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_STATIC_MASK, x)
 #define DEV_ADDR_TABLE_LOC(start, idx)	((start) + ((idx) << 2))
 
 #define I3C_BUS_SDR1_SCL_RATE		8000000
-- 
2.49.GIT


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses
  2025-12-02  8:26 [PATCH v5 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix adrianhoyin.ng
                   ` (3 preceding siblings ...)
  2025-12-02  8:26 ` [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros adrianhoyin.ng
@ 2025-12-02  8:26 ` adrianhoyin.ng
  2025-12-02 21:19   ` Frank Li
  4 siblings, 1 reply; 12+ messages in thread
From: adrianhoyin.ng @ 2025-12-02  8:26 UTC (permalink / raw)
  To: alexandre.belloni, Frank.Li, linux-i3c, linux-kernel; +Cc: adrianhoyin.ng

From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>

Update dw_i3c_master_restore_addrs() to preserve existing bits in each
Device Address Table (DAT) entry when restoring addresses. This prevents
overwriting configuration bits during PM runtime resumes.

Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
---
 drivers/i3c/master/dw-i3c-master.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 1c1418d0a62a..36afd8ff4e2f 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -1692,11 +1692,16 @@ static void dw_i3c_master_restore_addrs(struct dw_i3c_master *master)
 		if (master->free_pos & BIT(pos))
 			continue;
 
-		if (master->devs[pos].is_i2c_addr)
-			reg_val = DEV_ADDR_TABLE_LEGACY_I2C_DEV |
+		reg_val = readl(master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, pos));
+
+		if (master->devs[pos].is_i2c_addr) {
+			reg_val &= ~DEV_ADDR_TABLE_STATIC_MASK;
+			reg_val |= DEV_ADDR_TABLE_LEGACY_I2C_DEV |
 			       DEV_ADDR_TABLE_STATIC_ADDR(master->devs[pos].addr);
-		else
-			reg_val = DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr);
+		} else {
+			reg_val &= ~DEV_ADDR_TABLE_DYNAMIC_MASK;
+			reg_val |= DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr);
+		}
 
 		writel(reg_val, master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, pos));
 	}
-- 
2.49.GIT


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 2/5] i3c: add sysfs attribute for device NACK retry
  2025-12-02  8:26 ` [PATCH v5 2/5] i3c: add sysfs attribute for device NACK retry adrianhoyin.ng
@ 2025-12-02 21:12   ` Frank Li
  0 siblings, 0 replies; 12+ messages in thread
From: Frank Li @ 2025-12-02 21:12 UTC (permalink / raw)
  To: adrianhoyin.ng; +Cc: alexandre.belloni, linux-i3c, linux-kernel

On Tue, Dec 02, 2025 at 04:26:10PM +0800, adrianhoyin.ng@altera.com wrote:
> From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
>
> Add a `dev_nack_retry` sysfs attribute to allow reading and updating the
> device NACK retry count. A new `dev_nack_retry` field and an optional
> `set_dev_nack_retry()` callback are added to i3c_master_controller.
> The attribute is created only when the callback is implemented.
>
> Updates are applied under the I3C bus maintenance lock to ensure safe
> hardware reconfiguration.
>
> Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
> ---
>  drivers/i3c/master.c       | 44 ++++++++++++++++++++++++++++++++++++++
>  include/linux/i3c/master.h |  2 ++
>  2 files changed, 46 insertions(+)
>
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index d946db75df70..ab630c77b3c2 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -685,6 +685,44 @@ static ssize_t hotjoin_show(struct device *dev, struct device_attribute *da, cha
>
>  static DEVICE_ATTR_RW(hotjoin);
>
> +static ssize_t dev_nack_retry_show(struct device *dev, struct device_attribute *attr,
> +				   char *buf)
> +{
> +	struct i3c_bus *i3cbus = dev_to_i3cbus(dev);
> +
> +	return sysfs_emit(buf, "%u\n", i3cbus->cur_master->common.master->dev_nack_retry);
> +}
> +
> +static ssize_t dev_nack_retry_store(struct device *dev, struct device_attribute *attr,
> +				    const char *buf, size_t count)
> +{
> +	struct i3c_bus *i3cbus = dev_to_i3cbus(dev);
> +	struct i3c_master_controller *master;
> +	unsigned long val;
> +	int ret;
> +
> +	ret = kstrtoul(buf, 0, &val);
> +	if (ret)
> +		return ret;
> +
> +	master = i3cbus->cur_master->common.master;

why not use dev_to_i3cmaster() ?

> +
> +	if (i3cbus->cur_master->common.master->ops->set_dev_nack_retry) {

This file exist only if set_dev_nack_retry is not NULL. So needn't check
again here

> +		master->dev_nack_retry = val;
> +
> +		i3c_bus_maintenance_lock(i3cbus);
> +		ret = master->ops->set_dev_nack_retry(master);
> +		i3c_bus_maintenance_unlock(i3cbus);
> +	}
> +
> +	if (ret)
> +		return ret;
> +
> +	return count;
> +}
> +
> +static DEVICE_ATTR_RW(dev_nack_retry);
> +
>  static struct attribute *i3c_masterdev_attrs[] = {
>  	&dev_attr_mode.attr,
>  	&dev_attr_current_master.attr,
> @@ -2962,6 +3000,9 @@ int i3c_master_register(struct i3c_master_controller *master,
>  	i3c_master_register_new_i3c_devs(master);
>  	i3c_bus_normaluse_unlock(&master->bus);
>
> +	if (master->ops->set_dev_nack_retry)
> +		device_create_file(&master->dev, &dev_attr_dev_nack_retry);
> +
>  	return 0;
>
>  err_del_dev:
> @@ -2987,6 +3028,9 @@ void i3c_master_unregister(struct i3c_master_controller *master)
>  {
>  	i3c_bus_notify(&master->bus, I3C_NOTIFY_BUS_REMOVE);
>
> +	if (master->ops->set_dev_nack_retry)
> +		device_remove_file(&master->dev, &dev_attr_dev_nack_retry);
> +
>  	i3c_master_i2c_adapter_cleanup(master);
>  	i3c_master_unregister_i3c_devs(master);
>  	i3c_master_bus_cleanup(master);
> diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
> index c52a82dd79a6..ccbc9a14bd6e 100644
> --- a/include/linux/i3c/master.h
> +++ b/include/linux/i3c/master.h
> @@ -491,6 +491,7 @@ struct i3c_master_controller_ops {
>  	int (*enable_hotjoin)(struct i3c_master_controller *master);
>  	int (*disable_hotjoin)(struct i3c_master_controller *master);
>  	int (*set_speed)(struct i3c_master_controller *master, enum i3c_open_drain_speed speed);
> +	int (*set_dev_nack_retry)(struct i3c_master_controller *master);

Need update kernel doc.

Frank

>  };
>
>  /**
> @@ -534,6 +535,7 @@ struct i3c_master_controller {
>  	} boardinfo;
>  	struct i3c_bus bus;
>  	struct workqueue_struct *wq;
> +	unsigned int dev_nack_retry;
>  };
>
>  /**
> --
> 2.49.GIT
>

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 3/5] i3c: dw: Add support for Device NACK Retry configuration
  2025-12-02  8:26 ` [PATCH v5 3/5] i3c: dw: Add support for Device NACK Retry configuration adrianhoyin.ng
@ 2025-12-02 21:15   ` Frank Li
  0 siblings, 0 replies; 12+ messages in thread
From: Frank Li @ 2025-12-02 21:15 UTC (permalink / raw)
  To: adrianhoyin.ng; +Cc: alexandre.belloni, linux-i3c, linux-kernel

On Tue, Dec 02, 2025 at 04:26:11PM +0800, adrianhoyin.ng@altera.com wrote:
> From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
>
> The DesignWare I3C controller supports automatically retrying transactions
> when a device NACKs. This is useful for slave devices that may be
> temporarily busy and not ready to respond immediately.
>
> Add new ops to configure all active DAT entry with dev_nack_retry during
> runtime. Returns error when value exceeds hw specified limit.
>
> Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
> ---
>  drivers/i3c/master/dw-i3c-master.c | 36 ++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>
> diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
> index 9ceedf09c3b6..8288888be591 100644
> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
> @@ -204,8 +204,10 @@
>  #define EXTENDED_CAPABILITY		0xe8
>  #define SLAVE_CONFIG			0xec
>
> +#define DW_I3C_DEV_NACK_RETRY_CNT_MAX	0x3
>  #define DEV_ADDR_TABLE_IBI_MDB		BIT(12)
>  #define DEV_ADDR_TABLE_SIR_REJECT	BIT(13)
> +#define DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(x)	(((x) << 29) & GENMASK(30, 29))

Use FEILD_PREP()

>  #define DEV_ADDR_TABLE_LEGACY_I2C_DEV	BIT(31)
>  #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x)	(((x) << 16) & GENMASK(23, 16))
>  #define DEV_ADDR_TABLE_STATIC_ADDR(x)	((x) & GENMASK(6, 0))
> @@ -1484,6 +1486,39 @@ static irqreturn_t dw_i3c_master_irq_handler(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>
> +static int dw_i3c_master_set_dev_nack_retry(struct i3c_master_controller *m)
> +{
> +	struct dw_i3c_master *master = to_dw_i3c_master(m);
> +	u32 reg;
> +	int i;
> +
> +	if (m->dev_nack_retry > DW_I3C_DEV_NACK_RETRY_CNT_MAX) {
> +		dev_err(&master->base.dev,
> +			"Value %x exceeds maximum %d\n",
> +			m->dev_nack_retry, DW_I3C_DEV_NACK_RETRY_CNT_MAX);
> +		return -ERANGE;
> +	}
> +
> +	/*
> +	 * Update DAT entries for all currently attached devices.
> +	 * We directly iterate through the master's device array.
> +	 */
> +	for (i = 0; i < master->maxdevs; i++) {
> +		/* Skip free/empty slots */
> +		if (master->free_pos & BIT(i))
> +			continue;
> +
> +		reg = readl(master->regs +
> +				DEV_ADDR_TABLE_LOC(master->datstartaddr, i));
> +		reg &= ~GENMASK(30, 29);

define MACRO for GENMASK(30, 29), you can reuse this macro at
DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT()

Frank
> +		reg |= DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(m->dev_nack_retry);
> +		writel(reg, master->regs +
> +			DEV_ADDR_TABLE_LOC(master->datstartaddr, i));
> +	}
> +
> +	return 0;
> +}
> +
>  static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
>  	.bus_init = dw_i3c_master_bus_init,
>  	.bus_cleanup = dw_i3c_master_bus_cleanup,
> @@ -1504,6 +1539,7 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
>  	.recycle_ibi_slot = dw_i3c_master_recycle_ibi_slot,
>  	.enable_hotjoin = dw_i3c_master_enable_hotjoin,
>  	.disable_hotjoin = dw_i3c_master_disable_hotjoin,
> +	.set_dev_nack_retry = dw_i3c_master_set_dev_nack_retry,
>  };
>
>  /* default platform ops implementations */
> --
> 2.49.GIT
>

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros
  2025-12-02  8:26 ` [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros adrianhoyin.ng
@ 2025-12-02 21:16   ` Frank Li
  2025-12-02 22:49   ` kernel test robot
  2025-12-02 23:41   ` kernel test robot
  2 siblings, 0 replies; 12+ messages in thread
From: Frank Li @ 2025-12-02 21:16 UTC (permalink / raw)
  To: adrianhoyin.ng; +Cc: alexandre.belloni, linux-i3c, linux-kernel

On Tue, Dec 02, 2025 at 04:26:12PM +0800, adrianhoyin.ng@altera.com wrote:
> From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
>
> Add DEV_ADDR_TABLE_DYNAMIC_MASK / DEV_ADDR_TABLE_DYNAMIC_ADDR(x) for
> dynamic device addresses and DEV_ADDR_TABLE_STATIC_MASK /
> DEV_ADDR_TABLE_STATIC_ADDR(x) for static device addresses in the I3C
> address table. Replace manual shift-and-mask with FIELD_PREP() for both
> dynamic and static addresses for clarity and maintainability.
>
> Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/i3c/master/dw-i3c-master.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
> index 8288888be591..1c1418d0a62a 100644
> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
> @@ -205,12 +205,14 @@
>  #define SLAVE_CONFIG			0xec
>
>  #define DW_I3C_DEV_NACK_RETRY_CNT_MAX	0x3
> +#define DEV_ADDR_TABLE_DYNAMIC_MASK		GENMASK(23, 16)
> +#define DEV_ADDR_TABLE_STATIC_MASK		GENMASK(6, 0)
>  #define DEV_ADDR_TABLE_IBI_MDB		BIT(12)
>  #define DEV_ADDR_TABLE_SIR_REJECT	BIT(13)
>  #define DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(x)	(((x) << 29) & GENMASK(30, 29))
>  #define DEV_ADDR_TABLE_LEGACY_I2C_DEV	BIT(31)
> -#define DEV_ADDR_TABLE_DYNAMIC_ADDR(x)	(((x) << 16) & GENMASK(23, 16))
> -#define DEV_ADDR_TABLE_STATIC_ADDR(x)	((x) & GENMASK(6, 0))
> +#define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_DYNAMIC_MASK, x)
> +#define DEV_ADDR_TABLE_STATIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_STATIC_MASK, x)
>  #define DEV_ADDR_TABLE_LOC(start, idx)	((start) + ((idx) << 2))
>
>  #define I3C_BUS_SDR1_SCL_RATE		8000000
> --
> 2.49.GIT
>

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses
  2025-12-02  8:26 ` [PATCH v5 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses adrianhoyin.ng
@ 2025-12-02 21:19   ` Frank Li
  0 siblings, 0 replies; 12+ messages in thread
From: Frank Li @ 2025-12-02 21:19 UTC (permalink / raw)
  To: adrianhoyin.ng; +Cc: alexandre.belloni, linux-i3c, linux-kernel

On Tue, Dec 02, 2025 at 04:26:13PM +0800, adrianhoyin.ng@altera.com wrote:
> From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
>
> Update dw_i3c_master_restore_addrs() to preserve existing bits in each
> Device Address Table (DAT) entry when restoring addresses. This prevents
> overwriting configuration bits during PM runtime resumes.
>
> Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/i3c/master/dw-i3c-master.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
> index 1c1418d0a62a..36afd8ff4e2f 100644
> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
> @@ -1692,11 +1692,16 @@ static void dw_i3c_master_restore_addrs(struct dw_i3c_master *master)
>  		if (master->free_pos & BIT(pos))
>  			continue;
>
> -		if (master->devs[pos].is_i2c_addr)
> -			reg_val = DEV_ADDR_TABLE_LEGACY_I2C_DEV |
> +		reg_val = readl(master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, pos));
> +
> +		if (master->devs[pos].is_i2c_addr) {
> +			reg_val &= ~DEV_ADDR_TABLE_STATIC_MASK;
> +			reg_val |= DEV_ADDR_TABLE_LEGACY_I2C_DEV |
>  			       DEV_ADDR_TABLE_STATIC_ADDR(master->devs[pos].addr);
> -		else
> -			reg_val = DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr);
> +		} else {
> +			reg_val &= ~DEV_ADDR_TABLE_DYNAMIC_MASK;
> +			reg_val |= DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr);
> +		}
>
>  		writel(reg_val, master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, pos));
>  	}
> --
> 2.49.GIT
>

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros
  2025-12-02  8:26 ` [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros adrianhoyin.ng
  2025-12-02 21:16   ` Frank Li
@ 2025-12-02 22:49   ` kernel test robot
  2025-12-02 23:41   ` kernel test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2025-12-02 22:49 UTC (permalink / raw)
  To: adrianhoyin.ng, alexandre.belloni, Frank.Li, linux-i3c,
	linux-kernel
  Cc: oe-kbuild-all, adrianhoyin.ng

Hi,

kernel test robot noticed the following build errors:

[auto build test ERROR on i3c/i3c/next]
[also build test ERROR on linus/master v6.18 next-20251202]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/adrianhoyin-ng-altera-com/i3c-add-sysfs-entry-for-Device-NACK-Retry-count/20251202-163150
base:   https://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git i3c/next
patch link:    https://lore.kernel.org/r/4c4791c018d61beb9ff85ca68c5bf48940d2398e.1764663888.git.adrianhoyin.ng%40altera.com
patch subject: [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros
config: powerpc64-randconfig-r073-20251203 (https://download.01.org/0day-ci/archive/20251203/202512030652.72UiYSSA-lkp@intel.com/config)
compiler: powerpc64-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251203/202512030652.72UiYSSA-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512030652.72UiYSSA-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/i3c/master/dw-i3c-master.c: In function 'dw_i3c_master_daa':
>> drivers/i3c/master/dw-i3c-master.c:214:40: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
    #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_DYNAMIC_MASK, x)
                                           ^~~~~~~~~~
   drivers/i3c/master/dw-i3c-master.c:862:10: note: in expansion of macro 'DEV_ADDR_TABLE_DYNAMIC_ADDR'
      writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(ret),
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +/FIELD_PREP +214 drivers/i3c/master/dw-i3c-master.c

   206	
   207	#define DW_I3C_DEV_NACK_RETRY_CNT_MAX	0x3
   208	#define DEV_ADDR_TABLE_DYNAMIC_MASK		GENMASK(23, 16)
   209	#define DEV_ADDR_TABLE_STATIC_MASK		GENMASK(6, 0)
   210	#define DEV_ADDR_TABLE_IBI_MDB		BIT(12)
   211	#define DEV_ADDR_TABLE_SIR_REJECT	BIT(13)
   212	#define DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(x)	(((x) << 29) & GENMASK(30, 29))
   213	#define DEV_ADDR_TABLE_LEGACY_I2C_DEV	BIT(31)
 > 214	#define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_DYNAMIC_MASK, x)
   215	#define DEV_ADDR_TABLE_STATIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_STATIC_MASK, x)
   216	#define DEV_ADDR_TABLE_LOC(start, idx)	((start) + ((idx) << 2))
   217	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros
  2025-12-02  8:26 ` [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros adrianhoyin.ng
  2025-12-02 21:16   ` Frank Li
  2025-12-02 22:49   ` kernel test robot
@ 2025-12-02 23:41   ` kernel test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2025-12-02 23:41 UTC (permalink / raw)
  To: adrianhoyin.ng, alexandre.belloni, Frank.Li, linux-i3c,
	linux-kernel
  Cc: llvm, oe-kbuild-all, adrianhoyin.ng

Hi,

kernel test robot noticed the following build errors:

[auto build test ERROR on i3c/i3c/next]
[also build test ERROR on linus/master v6.18 next-20251202]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/adrianhoyin-ng-altera-com/i3c-add-sysfs-entry-for-Device-NACK-Retry-count/20251202-163150
base:   https://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git i3c/next
patch link:    https://lore.kernel.org/r/4c4791c018d61beb9ff85ca68c5bf48940d2398e.1764663888.git.adrianhoyin.ng%40altera.com
patch subject: [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros
config: i386-buildonly-randconfig-005-20251203 (https://download.01.org/0day-ci/archive/20251203/202512030728.3yMG8FZJ-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251203/202512030728.3yMG8FZJ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512030728.3yMG8FZJ-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/i3c/master/dw-i3c-master.c:862:10: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     862 |                 writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(ret),
         |                        ^
   drivers/i3c/master/dw-i3c-master.c:214:40: note: expanded from macro 'DEV_ADDR_TABLE_DYNAMIC_ADDR'
     214 | #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_DYNAMIC_MASK, x)
         |                                        ^
   drivers/i3c/master/dw-i3c-master.c:1017:9: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1017 |         writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr),
         |                ^
   drivers/i3c/master/dw-i3c-master.c:214:40: note: expanded from macro 'DEV_ADDR_TABLE_DYNAMIC_ADDR'
     214 | #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_DYNAMIC_MASK, x)
         |                                        ^
   drivers/i3c/master/dw-i3c-master.c:1046:9: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1046 |         writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr),
         |                ^
   drivers/i3c/master/dw-i3c-master.c:214:40: note: expanded from macro 'DEV_ADDR_TABLE_DYNAMIC_ADDR'
     214 | #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_DYNAMIC_MASK, x)
         |                                        ^
   drivers/i3c/master/dw-i3c-master.c:1165:9: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1165 |                DEV_ADDR_TABLE_STATIC_ADDR(dev->addr),
         |                ^
   drivers/i3c/master/dw-i3c-master.c:215:39: note: expanded from macro 'DEV_ADDR_TABLE_STATIC_ADDR'
     215 | #define DEV_ADDR_TABLE_STATIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_STATIC_MASK, x)
         |                                       ^
   drivers/i3c/master/dw-i3c-master.c:1719:11: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1719 |                                DEV_ADDR_TABLE_STATIC_ADDR(master->devs[pos].addr);
         |                                ^
   drivers/i3c/master/dw-i3c-master.c:215:39: note: expanded from macro 'DEV_ADDR_TABLE_STATIC_ADDR'
     215 | #define DEV_ADDR_TABLE_STATIC_ADDR(x) FIELD_PREP(DEV_ADDR_TABLE_STATIC_MASK, x)
         |                                       ^
   5 errors generated.


vim +/FIELD_PREP +862 drivers/i3c/master/dw-i3c-master.c

1dd728f5d4d4b8 Vitor Soares 2018-11-13  826  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  827  static int dw_i3c_master_daa(struct i3c_master_controller *m)
1dd728f5d4d4b8 Vitor Soares 2018-11-13  828  {
1dd728f5d4d4b8 Vitor Soares 2018-11-13  829  	struct dw_i3c_master *master = to_dw_i3c_master(m);
1dd728f5d4d4b8 Vitor Soares 2018-11-13  830  	struct dw_i3c_xfer *xfer;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  831  	struct dw_i3c_cmd *cmd;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  832  	u32 olddevs, newdevs;
e89cc14e96a99c Wolfram Sang 2025-01-07  833  	u8 last_addr = 0;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  834  	int ret, pos;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  835  
62fe9d06f5709c Aniket       2024-07-08  836  	ret = pm_runtime_resume_and_get(master->dev);
62fe9d06f5709c Aniket       2024-07-08  837  	if (ret < 0) {
62fe9d06f5709c Aniket       2024-07-08  838  		dev_err(master->dev,
62fe9d06f5709c Aniket       2024-07-08  839  			"<%s> cannot resume i3c bus master, err: %d\n",
62fe9d06f5709c Aniket       2024-07-08  840  			__func__, ret);
62fe9d06f5709c Aniket       2024-07-08  841  		return ret;
62fe9d06f5709c Aniket       2024-07-08  842  	}
62fe9d06f5709c Aniket       2024-07-08  843  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  844  	olddevs = ~(master->free_pos);
1dd728f5d4d4b8 Vitor Soares 2018-11-13  845  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  846  	/* Prepare DAT before launching DAA. */
1dd728f5d4d4b8 Vitor Soares 2018-11-13  847  	for (pos = 0; pos < master->maxdevs; pos++) {
1dd728f5d4d4b8 Vitor Soares 2018-11-13  848  		if (olddevs & BIT(pos))
1dd728f5d4d4b8 Vitor Soares 2018-11-13  849  			continue;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  850  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  851  		ret = i3c_master_get_free_addr(m, last_addr + 1);
62fe9d06f5709c Aniket       2024-07-08  852  		if (ret < 0) {
62fe9d06f5709c Aniket       2024-07-08  853  			ret = -ENOSPC;
62fe9d06f5709c Aniket       2024-07-08  854  			goto rpm_out;
62fe9d06f5709c Aniket       2024-07-08  855  		}
1dd728f5d4d4b8 Vitor Soares 2018-11-13  856  
e2d43101f61d6e Jeremy Kerr  2023-03-30  857  		master->devs[pos].addr = ret;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  858  		last_addr = ret;
e89cc14e96a99c Wolfram Sang 2025-01-07  859  
e89cc14e96a99c Wolfram Sang 2025-01-07  860  		ret |= parity8(ret) ? 0 : BIT(7);
1dd728f5d4d4b8 Vitor Soares 2018-11-13  861  
1dd728f5d4d4b8 Vitor Soares 2018-11-13 @862  		writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(ret),
1dd728f5d4d4b8 Vitor Soares 2018-11-13  863  		       master->regs +
1dd728f5d4d4b8 Vitor Soares 2018-11-13  864  		       DEV_ADDR_TABLE_LOC(master->datstartaddr, pos));
62fe9d06f5709c Aniket       2024-07-08  865  
62fe9d06f5709c Aniket       2024-07-08  866  		ret = 0;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  867  	}
1dd728f5d4d4b8 Vitor Soares 2018-11-13  868  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  869  	xfer = dw_i3c_master_alloc_xfer(master, 1);
62fe9d06f5709c Aniket       2024-07-08  870  	if (!xfer) {
62fe9d06f5709c Aniket       2024-07-08  871  		ret = -ENOMEM;
62fe9d06f5709c Aniket       2024-07-08  872  		goto rpm_out;
62fe9d06f5709c Aniket       2024-07-08  873  	}
1dd728f5d4d4b8 Vitor Soares 2018-11-13  874  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  875  	pos = dw_i3c_master_get_free_pos(master);
13462ba1815db5 Tom Rix      2022-01-08  876  	if (pos < 0) {
13462ba1815db5 Tom Rix      2022-01-08  877  		dw_i3c_master_free_xfer(xfer);
62fe9d06f5709c Aniket       2024-07-08  878  		ret = pos;
62fe9d06f5709c Aniket       2024-07-08  879  		goto rpm_out;
13462ba1815db5 Tom Rix      2022-01-08  880  	}
1dd728f5d4d4b8 Vitor Soares 2018-11-13  881  	cmd = &xfer->cmds[0];
1dd728f5d4d4b8 Vitor Soares 2018-11-13  882  	cmd->cmd_hi = 0x1;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  883  	cmd->cmd_lo = COMMAND_PORT_DEV_COUNT(master->maxdevs - pos) |
1dd728f5d4d4b8 Vitor Soares 2018-11-13  884  		      COMMAND_PORT_DEV_INDEX(pos) |
1dd728f5d4d4b8 Vitor Soares 2018-11-13  885  		      COMMAND_PORT_CMD(I3C_CCC_ENTDAA) |
1dd728f5d4d4b8 Vitor Soares 2018-11-13  886  		      COMMAND_PORT_ADDR_ASSGN_CMD |
1dd728f5d4d4b8 Vitor Soares 2018-11-13  887  		      COMMAND_PORT_TOC |
1dd728f5d4d4b8 Vitor Soares 2018-11-13  888  		      COMMAND_PORT_ROC;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  889  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  890  	dw_i3c_master_enqueue_xfer(master, xfer);
1dd728f5d4d4b8 Vitor Soares 2018-11-13  891  	if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT))
1dd728f5d4d4b8 Vitor Soares 2018-11-13  892  		dw_i3c_master_dequeue_xfer(master, xfer);
1dd728f5d4d4b8 Vitor Soares 2018-11-13  893  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  894  	newdevs = GENMASK(master->maxdevs - cmd->rx_len - 1, 0);
1dd728f5d4d4b8 Vitor Soares 2018-11-13  895  	newdevs &= ~olddevs;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  896  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  897  	for (pos = 0; pos < master->maxdevs; pos++) {
1dd728f5d4d4b8 Vitor Soares 2018-11-13  898  		if (newdevs & BIT(pos))
e2d43101f61d6e Jeremy Kerr  2023-03-30  899  			i3c_master_add_i3c_dev_locked(m, master->devs[pos].addr);
1dd728f5d4d4b8 Vitor Soares 2018-11-13  900  	}
1dd728f5d4d4b8 Vitor Soares 2018-11-13  901  
1dd728f5d4d4b8 Vitor Soares 2018-11-13  902  	dw_i3c_master_free_xfer(xfer);
1dd728f5d4d4b8 Vitor Soares 2018-11-13  903  
62fe9d06f5709c Aniket       2024-07-08  904  rpm_out:
62fe9d06f5709c Aniket       2024-07-08  905  	pm_runtime_put_autosuspend(master->dev);
62fe9d06f5709c Aniket       2024-07-08  906  	return ret;
1dd728f5d4d4b8 Vitor Soares 2018-11-13  907  }
1dd728f5d4d4b8 Vitor Soares 2018-11-13  908  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-12-02 23:42 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-02  8:26 [PATCH v5 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix adrianhoyin.ng
2025-12-02  8:26 ` [PATCH v5 1/5] i3c: add sysfs entry for Device NACK Retry count adrianhoyin.ng
2025-12-02  8:26 ` [PATCH v5 2/5] i3c: add sysfs attribute for device NACK retry adrianhoyin.ng
2025-12-02 21:12   ` Frank Li
2025-12-02  8:26 ` [PATCH v5 3/5] i3c: dw: Add support for Device NACK Retry configuration adrianhoyin.ng
2025-12-02 21:15   ` Frank Li
2025-12-02  8:26 ` [PATCH v5 4/5] i3c: dw: use FIELD_PREP for device address table macros adrianhoyin.ng
2025-12-02 21:16   ` Frank Li
2025-12-02 22:49   ` kernel test robot
2025-12-02 23:41   ` kernel test robot
2025-12-02  8:26 ` [PATCH v5 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses adrianhoyin.ng
2025-12-02 21:19   ` Frank Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox