Commit 8ea0b60b authored by David Nyström's avatar David Nyström Committed by Alexandre Belloni
Browse files

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: default avatarDavid Nyström <david.nystrom@est.tech>
Reviewed-by: default avatarFrank Li <Frank.Li@nxp.com>
Reviewed-by: default avatarMeagan Lloyd <meaganlloyd@linux.microsoft.com>
Link: https://patch.msgid.link/20260219-i3c_rescan-v6-1-b81d6cc3cb30@est.tech


Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent 335c21a2
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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-<bus-id>/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.
+27 −0
Original line number Diff line number Diff line
@@ -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);