[PATCH 4/5] i3c: dw: Do not use OF match data as a quirk bitmask

Akhil R akhilrajeev at nvidia.com
Tue Aug 4 03:13:00 PDT 2026


dw_i3c_common_probe() takes the match data as a plain bitmask of quirks
whenever the device has an ACPI companion, and as a pointer to struct
dw_i3c_drvdata otherwise. The two are not interchangeable.

A device that is enumerated from ACPI through the PRP0001 device ID
matches the OF table, so device_get_match_data() returns the drvdata
pointer of the matched entry. Casting that pointer to unsigned long
enables whatever quirks happen to line up with its address bits, for
instance disabling runtime PM or skipping the clock and reset setup.

Look for a match in the ACPI table of the driver instead of merely
testing for an ACPI companion, so that the match data is only read as a
bitmask when it really came from that table. acpi_match_device() returns
NULL when the driver has no ACPI table and when CONFIG_ACPI is disabled,
which keeps the ast2600 driver that shares this probe on the device tree
path.

Fixes: fba0e56ee752 ("i3c: dw: Disable runtime PM on Agilex5 to avoid bus hang on IBI")
Reported-by: Sashiko AI review <sashiko-bot at kernel.org>
Closes: https://lore.kernel.org/all/20260728071757.5B3CD1F000E9@smtp.kernel.org/
Cc: stable at vger.kernel.org
Assisted-by: Cursor:claude-opus-5
Signed-off-by: Akhil R <akhilrajeev at nvidia.com>
---
 drivers/i3c/master/dw-i3c-master.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 3816a50a52cc..17e1dd4fb5f3 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -5,6 +5,7 @@
  * Author: Vitor Soares <vitor.soares at synopsys.com>
  */
 
+#include <linux/acpi.h>
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
 #include <linux/cleanup.h>
@@ -1610,6 +1611,7 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
 {
 	int ret, irq;
 	u32 thld_ctrl;
+	const struct acpi_device_id *acpi_id;
 	const struct dw_i3c_drvdata *drvdata;
 	unsigned long quirks = 0;
 
@@ -1618,9 +1620,10 @@ 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) {
+	acpi_id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
+	if (acpi_id) {
+		quirks = acpi_id->driver_data;
+	} else {
 		drvdata = device_get_match_data(&pdev->dev);
 		if (drvdata)
 			quirks = drvdata->flags;
-- 
2.43.0




More information about the linux-i3c mailing list