* [PATCH v6 00/12] Support ACPI and SETAASA device discovery
@ 2026-07-21 4:07 Akhil R
2026-07-21 4:07 ` [PATCH v6 01/12] dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA Akhil R
` (12 more replies)
0 siblings, 13 replies; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
This patch series adds SETAASA device discovery to the I3C subsystem,
enabling support for SPD5118 temperature sensors found on DDR5 memory
modules. The changes also add ACPI support for all existing DAA
methods like SETDASA, SETNEWDA as well as I2C devices on I3C bus.
SPD5118 and similar devices on DDR5 memory modules differ from typical
I3C devices in their initialization. They use SETAASA broadcast CCC
instead of ENTDAA for address assignment, and per JEDEC specification,
are not required to have a Provisioned ID or implement standard device
information CCC commands (GETPID, GETDCR, GETBCR).
The series enables describing all I3C and I2C devices on both Device
Tree and the ACPI table, using unified device property APIs throughout
the I3C core and the Synopsys DesignWare I3C master driver.
Please note that the series modifies drivers across multiple subsystems,
like Device Tree bindings, ACPI, I3C and HWMON.
v5->v6:
* Do not take an extra fwnode reference when assigning the boardinfo
fwnode to a newly registered I3C device.
* Issue SETAASA after SETDASA pre-assignment and before ENTDAA.
* Prefer SETDASA over SETAASA when a device advertises both methods
and an explicit dynamic address (assigned-address) is provided.
* Reject PID 0 for non-SETAASA I3C boardinfo entries.
* Drop OF/ACPI uevent modalias emission; keep OF/ACPI matching for
SETAASA devices only.
* Resolve DesignWare quirks before core clock acquisition and fail
probe early when the clock is missing without the ACPI skip quirk.
v4->v5:
* Free ACPI I2C boardinfo when an ACPI child without an I2C resource is
ignored.
* Issue RSTDAA if SETAASA device attach fails after the static address is
used as the dynamic address.
* Emit OF and ACPI modaliases for firmware-matched I3C devices.
* Make the DesignWare core clock optional and use "clock-frequency" as
the fallback when core_clk is absent.
* Keep DesignWare pclk, reset, and match-data handling on their existing
optional paths.
v3->v4:
* Clarify mipi-i3c-static-method bit semantics and assigned-address
* Add I3C_ADDR_METHOD_VENDOR
* Fix fwnode reference handling while converting child property parsing
to use unified firmware-node APIs.
* Align ACPI child enumeration with the I2C core for multiple
I2cSerialBus resources, ignore ACPI child entries without an I2C
resource, and populate I2C modalias information from ACPI.
* Update SETAASA handling to use the static address as the dynamic
address, skip device-info retrieval for SETAASA devices, and tolerate
M2 for SETHID/SETAASA similarly to ENTDAA.
* Reorder DesignWare I3C clock/reset to include optional clock in the
ACPI skip clock/reset quirk.
* Add prints for missing ACPI clock-frequency and SPD5118 I3C
device type read failures.
* Fix grammar in comments and commit messages.
v2->v3:
* Fix maximum value and indent bit list for mipi-i3c-static-method.
* Move I3C_ADDR_METHOD_* macros to dt-bindings header.
* Drop ACPICA commit IDs, keep only the Link: tags.
* Revert the change which proceeds to register other devices if SETAASA
is not supported so that it aligns with the rest of the driver and to
avoid the issues pointed by Sashiko.
* Rework multiple commit messages.
v1->v2:
* Added patch to remove 16-bit addressing support for SPD5118
* Guard ACPI calls with #ifdef CONFIG_ACPI
* Remove CONFIG_OF guard for of_alias_get_highest_id()
* Mask mipi-i3c-static-method in the driver to select only valid values.
* Proceed to register other devices if SETAASA is not supported.
* Update commit message and links in the description of multiple commits.
Akhil R (12):
dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA
i3c: master: Use unified device property interface
i3c: master: Support ACPI enumeration of child devices
i3c: master: Add support for devices using SETAASA
i3c: master: Add support for devices without PID
i3c: master: match I3C device through DT and ACPI
i3c: dw-i3c-master: Add SETAASA as supported CCC
i3c: dw-i3c-master: Add ACPI core clock frequency quirk
i3c: dw-i3c-master: Add ACPI ID for Tegra410
hwmon: spd5118: Remove 16-bit addressing
hwmon: spd5118: Add I3C support
arm64: defconfig: Enable I3C and SPD5118 hwmon
.../devicetree/bindings/i3c/i3c.yaml | 36 +-
arch/arm64/configs/defconfig | 3 +
drivers/hwmon/Kconfig | 9 +-
drivers/hwmon/spd5118.c | 119 +++---
drivers/i3c/master.c | 390 +++++++++++++++---
drivers/i3c/master/dw-i3c-master.c | 59 ++-
include/dt-bindings/i3c/i3c.h | 4 +
include/linux/i3c/ccc.h | 1 +
include/linux/i3c/master.h | 20 +-
9 files changed, 498 insertions(+), 143 deletions(-)
base-commit: 6eb8711ece2ce27e52e327a5b7a628ed39b97f45
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v6 01/12] dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:16 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 02/12] i3c: master: Use unified device property interface Akhil R
` (11 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Add the 'mipi-i3c-static-method' property mentioned in the MIPI I3C
Discovery and Configuration Specification [1] to specify which discovery
method an I3C device supports during bus initialization. The property is
a bitmap, where a bit value of 1 indicates support for that method, and 0
indicates lack of support.
Bit 0: SETDASA CCC (Direct)
Bit 1: SETAASA CCC (Broadcast)
Bit 2: Other CCC (vendor / standards extension)
All other bits are reserved.
It is specifically needed when an I3C device requires SETAASA for the
address assignment. SETDASA will be supported by default if this property
is absent, which means for now the property just serves as a flag to
enable SETAASA, but keep the property as a bitmap to align with the
specifications.
[1] https://www.mipi.org/mipi-disco-for-i3c-download
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
.../devicetree/bindings/i3c/i3c.yaml | 36 ++++++++++++++++---
include/dt-bindings/i3c/i3c.h | 4 +++
2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/i3c/i3c.yaml b/Documentation/devicetree/bindings/i3c/i3c.yaml
index e25fa72fd785..5603f2e7807d 100644
--- a/Documentation/devicetree/bindings/i3c/i3c.yaml
+++ b/Documentation/devicetree/bindings/i3c/i3c.yaml
@@ -31,10 +31,12 @@ properties:
described in the device tree, which in turn means we have to describe
I3C devices.
- Another use case for describing an I3C device in the device tree is when
- this I3C device has a static I2C address and we want to assign it a
- specific I3C dynamic address before the DAA takes place (so that other
- devices on the bus can't take this dynamic address).
+ Other use-cases for describing an I3C device in the device tree are:
+ - When the I3C device has a static I2C address and we want to assign
+ it a specific I3C dynamic address before the DAA takes place (so
+ that other devices on the bus can't take this dynamic address).
+ - When the I3C device requires SETAASA for its discovery and uses a
+ pre-defined static address.
"#size-cells":
const: 0
@@ -145,7 +147,31 @@ patternProperties:
Dynamic address to be assigned to this device. In case static address is
present (first cell of the reg property != 0), this address is assigned
through SETDASA. If static address is not present, this address is assigned
- through SETNEWDA after assigning a temporary address via ENTDAA.
+ through SETNEWDA after assigning a temporary address via ENTDAA. If
+ SETAASA is used, this property is not used, and the static address itself
+ becomes the dynamic address.
+
+ mipi-i3c-static-method:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0x1
+ maximum: 0x7
+ default: 1
+ description: |
+ Bitmap describing which methods of Dynamic Address Assignment from a
+ static address are supported by this I3C Target. For each defined bit
+ position, a set bit indicates support for that method and a cleared
+ bit indicates lack of support.
+
+ Bit 0: SETDASA CCC (Direct)
+ Bit 1: SETAASA CCC (Broadcast)
+ Bit 2: Other CCC (vendor / standards extension)
+ All other bits are reserved.
+
+ This property follows the MIPI I3C specification. The primary use
+ of this property is to indicate support for SETAASA, i.e Bit 1, but
+ will allow other values mentioned in the specification so that it
+ mirrors the specification. SETDASA will remain as the default method
+ even if this property is not present.
required:
- reg
diff --git a/include/dt-bindings/i3c/i3c.h b/include/dt-bindings/i3c/i3c.h
index 373439218bba..78b8c634aad8 100644
--- a/include/dt-bindings/i3c/i3c.h
+++ b/include/dt-bindings/i3c/i3c.h
@@ -13,4 +13,8 @@
#define I2C_NO_FILTER_HIGH_FREQUENCY (1 << 5)
#define I2C_NO_FILTER_LOW_FREQUENCY (2 << 5)
+#define I3C_ADDR_METHOD_SETDASA (1 << 0)
+#define I3C_ADDR_METHOD_SETAASA (1 << 1)
+#define I3C_ADDR_METHOD_VENDOR (1 << 2)
+
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 02/12] i3c: master: Use unified device property interface
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
2026-07-21 4:07 ` [PATCH v6 01/12] dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:25 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 03/12] i3c: master: Support ACPI enumeration of child devices Akhil R
` (10 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Replace all OF-specific functions with unified device property functions
as a prerequisite to support both ACPI and device tree.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/i3c/master.c | 77 +++++++++++++++++++++-----------------
include/linux/i3c/master.h | 5 ++-
2 files changed, 46 insertions(+), 36 deletions(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index f1be38a640ca..4b3d9628bc39 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -13,10 +13,12 @@
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/export.h>
+#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
@@ -491,7 +493,7 @@ static void i3c_bus_cleanup(struct i3c_bus *i3cbus)
mutex_unlock(&i3c_core_lock);
}
-static int i3c_bus_init(struct i3c_bus *i3cbus, struct device_node *np)
+static int i3c_bus_init(struct i3c_bus *i3cbus, struct fwnode_handle *fwnode)
{
int ret, start, end, id = -1;
@@ -501,8 +503,8 @@ static int i3c_bus_init(struct i3c_bus *i3cbus, struct device_node *np)
i3c_bus_init_addrslots(i3cbus);
i3cbus->mode = I3C_BUS_MODE_PURE;
- if (np)
- id = of_alias_get_id(np, "i3c");
+ if (fwnode && is_of_node(fwnode))
+ id = of_alias_get_id(to_of_node(fwnode), "i3c");
mutex_lock(&i3c_core_lock);
if (id >= 0) {
@@ -837,7 +839,7 @@ static void i3c_masterdev_release(struct device *dev)
WARN_ON(!list_empty(&bus->devs.i2c) || !list_empty(&bus->devs.i3c));
i3c_bus_cleanup(bus);
- of_node_put(dev->of_node);
+ fwnode_handle_put(dev->fwnode);
}
static const struct device_type i3c_masterdev_type = {
@@ -1044,7 +1046,7 @@ static void i3c_device_release(struct device *dev)
WARN_ON(i3cdev->desc);
- of_node_put(i3cdev->dev.of_node);
+ fwnode_handle_put(dev->fwnode);
kfree(i3cdev);
}
@@ -1928,7 +1930,7 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
desc->info.pid);
if (desc->boardinfo)
- desc->dev->dev.of_node = desc->boardinfo->of_node;
+ device_set_node(&desc->dev->dev, desc->boardinfo->fwnode);
ret = device_register(&desc->dev->dev);
if (ret) {
@@ -2620,8 +2622,8 @@ EXPORT_SYMBOL_GPL(i3c_master_do_daa);
#define OF_I3C_REG1_IS_I2C_DEV BIT(31)
static int
-of_i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
- struct device_node *node, u32 *reg)
+i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
+ struct fwnode_handle *fwnode, u32 *reg)
{
struct i2c_dev_boardinfo *boardinfo;
struct device *dev = &master->dev;
@@ -2631,9 +2633,13 @@ of_i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
if (!boardinfo)
return -ENOMEM;
- ret = of_i2c_get_board_info(dev, node, &boardinfo->base);
- if (ret)
- return ret;
+ if (is_of_node(fwnode)) {
+ ret = of_i2c_get_board_info(dev, to_of_node(fwnode), &boardinfo->base);
+ if (ret)
+ return ret;
+ } else {
+ return -EINVAL;
+ }
/*
* The I3C Specification does not clearly say I2C devices with 10-bit
@@ -2649,14 +2655,14 @@ of_i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
boardinfo->lvr = reg[2];
list_add_tail(&boardinfo->node, &master->boardinfo.i2c);
- of_node_get(node);
+ fwnode_handle_get(fwnode);
return 0;
}
static int
-of_i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
- struct device_node *node, u32 *reg)
+i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
+ struct fwnode_handle *fwnode, u32 *reg)
{
struct i3c_dev_boardinfo *boardinfo;
struct device *dev = &master->dev;
@@ -2679,7 +2685,7 @@ of_i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
boardinfo->static_addr = reg[0];
- if (!of_property_read_u32(node, "assigned-address", &init_dyn_addr)) {
+ if (!fwnode_property_read_u32(fwnode, "assigned-address", &init_dyn_addr)) {
if (init_dyn_addr > I3C_MAX_ADDR)
return -EINVAL;
@@ -2696,14 +2702,14 @@ of_i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
return -EINVAL;
boardinfo->init_dyn_addr = init_dyn_addr;
- boardinfo->of_node = of_node_get(node);
+ boardinfo->fwnode = fwnode_handle_get(fwnode);
list_add_tail(&boardinfo->node, &master->boardinfo.i3c);
return 0;
}
-static int of_i3c_master_add_dev(struct i3c_master_controller *master,
- struct device_node *node)
+static int i3c_master_add_dev(struct i3c_master_controller *master,
+ struct fwnode_handle *fwnode)
{
u32 reg[3];
int ret;
@@ -2711,7 +2717,7 @@ static int of_i3c_master_add_dev(struct i3c_master_controller *master,
if (!master)
return -EINVAL;
- ret = of_property_read_u32_array(node, "reg", reg, ARRAY_SIZE(reg));
+ ret = fwnode_property_read_u32_array(fwnode, "reg", reg, ARRAY_SIZE(reg));
if (ret)
return ret;
@@ -2720,25 +2726,25 @@ static int of_i3c_master_add_dev(struct i3c_master_controller *master,
* dealing with an I2C device.
*/
if (!reg[1])
- ret = of_i3c_master_add_i2c_boardinfo(master, node, reg);
+ ret = i3c_master_add_i2c_boardinfo(master, fwnode, reg);
else
- ret = of_i3c_master_add_i3c_boardinfo(master, node, reg);
+ ret = i3c_master_add_i3c_boardinfo(master, fwnode, reg);
return ret;
}
-static int of_populate_i3c_bus(struct i3c_master_controller *master)
+static int fwnode_populate_i3c_bus(struct i3c_master_controller *master)
{
struct device *dev = &master->dev;
- struct device_node *i3cbus_np = dev->of_node;
+ struct fwnode_handle *fwnode = dev_fwnode(dev);
int ret;
u32 val;
- if (!i3cbus_np)
+ if (!fwnode)
return 0;
- for_each_available_child_of_node_scoped(i3cbus_np, node) {
- ret = of_i3c_master_add_dev(master, node);
+ fwnode_for_each_available_child_node_scoped(fwnode, child) {
+ ret = i3c_master_add_dev(master, child);
if (ret)
return ret;
}
@@ -2748,10 +2754,10 @@ static int of_populate_i3c_bus(struct i3c_master_controller *master)
* on the bus are not supporting typical rates, or if the bus topology
* prevents it from using max possible rate.
*/
- if (!of_property_read_u32(i3cbus_np, "i2c-scl-hz", &val))
+ if (!device_property_read_u32(dev, "i2c-scl-hz", &val))
master->bus.scl_rate.i2c = val;
- if (!of_property_read_u32(i3cbus_np, "i3c-scl-hz", &val))
+ if (!device_property_read_u32(dev, "i3c-scl-hz", &val))
master->bus.scl_rate.i3c = val;
return 0;
@@ -2806,7 +2812,7 @@ static u8 i3c_master_i2c_get_lvr(struct i2c_client *client)
u8 lvr = I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE;
u32 reg[3];
- if (!of_property_read_u32_array(client->dev.of_node, "reg", reg, ARRAY_SIZE(reg)))
+ if (!fwnode_property_read_u32_array(client->dev.fwnode, "reg", reg, ARRAY_SIZE(reg)))
lvr = reg[2];
return lvr;
@@ -2925,7 +2931,8 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master);
struct i2c_dev_desc *i2cdev;
struct i2c_dev_boardinfo *i2cboardinfo;
- int ret, id;
+ struct fwnode_handle *fwnode = dev_fwnode(&master->dev);
+ int ret, id = -1;
adap->dev.parent = master->dev.parent;
adap->owner = master->dev.parent->driver->owner;
@@ -2934,7 +2941,9 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
adap->timeout = HZ;
adap->retries = 3;
- id = of_alias_get_id(master->dev.of_node, "i2c");
+ if (fwnode && is_of_node(fwnode))
+ id = of_alias_get_id(to_of_node(fwnode), "i2c");
+
if (id >= 0) {
adap->nr = id;
ret = i2c_add_numbered_adapter(adap);
@@ -3235,7 +3244,7 @@ int i3c_master_register(struct i3c_master_controller *master,
return ret;
master->dev.parent = parent;
- master->dev.of_node = of_node_get(parent->of_node);
+ device_set_node(&master->dev, fwnode_handle_get(dev_fwnode(parent)));
master->dev.bus = &i3c_bus_type;
master->dev.type = &i3c_masterdev_type;
master->dev.release = i3c_masterdev_release;
@@ -3254,13 +3263,13 @@ int i3c_master_register(struct i3c_master_controller *master,
master->dev.coherent_dma_mask = parent->coherent_dma_mask;
master->dev.dma_parms = parent->dma_parms;
- ret = i3c_bus_init(i3cbus, master->dev.of_node);
+ ret = i3c_bus_init(i3cbus, dev_fwnode(&master->dev));
if (ret)
goto err_put_dev;
dev_set_name(&master->dev, "i3c-%d", i3cbus->id);
- ret = of_populate_i3c_bus(master);
+ ret = fwnode_populate_i3c_bus(master);
if (ret)
goto err_put_dev;
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
index 4d2a68793324..a16deb04b2e1 100644
--- a/include/linux/i3c/master.h
+++ b/include/linux/i3c/master.h
@@ -177,7 +177,8 @@ struct i3c_device_ibi_info {
* @pid: I3C Provisioned ID exposed by the device. This is a unique identifier
* that may be used to attach boardinfo to i3c_dev_desc when the device
* does not have a static address
- * @of_node: optional DT node in case the device has been described in the DT
+ * @fwnode: Firmware node (DT or ACPI) in case the device has been
+ * described in firmware
*
* This structure is used to attach board-level information to an I3C device.
* Not all I3C devices connected on the bus will have a boardinfo. It's only
@@ -189,7 +190,7 @@ struct i3c_dev_boardinfo {
u8 init_dyn_addr;
u8 static_addr;
u64 pid;
- struct device_node *of_node;
+ struct fwnode_handle *fwnode;
};
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 03/12] i3c: master: Support ACPI enumeration of child devices
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
2026-07-21 4:07 ` [PATCH v6 01/12] dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA Akhil R
2026-07-21 4:07 ` [PATCH v6 02/12] i3c: master: Use unified device property interface Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:32 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 04/12] i3c: master: Add support for devices using SETAASA Akhil R
` (9 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Although the existing subsystem allows host controllers to register
through the ACPI table, it was not possible to describe I3C or I2C
devices when using ACPI. This is because the driver relied on the reg
property to retrieve the PID, static address, etc., whereas ACPI uses
_ADR or serial resources to describe such devices.
Read _ADR and LVR from ACPI resources and extract the data as per the
ACPI specification for an I3C bus. Also read mipi-i3c-static-address as
per the MIPI DISCO specifications [1] to get the static address to be
used.
Enable describing I3C or I2C devices in the ACPI table. This is required
if the device uses a static address or if it needs device-specific
properties.
[1] https://www.mipi.org/mipi-disco-for-i3c-download
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/i3c/master.c | 151 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 143 insertions(+), 8 deletions(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 4b3d9628bc39..623c6b2247d9 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -5,6 +5,7 @@
* Author: Boris Brezillon <boris.brezillon@bootlin.com>
*/
+#include <linux/acpi.h>
#include <linux/atomic.h>
#include <linux/bitmap.h>
#include <linux/bug.h>
@@ -2621,6 +2622,55 @@ EXPORT_SYMBOL_GPL(i3c_master_do_daa);
#define OF_I3C_REG1_IS_I2C_DEV BIT(31)
+#ifdef CONFIG_ACPI
+static int i3c_acpi_get_i2c_resource(struct acpi_resource *ares, void *data)
+{
+ struct i2c_dev_boardinfo *boardinfo = data;
+ struct acpi_resource_i2c_serialbus *sb;
+
+ if (boardinfo->base.addr || !i2c_acpi_get_i2c_resource(ares, &sb))
+ return 1;
+
+ boardinfo->base.addr = sb->slave_address;
+ if (sb->access_mode == ACPI_I2C_10BIT_MODE)
+ boardinfo->base.flags |= I2C_CLIENT_TEN;
+
+ boardinfo->lvr = sb->lvr;
+
+ return 1;
+}
+
+static int i3c_acpi_add_i2c_boardinfo(struct i2c_dev_boardinfo *boardinfo,
+ struct fwnode_handle *fwnode)
+{
+ struct acpi_device *adev = to_acpi_device_node(fwnode);
+ LIST_HEAD(resources);
+ int ret;
+
+ boardinfo->base.fwnode = acpi_fwnode_handle(adev);
+ acpi_set_modalias(adev, dev_name(&adev->dev), boardinfo->base.type,
+ sizeof(boardinfo->base.type));
+
+ ret = acpi_dev_get_resources(adev, &resources,
+ i3c_acpi_get_i2c_resource, boardinfo);
+ if (ret < 0)
+ return ret;
+
+ acpi_dev_free_resource_list(&resources);
+
+ if (!boardinfo->base.addr)
+ return -ENODEV;
+
+ return 0;
+}
+#else
+static inline int i3c_acpi_add_i2c_boardinfo(struct i2c_dev_boardinfo *boardinfo,
+ struct fwnode_handle *fwnode)
+{
+ return -ENODEV;
+}
+#endif
+
static int
i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
struct fwnode_handle *fwnode, u32 *reg)
@@ -2637,6 +2687,15 @@ i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
ret = of_i2c_get_board_info(dev, to_of_node(fwnode), &boardinfo->base);
if (ret)
return ret;
+
+ /* LVR is encoded in reg[2] for Device Tree. */
+ boardinfo->lvr = reg[2];
+ } else if (is_acpi_device_node(fwnode)) {
+ ret = i3c_acpi_add_i2c_boardinfo(boardinfo, fwnode);
+ if (ret) {
+ devm_kfree(dev, boardinfo);
+ return ret;
+ }
} else {
return -EINVAL;
}
@@ -2651,9 +2710,6 @@ i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
return -EOPNOTSUPP;
}
- /* LVR is encoded in reg[2]. */
- boardinfo->lvr = reg[2];
-
list_add_tail(&boardinfo->node, &master->boardinfo.i2c);
fwnode_handle_get(fwnode);
@@ -2708,8 +2764,8 @@ i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
return 0;
}
-static int i3c_master_add_dev(struct i3c_master_controller *master,
- struct fwnode_handle *fwnode)
+static int i3c_master_add_of_dev(struct i3c_master_controller *master,
+ struct fwnode_handle *fwnode)
{
u32 reg[3];
int ret;
@@ -2733,6 +2789,74 @@ static int i3c_master_add_dev(struct i3c_master_controller *master,
return ret;
}
+#ifdef CONFIG_ACPI
+static int i3c_master_add_acpi_dev(struct i3c_master_controller *master,
+ struct fwnode_handle *fwnode)
+{
+ struct acpi_device *adev = to_acpi_device_node(fwnode);
+ acpi_bus_address adr;
+ u32 reg[3] = { 0 };
+ int ret;
+
+ /*
+ * If the ACPI table entry has _ADR method, it's an I3C device.
+ * Otherwise it may be an I2C device described by an I2cSerialBus
+ * resource. If no I2cSerialBus resource is found, ignore the entry.
+ */
+ if (!acpi_has_method(adev->handle, "_ADR")) {
+ ret = i3c_master_add_i2c_boardinfo(master, fwnode, reg);
+ if (ret == -ENODEV)
+ return 0;
+
+ return ret;
+ }
+
+ adr = acpi_device_adr(adev);
+
+ /* For I3C devices, _ADR will have the 48 bit PID of the device */
+ reg[1] = upper_32_bits(adr);
+ reg[2] = lower_32_bits(adr);
+
+ fwnode_property_read_u32(fwnode, "mipi-i3c-static-address", ®[0]);
+
+ return i3c_master_add_i3c_boardinfo(master, fwnode, reg);
+}
+
+static u8 i3c_acpi_i2c_get_lvr(struct i2c_client *client)
+{
+ struct acpi_device *adev = to_acpi_device_node(client->dev.fwnode);
+ struct i2c_dev_boardinfo boardinfo = {};
+ LIST_HEAD(resources);
+ int ret;
+ u8 lvr;
+
+ lvr = I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE;
+
+ ret = acpi_dev_get_resources(adev, &resources,
+ i3c_acpi_get_i2c_resource, &boardinfo);
+ if (ret < 0)
+ return lvr;
+
+ if (boardinfo.base.addr)
+ lvr = boardinfo.lvr;
+
+ acpi_dev_free_resource_list(&resources);
+
+ return lvr;
+}
+#else
+static inline int i3c_master_add_acpi_dev(struct i3c_master_controller *master,
+ struct fwnode_handle *fwnode)
+{
+ return -ENODEV;
+}
+
+static inline u8 i3c_acpi_i2c_get_lvr(struct i2c_client *client)
+{
+ return I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE;
+}
+#endif
+
static int fwnode_populate_i3c_bus(struct i3c_master_controller *master)
{
struct device *dev = &master->dev;
@@ -2744,7 +2868,13 @@ static int fwnode_populate_i3c_bus(struct i3c_master_controller *master)
return 0;
fwnode_for_each_available_child_node_scoped(fwnode, child) {
- ret = i3c_master_add_dev(master, child);
+ if (is_of_node(child))
+ ret = i3c_master_add_of_dev(master, child);
+ else if (is_acpi_device_node(child))
+ ret = i3c_master_add_acpi_dev(master, child);
+ else
+ continue;
+
if (ret)
return ret;
}
@@ -2812,8 +2942,13 @@ static u8 i3c_master_i2c_get_lvr(struct i2c_client *client)
u8 lvr = I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE;
u32 reg[3];
- if (!fwnode_property_read_u32_array(client->dev.fwnode, "reg", reg, ARRAY_SIZE(reg)))
- lvr = reg[2];
+ if (is_of_node(client->dev.fwnode)) {
+ if (!fwnode_property_read_u32_array(client->dev.fwnode, "reg",
+ reg, ARRAY_SIZE(reg)))
+ lvr = reg[2];
+ } else if (is_acpi_device_node(client->dev.fwnode)) {
+ lvr = i3c_acpi_i2c_get_lvr(client);
+ }
return lvr;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 04/12] i3c: master: Add support for devices using SETAASA
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (2 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 03/12] i3c: master: Support ACPI enumeration of child devices Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:30 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 05/12] i3c: master: Add support for devices without PID Akhil R
` (8 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Add support for devices using SETAASA, such as SPD5118 and SPD5108
attached to DDR5 memory modules that do not support ENTDAA. Follow the
guidelines proposed by the MIPI Discovery and Configuration
Specification [1] for discovering such devices.
SETAASA (Set All Addresses to Static Address) differs from standard I3C
address assignment that uses ENTDAA or SETDASA to assign dynamic
addresses. Devices using SETAASA assign their pre-defined static addresses
as their dynamic addresses during DAA, and it is not mandatory for these
devices to implement standard CCC commands like GETPID, GETDCR, or GETBCR.
For such devices, it is generally recommended to issue SETHID (specified
by JEDEC JESD300) as a prerequisite for SETAASA to stop HID bit flipping.
[1] https://www.mipi.org/mipi-disco-for-i3c-download
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/i3c/master.c | 98 +++++++++++++++++++++++++++++++++++++-
include/linux/i3c/ccc.h | 1 +
include/linux/i3c/master.h | 15 ++++++
3 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 623c6b2247d9..b18dda89c473 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -5,6 +5,7 @@
* Author: Boris Brezillon <boris.brezillon@bootlin.com>
*/
+#include <dt-bindings/i3c/i3c.h>
#include <linux/acpi.h>
#include <linux/atomic.h>
#include <linux/bitmap.h>
@@ -1102,6 +1103,51 @@ static int i3c_master_rstdaa_locked(struct i3c_master_controller *master,
return ret;
}
+/**
+ * i3c_master_setaasa_locked() - start a SETAASA procedure (Set All Addresses to Static Address)
+ * @master: I3C master object
+ *
+ * Send a SETAASA CCC command to set all attached I3C devices' dynamic addresses to
+ * their static address.
+ *
+ * This function must be called with the bus lock held in write mode.
+ *
+ * First, the SETHID CCC command is sent, followed by the SETAASA CCC.
+ *
+ * Return: 0 in case of success, a positive I3C error code if the error is
+ * one of the official Mx error codes, and a negative error code otherwise.
+ */
+static int i3c_master_setaasa_locked(struct i3c_master_controller *master)
+{
+ struct i3c_ccc_cmd_dest dest;
+ struct i3c_ccc_cmd cmd;
+ int ret;
+
+ /*
+ * Send SETHID CCC command. Though it is a standard CCC command specified
+ * in JESD300-5, we are not defining a separate macro to be explicit that
+ * the value falls under the vendor specific range.
+ */
+ i3c_ccc_cmd_dest_init(&dest, I3C_BROADCAST_ADDR, 0);
+ i3c_ccc_cmd_init(&cmd, false, I3C_CCC_VENDOR(0, true), &dest, 1);
+ ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
+ i3c_ccc_cmd_dest_cleanup(&dest);
+ if (ret && cmd.err == I3C_ERROR_M2)
+ ret = 0;
+ if (ret)
+ return ret;
+
+ /* Send SETAASA CCC command */
+ i3c_ccc_cmd_dest_init(&dest, I3C_BROADCAST_ADDR, 0);
+ i3c_ccc_cmd_init(&cmd, false, I3C_CCC_SETAASA, &dest, 1);
+ ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
+ i3c_ccc_cmd_dest_cleanup(&dest);
+ if (ret && cmd.err == I3C_ERROR_M2)
+ ret = 0;
+
+ return ret;
+}
+
/**
* i3c_master_entdaa_locked() - start a DAA (Dynamic Address Assignment)
* procedure
@@ -1878,6 +1924,22 @@ static int i3c_master_early_i3c_dev_add(struct i3c_master_controller *master,
if (ret)
goto err_free_dev;
+ /*
+ * For devices using SETAASA instead of ENTDAA, the address is statically
+ * assigned. Update the dynamic address to the provided static address.
+ * Reattach the I3C device after updating the dynamic address with the same
+ * static address. It is not mandatory for such devices to implement CCC
+ * commands like GETPID, GETDCR etc. Hence, we can return after reattaching.
+ */
+ if (i3cdev->boardinfo->static_addr_method & I3C_ADDR_METHOD_SETAASA) {
+ i3cdev->info.dyn_addr = i3cdev->boardinfo->static_addr;
+ ret = i3c_master_reattach_i3c_dev_locked(i3cdev, 0);
+ if (ret)
+ goto err_rstdaa;
+
+ return 0;
+ }
+
ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr,
i3cdev->boardinfo->init_dyn_addr);
if (ret)
@@ -2272,6 +2334,19 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
i3c_master_early_i3c_dev_add(master, i3cboardinfo);
}
+ /*
+ * SETAASA is a broadcast CCC. Issue it after SETDASA so that devices
+ * configured for SETDASA (or supporting both methods) are assigned
+ * first, matching MIPI DISCO guidance to prefer SETDASA when both are
+ * available. Targets that already have a dynamic address ignore the
+ * later SETAASA broadcast.
+ */
+ if (master->addr_method & I3C_ADDR_METHOD_SETAASA) {
+ ret = i3c_master_setaasa_locked(master);
+ if (ret)
+ goto err_rstdaa;
+ }
+
ret = i3c_master_do_daa(master);
if (ret)
goto err_rstdaa;
@@ -2723,7 +2798,7 @@ i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
struct i3c_dev_boardinfo *boardinfo;
struct device *dev = &master->dev;
enum i3c_addr_slot_status addrstatus;
- u32 init_dyn_addr = 0;
+ u32 init_dyn_addr = 0, static_addr_method = 0;
boardinfo = devm_kzalloc(dev, sizeof(*boardinfo), GFP_KERNEL);
if (!boardinfo)
@@ -2741,7 +2816,19 @@ i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
boardinfo->static_addr = reg[0];
+ if (!fwnode_property_read_u32(fwnode, "mipi-i3c-static-method", &static_addr_method))
+ boardinfo->static_addr_method = static_addr_method &
+ (I3C_ADDR_METHOD_SETDASA | I3C_ADDR_METHOD_SETAASA);
+
if (!fwnode_property_read_u32(fwnode, "assigned-address", &init_dyn_addr)) {
+ /*
+ * When a device advertises both SETDASA and SETAASA, an explicit
+ * dynamic address selects SETDASA (MIPI DISCO prefers it); drop
+ * SETAASA so it is not used for this device.
+ */
+ if (boardinfo->static_addr_method & I3C_ADDR_METHOD_SETDASA)
+ boardinfo->static_addr_method &= ~I3C_ADDR_METHOD_SETAASA;
+
if (init_dyn_addr > I3C_MAX_ADDR)
return -EINVAL;
@@ -2751,6 +2838,14 @@ i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
return -EINVAL;
}
+ if (boardinfo->static_addr_method & I3C_ADDR_METHOD_SETAASA) {
+ /* For SETAASA, static address is taken as the dynamic address. */
+ init_dyn_addr = boardinfo->static_addr;
+ }
+
+ /* Update the address methods required for device discovery */
+ master->addr_method |= boardinfo->static_addr_method;
+
boardinfo->pid = ((u64)reg[1] << 32) | reg[2];
if ((boardinfo->pid & GENMASK_ULL(63, 48)) ||
@@ -3385,6 +3480,7 @@ int i3c_master_register(struct i3c_master_controller *master,
master->dev.release = i3c_masterdev_release;
master->ops = ops;
master->secondary = secondary;
+ master->addr_method = I3C_ADDR_METHOD_SETDASA;
INIT_LIST_HEAD(&master->boardinfo.i2c);
INIT_LIST_HEAD(&master->boardinfo.i3c);
diff --git a/include/linux/i3c/ccc.h b/include/linux/i3c/ccc.h
index ad59a4ae60d1..a145d766ab6f 100644
--- a/include/linux/i3c/ccc.h
+++ b/include/linux/i3c/ccc.h
@@ -32,6 +32,7 @@
#define I3C_CCC_DEFSLVS I3C_CCC_ID(0x8, true)
#define I3C_CCC_ENTTM I3C_CCC_ID(0xb, true)
#define I3C_CCC_ENTHDR(x) I3C_CCC_ID(0x20 + (x), true)
+#define I3C_CCC_SETAASA I3C_CCC_ID(0x29, true)
/* Unicast-only commands */
#define I3C_CCC_SETDASA I3C_CCC_ID(0x7, false)
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
index a16deb04b2e1..2dc139a217bf 100644
--- a/include/linux/i3c/master.h
+++ b/include/linux/i3c/master.h
@@ -174,6 +174,14 @@ struct i3c_device_ibi_info {
* assigned a dynamic address by the master. Will be used during
* bus initialization to assign it a specific dynamic address
* before starting DAA (Dynamic Address Assignment)
+ * @static_addr_method: Bitmap describing which methods of Dynamic Address
+ * Assignment from a Static Address are supported by this I3C Target.
+ * A value of 1 in a bit position indicates that the I3C target
+ * supports that method, and a value of 0 indicates that the I3C
+ * target does not support that method.
+ * Bit 0: SETDASA
+ * Bit 1: SETAASA
+ * All other bits are reserved.
* @pid: I3C Provisioned ID exposed by the device. This is a unique identifier
* that may be used to attach boardinfo to i3c_dev_desc when the device
* does not have a static address
@@ -189,6 +197,7 @@ struct i3c_dev_boardinfo {
struct list_head node;
u8 init_dyn_addr;
u8 static_addr;
+ u8 static_addr_method;
u64 pid;
struct fwnode_handle *fwnode;
};
@@ -517,6 +526,11 @@ struct i3c_master_controller_ops {
* @boardinfo.i2c: list of I2C boardinfo objects
* @boardinfo: board-level information attached to devices connected on the bus
* @bus: I3C bus exposed by this master
+ * @addr_method: Bitmap describing which methods of Address Assignment required
+ * to be run for discovering all the devices on the bus.
+ * Bit 0: SETDASA
+ * Bit 1: SETAASA
+ * All other bits are reserved.
* @wq: freezable workqueue which can be used by master
* drivers if they need to postpone operations that need to take place
* in a thread context. Typical examples are Hot Join processing which
@@ -552,6 +566,7 @@ struct i3c_master_controller {
struct list_head i2c;
} boardinfo;
struct i3c_bus bus;
+ u8 addr_method;
struct workqueue_struct *wq;
struct work_struct hj_work;
struct work_struct reg_work;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 05/12] i3c: master: Add support for devices without PID
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (3 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 04/12] i3c: master: Add support for devices using SETAASA Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:26 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 06/12] i3c: master: match I3C device through DT and ACPI Akhil R
` (7 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Devices using SETAASA for address assignment are not required to have
a 48-bit PID according to the I3C specification. Allow such devices to
register and use the static address where PID was required.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/i3c/master.c | 52 ++++++++++++++++++++++++++++++++++----------
1 file changed, 41 insertions(+), 11 deletions(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index b18dda89c473..7b2f819bf443 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -1989,8 +1989,17 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
desc->dev->dev.type = &i3c_device_type;
desc->dev->dev.bus = &i3c_bus_type;
desc->dev->dev.release = i3c_device_release;
- dev_set_name(&desc->dev->dev, "%d-%llx", master->bus.id,
- desc->info.pid);
+
+ /*
+ * For devices without PID (e.g., SETAASA devices), use
+ * static address for naming instead.
+ */
+ if (desc->info.pid)
+ dev_set_name(&desc->dev->dev, "%d-%llx", master->bus.id,
+ desc->info.pid);
+ else
+ dev_set_name(&desc->dev->dev, "%d-%02x", master->bus.id,
+ desc->info.static_addr);
if (desc->boardinfo)
device_set_node(&desc->dev->dev, desc->boardinfo->fwnode);
@@ -2389,8 +2398,18 @@ static void i3c_master_attach_boardinfo(struct i3c_dev_desc *i3cdev)
struct i3c_dev_boardinfo *i3cboardinfo;
list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) {
- if (i3cdev->info.pid != i3cboardinfo->pid)
- continue;
+ /*
+ * For devices without PID (e.g., SETAASA devices), match by
+ * static address. For devices with PID, match by PID.
+ */
+ if (i3cboardinfo->pid) {
+ if (i3cdev->info.pid != i3cboardinfo->pid)
+ continue;
+ } else {
+ if (!i3cboardinfo->static_addr ||
+ i3cdev->info.static_addr != i3cboardinfo->static_addr)
+ continue;
+ }
i3cdev->boardinfo = i3cboardinfo;
i3cdev->info.static_addr = i3cboardinfo->static_addr;
@@ -2404,8 +2423,12 @@ i3c_master_search_i3c_dev_duplicate(struct i3c_dev_desc *refdev)
struct i3c_master_controller *master = i3c_dev_get_master(refdev);
struct i3c_dev_desc *i3cdev;
+ if (!refdev->info.pid)
+ return NULL;
+
i3c_bus_for_each_i3cdev(&master->bus, i3cdev) {
- if (i3cdev != refdev && i3cdev->info.pid == refdev->info.pid)
+ if (i3cdev != refdev && i3cdev->info.pid &&
+ i3cdev->info.pid == refdev->info.pid)
return i3cdev;
}
@@ -2848,9 +2871,16 @@ i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
boardinfo->pid = ((u64)reg[1] << 32) | reg[2];
- if ((boardinfo->pid & GENMASK_ULL(63, 48)) ||
- I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
- return -EINVAL;
+ /* For SETAASA devices, validate the static address instead of PID */
+ if (boardinfo->static_addr_method & I3C_ADDR_METHOD_SETAASA) {
+ if (!boardinfo->static_addr)
+ return -EINVAL;
+ } else {
+ if (!boardinfo->pid ||
+ (boardinfo->pid & GENMASK_ULL(63, 48)) ||
+ I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
+ return -EINVAL;
+ }
boardinfo->init_dyn_addr = init_dyn_addr;
boardinfo->fwnode = fwnode_handle_get(fwnode);
@@ -2873,10 +2903,10 @@ static int i3c_master_add_of_dev(struct i3c_master_controller *master,
return ret;
/*
- * The manufacturer ID can't be 0. If reg[1] == 0 that means we're
- * dealing with an I2C device.
+ * I3C device should have either the manufacturer ID specified or the
+ * address discovery method specified. Else treat it as an I2C device.
*/
- if (!reg[1])
+ if (!reg[1] && !fwnode_property_present(fwnode, "mipi-i3c-static-method"))
ret = i3c_master_add_i2c_boardinfo(master, fwnode, reg);
else
ret = i3c_master_add_i3c_boardinfo(master, fwnode, reg);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 06/12] i3c: master: match I3C device through DT and ACPI
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (4 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 05/12] i3c: master: Add support for devices without PID Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:25 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 07/12] i3c: dw-i3c-master: Add SETAASA as supported CCC Akhil R
` (6 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
SETAASA-based devices cannot always be identified by PID or DCR; the
standard I3C id_table matching may not be applicable. Allow such devices to
match through Device Tree or ACPI.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/i3c/master.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 7b2f819bf443..43bf530bc661 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/slab.h>
@@ -345,15 +346,32 @@ static int i3c_device_match(struct device *dev, const struct device_driver *drv)
{
struct i3c_device *i3cdev;
const struct i3c_driver *i3cdrv;
+ u8 static_addr_method = 0;
if (dev->type != &i3c_device_type)
return 0;
i3cdev = dev_to_i3cdev(dev);
i3cdrv = drv_to_i3cdrv(drv);
- if (i3c_device_match_id(i3cdev, i3cdrv->id_table))
+
+ if (i3cdev->desc && i3cdev->desc->boardinfo)
+ static_addr_method = i3cdev->desc->boardinfo->static_addr_method;
+
+ /*
+ * SETAASA-based devices need not always have a matching ID since
+ * it is not mandatory for such devices to implement deviceinfo
+ * CCC commands. Allow them to register through DT or ACPI.
+ */
+ if (i3cdrv->id_table && i3c_device_match_id(i3cdev, i3cdrv->id_table))
return 1;
+ if (static_addr_method & I3C_ADDR_METHOD_SETAASA) {
+ if (of_driver_match_device(dev, drv))
+ return 1;
+ if (acpi_driver_match_device(dev, drv))
+ return 1;
+ }
+
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 07/12] i3c: dw-i3c-master: Add SETAASA as supported CCC
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (5 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 06/12] i3c: master: match I3C device through DT and ACPI Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:24 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 08/12] i3c: dw-i3c-master: Add ACPI core clock frequency quirk Akhil R
` (5 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Add SETAASA and SETHID to the supported list of CCC commands for
DesignWare I3C host controller.
SETAASA is a broadcast command that assigns predefined static addresses
to all I3C devices on the bus.
SETHID is to stop HID bit flipping by the SPD Hub to which the SPD devices
are connected. It is a prerequisite command to be sent before SETAASA as
recommended by JESD300-5 and JESD403 sideband bus specifications.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/i3c/master/dw-i3c-master.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 2f8c0c4683e0..29030fd9594a 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -309,6 +309,8 @@ static bool dw_i3c_master_supports_ccc_cmd(struct i3c_master_controller *m,
case I3C_CCC_GETSTATUS:
case I3C_CCC_GETMXDS:
case I3C_CCC_GETHDRCAP:
+ case I3C_CCC_SETAASA:
+ case I3C_CCC_VENDOR(0, true): /* SETHID */
return true;
default:
return false;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 08/12] i3c: dw-i3c-master: Add ACPI core clock frequency quirk
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (6 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 07/12] i3c: dw-i3c-master: Add SETAASA as supported CCC Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:26 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 09/12] i3c: dw-i3c-master: Add ACPI ID for Tegra410 Akhil R
` (4 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Some ACPI-enumerated devices like Tegra410 do not expose the controller
core clock through the clk framework. Unlike device tree, ACPI on Arm does
not model clock providers. The hardware is expected to have its clocks
enabled by firmware before the OS takes over.
Make the core clock optional and allow selected ACPI devices to provide the
core clock rate through the "clock-frequency" _DSD property when the core
clock is absent.
Resolve device quirks before acquiring the core clock so platforms without
the ACPI skip-clock quirk still fail probe immediately when the clock is
missing, before any MMIO access.
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/i3c/master/dw-i3c-master.c | 50 +++++++++++++++++++++++-------
1 file changed, 38 insertions(+), 12 deletions(-)
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 29030fd9594a..3ec3ab1c13b4 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -242,6 +242,7 @@
/* List of quirks */
#define AMD_I3C_OD_PP_TIMING BIT(1)
#define DW_I3C_DISABLE_RUNTIME_PM_QUIRK BIT(2)
+#define DW_I3C_ACPI_SKIP_CLK_RST BIT(3)
struct dw_i3c_cmd {
u32 cmd_lo;
@@ -556,13 +557,33 @@ static void dw_i3c_master_set_intr_regs(struct dw_i3c_master *master)
writel(IBI_REQ_REJECT_ALL, master->regs + IBI_MR_REQ_REJECT);
}
+static unsigned long dw_i3c_master_get_core_rate(struct dw_i3c_master *master)
+{
+ unsigned int core_rate_prop;
+
+ if (master->core_clk)
+ return clk_get_rate(master->core_clk);
+
+ if (!(master->quirks & DW_I3C_ACPI_SKIP_CLK_RST)) {
+ dev_err(master->dev, "missing core clock\n");
+ return 0;
+ }
+
+ if (device_property_read_u32(master->dev, "clock-frequency", &core_rate_prop)) {
+ dev_err(master->dev, "missing clock-frequency property\n");
+ return 0;
+ }
+
+ return core_rate_prop;
+}
+
static int dw_i3c_clk_cfg(struct dw_i3c_master *master)
{
unsigned long core_rate, core_period;
u32 scl_timing;
u8 hcnt, lcnt;
- core_rate = clk_get_rate(master->core_clk);
+ core_rate = dw_i3c_master_get_core_rate(master);
if (!core_rate)
return -EINVAL;
@@ -615,7 +636,7 @@ static int dw_i2c_clk_cfg(struct dw_i3c_master *master)
u16 hcnt, lcnt;
u32 scl_timing;
- core_rate = clk_get_rate(master->core_clk);
+ core_rate = dw_i3c_master_get_core_rate(master);
if (!core_rate)
return -EINVAL;
@@ -1573,14 +1594,28 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
master->dev = &pdev->dev;
+ if (has_acpi_companion(&pdev->dev)) {
+ quirks = (unsigned long)device_get_match_data(&pdev->dev);
+ } else if (pdev->dev.of_node) {
+ drvdata = device_get_match_data(&pdev->dev);
+ if (drvdata)
+ quirks = drvdata->flags;
+ }
+ master->quirks = quirks;
+
master->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(master->regs))
return PTR_ERR(master->regs);
- master->core_clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ master->core_clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
if (IS_ERR(master->core_clk))
return PTR_ERR(master->core_clk);
+ if (!master->core_clk && !(master->quirks & DW_I3C_ACPI_SKIP_CLK_RST)) {
+ dev_err(&pdev->dev, "missing core clock\n");
+ return -EINVAL;
+ }
+
master->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk");
if (IS_ERR(master->pclk))
return PTR_ERR(master->pclk);
@@ -1636,15 +1671,6 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
master->has_ibi_data = true;
writel(thld_ctrl, master->regs + QUEUE_THLD_CTRL);
- if (has_acpi_companion(&pdev->dev)) {
- quirks = (unsigned long)device_get_match_data(&pdev->dev);
- } else if (pdev->dev.of_node) {
- drvdata = device_get_match_data(&pdev->dev);
- if (drvdata)
- quirks = drvdata->flags;
- }
- master->quirks = quirks;
-
/* Keep controller enabled by preventing runtime suspend */
if (master->quirks & DW_I3C_DISABLE_RUNTIME_PM_QUIRK)
pm_runtime_get_noresume(&pdev->dev);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 09/12] i3c: dw-i3c-master: Add ACPI ID for Tegra410
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (7 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 08/12] i3c: dw-i3c-master: Add ACPI core clock frequency quirk Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:22 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 10/12] hwmon: spd5118: Remove 16-bit addressing Akhil R
` (3 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Update variable names to generic names and add Tegra410 ACPI ID to
support the I3C controller in Tegra410, which is a DesignWare I3C host
controller.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/i3c/master/dw-i3c-master.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 3ec3ab1c13b4..efe37f5224c7 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -1860,11 +1860,12 @@ static const struct of_device_id dw_i3c_master_of_match[] = {
};
MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
-static const struct acpi_device_id amd_i3c_device_match[] = {
+static const struct acpi_device_id dw_i3c_master_acpi_match[] = {
{ "AMDI0015", AMD_I3C_OD_PP_TIMING },
+ { "NVDA2018", DW_I3C_ACPI_SKIP_CLK_RST },
{ }
};
-MODULE_DEVICE_TABLE(acpi, amd_i3c_device_match);
+MODULE_DEVICE_TABLE(acpi, dw_i3c_master_acpi_match);
static struct platform_driver dw_i3c_driver = {
.probe = dw_i3c_probe,
@@ -1873,7 +1874,7 @@ static struct platform_driver dw_i3c_driver = {
.driver = {
.name = "dw-i3c-master",
.of_match_table = dw_i3c_master_of_match,
- .acpi_match_table = amd_i3c_device_match,
+ .acpi_match_table = dw_i3c_master_acpi_match,
.pm = &dw_i3c_pm_ops,
},
};
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 10/12] hwmon: spd5118: Remove 16-bit addressing
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (8 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 09/12] i3c: dw-i3c-master: Add ACPI ID for Tegra410 Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:25 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 11/12] hwmon: spd5118: Add I3C support Akhil R
` (2 subsequent siblings)
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
The intent of introducing 16-bit addressing was to support I3C, but it
turns out that I3C does not require reading the Legacy Mode register,
nor any specific encoding for page translation. The testing of 16-bit
code was limited and there are no known users for this feature. Remove
the sections that support 16-bit addressing and prepare the driver to
support I3C appropriately.
Suggested-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/hwmon/spd5118.c | 79 +++--------------------------------------
1 file changed, 5 insertions(+), 74 deletions(-)
diff --git a/drivers/hwmon/spd5118.c b/drivers/hwmon/spd5118.c
index cc40661cab21..6ba37a719300 100644
--- a/drivers/hwmon/spd5118.c
+++ b/drivers/hwmon/spd5118.c
@@ -66,9 +66,6 @@ static const unsigned short normal_i2c[] = {
#define SPD5118_EEPROM_BASE 0x80
#define SPD5118_EEPROM_SIZE (SPD5118_PAGE_SIZE * SPD5118_NUM_PAGES)
-#define PAGE_ADDR0(page) (((page) & BIT(0)) << 6)
-#define PAGE_ADDR1_4(page) (((page) & GENMASK(4, 1)) >> 1)
-
/* Temperature unit in millicelsius */
#define SPD5118_TEMP_UNIT (MILLIDEGREE_PER_DEGREE / 4)
/* Representable temperature range in millicelsius */
@@ -78,7 +75,6 @@ static const unsigned short normal_i2c[] = {
struct spd5118_data {
struct regmap *regmap;
struct mutex nvmem_lock;
- bool is_16bit;
};
/* hwmon */
@@ -348,12 +344,7 @@ static ssize_t spd5118_nvmem_read_page(struct spd5118_data *data, char *buf,
if (offset + count > SPD5118_PAGE_SIZE)
count = SPD5118_PAGE_SIZE - offset;
- if (data->is_16bit) {
- addr = SPD5118_EEPROM_BASE | PAGE_ADDR0(page) |
- (PAGE_ADDR1_4(page) << 8);
- } else {
- addr = page * 0x100 + SPD5118_EEPROM_BASE;
- }
+ addr = page * 0x100 + SPD5118_EEPROM_BASE;
err = regmap_bulk_read(regmap, addr + offset, buf, count);
if (err)
return err;
@@ -473,15 +464,6 @@ static const struct regmap_config spd5118_regmap8_config = {
.num_ranges = ARRAY_SIZE(spd5118_i2c_regmap_range_cfg),
};
-static const struct regmap_config spd5118_regmap16_config = {
- .reg_bits = 16,
- .val_bits = 8,
- .max_register = 0x7ff,
- .writeable_reg = spd5118_writeable_reg,
- .volatile_reg = spd5118_volatile_reg,
- .cache_type = REGCACHE_MAPLE,
-};
-
static int spd5118_suspend(struct device *dev)
{
struct spd5118_data *data = dev_get_drvdata(dev);
@@ -519,8 +501,7 @@ static int spd5118_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(spd5118_pm_ops, spd5118_suspend, spd5118_resume);
-static int spd5118_common_probe(struct device *dev, struct regmap *regmap,
- bool is_16bit)
+static int spd5118_common_probe(struct device *dev, struct regmap *regmap)
{
unsigned int capability, revision, vendor, bank;
struct spd5118_data *data;
@@ -537,8 +518,6 @@ static int spd5118_common_probe(struct device *dev, struct regmap *regmap,
if (!(capability & SPD5118_CAP_TS_SUPPORT))
return -ENODEV;
- data->is_16bit = is_16bit;
-
err = regmap_read(regmap, SPD5118_REG_REVISION, &revision);
if (err)
return err;
@@ -680,69 +659,21 @@ static int spd5118_i2c_init(struct i2c_client *client)
return 0;
}
-/*
- * 16-bit addressing note:
- *
- * If I2C_FUNC_I2C is not supported by an I2C adapter driver, regmap uses
- * SMBus operations as alternative. To simulate a read operation with a 16-bit
- * address, it writes the address using i2c_smbus_write_byte_data(), followed
- * by one or more calls to i2c_smbus_read_byte() to read the data.
- * Per spd5118 standard, a read operation after writing the address must start
- * with <Sr> (Repeat Start). However, a SMBus read byte operation starts with
- * <S> (Start). This resets the register address in the spd5118 chip. As result,
- * i2c_smbus_read_byte() always returns data from register address 0x00.
- *
- * A working alternative to access chips with 16-bit register addresses in the
- * absence of I2C_FUNC_I2C support is not known.
- *
- * For this reason, 16-bit addressing can only be supported with I2C if the
- * adapter supports I2C_FUNC_I2C.
- *
- * For I2C, the addressing mode selected by the BIOS must not be changed.
- * Experiments show that at least some PC BIOS versions will not change the
- * addressing mode on a soft reboot and end up in setup, claiming that some
- * configuration change happened. This will happen again after a power cycle,
- * which does reset the addressing mode. To prevent this from happening,
- * detect if 16-bit addressing is enabled and always use the currently
- * configured addressing mode.
- */
-
static int spd5118_i2c_probe(struct i2c_client *client)
{
- const struct regmap_config *config;
struct device *dev = &client->dev;
struct regmap *regmap;
- int err, mode;
- bool is_16bit;
+ int err;
err = spd5118_i2c_init(client);
if (err)
return err;
- mode = i2c_smbus_read_byte_data(client, SPD5118_REG_I2C_LEGACY_MODE);
- if (mode < 0)
- return mode;
-
- is_16bit = mode & SPD5118_LEGACY_MODE_ADDR;
- if (is_16bit) {
- /*
- * See 16-bit addressing note above explaining why it is
- * necessary to check for I2C_FUNC_I2C support here.
- */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- dev_err(dev, "Adapter does not support 16-bit register addresses\n");
- return -ENODEV;
- }
- config = &spd5118_regmap16_config;
- } else {
- config = &spd5118_regmap8_config;
- }
-
- regmap = devm_regmap_init_i2c(client, config);
+ regmap = devm_regmap_init_i2c(client, &spd5118_regmap8_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "regmap init failed\n");
- return spd5118_common_probe(dev, regmap, is_16bit);
+ return spd5118_common_probe(dev, regmap);
}
static const struct i2c_device_id spd5118_i2c_id[] = {
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 11/12] hwmon: spd5118: Add I3C support
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (9 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 10/12] hwmon: spd5118: Remove 16-bit addressing Akhil R
@ 2026-07-21 4:07 ` Akhil R
2026-07-21 4:35 ` sashiko-bot
2026-07-21 4:08 ` [PATCH v6 12/12] arm64: defconfig: Enable I3C and SPD5118 hwmon Akhil R
2026-07-21 16:52 ` [PATCH v6 00/12] Support ACPI and SETAASA device discovery Frank Li
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:07 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Add a regmap config and a probe function to support I3C-based
communication with SPD5118 devices.
On an I3C bus, SPD5118 devices are enumerated via SETAASA and always
require an ACPI or device tree entry. Device matching is hence through
the OF match tables only and does not need an I3C class match table. The
device identity is verified in the type registers before proceeding to
the common probe function.
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
drivers/hwmon/Kconfig | 9 ++++---
drivers/hwmon/spd5118.c | 56 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index b2e445b5536e..d9feba036ba4 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2370,12 +2370,15 @@ config SENSORS_INA3221
config SENSORS_SPD5118
tristate "SPD5118 Compliant Temperature Sensors"
- depends on I2C
+ depends on I3C_OR_I2C
select REGMAP_I2C
+ select REGMAP_I3C if I3C
help
If you say yes here you get support for SPD5118 (JEDEC JESD300)
- compliant temperature sensors. Such sensors are found on DDR5 memory
- modules.
+ compliant temperature sensors using I2C or I3C bus interface.
+ Such sensors are found on DDR5 memory modules.
+
+ This driver supports both I2C and I3C interfaces.
This driver can also be built as a module. If so, the module
will be called spd5118.
diff --git a/drivers/hwmon/spd5118.c b/drivers/hwmon/spd5118.c
index 6ba37a719300..9724cf70b61d 100644
--- a/drivers/hwmon/spd5118.c
+++ b/drivers/hwmon/spd5118.c
@@ -18,6 +18,7 @@
#include <linux/bits.h>
#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/i3c/device.h>
#include <linux/hwmon.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -464,6 +465,27 @@ static const struct regmap_config spd5118_regmap8_config = {
.num_ranges = ARRAY_SIZE(spd5118_i2c_regmap_range_cfg),
};
+/*
+ * SPD5118 2-byte register address format (JESD300-5, Tables 7 & 20):
+ * Byte 1 (on wire first): MemReg | BlkAddr[0] | Address[5:0]
+ * Byte 2 (on wire second): 0000 | BlkAddr[4:1]
+ *
+ * The address byte (with MemReg and lower address bits) must be sent first,
+ * followed by the upper block address byte. With regmap 16-bit register
+ * format, this maps to little-endian: the low byte of the 16-bit value is
+ * transmitted first. No range config is needed since I3C does not use MR11
+ * page switching.
+ */
+static const struct regmap_config spd5118_regmap_i3c_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0x7ff,
+ .reg_format_endian = REGMAP_ENDIAN_LITTLE,
+ .writeable_reg = spd5118_writeable_reg,
+ .volatile_reg = spd5118_volatile_reg,
+ .cache_type = REGCACHE_MAPLE,
+};
+
static int spd5118_suspend(struct device *dev)
{
struct spd5118_data *data = dev_get_drvdata(dev);
@@ -701,7 +723,39 @@ static struct i2c_driver spd5118_i2c_driver = {
.address_list = IS_ENABLED(CONFIG_SENSORS_SPD5118_DETECT) ? normal_i2c : NULL,
};
-module_i2c_driver(spd5118_i2c_driver);
+/* I3C */
+
+static int spd5118_i3c_probe(struct i3c_device *i3cdev)
+{
+ struct device *dev = i3cdev_to_dev(i3cdev);
+ struct regmap *regmap;
+ u8 regval[2];
+ int err;
+
+ regmap = devm_regmap_init_i3c(i3cdev, &spd5118_regmap_i3c_config);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap), "regmap init failed\n");
+
+ err = regmap_bulk_read(regmap, SPD5118_REG_TYPE, regval, 2);
+ if (err)
+ return dev_err_probe(dev, err, "failed to read device type\n");
+
+ if (regval[0] != 0x51 || regval[1] != 0x18)
+ return -ENODEV;
+
+ return spd5118_common_probe(dev, regmap);
+}
+
+static struct i3c_driver spd5118_i3c_driver = {
+ .driver = {
+ .name = "spd5118_i3c",
+ .of_match_table = spd5118_of_ids,
+ .pm = pm_sleep_ptr(&spd5118_pm_ops),
+ },
+ .probe = spd5118_i3c_probe,
+};
+
+module_i3c_i2c_driver(spd5118_i3c_driver, &spd5118_i2c_driver);
MODULE_AUTHOR("René Rebe <rene@exactcode.de>");
MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 12/12] arm64: defconfig: Enable I3C and SPD5118 hwmon
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (10 preceding siblings ...)
2026-07-21 4:07 ` [PATCH v6 11/12] hwmon: spd5118: Add I3C support Akhil R
@ 2026-07-21 4:08 ` Akhil R
2026-07-21 4:28 ` sashiko-bot
2026-07-21 16:52 ` [PATCH v6 00/12] Support ACPI and SETAASA device discovery Frank Li
12 siblings, 1 reply; 26+ messages in thread
From: Akhil R @ 2026-07-21 4:08 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Frank Li, Miquel Raynal, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Guenter Roeck, Philipp Zabel, Jon Hunter,
Thierry Reding, linux-i3c, devicetree, linux-hwmon, linux-tegra,
linux-kernel, Akhil R
Enable I3C subsystem (I3C), Synopsys DesignWare I3C master controller
(DW_I3C_MASTER), and SPD5118 hwmon temperature sensor (SENSORS_SPD5118)
as modules.
The NVIDIA Vera CPU uses SOCAMM LPDDR5X memory module, which contains
SPD5118 (JEDEC JESD300) compliant temperature sensor. This sensor is
accessible over the I3C bus through the DesignWare I3C controller present
on the SoC. Enabling these configs allows monitoring memory module
temperatures on platforms such as Vera Rubin. Vera is an ACPI-based
platform and does not use device tree.
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
arch/arm64/configs/defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c267f0906460..36a7cafef3a0 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -639,6 +639,8 @@ CONFIG_I2C_UNIPHIER_F=y
CONFIG_I2C_XILINX=m
CONFIG_I2C_RCAR=y
CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_I3C=m
+CONFIG_DW_I3C_MASTER=m
CONFIG_SPI=y
CONFIG_SPI_APPLE=m
CONFIG_SPI_ARMADA_3700=y
@@ -768,6 +770,7 @@ CONFIG_SENSORS_SL28CPLD=m
CONFIG_SENSORS_AMC6821=m
CONFIG_SENSORS_INA2XX=m
CONFIG_SENSORS_INA3221=m
+CONFIG_SENSORS_SPD5118=m
CONFIG_SENSORS_TMP102=m
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v6 01/12] dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA
2026-07-21 4:07 ` [PATCH v6 01/12] dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA Akhil R
@ 2026-07-21 4:16 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:16 UTC (permalink / raw)
To: Akhil R
Cc: linux-i3c, devicetree, linux-hwmon, conor+dt, robh,
Alexandre Belloni, Frank.Li
> Add the 'mipi-i3c-static-method' property mentioned in the MIPI I3C
> Discovery and Configuration Specification [1] to specify which discovery
> method an I3C device supports during bus initialization. The property is
> a bitmap, where a bit value of 1 indicates support for that method, and 0
> indicates lack of support.
>
> Bit 0: SETDASA CCC (Direct)
> Bit 1: SETAASA CCC (Broadcast)
> Bit 2: Other CCC (vendor / standards extension)
> All other bits are reserved.
>
> It is specifically needed when an I3C device requires SETAASA for the
> address assignment. SETDASA will be supported by default if this property
> is absent, which means for now the property just serves as a flag to
> enable SETAASA, but keep the property as a bitmap to align with the
> specifications.
>
> [1] https://www.mipi.org/mipi-disco-for-i3c-download
>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=1
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 09/12] i3c: dw-i3c-master: Add ACPI ID for Tegra410
2026-07-21 4:07 ` [PATCH v6 09/12] i3c: dw-i3c-master: Add ACPI ID for Tegra410 Akhil R
@ 2026-07-21 4:22 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:22 UTC (permalink / raw)
To: Akhil R
Cc: devicetree, linux-i3c, Frank.Li, Alexandre Belloni, robh,
linux-hwmon, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Unsafe pointer cast of device_get_match_data() return value when binding via ACPI PRP0001.
- [High] Double-disable of core clocks during driver removal if the device is in runtime suspend.
--
--- Patch [9]: [PATCH v6 09/12] i3c: dw-i3c-master: Add ACPI ID for Tegra410 ---
commit bf82e9c156c66763c855e5549bd1a91bafc5fdf3
Author: Akhil R <akhilrajeev@nvidia.com>
i3c: dw-i3c-master: Add ACPI ID for Tegra410
Update variable names to generic names and add Tegra410 ACPI ID to
support the I3C controller in Tegra410, which is a DesignWare I3C host
controller.
> diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
> index 3ec3ab1c13b4c..efe37f5224c71 100644
> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
> @@ -1860,11 +1860,12 @@ static const struct of_device_id dw_i3c_master_of_match[] = {
> };
> MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
>
> -static const struct acpi_device_id amd_i3c_device_match[] = {
> +static const struct acpi_device_id dw_i3c_master_acpi_match[] = {
> { "AMDI0015", AMD_I3C_OD_PP_TIMING },
> + { "NVDA2018", DW_I3C_ACPI_SKIP_CLK_RST },
[Severity: High]
This isn't a bug introduced by this patch, but adding a new ACPI ID brings
attention to a pre-existing issue when handling ACPI bindings.
Does this driver safely handle ACPI PRP0001 bindings?
In dw_i3c_common_probe(), if an ACPI companion is present, the match data is
cast to an integer bitmask:
if (has_acpi_companion(&pdev->dev)) {
quirks = (unsigned long)device_get_match_data(&pdev->dev);
} else if (pdev->dev.of_node) {
...
When an ACPI device binds using the PRP0001 mechanism, it utilizes the OF
compatible strings and the OF match table. In this scenario,
device_get_match_data() returns the .data pointer from the of_device_id
table (e.g. &altr_agilex5_drvdata), rather than an integer quirk bitmask
from the acpi_device_id table.
Because of the unconditional cast, won't this store a kernel memory address
into master->quirks instead of a valid bitmask, thereby activating random
driver quirks?
[Severity: High]
This is also a pre-existing issue, but does dw_i3c_common_remove() correctly
handle devres clock cleanup when the device is in runtime suspend?
The probe function acquires and enables the core and pclk clocks using
devm_clk_get_optional_enabled():
master->core_clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
...
master->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk");
These clocks are explicitly disabled in dw_i3c_master_runtime_suspend().
If dw_i3c_common_remove() is invoked while the device is in runtime suspend,
the clocks are already disabled. Since dw_i3c_common_remove() does not wake
the device (e.g., via pm_runtime_get_sync()), won't the devres cleanup
routine run clk_disable_unprepare() again on already disabled clocks,
leading to a negative clock enable count?
> { }
> };
> -MODULE_DEVICE_TABLE(acpi, amd_i3c_device_match);
> +MODULE_DEVICE_TABLE(acpi, dw_i3c_master_acpi_match);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=9
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 07/12] i3c: dw-i3c-master: Add SETAASA as supported CCC
2026-07-21 4:07 ` [PATCH v6 07/12] i3c: dw-i3c-master: Add SETAASA as supported CCC Akhil R
@ 2026-07-21 4:24 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:24 UTC (permalink / raw)
To: Akhil R
Cc: linux-hwmon, devicetree, linux-i3c, Frank.Li, Alexandre Belloni,
robh, conor+dt
> Add SETAASA and SETHID to the supported list of CCC commands for
> DesignWare I3C host controller.
>
> SETAASA is a broadcast command that assigns predefined static addresses
> to all I3C devices on the bus.
>
> SETHID is to stop HID bit flipping by the SPD Hub to which the SPD devices
> are connected. It is a prerequisite command to be sent before SETAASA as
> recommended by JESD300-5 and JESD403 sideband bus specifications.
>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=7
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 02/12] i3c: master: Use unified device property interface
2026-07-21 4:07 ` [PATCH v6 02/12] i3c: master: Use unified device property interface Akhil R
@ 2026-07-21 4:25 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:25 UTC (permalink / raw)
To: Akhil R
Cc: robh, Alexandre Belloni, linux-hwmon, conor+dt, linux-i3c,
Frank.Li, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Use-After-Free and Double-Free on device_register() error path.
--
--- Patch [2]: [PATCH v6 02/12] i3c: master: Use unified device property interface ---
commit 4cd8615c6224b9a8e9ae3761f1ef4f19b3063c29
Author: Akhil R <akhilrajeev@nvidia.com>
i3c: master: Use unified device property interface
Replace all OF-specific functions with unified device property functions
as a prerequisite to support both ACPI and device tree.
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index f1be38a640ca1..4b3d9628bc39b 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
[ ... ]
> @@ -1928,7 +1930,7 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
> desc->info.pid);
>
> if (desc->boardinfo)
> - desc->dev->dev.of_node = desc->boardinfo->of_node;
> + device_set_node(&desc->dev->dev, desc->boardinfo->fwnode);
>
> ret = device_register(&desc->dev->dev);
> if (ret) {
> dev_err(&master->dev,
> "Failed to add I3C device (err = %d)\n", ret);
> put_device(&desc->dev->dev);
[Severity: High]
This is a pre-existing issue, but does the error path here leave a
dangling pointer in desc->dev?
If device_register() fails, put_device() drops the reference and
i3c_device_release() frees the underlying memory via kfree().
However, desc->dev is not set to NULL.
Later, when the master controller is unregistered, could this lead to a
write-after-free and double-free when the teardown path iterates over
the devices?
drivers/i3c/master.c:i3c_master_unregister_i3c_devs() {
...
i3c_bus_for_each_i3cdev(&master->bus, i3cdev) {
if (!i3cdev->dev)
continue;
i3cdev->dev->desc = NULL;
if (device_is_registered(&i3cdev->dev->dev))
device_unregister(&i3cdev->dev->dev);
else
put_device(&i3cdev->dev->dev);
...
}
> }
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=2
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 10/12] hwmon: spd5118: Remove 16-bit addressing
2026-07-21 4:07 ` [PATCH v6 10/12] hwmon: spd5118: Remove 16-bit addressing Akhil R
@ 2026-07-21 4:25 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:25 UTC (permalink / raw)
To: Akhil R
Cc: devicetree, conor+dt, linux-i3c, robh, Alexandre Belloni,
linux-hwmon, Frank.Li
> The intent of introducing 16-bit addressing was to support I3C, but it
> turns out that I3C does not require reading the Legacy Mode register,
> nor any specific encoding for page translation. The testing of 16-bit
> code was limited and there are no known users for this feature. Remove
> the sections that support 16-bit addressing and prepare the driver to
> support I3C appropriately.
>
> Suggested-by: Guenter Roeck <linux@roeck-us.net>
> Acked-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=10
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 06/12] i3c: master: match I3C device through DT and ACPI
2026-07-21 4:07 ` [PATCH v6 06/12] i3c: master: match I3C device through DT and ACPI Akhil R
@ 2026-07-21 4:25 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:25 UTC (permalink / raw)
To: Akhil R
Cc: robh, conor+dt, devicetree, linux-i3c, linux-hwmon, Frank.Li,
Alexandre Belloni
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] Time-of-Check to Time-of-Use (TOCTOU) race condition leading to a NULL pointer dereference during device matching.
- [High] Missing OF and ACPI MODALIAS generation in the bus uevent callback, preventing module autoloading for newly supported devices.
- [Medium] Latent API trap: DT/ACPI matching bypasses the I3C ID table match, causing a NULL pointer dereference in driver probe functions.
Pre-existing issues:
- [High] Uninitialized kernel stack memory is deterministically leaked to user-space via the `KOBJ_REMOVE` uevent.
--
--- Patch [6]: [PATCH v6 06/12] i3c: master: match I3C device through DT and ACPI ---
commit 7db2eb24719ceb614bd3ec6e5efb369d3b92fe6e
Author: Akhil R <akhilrajeev@nvidia.com>
i3c: master: match I3C device through DT and ACPI
SETAASA-based devices cannot always be identified by PID or DCR; the
standard I3C id_table matching may not be applicable. Allow such devices to
match through Device Tree or ACPI.
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 7b2f819bf4437..43bf530bc6619 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
[ ... ]
> @@ -345,15 +346,32 @@ static int i3c_device_match(struct device *dev, const struct device_driver *drv)
> {
> struct i3c_device *i3cdev;
> const struct i3c_driver *i3cdrv;
> + u8 static_addr_method = 0;
>
> if (dev->type != &i3c_device_type)
> return 0;
>
> i3cdev = dev_to_i3cdev(dev);
> i3cdrv = drv_to_i3cdrv(drv);
> - if (i3c_device_match_id(i3cdev, i3cdrv->id_table))
> +
> + if (i3cdev->desc && i3cdev->desc->boardinfo)
> + static_addr_method = i3cdev->desc->boardinfo->static_addr_method;
[Severity: High]
Can i3cdev->desc be modified concurrently here?
Looking at i3c_master_unregister_i3c_devs(), it locklessly sets
i3cdev->dev->desc = NULL during device unregistration.
Since the check in i3c_device_match() is done without locks or READ_ONCE(),
could the compiler emit multiple loads for i3cdev->desc, leading to a NULL
pointer dereference when subsequently accessing boardinfo?
> +
> + /*
> + * SETAASA-based devices need not always have a matching ID since
> + * it is not mandatory for such devices to implement deviceinfo
> + * CCC commands. Allow them to register through DT or ACPI.
> + */
> + if (i3cdrv->id_table && i3c_device_match_id(i3cdev, i3cdrv->id_table))
> return 1;
>
> + if (static_addr_method & I3C_ADDR_METHOD_SETAASA) {
> + if (of_driver_match_device(dev, drv))
> + return 1;
> + if (acpi_driver_match_device(dev, drv))
> + return 1;
> + }
[Severity: Medium]
Will this fallback matching break the assumptions in existing driver probe
functions?
Currently, drivers typically call i3c_device_match_id() in their probe
routine and unconditionally dereference the returned pointer.
When an I3C device binds via DT or ACPI through this new path,
i3c_device_match_id() will return NULL. If developers add an of_match_table
to existing drivers to support SETAASA devices, won't this cause an immediate
NULL pointer dereference during probe?
[Severity: High]
How does this change affect module autoloading for newly supported devices?
While the patch allows devices to match via DT or ACPI, it appears the bus
uevent callback, i3c_device_uevent(), was not updated and only emits the
generic I3C modalias.
Since of_device_uevent_modalias() or acpi_device_uevent_modalias() are not
called, won't the uevent lack the required of:N... string, preventing udev
from matching the device against the driver's MODULE_DEVICE_TABLE(of, ...)?
[Severity: High]
This is a pre-existing issue, but can the removal of an I3C device leak
uninitialized kernel stack memory to user-space?
When an I3C device is removed, i3c_master_unregister_i3c_devs() sets
i3cdev->dev->desc = NULL before calling device_unregister(), which
triggers a KOBJ_REMOVE uevent.
In i3c_device_uevent():
struct i3c_device_info devinfo;
if (i3cdev->desc)
devinfo = i3cdev->desc->info;
Since i3cdev->desc is unconditionally NULL during removal, devinfo is left
uninitialized. The function then proceeds to construct the MODALIAS string
using devinfo:
return add_uevent_var(env,
"MODALIAS=i3c:dcr%02Xmanuf%04Xpart%04Xext%04X",
devinfo.dcr, manuf, part, ext);
Doesn't this deterministically embed uninitialized kernel stack data into the
uevent environment variables, exposing it to user-space programs like udev?
> +
> return 0;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=6
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 05/12] i3c: master: Add support for devices without PID
2026-07-21 4:07 ` [PATCH v6 05/12] i3c: master: Add support for devices without PID Akhil R
@ 2026-07-21 4:26 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:26 UTC (permalink / raw)
To: Akhil R
Cc: Frank.Li, Alexandre Belloni, robh, devicetree, linux-hwmon,
conor+dt, linux-i3c
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The static address matching logic for devices without a PID in `i3c_master_attach_boardinfo` is unreachable and contains a structurally impossible condition.
- [Medium] Devices requiring a PID can now be registered with an invalid Manufacturer ID of 0.
--
--- Patch [5]: [PATCH v6 05/12] i3c: master: Add support for devices without PID ---
commit 671c3fae66002e874a13051a9c956e9987d76674
Author: Akhil R <akhilrajeev@nvidia.com>
i3c: master: Add support for devices without PID
Devices using SETAASA for address assignment are not required to have
a 48-bit PID according to the I3C specification. Allow such devices to
register and use the static address where PID was required.
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index b18dda89c4737..7b2f819bf4437 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
[ ... ]
> @@ -2389,8 +2398,18 @@ static void i3c_master_attach_boardinfo(struct i3c_dev_desc *i3cdev)
> struct i3c_dev_boardinfo *i3cboardinfo;
>
> list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) {
> - if (i3cdev->info.pid != i3cboardinfo->pid)
> - continue;
> + /*
> + * For devices without PID (e.g., SETAASA devices), match by
> + * static address. For devices with PID, match by PID.
> + */
> + if (i3cboardinfo->pid) {
> + if (i3cdev->info.pid != i3cboardinfo->pid)
> + continue;
> + } else {
> + if (!i3cboardinfo->static_addr ||
> + i3cdev->info.static_addr != i3cboardinfo->static_addr)
> + continue;
> + }
[Severity: Medium]
Will this static address matching logic ever evaluate to false?
Since i3c_master_attach_boardinfo() is only called during the dynamic
address assignment (ENTDAA) phase, i3cdev->info.static_addr is inherently 0
in this context.
Because i3cboardinfo->static_addr is validated to be non-zero at creation,
the condition i3cdev->info.static_addr != i3cboardinfo->static_addr will
evaluate to 0 != non-zero, which is always true.
This means the loop will always continue, making this branch effectively
dead code that fails to perform the intended matching.
>
> i3cdev->boardinfo = i3cboardinfo;
> i3cdev->info.static_addr = i3cboardinfo->static_addr;
[ ... ]
> @@ -2848,9 +2871,16 @@ i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
>
> boardinfo->pid = ((u64)reg[1] << 32) | reg[2];
>
> - if ((boardinfo->pid & GENMASK_ULL(63, 48)) ||
> - I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
> - return -EINVAL;
> + /* For SETAASA devices, validate the static address instead of PID */
> + if (boardinfo->static_addr_method & I3C_ADDR_METHOD_SETAASA) {
> + if (!boardinfo->static_addr)
> + return -EINVAL;
> + } else {
> + if (!boardinfo->pid ||
> + (boardinfo->pid & GENMASK_ULL(63, 48)) ||
> + I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
> + return -EINVAL;
> + }
>
> boardinfo->init_dyn_addr = init_dyn_addr;
> boardinfo->fwnode = fwnode_handle_get(fwnode);
> @@ -2873,10 +2903,10 @@ static int i3c_master_add_of_dev(struct i3c_master_controller *master,
> return ret;
>
> /*
> - * The manufacturer ID can't be 0. If reg[1] == 0 that means we're
> - * dealing with an I2C device.
> + * I3C device should have either the manufacturer ID specified or the
> + * address discovery method specified. Else treat it as an I2C device.
> */
> - if (!reg[1])
> + if (!reg[1] && !fwnode_property_present(fwnode, "mipi-i3c-static-method"))
> ret = i3c_master_add_i2c_boardinfo(master, fwnode, reg);
> else
> ret = i3c_master_add_i3c_boardinfo(master, fwnode, reg);
[Severity: Medium]
Could this change allow devices requiring a PID to be registered with an
invalid Manufacturer ID of 0?
By permitting reg[1] == 0 when mipi-i3c-static-method is present in
i3c_master_add_of_dev(), it appears we can bypass the strict Manufacturer ID
validation in i3c_master_add_i3c_boardinfo().
If the method is SETDASA, which still requires a PID, boardinfo->pid is set
to ((u64)0 << 32) | reg[2]. If reg[2] is non-zero, !boardinfo->pid is false.
Would this result in successfully registering the device despite the zero
Manufacturer ID, violating the MIPI I3C specification?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=5
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 08/12] i3c: dw-i3c-master: Add ACPI core clock frequency quirk
2026-07-21 4:07 ` [PATCH v6 08/12] i3c: dw-i3c-master: Add ACPI core clock frequency quirk Akhil R
@ 2026-07-21 4:26 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:26 UTC (permalink / raw)
To: Akhil R
Cc: linux-i3c, Frank.Li, devicetree, robh, linux-hwmon,
Alexandre Belloni, conor+dt
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [Low] Structurally unreachable error condition in `dw_i3c_master_get_core_rate()`.
Pre-existing issues:
- [High] Missing pm_runtime_get_sync() in device removal path causes unclocked MMIO access bus faults and devres clock refcount underflows.
- [High] Incorrect casting of device_get_match_data() result for ACPI PRP0001 devices causes random kernel pointers to be used as quirk bitmasks.
--
--- Patch [8]: [PATCH v6 08/12] i3c: dw-i3c-master: Add ACPI core clock frequency quirk ---
commit f3333de342eb1c266eb94909516ea27afe8378d5
Author: Akhil R <akhilrajeev@nvidia.com>
i3c: dw-i3c-master: Add ACPI core clock frequency quirk
Some ACPI-enumerated devices like Tegra410 do not expose the controller
core clock through the clk framework. Unlike device tree, ACPI on Arm does
not model clock providers. The hardware is expected to have its clocks
enabled by firmware before the OS takes over.
> diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
> index 29030fd9594aa..3ec3ab1c13b4c 100644
> --- a/drivers/i3c/master/dw-i3c-master.c
> +++ b/drivers/i3c/master/dw-i3c-master.c
[ ... ]
> @@ -556,13 +557,33 @@ static void dw_i3c_master_set_intr_regs(struct dw_i3c_master *master)
> writel(IBI_REQ_REJECT_ALL, master->regs + IBI_MR_REQ_REJECT);
> }
>
> +static unsigned long dw_i3c_master_get_core_rate(struct dw_i3c_master *master)
> +{
> + unsigned int core_rate_prop;
> +
> + if (master->core_clk)
> + return clk_get_rate(master->core_clk);
> +
> + if (!(master->quirks & DW_I3C_ACPI_SKIP_CLK_RST)) {
> + dev_err(master->dev, "missing core clock\n");
> + return 0;
> + }
[Severity: Low]
Is this check reachable?
During initialization in dw_i3c_common_probe(), if the core clock is missing
and DW_I3C_ACPI_SKIP_CLK_RST is not set, probe immediately aborts with -EINVAL.
By the time dw_i3c_master_get_core_rate() is executed, it seems guaranteed
that if core_clk is missing, the DW_I3C_ACPI_SKIP_CLK_RST quirk is already
set, making this fallback check dead code.
> +
> + if (device_property_read_u32(master->dev, "clock-frequency", &core_rate_prop)) {
> + dev_err(master->dev, "missing clock-frequency property\n");
> + return 0;
> + }
> +
> + return core_rate_prop;
> +}
[ ... ]
> @@ -1573,14 +1594,28 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
>
> master->dev = &pdev->dev;
>
> + if (has_acpi_companion(&pdev->dev)) {
> + quirks = (unsigned long)device_get_match_data(&pdev->dev);
> + } else if (pdev->dev.of_node) {
[Severity: High]
This isn't a bug introduced by this patch, but since this block was
relocated, I noticed a potential issue for devices using ACPI PRP0001.
If the device is instantiated via ACPI using the PRP0001 HID,
device_get_match_data() correctly falls back to the OF match table and
returns a pointer to struct dw_i3c_drvdata.
Does casting this pointer to an unsigned long and assigning it to
master->quirks cause random kernel pointers to be used as a quirk bitmask?
Depending on the kernel layout, this might cause erratic driver behavior such
as missing PM operations.
> + drvdata = device_get_match_data(&pdev->dev);
> + if (drvdata)
> + quirks = drvdata->flags;
> + }
> + master->quirks = quirks;
> +
> master->regs = devm_platform_ioremap_resource(pdev, 0);
[ ... ]
> @@ -1636,15 +1671,6 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
> master->has_ibi_data = true;
> writel(thld_ctrl, master->regs + QUEUE_THLD_CTRL);
>
> - if (has_acpi_companion(&pdev->dev)) {
> - quirks = (unsigned long)device_get_match_data(&pdev->dev);
> - } else if (pdev->dev.of_node) {
> - drvdata = device_get_match_data(&pdev->dev);
> - if (drvdata)
> - quirks = drvdata->flags;
> - }
> - master->quirks = quirks;
> -
> /* Keep controller enabled by preventing runtime suspend */
> if (master->quirks & DW_I3C_DISABLE_RUNTIME_PM_QUIRK)
> pm_runtime_get_noresume(&pdev->dev);
[Severity: High]
This is a pre-existing issue, but I noticed a potential problem in the device
removal path regarding runtime PM state.
When the driver is unbound, dw_i3c_common_remove() calls
i3c_master_unregister(), which internally calls dw_i3c_master_bus_cleanup():
dw_i3c_common_remove()
i3c_master_unregister()
dw_i3c_master_bus_cleanup()
The dw_i3c_master_bus_cleanup() function accesses the DEVICE_CTRL MMIO
register. Because the driver does not wake the device via
pm_runtime_get_sync() before unregistration, the device may be in a
runtime-suspended state with its core clocks disabled.
Could this cause a fatal bus fault on platforms like ARM due to unclocked MMIO
accesses?
Additionally, if the device remains suspended, will the subsequent devres
cleanup attempt to disable the already-disabled clocks, causing a clock enable
counter underflow warning?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=8
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 12/12] arm64: defconfig: Enable I3C and SPD5118 hwmon
2026-07-21 4:08 ` [PATCH v6 12/12] arm64: defconfig: Enable I3C and SPD5118 hwmon Akhil R
@ 2026-07-21 4:28 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:28 UTC (permalink / raw)
To: Akhil R
Cc: linux-i3c, robh, Frank.Li, linux-hwmon, conor+dt, devicetree,
Alexandre Belloni
> Enable I3C subsystem (I3C), Synopsys DesignWare I3C master controller
> (DW_I3C_MASTER), and SPD5118 hwmon temperature sensor (SENSORS_SPD5118)
> as modules.
>
> The NVIDIA Vera CPU uses SOCAMM LPDDR5X memory module, which contains
> SPD5118 (JEDEC JESD300) compliant temperature sensor. This sensor is
> accessible over the I3C bus through the DesignWare I3C controller present
> on the SoC. Enabling these configs allows monitoring memory module
> temperatures on platforms such as Vera Rubin. Vera is an ACPI-based
> platform and does not use device tree.
>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=12
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 04/12] i3c: master: Add support for devices using SETAASA
2026-07-21 4:07 ` [PATCH v6 04/12] i3c: master: Add support for devices using SETAASA Akhil R
@ 2026-07-21 4:30 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:30 UTC (permalink / raw)
To: Akhil R
Cc: linux-hwmon, Frank.Li, Alexandre Belloni, conor+dt, linux-i3c,
devicetree, robh
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] State inconsistency on error path: a SETAASA device failing software attachment will still claim its static address when the SETAASA broadcast is sent, leading to an address collision.
- [High] Multiple SETAASA devices without specified PIDs will cause a kobject name collision during `device_register()`, preventing registration of subsequent devices.
- [High] The newly introduced SETAASA and SETHID (vendor) CCC commands are not whitelisted in the majority of I3C master controller drivers, causing the entire bus initialization to fail.
Pre-existing issues:
- [High] Preexisting SETDASA Hardware/Software state mismatch on failure due to premature slot freeing before hardware reset.
--
--- Patch [4]: [PATCH v6 04/12] i3c: master: Add support for devices using SETAASA ---
commit e158b576a9f733695d868ee16f34bacdb43285b3
Author: Akhil R <akhilrajeev@nvidia.com>
i3c: master: Add support for devices using SETAASA
This commit adds support for discovering I3C devices using the SETAASA
procedure, such as SPD5118 and SPD5108 attached to DDR5 memory modules. It
adds the SETAASA and SETHID CCC commands and updates the discovery logic.
Link: https://www.mipi.org/mipi-disco-for-i3c-download
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 623c6b2247d9f..b18dda89c4737 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
[ ... ]
> @@ -1102,6 +1103,51 @@ static int i3c_master_rstdaa_locked(struct i3c_master_controller *master,
> return ret;
> }
>
> +/**
> + * i3c_master_setaasa_locked() - start a SETAASA procedure (Set All Addresses to Static Address)
[ ... ]
> +static int i3c_master_setaasa_locked(struct i3c_master_controller *master)
> +{
> + struct i3c_ccc_cmd_dest dest;
> + struct i3c_ccc_cmd cmd;
> + int ret;
> +
> + /*
> + * Send SETHID CCC command. Though it is a standard CCC command specified
> + * in JESD300-5, we are not defining a separate macro to be explicit that
> + * the value falls under the vendor specific range.
> + */
> + i3c_ccc_cmd_dest_init(&dest, I3C_BROADCAST_ADDR, 0);
> + i3c_ccc_cmd_init(&cmd, false, I3C_CCC_VENDOR(0, true), &dest, 1);
> + ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
[Severity: High]
Will this fail on most existing I3C master controllers?
Looking at i3c_master_send_ccc_cmd_locked(), it calls
master->ops->supports_ccc_cmd() before sending. Many core controller drivers
(like dw-i3c-master.c) have strict switch-statement whitelists for supported
CCC IDs that do not include these new SETAASA (0x29) and SETHID (0x61)
commands.
Would this result in returning -EOPNOTSUPP and aborting the entire bus
initialization on systems with these controllers?
> + i3c_ccc_cmd_dest_cleanup(&dest);
> + if (ret && cmd.err == I3C_ERROR_M2)
> + ret = 0;
> + if (ret)
> + return ret;
[ ... ]
> @@ -1878,6 +1924,22 @@ static int i3c_master_early_i3c_dev_add(struct i3c_master_controller *master,
> if (ret)
> goto err_free_dev;
>
> + /*
> + * For devices using SETAASA instead of ENTDAA, the address is statically
> + * assigned. Update the dynamic address to the provided static address.
> + * Reattach the I3C device after updating the dynamic address with the same
> + * static address. It is not mandatory for such devices to implement CCC
> + * commands like GETPID, GETDCR etc. Hence, we can return after reattaching.
> + */
> + if (i3cdev->boardinfo->static_addr_method & I3C_ADDR_METHOD_SETAASA) {
> + i3cdev->info.dyn_addr = i3cdev->boardinfo->static_addr;
> + ret = i3c_master_reattach_i3c_dev_locked(i3cdev, 0);
> + if (ret)
> + goto err_rstdaa;
[Severity: High]
If i3c_master_reattach_i3c_dev_locked() fails here, we jump to err_rstdaa
and eventually free the device structure. However, i3c_master_bus_init()
later unconditionally broadcasts SETAASA to the bus.
Won't the physical device claim this static address during the broadcast,
even though the controller software no longer tracks it? This could lead to
a bus collision when the software later tries to dynamically assign this
"free" address slot to a different device.
[Severity: High]
This is a pre-existing issue, but does jumping to err_rstdaa correctly reset
the hardware if reattachment fails during SETDASA or SETAASA?
If i3c_master_reattach_i3c_dev_locked() fails, its internal error path calls
i3c_master_put_i3c_addrs(), which marks the slot as I3C_ADDR_SLOT_FREE.
When we reach the err_rstdaa path:
err_rstdaa:
i3c_master_rstdaa_locked(master, i3cdev->boardinfo->init_dyn_addr);
i3c_master_rstdaa_locked() checks i3c_bus_get_addr_slot_status(). Because the
slot is already marked FREE, it returns -EINVAL and silently aborts without
sending the RSTDAA command to the hardware.
Does this leave the physical device holding the address while the software
considers it free?
> +
> + return 0;
> + }
> +
> ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr,
> i3cdev->boardinfo->init_dyn_addr);
[ ... ]
> @@ -2741,7 +2816,19 @@ i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
>
> boardinfo->static_addr = reg[0];
>
> + if (!fwnode_property_read_u32(fwnode, "mipi-i3c-static-method", &static_addr_method))
> + boardinfo->static_addr_method = static_addr_method &
> + (I3C_ADDR_METHOD_SETDASA | I3C_ADDR_METHOD_SETAASA);
> +
[ ... ]
> + if (boardinfo->static_addr_method & I3C_ADDR_METHOD_SETAASA) {
> + /* For SETAASA, static address is taken as the dynamic address. */
> + init_dyn_addr = boardinfo->static_addr;
> + }
> +
> + /* Update the address methods required for device discovery */
> + master->addr_method |= boardinfo->static_addr_method;
> +
> boardinfo->pid = ((u64)reg[1] << 32) | reg[2];
>
> if ((boardinfo->pid & GENMASK_ULL(63, 48)) ||
[Severity: High]
By relaxing the PID validation for SETAASA devices in this function, pid can
default to 0. If a system configures multiple SETAASA devices (like DDR5
SPDs) without PIDs, will this cause a kobject name collision?
During registration, i3c_master_register_new_i3c_devs() names the device
using its bus ID and PID:
dev_set_name(&desc->dev->dev, "%d-%llx", master->bus.id, desc->info.pid);
If multiple devices have pid=0, they would all be named "0-0", causing
device_register() to fail with -EEXIST for subsequent devices and preventing
them from functioning.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=4
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 03/12] i3c: master: Support ACPI enumeration of child devices
2026-07-21 4:07 ` [PATCH v6 03/12] i3c: master: Support ACPI enumeration of child devices Akhil R
@ 2026-07-21 4:32 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:32 UTC (permalink / raw)
To: Akhil R
Cc: Frank.Li, conor+dt, linux-hwmon, linux-i3c, robh, devicetree,
Alexandre Belloni
> Although the existing subsystem allows host controllers to register
> through the ACPI table, it was not possible to describe I3C or I2C
> devices when using ACPI. This is because the driver relied on the reg
> property to retrieve the PID, static address, etc., whereas ACPI uses
> _ADR or serial resources to describe such devices.
>
> Read _ADR and LVR from ACPI resources and extract the data as per the
> ACPI specification for an I3C bus. Also read mipi-i3c-static-address as
> per the MIPI DISCO specifications [1] to get the static address to be
> used.
>
> Enable describing I3C or I2C devices in the ACPI table. This is required
> if the device uses a static address or if it needs device-specific
> properties.
>
> [1] https://www.mipi.org/mipi-disco-for-i3c-download
>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=3
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 11/12] hwmon: spd5118: Add I3C support
2026-07-21 4:07 ` [PATCH v6 11/12] hwmon: spd5118: Add I3C support Akhil R
@ 2026-07-21 4:35 ` sashiko-bot
0 siblings, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-21 4:35 UTC (permalink / raw)
To: Akhil R
Cc: Alexandre Belloni, linux-i3c, conor+dt, devicetree, robh,
Frank.Li, linux-hwmon
> Add a regmap config and a probe function to support I3C-based
> communication with SPD5118 devices.
>
> On an I3C bus, SPD5118 devices are enumerated via SETAASA and always
> require an ACPI or device tree entry. Device matching is hence through
> the OF match tables only and does not need an I3C class match table. The
> device identity is verified in the type registers before proceeding to
> the common probe function.
>
> Acked-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721040805.1696503-1-akhilrajeev@nvidia.com?part=11
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 00/12] Support ACPI and SETAASA device discovery
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
` (11 preceding siblings ...)
2026-07-21 4:08 ` [PATCH v6 12/12] arm64: defconfig: Enable I3C and SPD5118 hwmon Akhil R
@ 2026-07-21 16:52 ` Frank Li
12 siblings, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-21 16:52 UTC (permalink / raw)
To: Akhil R
Cc: Alexandre Belloni, Frank Li, Miquel Raynal, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Guenter Roeck, Philipp Zabel,
Jon Hunter, Thierry Reding, linux-i3c, devicetree, linux-hwmon,
linux-tegra, linux-kernel
On Tue, Jul 21, 2026 at 04:07:48AM +0000, Akhil R wrote:
> This patch series adds SETAASA device discovery to the I3C subsystem,
> enabling support for SPD5118 temperature sensors found on DDR5 memory
> modules. The changes also add ACPI support for all existing DAA
> methods like SETDASA, SETNEWDA as well as I2C devices on I3C bus.
>
> SPD5118 and similar devices on DDR5 memory modules differ from typical
> I3C devices in their initialization. They use SETAASA broadcast CCC
> instead of ENTDAA for address assignment, and per JEDEC specification,
> are not required to have a Provisioned ID or implement standard device
> information CCC commands (GETPID, GETDCR, GETBCR).
>
> The series enables describing all I3C and I2C devices on both Device
> Tree and the ACPI table, using unified device property APIs throughout
> the I3C core and the Synopsys DesignWare I3C master driver.
>
> Please note that the series modifies drivers across multiple subsystems,
> like Device Tree bindings, ACPI, I3C and HWMON.
>
> v5->v6:
Thank you for hard work. I glance at there are some important sashiko AI
review need be figured out. let me know if you think it is ready for me
to do manual check.
You can simple reply sashiko review result by providing your justify.
Frank
> * Do not take an extra fwnode reference when assigning the boardinfo
> fwnode to a newly registered I3C device.
> * Issue SETAASA after SETDASA pre-assignment and before ENTDAA.
> * Prefer SETDASA over SETAASA when a device advertises both methods
> and an explicit dynamic address (assigned-address) is provided.
> * Reject PID 0 for non-SETAASA I3C boardinfo entries.
> * Drop OF/ACPI uevent modalias emission; keep OF/ACPI matching for
> SETAASA devices only.
> * Resolve DesignWare quirks before core clock acquisition and fail
> probe early when the clock is missing without the ACPI skip quirk.
>
> v4->v5:
> * Free ACPI I2C boardinfo when an ACPI child without an I2C resource is
> ignored.
> * Issue RSTDAA if SETAASA device attach fails after the static address is
> used as the dynamic address.
> * Emit OF and ACPI modaliases for firmware-matched I3C devices.
> * Make the DesignWare core clock optional and use "clock-frequency" as
> the fallback when core_clk is absent.
> * Keep DesignWare pclk, reset, and match-data handling on their existing
> optional paths.
>
> v3->v4:
> * Clarify mipi-i3c-static-method bit semantics and assigned-address
> * Add I3C_ADDR_METHOD_VENDOR
> * Fix fwnode reference handling while converting child property parsing
> to use unified firmware-node APIs.
> * Align ACPI child enumeration with the I2C core for multiple
> I2cSerialBus resources, ignore ACPI child entries without an I2C
> resource, and populate I2C modalias information from ACPI.
> * Update SETAASA handling to use the static address as the dynamic
> address, skip device-info retrieval for SETAASA devices, and tolerate
> M2 for SETHID/SETAASA similarly to ENTDAA.
> * Reorder DesignWare I3C clock/reset to include optional clock in the
> ACPI skip clock/reset quirk.
> * Add prints for missing ACPI clock-frequency and SPD5118 I3C
> device type read failures.
> * Fix grammar in comments and commit messages.
>
> v2->v3:
> * Fix maximum value and indent bit list for mipi-i3c-static-method.
> * Move I3C_ADDR_METHOD_* macros to dt-bindings header.
> * Drop ACPICA commit IDs, keep only the Link: tags.
> * Revert the change which proceeds to register other devices if SETAASA
> is not supported so that it aligns with the rest of the driver and to
> avoid the issues pointed by Sashiko.
> * Rework multiple commit messages.
>
> v1->v2:
> * Added patch to remove 16-bit addressing support for SPD5118
> * Guard ACPI calls with #ifdef CONFIG_ACPI
> * Remove CONFIG_OF guard for of_alias_get_highest_id()
> * Mask mipi-i3c-static-method in the driver to select only valid values.
> * Proceed to register other devices if SETAASA is not supported.
> * Update commit message and links in the description of multiple commits.
>
> Akhil R (12):
> dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA
> i3c: master: Use unified device property interface
> i3c: master: Support ACPI enumeration of child devices
> i3c: master: Add support for devices using SETAASA
> i3c: master: Add support for devices without PID
> i3c: master: match I3C device through DT and ACPI
> i3c: dw-i3c-master: Add SETAASA as supported CCC
> i3c: dw-i3c-master: Add ACPI core clock frequency quirk
> i3c: dw-i3c-master: Add ACPI ID for Tegra410
> hwmon: spd5118: Remove 16-bit addressing
> hwmon: spd5118: Add I3C support
> arm64: defconfig: Enable I3C and SPD5118 hwmon
>
> .../devicetree/bindings/i3c/i3c.yaml | 36 +-
> arch/arm64/configs/defconfig | 3 +
> drivers/hwmon/Kconfig | 9 +-
> drivers/hwmon/spd5118.c | 119 +++---
> drivers/i3c/master.c | 390 +++++++++++++++---
> drivers/i3c/master/dw-i3c-master.c | 59 ++-
> include/dt-bindings/i3c/i3c.h | 4 +
> include/linux/i3c/ccc.h | 1 +
> include/linux/i3c/master.h | 20 +-
> 9 files changed, 498 insertions(+), 143 deletions(-)
>
>
> base-commit: 6eb8711ece2ce27e52e327a5b7a628ed39b97f45
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-07-21 16:52 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 4:07 [PATCH v6 00/12] Support ACPI and SETAASA device discovery Akhil R
2026-07-21 4:07 ` [PATCH v6 01/12] dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA Akhil R
2026-07-21 4:16 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 02/12] i3c: master: Use unified device property interface Akhil R
2026-07-21 4:25 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 03/12] i3c: master: Support ACPI enumeration of child devices Akhil R
2026-07-21 4:32 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 04/12] i3c: master: Add support for devices using SETAASA Akhil R
2026-07-21 4:30 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 05/12] i3c: master: Add support for devices without PID Akhil R
2026-07-21 4:26 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 06/12] i3c: master: match I3C device through DT and ACPI Akhil R
2026-07-21 4:25 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 07/12] i3c: dw-i3c-master: Add SETAASA as supported CCC Akhil R
2026-07-21 4:24 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 08/12] i3c: dw-i3c-master: Add ACPI core clock frequency quirk Akhil R
2026-07-21 4:26 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 09/12] i3c: dw-i3c-master: Add ACPI ID for Tegra410 Akhil R
2026-07-21 4:22 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 10/12] hwmon: spd5118: Remove 16-bit addressing Akhil R
2026-07-21 4:25 ` sashiko-bot
2026-07-21 4:07 ` [PATCH v6 11/12] hwmon: spd5118: Add I3C support Akhil R
2026-07-21 4:35 ` sashiko-bot
2026-07-21 4:08 ` [PATCH v6 12/12] arm64: defconfig: Enable I3C and SPD5118 hwmon Akhil R
2026-07-21 4:28 ` sashiko-bot
2026-07-21 16:52 ` [PATCH v6 00/12] Support ACPI and SETAASA device discovery Frank Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox