From: David Nyström Date: Thu, 19 Feb 2026 20:58:03 +0000 (+0100) Subject: i3c: master: Add sysfs option to rescan bus via entdaa X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=8ea0b60bc00d86b5ce33837487f4d16ae212f70a;p=thirdparty%2Fkernel%2Flinux.git i3c: master: Add sysfs option to rescan bus via entdaa Allow userspace to request dynamic address assignment, which is useful for i3cdev devices with broken hot-join support. This will assign dynamic addresses to all devices on the I3C bus which are currently unassigned. Signed-off-by: David Nyström Reviewed-by: Frank Li Reviewed-by: Meagan Lloyd Link: https://patch.msgid.link/20260219-i3c_rescan-v6-1-b81d6cc3cb30@est.tech Signed-off-by: Alexandre Belloni --- diff --git a/Documentation/ABI/testing/sysfs-bus-i3c b/Documentation/ABI/testing/sysfs-bus-i3c index c1e048957a01..19f5cf8b1b11 100644 --- a/Documentation/ABI/testing/sysfs-bus-i3c +++ b/Documentation/ABI/testing/sysfs-bus-i3c @@ -172,3 +172,23 @@ Description: the automatic retries. Exist only when I3C constroller supports this retry on nack feature. +What: /sys/bus/i3c/devices/i3c-/do_daa +KernelVersion: 7.0 +Contact: linux-i3c@vger.kernel.org +Description: + Write-only attribute that triggers a Dynamic Address Assignment + (DAA) procedure which discovers new I3C devices on the bus. + Writing a boolean true value (1, y, yes, true, on) to this + attribute causes the master controller to perform DAA, which + includes broadcasting an ENTDAA (Enter Dynamic Address Assignment) + Common Command Code (CCC) on the bus. Writing a false value + returns -EINVAL. + + This is useful for discovering I3C devices that were not present + during initial bus initialization and are unable to issue + Hot-Join. Only devices without a currently assigned dynamic address + will respond to the ENTDAA broadcast and be assigned addresses. + + Note that this mechanism is distinct from Hot-Join, since this is + controller-initiated discovery, while Hot-Join is device-initiated + method to provoke controller discovery procedure. diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 9e6be49bebb2..53b34b4f44a2 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -758,6 +758,32 @@ static ssize_t dev_nack_retry_count_store(struct device *dev, static DEVICE_ATTR_RW(dev_nack_retry_count); +static ssize_t do_daa_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i3c_master_controller *master = dev_to_i3cmaster(dev); + bool val; + int ret; + + if (kstrtobool(buf, &val)) + return -EINVAL; + + if (!val) + return -EINVAL; + + if (!master->init_done) + return -EAGAIN; + + ret = i3c_master_do_daa(master); + if (ret) + return ret; + + return count; +} + +static DEVICE_ATTR_WO(do_daa); + static struct attribute *i3c_masterdev_attrs[] = { &dev_attr_mode.attr, &dev_attr_current_master.attr, @@ -769,6 +795,7 @@ static struct attribute *i3c_masterdev_attrs[] = { &dev_attr_dynamic_address.attr, &dev_attr_hdrcap.attr, &dev_attr_hotjoin.attr, + &dev_attr_do_daa.attr, NULL, }; ATTRIBUTE_GROUPS(i3c_masterdev);