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

Frank Li Frank.li at oss.nxp.com
Wed Aug 5 12:53:12 PDT 2026


On Tue, Aug 04, 2026 at 10:13:00AM +0000, Akhil R wrote:
> 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.
Suggest commit message

i3c: dw: use acpi_match_device() for ACPI-specific match data

The driver uses has_acpi_companion() to decide whether to obtain quirks
from ACPI match data. However, the presence of an ACPI companion does not
guarantee that the device was matched through the ACPI ID table.
 
When an ACPI device binds through the PRP0001 OF-compatibility mechanism,
device_get_match_data() returns a pointer to struct dw_i3c_drvdata. Since
has_acpi_companion() still returns true, the driver incorrectly casts that
pointer to an unsigned long quirk bitmask, corrupting the driver state.
 
Use acpi_match_device() instead of has_acpi_companion() to obtain ACPI
match data. Ensure quirk bits are only retrieved when the device actually
matches an ACPI entry. acpi_match_device() also returns NULL when the
driver has no ACPI match table or when CONFIG_ACPI is disabled, preserving
the existing device tree probe path used by the AST2600 driver.

Frank
>
> 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