* [PATCH v7 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix @ 2025-12-08 7:11 ` adrianhoyin.ng 0 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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: v6->v7 * Update dev_nack_retry_show to remove redundant i3cbus variable. * Refactor dev_nack_retry_store to store dev_nack_retry val only if set_dev_nack_retry does not return error. * Update set_dev_nack_retry in master and dw-i3c-master to take additional param which is the dev_nack_retry_cnt. v6 patch link: https://lore.kernel.org/all/cover.1764746266.git.adrianhoyin.ng@altera.com/ v5->v6 * Use dev_to_i3cmaster to get i3cmaster insteasd of direct assignment. * Remove redundant set_dev_nack_retry callback function check. * Update kernel doc for set_dev_nack_retry. * Add macro for dev nack retry mask. v5 patch link: https://lore.kernel.org/all/cover.1764663888.git.adrianhoyin.ng@altera.com/ 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 | 38 ++++++++++++++++ drivers/i3c/master/dw-i3c-master.c | 59 ++++++++++++++++++++++--- include/linux/i3c/master.h | 6 +++ 4 files changed, 109 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] 20+ messages in thread
* [PATCH v7 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix @ 2025-12-08 7:11 ` adrianhoyin.ng 0 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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: v6->v7 * Update dev_nack_retry_show to remove redundant i3cbus variable. * Refactor dev_nack_retry_store to store dev_nack_retry val only if set_dev_nack_retry does not return error. * Update set_dev_nack_retry in master and dw-i3c-master to take additional param which is the dev_nack_retry_cnt. v6 patch link: https://lore.kernel.org/all/cover.1764746266.git.adrianhoyin.ng@altera.com/ v5->v6 * Use dev_to_i3cmaster to get i3cmaster insteasd of direct assignment. * Remove redundant set_dev_nack_retry callback function check. * Update kernel doc for set_dev_nack_retry. * Add macro for dev nack retry mask. v5 patch link: https://lore.kernel.org/all/cover.1764663888.git.adrianhoyin.ng@altera.com/ 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 | 38 ++++++++++++++++ drivers/i3c/master/dw-i3c-master.c | 59 ++++++++++++++++++++++--- include/linux/i3c/master.h | 6 +++ 4 files changed, 109 insertions(+), 6 deletions(-) -- 2.49.GIT ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 1/5] i3c: add sysfs entry for Device NACK Retry count 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-08 7:11 ` adrianhoyin.ng -1 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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] 20+ messages in thread
* [PATCH v7 1/5] i3c: add sysfs entry for Device NACK Retry count @ 2025-12-08 7:11 ` adrianhoyin.ng 0 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v7 1/5] i3c: add sysfs entry for Device NACK Retry count 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-10 16:21 ` Alexandre Belloni -1 siblings, 0 replies; 20+ messages in thread From: Alexandre Belloni @ 2025-12-10 16:21 UTC (permalink / raw) To: adrianhoyin.ng; +Cc: Frank.Li, linux-i3c, linux-kernel On 08/12/2025 15:11:16+0800, adrianhoyin.ng@altera.com wrote: > 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(+) > Please squash 1/5 and 2/5. > 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 > -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com -- linux-i3c mailing list linux-i3c@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-i3c ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 1/5] i3c: add sysfs entry for Device NACK Retry count @ 2025-12-10 16:21 ` Alexandre Belloni 0 siblings, 0 replies; 20+ messages in thread From: Alexandre Belloni @ 2025-12-10 16:21 UTC (permalink / raw) To: adrianhoyin.ng; +Cc: Frank.Li, linux-i3c, linux-kernel On 08/12/2025 15:11:16+0800, adrianhoyin.ng@altera.com wrote: > 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(+) > Please squash 1/5 and 2/5. > 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 > -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 2/5] i3c: add sysfs attribute for device NACK retry 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-08 7:11 ` adrianhoyin.ng -1 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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 | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/i3c/master.h | 6 ++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index d946db75df70..2903725bee03 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -685,6 +685,38 @@ 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) +{ + return sysfs_emit(buf, "%u\n", dev_to_i3cmaster(dev)->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 = dev_to_i3cmaster(dev); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + i3c_bus_maintenance_lock(i3cbus); + ret = master->ops->set_dev_nack_retry(master, val); + i3c_bus_maintenance_unlock(i3cbus); + + if (ret) + return ret; + + master->dev_nack_retry = val; + + 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 +2994,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 +3022,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..5a03e5aea6c2 100644 --- a/include/linux/i3c/master.h +++ b/include/linux/i3c/master.h @@ -462,6 +462,8 @@ struct i3c_bus { * @enable_hotjoin: enable hot join event detect. * @disable_hotjoin: disable hot join event detect. * @set_speed: adjust I3C open drain mode timing. + * @set_dev_nack_retry: configure device NACK retry count for the master + * controller. */ struct i3c_master_controller_ops { int (*bus_init)(struct i3c_master_controller *master); @@ -491,6 +493,8 @@ 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, + unsigned long dev_nack_retry_cnt); }; /** @@ -510,6 +514,7 @@ struct i3c_master_controller_ops { * @boardinfo: board-level information attached to devices connected on the bus * @bus: I3C bus exposed by this master * @wq: workqueue which can be used by master + * @dev_nack_retry: retry count when slave device nack * drivers if they need to postpone operations that need to take place * in a thread context. Typical examples are Hot Join processing which * requires taking the bus lock in maintenance, which in turn, can only @@ -534,6 +539,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] 20+ messages in thread
* [PATCH v7 2/5] i3c: add sysfs attribute for device NACK retry @ 2025-12-08 7:11 ` adrianhoyin.ng 0 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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 | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/i3c/master.h | 6 ++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index d946db75df70..2903725bee03 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -685,6 +685,38 @@ 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) +{ + return sysfs_emit(buf, "%u\n", dev_to_i3cmaster(dev)->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 = dev_to_i3cmaster(dev); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + i3c_bus_maintenance_lock(i3cbus); + ret = master->ops->set_dev_nack_retry(master, val); + i3c_bus_maintenance_unlock(i3cbus); + + if (ret) + return ret; + + master->dev_nack_retry = val; + + 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 +2994,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 +3022,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..5a03e5aea6c2 100644 --- a/include/linux/i3c/master.h +++ b/include/linux/i3c/master.h @@ -462,6 +462,8 @@ struct i3c_bus { * @enable_hotjoin: enable hot join event detect. * @disable_hotjoin: disable hot join event detect. * @set_speed: adjust I3C open drain mode timing. + * @set_dev_nack_retry: configure device NACK retry count for the master + * controller. */ struct i3c_master_controller_ops { int (*bus_init)(struct i3c_master_controller *master); @@ -491,6 +493,8 @@ 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, + unsigned long dev_nack_retry_cnt); }; /** @@ -510,6 +514,7 @@ struct i3c_master_controller_ops { * @boardinfo: board-level information attached to devices connected on the bus * @bus: I3C bus exposed by this master * @wq: workqueue which can be used by master + * @dev_nack_retry: retry count when slave device nack * drivers if they need to postpone operations that need to take place * in a thread context. Typical examples are Hot Join processing which * requires taking the bus lock in maintenance, which in turn, can only @@ -534,6 +539,7 @@ struct i3c_master_controller { } boardinfo; struct i3c_bus bus; struct workqueue_struct *wq; + unsigned int dev_nack_retry; }; /** -- 2.49.GIT ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v7 2/5] i3c: add sysfs attribute for device NACK retry 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-08 15:25 ` Frank Li -1 siblings, 0 replies; 20+ messages in thread From: Frank Li @ 2025-12-08 15:25 UTC (permalink / raw) To: adrianhoyin.ng; +Cc: alexandre.belloni, linux-i3c, linux-kernel On Mon, Dec 08, 2025 at 03:11:17PM +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> > --- Reviewed-by: Frank Li <Frank.Li@nxp.com> > drivers/i3c/master.c | 38 ++++++++++++++++++++++++++++++++++++++ > include/linux/i3c/master.h | 6 ++++++ > 2 files changed, 44 insertions(+) > > diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c > index d946db75df70..2903725bee03 100644 > --- a/drivers/i3c/master.c > +++ b/drivers/i3c/master.c > @@ -685,6 +685,38 @@ 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) > +{ > + return sysfs_emit(buf, "%u\n", dev_to_i3cmaster(dev)->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 = dev_to_i3cmaster(dev); > + unsigned long val; > + int ret; > + > + ret = kstrtoul(buf, 0, &val); > + if (ret) > + return ret; > + > + i3c_bus_maintenance_lock(i3cbus); > + ret = master->ops->set_dev_nack_retry(master, val); > + i3c_bus_maintenance_unlock(i3cbus); > + > + if (ret) > + return ret; > + > + master->dev_nack_retry = val; > + > + 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 +2994,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 +3022,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..5a03e5aea6c2 100644 > --- a/include/linux/i3c/master.h > +++ b/include/linux/i3c/master.h > @@ -462,6 +462,8 @@ struct i3c_bus { > * @enable_hotjoin: enable hot join event detect. > * @disable_hotjoin: disable hot join event detect. > * @set_speed: adjust I3C open drain mode timing. > + * @set_dev_nack_retry: configure device NACK retry count for the master > + * controller. > */ > struct i3c_master_controller_ops { > int (*bus_init)(struct i3c_master_controller *master); > @@ -491,6 +493,8 @@ 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, > + unsigned long dev_nack_retry_cnt); > }; > > /** > @@ -510,6 +514,7 @@ struct i3c_master_controller_ops { > * @boardinfo: board-level information attached to devices connected on the bus > * @bus: I3C bus exposed by this master > * @wq: workqueue which can be used by master > + * @dev_nack_retry: retry count when slave device nack > * drivers if they need to postpone operations that need to take place > * in a thread context. Typical examples are Hot Join processing which > * requires taking the bus lock in maintenance, which in turn, can only > @@ -534,6 +539,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] 20+ messages in thread
* Re: [PATCH v7 2/5] i3c: add sysfs attribute for device NACK retry @ 2025-12-08 15:25 ` Frank Li 0 siblings, 0 replies; 20+ messages in thread From: Frank Li @ 2025-12-08 15:25 UTC (permalink / raw) To: adrianhoyin.ng; +Cc: alexandre.belloni, linux-i3c, linux-kernel On Mon, Dec 08, 2025 at 03:11:17PM +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> > --- Reviewed-by: Frank Li <Frank.Li@nxp.com> > drivers/i3c/master.c | 38 ++++++++++++++++++++++++++++++++++++++ > include/linux/i3c/master.h | 6 ++++++ > 2 files changed, 44 insertions(+) > > diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c > index d946db75df70..2903725bee03 100644 > --- a/drivers/i3c/master.c > +++ b/drivers/i3c/master.c > @@ -685,6 +685,38 @@ 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) > +{ > + return sysfs_emit(buf, "%u\n", dev_to_i3cmaster(dev)->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 = dev_to_i3cmaster(dev); > + unsigned long val; > + int ret; > + > + ret = kstrtoul(buf, 0, &val); > + if (ret) > + return ret; > + > + i3c_bus_maintenance_lock(i3cbus); > + ret = master->ops->set_dev_nack_retry(master, val); > + i3c_bus_maintenance_unlock(i3cbus); > + > + if (ret) > + return ret; > + > + master->dev_nack_retry = val; > + > + 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 +2994,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 +3022,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..5a03e5aea6c2 100644 > --- a/include/linux/i3c/master.h > +++ b/include/linux/i3c/master.h > @@ -462,6 +462,8 @@ struct i3c_bus { > * @enable_hotjoin: enable hot join event detect. > * @disable_hotjoin: disable hot join event detect. > * @set_speed: adjust I3C open drain mode timing. > + * @set_dev_nack_retry: configure device NACK retry count for the master > + * controller. > */ > struct i3c_master_controller_ops { > int (*bus_init)(struct i3c_master_controller *master); > @@ -491,6 +493,8 @@ 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, > + unsigned long dev_nack_retry_cnt); > }; > > /** > @@ -510,6 +514,7 @@ struct i3c_master_controller_ops { > * @boardinfo: board-level information attached to devices connected on the bus > * @bus: I3C bus exposed by this master > * @wq: workqueue which can be used by master > + * @dev_nack_retry: retry count when slave device nack > * drivers if they need to postpone operations that need to take place > * in a thread context. Typical examples are Hot Join processing which > * requires taking the bus lock in maintenance, which in turn, can only > @@ -534,6 +539,7 @@ struct i3c_master_controller { > } boardinfo; > struct i3c_bus bus; > struct workqueue_struct *wq; > + unsigned int dev_nack_retry; > }; > > /** > -- > 2.49.GIT > ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 2/5] i3c: add sysfs attribute for device NACK retry 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-10 16:22 ` Alexandre Belloni -1 siblings, 0 replies; 20+ messages in thread From: Alexandre Belloni @ 2025-12-10 16:22 UTC (permalink / raw) To: adrianhoyin.ng; +Cc: Frank.Li, linux-i3c, linux-kernel On 08/12/2025 15:11:17+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 | 38 ++++++++++++++++++++++++++++++++++++++ > include/linux/i3c/master.h | 6 ++++++ > 2 files changed, 44 insertions(+) > > diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c > index d946db75df70..2903725bee03 100644 > --- a/drivers/i3c/master.c > +++ b/drivers/i3c/master.c > @@ -685,6 +685,38 @@ 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) > +{ > + return sysfs_emit(buf, "%u\n", dev_to_i3cmaster(dev)->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 = dev_to_i3cmaster(dev); > + unsigned long val; > + int ret; > + > + ret = kstrtoul(buf, 0, &val); > + if (ret) > + return ret; > + > + i3c_bus_maintenance_lock(i3cbus); > + ret = master->ops->set_dev_nack_retry(master, val); > + i3c_bus_maintenance_unlock(i3cbus); > + > + if (ret) > + return ret; > + > + master->dev_nack_retry = val; > + > + return count; > +} > + > +static DEVICE_ATTR_RW(dev_nack_retry); Shouldn't that be dev_nack_retry_count ? > + > static struct attribute *i3c_masterdev_attrs[] = { > &dev_attr_mode.attr, > &dev_attr_current_master.attr, > @@ -2962,6 +2994,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 +3022,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..5a03e5aea6c2 100644 > --- a/include/linux/i3c/master.h > +++ b/include/linux/i3c/master.h > @@ -462,6 +462,8 @@ struct i3c_bus { > * @enable_hotjoin: enable hot join event detect. > * @disable_hotjoin: disable hot join event detect. > * @set_speed: adjust I3C open drain mode timing. > + * @set_dev_nack_retry: configure device NACK retry count for the master > + * controller. > */ > struct i3c_master_controller_ops { > int (*bus_init)(struct i3c_master_controller *master); > @@ -491,6 +493,8 @@ 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, > + unsigned long dev_nack_retry_cnt); > }; > > /** > @@ -510,6 +514,7 @@ struct i3c_master_controller_ops { > * @boardinfo: board-level information attached to devices connected on the bus > * @bus: I3C bus exposed by this master > * @wq: workqueue which can be used by master > + * @dev_nack_retry: retry count when slave device nack > * drivers if they need to postpone operations that need to take place > * in a thread context. Typical examples are Hot Join processing which > * requires taking the bus lock in maintenance, which in turn, can only > @@ -534,6 +539,7 @@ struct i3c_master_controller { > } boardinfo; > struct i3c_bus bus; > struct workqueue_struct *wq; > + unsigned int dev_nack_retry; > }; > > /** > -- > 2.49.GIT > -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com -- linux-i3c mailing list linux-i3c@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-i3c ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v7 2/5] i3c: add sysfs attribute for device NACK retry @ 2025-12-10 16:22 ` Alexandre Belloni 0 siblings, 0 replies; 20+ messages in thread From: Alexandre Belloni @ 2025-12-10 16:22 UTC (permalink / raw) To: adrianhoyin.ng; +Cc: Frank.Li, linux-i3c, linux-kernel On 08/12/2025 15:11:17+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 | 38 ++++++++++++++++++++++++++++++++++++++ > include/linux/i3c/master.h | 6 ++++++ > 2 files changed, 44 insertions(+) > > diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c > index d946db75df70..2903725bee03 100644 > --- a/drivers/i3c/master.c > +++ b/drivers/i3c/master.c > @@ -685,6 +685,38 @@ 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) > +{ > + return sysfs_emit(buf, "%u\n", dev_to_i3cmaster(dev)->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 = dev_to_i3cmaster(dev); > + unsigned long val; > + int ret; > + > + ret = kstrtoul(buf, 0, &val); > + if (ret) > + return ret; > + > + i3c_bus_maintenance_lock(i3cbus); > + ret = master->ops->set_dev_nack_retry(master, val); > + i3c_bus_maintenance_unlock(i3cbus); > + > + if (ret) > + return ret; > + > + master->dev_nack_retry = val; > + > + return count; > +} > + > +static DEVICE_ATTR_RW(dev_nack_retry); Shouldn't that be dev_nack_retry_count ? > + > static struct attribute *i3c_masterdev_attrs[] = { > &dev_attr_mode.attr, > &dev_attr_current_master.attr, > @@ -2962,6 +2994,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 +3022,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..5a03e5aea6c2 100644 > --- a/include/linux/i3c/master.h > +++ b/include/linux/i3c/master.h > @@ -462,6 +462,8 @@ struct i3c_bus { > * @enable_hotjoin: enable hot join event detect. > * @disable_hotjoin: disable hot join event detect. > * @set_speed: adjust I3C open drain mode timing. > + * @set_dev_nack_retry: configure device NACK retry count for the master > + * controller. > */ > struct i3c_master_controller_ops { > int (*bus_init)(struct i3c_master_controller *master); > @@ -491,6 +493,8 @@ 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, > + unsigned long dev_nack_retry_cnt); > }; > > /** > @@ -510,6 +514,7 @@ struct i3c_master_controller_ops { > * @boardinfo: board-level information attached to devices connected on the bus > * @bus: I3C bus exposed by this master > * @wq: workqueue which can be used by master > + * @dev_nack_retry: retry count when slave device nack > * drivers if they need to postpone operations that need to take place > * in a thread context. Typical examples are Hot Join processing which > * requires taking the bus lock in maintenance, which in turn, can only > @@ -534,6 +539,7 @@ struct i3c_master_controller { > } boardinfo; > struct i3c_bus bus; > struct workqueue_struct *wq; > + unsigned int dev_nack_retry; > }; > > /** > -- > 2.49.GIT > -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 3/5] i3c: dw: Add support for Device NACK Retry configuration 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-08 7:11 ` adrianhoyin.ng -1 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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 | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c index 9ceedf09c3b6..ce33600d4c5e 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -5,6 +5,7 @@ * Author: Vitor Soares <vitor.soares@synopsys.com> */ +#include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/clk.h> #include <linux/completion.h> @@ -204,8 +205,12 @@ #define EXTENDED_CAPABILITY 0xe8 #define SLAVE_CONFIG 0xec +#define DW_I3C_DEV_NACK_RETRY_CNT_MAX 0x3 +#define DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK GENMASK(30, 29) #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) \ + FIELD_PREP(DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK, (x)) #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 +1489,40 @@ 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, + unsigned long dev_nack_retry_cnt) +{ + struct dw_i3c_master *master = to_dw_i3c_master(m); + u32 reg; + int i; + + if (dev_nack_retry_cnt > DW_I3C_DEV_NACK_RETRY_CNT_MAX) { + dev_err(&master->base.dev, + "Value %ld exceeds maximum %d\n", + dev_nack_retry_cnt, 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 &= ~DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK; + reg |= DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(dev_nack_retry_cnt); + 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 +1543,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] 20+ messages in thread
* [PATCH v7 3/5] i3c: dw: Add support for Device NACK Retry configuration @ 2025-12-08 7:11 ` adrianhoyin.ng 0 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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 | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c index 9ceedf09c3b6..ce33600d4c5e 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -5,6 +5,7 @@ * Author: Vitor Soares <vitor.soares@synopsys.com> */ +#include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/clk.h> #include <linux/completion.h> @@ -204,8 +205,12 @@ #define EXTENDED_CAPABILITY 0xe8 #define SLAVE_CONFIG 0xec +#define DW_I3C_DEV_NACK_RETRY_CNT_MAX 0x3 +#define DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK GENMASK(30, 29) #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) \ + FIELD_PREP(DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK, (x)) #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 +1489,40 @@ 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, + unsigned long dev_nack_retry_cnt) +{ + struct dw_i3c_master *master = to_dw_i3c_master(m); + u32 reg; + int i; + + if (dev_nack_retry_cnt > DW_I3C_DEV_NACK_RETRY_CNT_MAX) { + dev_err(&master->base.dev, + "Value %ld exceeds maximum %d\n", + dev_nack_retry_cnt, 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 &= ~DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK; + reg |= DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(dev_nack_retry_cnt); + 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 +1543,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 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v7 3/5] i3c: dw: Add support for Device NACK Retry configuration 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-08 15:27 ` Frank Li -1 siblings, 0 replies; 20+ messages in thread From: Frank Li @ 2025-12-08 15:27 UTC (permalink / raw) To: adrianhoyin.ng; +Cc: alexandre.belloni, linux-i3c, linux-kernel On Mon, Dec 08, 2025 at 03:11:18PM +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 | 40 ++++++++++++++++++++++++++++++ Reviewed-by: Frank Li <Frank.Li@nxp.com> > 1 file changed, 40 insertions(+) > > diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c > index 9ceedf09c3b6..ce33600d4c5e 100644 > --- a/drivers/i3c/master/dw-i3c-master.c > +++ b/drivers/i3c/master/dw-i3c-master.c > @@ -5,6 +5,7 @@ > * Author: Vitor Soares <vitor.soares@synopsys.com> > */ > > +#include <linux/bitfield.h> > #include <linux/bitops.h> > #include <linux/clk.h> > #include <linux/completion.h> > @@ -204,8 +205,12 @@ > #define EXTENDED_CAPABILITY 0xe8 > #define SLAVE_CONFIG 0xec > > +#define DW_I3C_DEV_NACK_RETRY_CNT_MAX 0x3 > +#define DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK GENMASK(30, 29) > #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) \ > + FIELD_PREP(DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK, (x)) > #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 +1489,40 @@ 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, > + unsigned long dev_nack_retry_cnt) > +{ > + struct dw_i3c_master *master = to_dw_i3c_master(m); > + u32 reg; > + int i; > + > + if (dev_nack_retry_cnt > DW_I3C_DEV_NACK_RETRY_CNT_MAX) { > + dev_err(&master->base.dev, > + "Value %ld exceeds maximum %d\n", > + dev_nack_retry_cnt, 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 &= ~DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK; > + reg |= DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(dev_nack_retry_cnt); > + 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 +1543,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] 20+ messages in thread
* Re: [PATCH v7 3/5] i3c: dw: Add support for Device NACK Retry configuration @ 2025-12-08 15:27 ` Frank Li 0 siblings, 0 replies; 20+ messages in thread From: Frank Li @ 2025-12-08 15:27 UTC (permalink / raw) To: adrianhoyin.ng; +Cc: alexandre.belloni, linux-i3c, linux-kernel On Mon, Dec 08, 2025 at 03:11:18PM +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 | 40 ++++++++++++++++++++++++++++++ Reviewed-by: Frank Li <Frank.Li@nxp.com> > 1 file changed, 40 insertions(+) > > diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c > index 9ceedf09c3b6..ce33600d4c5e 100644 > --- a/drivers/i3c/master/dw-i3c-master.c > +++ b/drivers/i3c/master/dw-i3c-master.c > @@ -5,6 +5,7 @@ > * Author: Vitor Soares <vitor.soares@synopsys.com> > */ > > +#include <linux/bitfield.h> > #include <linux/bitops.h> > #include <linux/clk.h> > #include <linux/completion.h> > @@ -204,8 +205,12 @@ > #define EXTENDED_CAPABILITY 0xe8 > #define SLAVE_CONFIG 0xec > > +#define DW_I3C_DEV_NACK_RETRY_CNT_MAX 0x3 > +#define DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK GENMASK(30, 29) > #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) \ > + FIELD_PREP(DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK, (x)) > #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 +1489,40 @@ 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, > + unsigned long dev_nack_retry_cnt) > +{ > + struct dw_i3c_master *master = to_dw_i3c_master(m); > + u32 reg; > + int i; > + > + if (dev_nack_retry_cnt > DW_I3C_DEV_NACK_RETRY_CNT_MAX) { > + dev_err(&master->base.dev, > + "Value %ld exceeds maximum %d\n", > + dev_nack_retry_cnt, 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 &= ~DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK; > + reg |= DEV_ADDR_TABLE_DEV_NACK_RETRY_CNT(dev_nack_retry_cnt); > + 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 +1543,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 > ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v7 4/5] i3c: dw: use FIELD_PREP for device address table macros 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-08 7:11 ` adrianhoyin.ng -1 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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> 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 ce33600d4c5e..f96b30c4cbfc 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -207,13 +207,15 @@ #define DW_I3C_DEV_NACK_RETRY_CNT_MAX 0x3 #define DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK GENMASK(30, 29) +#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) \ FIELD_PREP(DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK, (x)) #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] 20+ messages in thread
* [PATCH v7 4/5] i3c: dw: use FIELD_PREP for device address table macros @ 2025-12-08 7:11 ` adrianhoyin.ng 0 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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> 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 ce33600d4c5e..f96b30c4cbfc 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -207,13 +207,15 @@ #define DW_I3C_DEV_NACK_RETRY_CNT_MAX 0x3 #define DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK GENMASK(30, 29) +#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) \ FIELD_PREP(DEV_ADDR_TABLE_DEV_NACK_RETRY_MASK, (x)) #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 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v7 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses 2025-12-08 7:11 ` adrianhoyin.ng @ 2025-12-08 7:11 ` adrianhoyin.ng -1 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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> 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 f96b30c4cbfc..9ca609df593f 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -1696,11 +1696,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] 20+ messages in thread
* [PATCH v7 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses @ 2025-12-08 7:11 ` adrianhoyin.ng 0 siblings, 0 replies; 20+ messages in thread From: adrianhoyin.ng @ 2025-12-08 7:11 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> 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 f96b30c4cbfc..9ca609df593f 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -1696,11 +1696,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 ^ permalink raw reply related [flat|nested] 20+ messages in thread
end of thread, other threads:[~2025-12-10 16:22 UTC | newest] Thread overview: 20+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-12-08 7:11 [PATCH v7 0/5] i3c: dw-i3c: Enable support for dw-i3c controller NACK retry sysfs and DAT restore fix adrianhoyin.ng 2025-12-08 7:11 ` adrianhoyin.ng 2025-12-08 7:11 ` [PATCH v7 1/5] i3c: add sysfs entry for Device NACK Retry count adrianhoyin.ng 2025-12-08 7:11 ` adrianhoyin.ng 2025-12-10 16:21 ` Alexandre Belloni 2025-12-10 16:21 ` Alexandre Belloni 2025-12-08 7:11 ` [PATCH v7 2/5] i3c: add sysfs attribute for device NACK retry adrianhoyin.ng 2025-12-08 7:11 ` adrianhoyin.ng 2025-12-08 15:25 ` Frank Li 2025-12-08 15:25 ` Frank Li 2025-12-10 16:22 ` Alexandre Belloni 2025-12-10 16:22 ` Alexandre Belloni 2025-12-08 7:11 ` [PATCH v7 3/5] i3c: dw: Add support for Device NACK Retry configuration adrianhoyin.ng 2025-12-08 7:11 ` adrianhoyin.ng 2025-12-08 15:27 ` Frank Li 2025-12-08 15:27 ` Frank Li 2025-12-08 7:11 ` [PATCH v7 4/5] i3c: dw: use FIELD_PREP for device address table macros adrianhoyin.ng 2025-12-08 7:11 ` adrianhoyin.ng 2025-12-08 7:11 ` [PATCH v7 5/5] i3c: dw: Preserve DAT entry bits when restoring addresses adrianhoyin.ng 2025-12-08 7:11 ` adrianhoyin.ng
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.