[PATCH 04/12] i3c: master: Support ACPI enumeration

Akhil R posted 12 patches 2 weeks, 4 days ago
[PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Akhil R 2 weeks, 4 days ago
Support ACPI enumeration for I2C and I3C devices on an I3C bus.
Read _ADR and LVR from the 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.

Although the existing subsystem allows host controllers to register
through the ACPI table, it was not possible to describe I3C or I2C
devices there. This change enables describing the I3C or I2C devices
in the ACPI table, which is required if the device is using a static
address or if it needs some specific properties to be attached to it.

[1] https://www.mipi.org/specifications/disco

Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
 drivers/i3c/master.c | 101 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 93 insertions(+), 8 deletions(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 2c479fecbfdf..15a356a2b3c8 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -2404,12 +2404,31 @@ EXPORT_SYMBOL_GPL(i3c_master_add_i3c_dev_locked);
 
 #define OF_I3C_REG1_IS_I2C_DEV			BIT(31)
 
+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 (!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 0;
+}
+
 static int
 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;
+	struct acpi_device *adev;
+	LIST_HEAD(resources);
 	int ret;
 
 	boardinfo = devm_kzalloc(dev, sizeof(*boardinfo), GFP_KERNEL);
@@ -2420,6 +2439,23 @@ 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)) {
+		adev = to_acpi_device_node(fwnode);
+		boardinfo->base.fwnode = acpi_fwnode_handle(adev);
+
+		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;
 	} else {
 		return -EINVAL;
 	}
@@ -2434,9 +2470,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);
 
@@ -2491,8 +2524,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;
@@ -2516,6 +2549,31 @@ static int i3c_master_add_dev(struct i3c_master_controller *master,
 	return ret;
 }
 
+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 };
+
+	/*
+	 * If the ACPI table entry does not have _ADR method, it's an I2C device
+	 * If the ACPI table entry has _ADR method, it's an I3C device
+	 */
+	if (!acpi_has_method(adev->handle, "_ADR"))
+		return i3c_master_add_i2c_boardinfo(master, fwnode, reg);
+
+	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", &reg[0]);
+
+	return i3c_master_add_i3c_boardinfo(master, fwnode, reg);
+}
+
 static int fwnode_populate_i3c_bus(struct i3c_master_controller *master)
 {
 	struct device *dev = &master->dev;
@@ -2527,7 +2585,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;
 	}
@@ -2593,10 +2657,31 @@ static u8 i3c_master_i2c_get_lvr(struct i2c_client *client)
 {
 	/* Fall back to no spike filters and FM bus mode. */
 	u8 lvr = I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE;
+	struct i2c_dev_boardinfo boardinfo;
+	struct acpi_device *adev;
+	LIST_HEAD(resources);
 	u32 reg[3];
+	int ret;
+
+	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)) {
+		adev = to_acpi_device_node(client->dev.fwnode);
+		memset(&boardinfo, 0, sizeof(boardinfo));
+
+		ret = acpi_dev_get_resources(adev, &resources,
+					     i3c_acpi_get_i2c_resource, &boardinfo);
 
-	if (!fwnode_property_read_u32_array(client->dev.fwnode, "reg", reg, ARRAY_SIZE(reg)))
-		lvr = reg[2];
+		if (ret < 0)
+			return lvr;
+
+		if (boardinfo.base.addr)
+			lvr = boardinfo.lvr;
+
+		acpi_dev_free_resource_list(&resources);
+	}
 
 	return lvr;
 }
-- 
2.50.1
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by kernel test robot 2 weeks ago
Hi Akhil,

kernel test robot noticed the following build errors:

[auto build test ERROR on next-20260320]
[also build test ERROR on linus/master v7.0-rc4]
[cannot apply to i3c/i3c/next rafael-pm/linux-next rafael-pm/bleeding-edge groeck-staging/hwmon-next v7.0-rc4 v7.0-rc3 v7.0-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Akhil-R/dt-bindings-i3c-Add-mipi-i3c-static-method-to-support-SETAASA/20260322-174037
base:   next-20260320
patch link:    https://lore.kernel.org/r/20260318172820.13771-5-akhilrajeev%40nvidia.com
patch subject: [PATCH 04/12] i3c: master: Support ACPI enumeration
config: hexagon-randconfig-002-20260322 (https://download.01.org/0day-ci/archive/20260323/202603230124.VFt6CPBe-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 4abb927bacf37f18f6359a41639a6d1b3bffffb5)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260323/202603230124.VFt6CPBe-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603230124.VFt6CPBe-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/i3c/master.c:2449:9: error: call to undeclared function 'acpi_dev_get_resources'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2449 |                 ret = acpi_dev_get_resources(adev, &resources,
         |                       ^
   drivers/i3c/master.c:2449:9: note: did you mean 'acpi_get_event_resources'?
   include/acpi/acpixf.h:816:9: note: 'acpi_get_event_resources' declared here
     816 |                              acpi_get_event_resources(acpi_handle device_handle,
         |                              ^
   include/acpi/platform/aclinux.h:93:21: note: expanded from macro 'ACPI_EXTERNAL_RETURN_STATUS'
      93 |         static ACPI_INLINE prototype {return(AE_NOT_CONFIGURED);}
         |                            ^
>> drivers/i3c/master.c:2455:3: error: call to undeclared function 'acpi_dev_free_resource_list'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2455 |                 acpi_dev_free_resource_list(&resources);
         |                 ^
   drivers/i3c/master.c:2556:2: error: unknown type name 'acpi_bus_address'; did you mean 'acpi_io_address'?
    2556 |         acpi_bus_address adr;
         |         ^~~~~~~~~~~~~~~~
         |         acpi_io_address
   include/acpi/actypes.h:187:13: note: 'acpi_io_address' declared here
     187 | typedef u64 acpi_io_address;
         |             ^
>> drivers/i3c/master.c:2563:7: error: call to undeclared function 'acpi_has_method'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
         |              ^
   drivers/i3c/master.c:2563:7: note: did you mean 'acpi_has_watchdog'?
   include/linux/acpi.h:1504:20: note: 'acpi_has_watchdog' declared here
    1504 | static inline bool acpi_has_watchdog(void) { return false; }
         |                    ^
>> drivers/i3c/master.c:2563:27: error: incomplete definition of type 'struct acpi_device'
    2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
         |                              ~~~~^
   include/linux/device/bus.h:224:8: note: forward declaration of 'struct acpi_device'
     224 | struct acpi_device;
         |        ^
>> drivers/i3c/master.c:2566:8: error: call to undeclared function 'acpi_device_adr'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2566 |         adr = acpi_device_adr(adev);
         |               ^
   drivers/i3c/master.c:2566:8: note: did you mean 'acpi_device_handle'?
   include/linux/acpi.h:883:27: note: 'acpi_device_handle' declared here
     883 | static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
         |                           ^
   drivers/i3c/master.c:2674:9: error: call to undeclared function 'acpi_dev_get_resources'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2674 |                 ret = acpi_dev_get_resources(adev, &resources,
         |                       ^
   drivers/i3c/master.c:2683:3: error: call to undeclared function 'acpi_dev_free_resource_list'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2683 |                 acpi_dev_free_resource_list(&resources);
         |                 ^
   8 errors generated.


vim +/acpi_dev_get_resources +2449 drivers/i3c/master.c

  2423	
  2424	static int
  2425	i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
  2426				     struct fwnode_handle *fwnode, u32 *reg)
  2427	{
  2428		struct i2c_dev_boardinfo *boardinfo;
  2429		struct device *dev = &master->dev;
  2430		struct acpi_device *adev;
  2431		LIST_HEAD(resources);
  2432		int ret;
  2433	
  2434		boardinfo = devm_kzalloc(dev, sizeof(*boardinfo), GFP_KERNEL);
  2435		if (!boardinfo)
  2436			return -ENOMEM;
  2437	
  2438		if (is_of_node(fwnode)) {
  2439			ret = of_i2c_get_board_info(dev, to_of_node(fwnode), &boardinfo->base);
  2440			if (ret)
  2441				return ret;
  2442	
  2443			/* LVR is encoded in reg[2] for Device Tree. */
  2444			boardinfo->lvr = reg[2];
  2445		} else if (is_acpi_device_node(fwnode)) {
  2446			adev = to_acpi_device_node(fwnode);
  2447			boardinfo->base.fwnode = acpi_fwnode_handle(adev);
  2448	
> 2449			ret = acpi_dev_get_resources(adev, &resources,
  2450						     i3c_acpi_get_i2c_resource, boardinfo);
  2451	
  2452			if (ret < 0)
  2453				return ret;
  2454	
> 2455			acpi_dev_free_resource_list(&resources);
  2456	
  2457			if (!boardinfo->base.addr)
  2458				return -ENODEV;
  2459		} else {
  2460			return -EINVAL;
  2461		}
  2462	
  2463		/*
  2464		 * The I3C Specification does not clearly say I2C devices with 10-bit
  2465		 * address are supported. These devices can't be passed properly through
  2466		 * DEFSLVS command.
  2467		 */
  2468		if (boardinfo->base.flags & I2C_CLIENT_TEN) {
  2469			dev_err(dev, "I2C device with 10 bit address not supported.");
  2470			return -EOPNOTSUPP;
  2471		}
  2472	
  2473		list_add_tail(&boardinfo->node, &master->boardinfo.i2c);
  2474		fwnode_handle_get(fwnode);
  2475	
  2476		return 0;
  2477	}
  2478	
  2479	static int
  2480	i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
  2481				     struct fwnode_handle *fwnode, u32 *reg)
  2482	{
  2483		struct i3c_dev_boardinfo *boardinfo;
  2484		struct device *dev = &master->dev;
  2485		enum i3c_addr_slot_status addrstatus;
  2486		u32 init_dyn_addr = 0;
  2487	
  2488		boardinfo = devm_kzalloc(dev, sizeof(*boardinfo), GFP_KERNEL);
  2489		if (!boardinfo)
  2490			return -ENOMEM;
  2491	
  2492		if (reg[0]) {
  2493			if (reg[0] > I3C_MAX_ADDR)
  2494				return -EINVAL;
  2495	
  2496			addrstatus = i3c_bus_get_addr_slot_status(&master->bus,
  2497								  reg[0]);
  2498			if (addrstatus != I3C_ADDR_SLOT_FREE)
  2499				return -EINVAL;
  2500		}
  2501	
  2502		boardinfo->static_addr = reg[0];
  2503	
  2504		if (!fwnode_property_read_u32(fwnode, "assigned-address", &init_dyn_addr)) {
  2505			if (init_dyn_addr > I3C_MAX_ADDR)
  2506				return -EINVAL;
  2507	
  2508			addrstatus = i3c_bus_get_addr_slot_status(&master->bus,
  2509								  init_dyn_addr);
  2510			if (addrstatus != I3C_ADDR_SLOT_FREE)
  2511				return -EINVAL;
  2512		}
  2513	
  2514		boardinfo->pid = ((u64)reg[1] << 32) | reg[2];
  2515	
  2516		if ((boardinfo->pid & GENMASK_ULL(63, 48)) ||
  2517		    I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
  2518			return -EINVAL;
  2519	
  2520		boardinfo->init_dyn_addr = init_dyn_addr;
  2521		boardinfo->fwnode = fwnode_handle_get(fwnode);
  2522		list_add_tail(&boardinfo->node, &master->boardinfo.i3c);
  2523	
  2524		return 0;
  2525	}
  2526	
  2527	static int i3c_master_add_of_dev(struct i3c_master_controller *master,
  2528					 struct fwnode_handle *fwnode)
  2529	{
  2530		u32 reg[3];
  2531		int ret;
  2532	
  2533		if (!master)
  2534			return -EINVAL;
  2535	
  2536		ret = fwnode_property_read_u32_array(fwnode, "reg", reg, ARRAY_SIZE(reg));
  2537		if (ret)
  2538			return ret;
  2539	
  2540		/*
  2541		 * The manufacturer ID can't be 0. If reg[1] == 0 that means we're
  2542		 * dealing with an I2C device.
  2543		 */
  2544		if (!reg[1])
  2545			ret = i3c_master_add_i2c_boardinfo(master, fwnode, reg);
  2546		else
  2547			ret = i3c_master_add_i3c_boardinfo(master, fwnode, reg);
  2548	
  2549		return ret;
  2550	}
  2551	
  2552	static int i3c_master_add_acpi_dev(struct i3c_master_controller *master,
  2553					   struct fwnode_handle *fwnode)
  2554	{
  2555		struct acpi_device *adev = to_acpi_device_node(fwnode);
> 2556		acpi_bus_address adr;
  2557		u32 reg[3] = { 0 };
  2558	
  2559		/*
  2560		 * If the ACPI table entry does not have _ADR method, it's an I2C device
  2561		 * If the ACPI table entry has _ADR method, it's an I3C device
  2562		 */
> 2563		if (!acpi_has_method(adev->handle, "_ADR"))
  2564			return i3c_master_add_i2c_boardinfo(master, fwnode, reg);
  2565	
> 2566		adr = acpi_device_adr(adev);
  2567	
  2568		/* For I3C devices, _ADR will have the 48 bit PID of the device  */
  2569		reg[1] = upper_32_bits(adr);
  2570		reg[2] = lower_32_bits(adr);
  2571	
  2572		fwnode_property_read_u32(fwnode, "mipi-i3c-static-address", &reg[0]);
  2573	
  2574		return i3c_master_add_i3c_boardinfo(master, fwnode, reg);
  2575	}
  2576	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Akhil R 1 week, 6 days ago
On Mon, 23 Mar 2026 01:47:20 +0800, kernel test robot wrote:
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on next-20260320]
> [also build test ERROR on linus/master v7.0-rc4]
> [cannot apply to i3c/i3c/next rafael-pm/linux-next rafael-pm/bleeding-edge groeck-staging/hwmon-next v7.0-rc4 v7.0-rc3 v7.0-rc2]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Akhil-R/dt-bindings-i3c-Add-mipi-i3c-static-method-to-support-SETAASA/20260322-174037
> base:   next-20260320
> patch link:    https://lore.kernel.org/r/20260318172820.13771-5-akhilrajeev%40nvidia.com
> patch subject: [PATCH 04/12] i3c: master: Support ACPI enumeration
> config: sparc-randconfig-002-20260322 (https://download.01.org/0day-ci/archive/20260323/202603230007.WOMwklQ6-lkp@intel.com/config)
> compiler: sparc-linux-gcc (GCC) 15.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260323/202603230007.WOMwklQ6-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202603230007.WOMwklQ6-lkp@intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>    drivers/i3c/master.c: In function 'i3c_master_add_i2c_boardinfo':
>>> drivers/i3c/master.c:2449:23: error: implicit declaration of function 'acpi_dev_get_resources'; did you mean 'acpi_get_event_resources'? [-Wimplicit-function-declaration]
>     2449 |                 ret = acpi_dev_get_resources(adev, &resources,
>          |                       ^~~~~~~~~~~~~~~~~~~~~~
>          |                       acpi_get_event_resources
>>> drivers/i3c/master.c:2455:17: error: implicit declaration of function 'acpi_dev_free_resource_list' [-Wimplicit-function-declaration]
>     2455 |                 acpi_dev_free_resource_list(&resources);
>          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>    drivers/i3c/master.c: In function 'i3c_master_add_acpi_dev':
>>> drivers/i3c/master.c:2556:9: error: unknown type name 'acpi_bus_address'; did you mean 'acpi_io_address'?
>     2556 |         acpi_bus_address adr;
>          |         ^~~~~~~~~~~~~~~~
>          |         acpi_io_address
>>> drivers/i3c/master.c:2563:14: error: implicit declaration of function 'acpi_has_method'; did you mean 'acpi_has_watchdog'? [-Wimplicit-function-declaration]
>     2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
>          |              ^~~~~~~~~~~~~~~
>          |              acpi_has_watchdog
>>> drivers/i3c/master.c:2563:34: error: invalid use of undefined type 'struct acpi_device'
>     2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
>          |                                  ^~
>>> drivers/i3c/master.c:2566:15: error: implicit declaration of function 'acpi_device_adr'; did you mean 'acpi_device_handle'? [-Wimplicit-function-declaration]
>     2566 |         adr = acpi_device_adr(adev);
>          |               ^~~~~~~~~~~~~~~
>          |               acpi_device_handle

#include <linux/acpi.h> is added in PATCH 03/12. The functions' prototypes
are present in acpi.h. I think the bot checked this patch individually,
or did I miss something?

Best Regards,
Akhil
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Alexandre Belloni 1 week, 6 days ago
On 24/03/2026 00:12:07+0530, Akhil R wrote:
> On Mon, 23 Mar 2026 01:47:20 +0800, kernel test robot wrote:
> > kernel test robot noticed the following build errors:
> > 
> > [auto build test ERROR on next-20260320]
> > [also build test ERROR on linus/master v7.0-rc4]
> > [cannot apply to i3c/i3c/next rafael-pm/linux-next rafael-pm/bleeding-edge groeck-staging/hwmon-next v7.0-rc4 v7.0-rc3 v7.0-rc2]
> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > And when submitting patch, we suggest to use '--base' as documented in
> > https://git-scm.com/docs/git-format-patch#_base_tree_information]
> > 
> > url:    https://github.com/intel-lab-lkp/linux/commits/Akhil-R/dt-bindings-i3c-Add-mipi-i3c-static-method-to-support-SETAASA/20260322-174037
> > base:   next-20260320
> > patch link:    https://lore.kernel.org/r/20260318172820.13771-5-akhilrajeev%40nvidia.com
> > patch subject: [PATCH 04/12] i3c: master: Support ACPI enumeration
> > config: sparc-randconfig-002-20260322 (https://download.01.org/0day-ci/archive/20260323/202603230007.WOMwklQ6-lkp@intel.com/config)
> > compiler: sparc-linux-gcc (GCC) 15.2.0
> > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260323/202603230007.WOMwklQ6-lkp@intel.com/reproduce)
> > 
> > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > the same patch/commit), kindly add following tags
> > | Reported-by: kernel test robot <lkp@intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202603230007.WOMwklQ6-lkp@intel.com/
> > 
> > All errors (new ones prefixed by >>):
> > 
> >    drivers/i3c/master.c: In function 'i3c_master_add_i2c_boardinfo':
> >>> drivers/i3c/master.c:2449:23: error: implicit declaration of function 'acpi_dev_get_resources'; did you mean 'acpi_get_event_resources'? [-Wimplicit-function-declaration]
> >     2449 |                 ret = acpi_dev_get_resources(adev, &resources,
> >          |                       ^~~~~~~~~~~~~~~~~~~~~~
> >          |                       acpi_get_event_resources
> >>> drivers/i3c/master.c:2455:17: error: implicit declaration of function 'acpi_dev_free_resource_list' [-Wimplicit-function-declaration]
> >     2455 |                 acpi_dev_free_resource_list(&resources);
> >          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
> >    drivers/i3c/master.c: In function 'i3c_master_add_acpi_dev':
> >>> drivers/i3c/master.c:2556:9: error: unknown type name 'acpi_bus_address'; did you mean 'acpi_io_address'?
> >     2556 |         acpi_bus_address adr;
> >          |         ^~~~~~~~~~~~~~~~
> >          |         acpi_io_address
> >>> drivers/i3c/master.c:2563:14: error: implicit declaration of function 'acpi_has_method'; did you mean 'acpi_has_watchdog'? [-Wimplicit-function-declaration]
> >     2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
> >          |              ^~~~~~~~~~~~~~~
> >          |              acpi_has_watchdog
> >>> drivers/i3c/master.c:2563:34: error: invalid use of undefined type 'struct acpi_device'
> >     2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
> >          |                                  ^~
> >>> drivers/i3c/master.c:2566:15: error: implicit declaration of function 'acpi_device_adr'; did you mean 'acpi_device_handle'? [-Wimplicit-function-declaration]
> >     2566 |         adr = acpi_device_adr(adev);
> >          |               ^~~~~~~~~~~~~~~
> >          |               acpi_device_handle
> 
> #include <linux/acpi.h> is added in PATCH 03/12. The functions' prototypes
> are present in acpi.h. I think the bot checked this patch individually,
> or did I miss something?
> 


#include <acpi/acpi_bus.h> is behind an #ifdef in acpi.h and your code
is not.

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Akhil R 1 week, 5 days ago
On Tue, 24 Mar 2026 09:43:27 +0100, Alexandre Belloni wrote:

...

>> #include <linux/acpi.h> is added in PATCH 03/12. The functions' prototypes
>> are present in acpi.h. I think the bot checked this patch individually,
>> or did I miss something?
>> 
> 
> #include <acpi/acpi_bus.h> is behind an #ifdef in acpi.h and your code
> is not.

Thanks for pointing Alexandre and Guenter. I also noticed that we do not
have stub functions for a few of the acpi_* functions in #else.

Looks like I will have to guard calls to these functions under
#ifdef CONFIG_ACPI.

Best Regards,
Akhil
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Thierry Reding 1 week, 5 days ago
On Tue, Mar 24, 2026 at 10:52:15PM +0530, Akhil R wrote:
> On Tue, 24 Mar 2026 09:43:27 +0100, Alexandre Belloni wrote:
> 
> ...
> 
> >> #include <linux/acpi.h> is added in PATCH 03/12. The functions' prototypes
> >> are present in acpi.h. I think the bot checked this patch individually,
> >> or did I miss something?
> >> 
> > 
> > #include <acpi/acpi_bus.h> is behind an #ifdef in acpi.h and your code
> > is not.
> 
> Thanks for pointing Alexandre and Guenter. I also noticed that we do not
> have stub functions for a few of the acpi_* functions in #else.
> 
> Looks like I will have to guard calls to these functions under
> #ifdef CONFIG_ACPI.

Alternatively it might make sense to add the stubs in a separate patch.
I don't know if they were purposefully left out or nobody's ever run
into the lack of these before.

Thierry
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Akhil R 6 days, 6 hours ago
On Wed, 25 Mar 2026 11:59:12 +0100, Thierry Reding wrote:
> On Tue, Mar 24, 2026 at 10:52:15PM +0530, Akhil R wrote:
>> On Tue, 24 Mar 2026 09:43:27 +0100, Alexandre Belloni wrote:
>> 
>> ...
>> 
>> >> #include <linux/acpi.h> is added in PATCH 03/12. The functions' prototypes
>> >> are present in acpi.h. I think the bot checked this patch individually,
>> >> or did I miss something?
>> >> 
>> > 
>> > #include <acpi/acpi_bus.h> is behind an #ifdef in acpi.h and your code
>> > is not.
>> 
>> Thanks for pointing Alexandre and Guenter. I also noticed that we do not
>> have stub functions for a few of the acpi_* functions in #else.
>> 
>> Looks like I will have to guard calls to these functions under
>> #ifdef CONFIG_ACPI.
> 
> Alternatively it might make sense to add the stubs in a separate patch.
> I don't know if they were purposefully left out or nobody's ever run
> into the lack of these before.

I looked into this and it turns out to be more involved than expected,
and requires adding stubs at multiple layers. We may end up either
sneaking in only what we require or a non-trivial change which may
involve too many parameters.

If you would agree, I will guard the ACPI calls used in this patchset with
#ifdef CONFIG_ACPI to keep things self-contained. If you think adding the
stubs is worthwhile, we can take them up as a separate series.

Best Regards,
Akhil
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Guenter Roeck 1 week, 6 days ago
On 3/23/26 11:42, Akhil R wrote:
> On Mon, 23 Mar 2026 01:47:20 +0800, kernel test robot wrote:
>> kernel test robot noticed the following build errors:
>>
>> [auto build test ERROR on next-20260320]
>> [also build test ERROR on linus/master v7.0-rc4]
>> [cannot apply to i3c/i3c/next rafael-pm/linux-next rafael-pm/bleeding-edge groeck-staging/hwmon-next v7.0-rc4 v7.0-rc3 v7.0-rc2]
>> [If your patch is applied to the wrong git tree, kindly drop us a note.
>> And when submitting patch, we suggest to use '--base' as documented in
>> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>>
>> url:    https://github.com/intel-lab-lkp/linux/commits/Akhil-R/dt-bindings-i3c-Add-mipi-i3c-static-method-to-support-SETAASA/20260322-174037
>> base:   next-20260320
>> patch link:    https://lore.kernel.org/r/20260318172820.13771-5-akhilrajeev%40nvidia.com
>> patch subject: [PATCH 04/12] i3c: master: Support ACPI enumeration
>> config: sparc-randconfig-002-20260322 (https://download.01.org/0day-ci/archive/20260323/202603230007.WOMwklQ6-lkp@intel.com/config)
>> compiler: sparc-linux-gcc (GCC) 15.2.0
>> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260323/202603230007.WOMwklQ6-lkp@intel.com/reproduce)
>>
>> If you fix the issue in a separate patch/commit (i.e. not just a new version of
>> the same patch/commit), kindly add following tags
>> | Reported-by: kernel test robot <lkp@intel.com>
>> | Closes: https://lore.kernel.org/oe-kbuild-all/202603230007.WOMwklQ6-lkp@intel.com/
>>
>> All errors (new ones prefixed by >>):
>>
>>     drivers/i3c/master.c: In function 'i3c_master_add_i2c_boardinfo':
>>>> drivers/i3c/master.c:2449:23: error: implicit declaration of function 'acpi_dev_get_resources'; did you mean 'acpi_get_event_resources'? [-Wimplicit-function-declaration]
>>      2449 |                 ret = acpi_dev_get_resources(adev, &resources,
>>           |                       ^~~~~~~~~~~~~~~~~~~~~~
>>           |                       acpi_get_event_resources
>>>> drivers/i3c/master.c:2455:17: error: implicit declaration of function 'acpi_dev_free_resource_list' [-Wimplicit-function-declaration]
>>      2455 |                 acpi_dev_free_resource_list(&resources);
>>           |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>     drivers/i3c/master.c: In function 'i3c_master_add_acpi_dev':
>>>> drivers/i3c/master.c:2556:9: error: unknown type name 'acpi_bus_address'; did you mean 'acpi_io_address'?
>>      2556 |         acpi_bus_address adr;
>>           |         ^~~~~~~~~~~~~~~~
>>           |         acpi_io_address
>>>> drivers/i3c/master.c:2563:14: error: implicit declaration of function 'acpi_has_method'; did you mean 'acpi_has_watchdog'? [-Wimplicit-function-declaration]
>>      2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
>>           |              ^~~~~~~~~~~~~~~
>>           |              acpi_has_watchdog
>>>> drivers/i3c/master.c:2563:34: error: invalid use of undefined type 'struct acpi_device'
>>      2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
>>           |                                  ^~
>>>> drivers/i3c/master.c:2566:15: error: implicit declaration of function 'acpi_device_adr'; did you mean 'acpi_device_handle'? [-Wimplicit-function-declaration]
>>      2566 |         adr = acpi_device_adr(adev);
>>           |               ^~~~~~~~~~~~~~~
>>           |               acpi_device_handle
> 
> #include <linux/acpi.h> is added in PATCH 03/12. The functions' prototypes
> are present in acpi.h. I think the bot checked this patch individually,
> or did I miss something?
> 

Did you try to build this code with a sparc cross-compiler ?
Because, as far as I can see, the functions are not declared or available
if ACPI is not enabled (or available, as with sparc).

Guenter
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by kernel test robot 2 weeks ago
Hi Akhil,

kernel test robot noticed the following build errors:

[auto build test ERROR on next-20260320]
[also build test ERROR on linus/master v7.0-rc4]
[cannot apply to i3c/i3c/next rafael-pm/linux-next rafael-pm/bleeding-edge groeck-staging/hwmon-next v7.0-rc4 v7.0-rc3 v7.0-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Akhil-R/dt-bindings-i3c-Add-mipi-i3c-static-method-to-support-SETAASA/20260322-174037
base:   next-20260320
patch link:    https://lore.kernel.org/r/20260318172820.13771-5-akhilrajeev%40nvidia.com
patch subject: [PATCH 04/12] i3c: master: Support ACPI enumeration
config: sparc-randconfig-002-20260322 (https://download.01.org/0day-ci/archive/20260323/202603230007.WOMwklQ6-lkp@intel.com/config)
compiler: sparc-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260323/202603230007.WOMwklQ6-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603230007.WOMwklQ6-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/i3c/master.c: In function 'i3c_master_add_i2c_boardinfo':
>> drivers/i3c/master.c:2449:23: error: implicit declaration of function 'acpi_dev_get_resources'; did you mean 'acpi_get_event_resources'? [-Wimplicit-function-declaration]
    2449 |                 ret = acpi_dev_get_resources(adev, &resources,
         |                       ^~~~~~~~~~~~~~~~~~~~~~
         |                       acpi_get_event_resources
>> drivers/i3c/master.c:2455:17: error: implicit declaration of function 'acpi_dev_free_resource_list' [-Wimplicit-function-declaration]
    2455 |                 acpi_dev_free_resource_list(&resources);
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/i3c/master.c: In function 'i3c_master_add_acpi_dev':
>> drivers/i3c/master.c:2556:9: error: unknown type name 'acpi_bus_address'; did you mean 'acpi_io_address'?
    2556 |         acpi_bus_address adr;
         |         ^~~~~~~~~~~~~~~~
         |         acpi_io_address
>> drivers/i3c/master.c:2563:14: error: implicit declaration of function 'acpi_has_method'; did you mean 'acpi_has_watchdog'? [-Wimplicit-function-declaration]
    2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
         |              ^~~~~~~~~~~~~~~
         |              acpi_has_watchdog
>> drivers/i3c/master.c:2563:34: error: invalid use of undefined type 'struct acpi_device'
    2563 |         if (!acpi_has_method(adev->handle, "_ADR"))
         |                                  ^~
>> drivers/i3c/master.c:2566:15: error: implicit declaration of function 'acpi_device_adr'; did you mean 'acpi_device_handle'? [-Wimplicit-function-declaration]
    2566 |         adr = acpi_device_adr(adev);
         |               ^~~~~~~~~~~~~~~
         |               acpi_device_handle


vim +2449 drivers/i3c/master.c

  2423	
  2424	static int
  2425	i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
  2426				     struct fwnode_handle *fwnode, u32 *reg)
  2427	{
  2428		struct i2c_dev_boardinfo *boardinfo;
  2429		struct device *dev = &master->dev;
  2430		struct acpi_device *adev;
  2431		LIST_HEAD(resources);
  2432		int ret;
  2433	
  2434		boardinfo = devm_kzalloc(dev, sizeof(*boardinfo), GFP_KERNEL);
  2435		if (!boardinfo)
  2436			return -ENOMEM;
  2437	
  2438		if (is_of_node(fwnode)) {
  2439			ret = of_i2c_get_board_info(dev, to_of_node(fwnode), &boardinfo->base);
  2440			if (ret)
  2441				return ret;
  2442	
  2443			/* LVR is encoded in reg[2] for Device Tree. */
  2444			boardinfo->lvr = reg[2];
  2445		} else if (is_acpi_device_node(fwnode)) {
  2446			adev = to_acpi_device_node(fwnode);
  2447			boardinfo->base.fwnode = acpi_fwnode_handle(adev);
  2448	
> 2449			ret = acpi_dev_get_resources(adev, &resources,
  2450						     i3c_acpi_get_i2c_resource, boardinfo);
  2451	
  2452			if (ret < 0)
  2453				return ret;
  2454	
> 2455			acpi_dev_free_resource_list(&resources);
  2456	
  2457			if (!boardinfo->base.addr)
  2458				return -ENODEV;
  2459		} else {
  2460			return -EINVAL;
  2461		}
  2462	
  2463		/*
  2464		 * The I3C Specification does not clearly say I2C devices with 10-bit
  2465		 * address are supported. These devices can't be passed properly through
  2466		 * DEFSLVS command.
  2467		 */
  2468		if (boardinfo->base.flags & I2C_CLIENT_TEN) {
  2469			dev_err(dev, "I2C device with 10 bit address not supported.");
  2470			return -EOPNOTSUPP;
  2471		}
  2472	
  2473		list_add_tail(&boardinfo->node, &master->boardinfo.i2c);
  2474		fwnode_handle_get(fwnode);
  2475	
  2476		return 0;
  2477	}
  2478	
  2479	static int
  2480	i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
  2481				     struct fwnode_handle *fwnode, u32 *reg)
  2482	{
  2483		struct i3c_dev_boardinfo *boardinfo;
  2484		struct device *dev = &master->dev;
  2485		enum i3c_addr_slot_status addrstatus;
  2486		u32 init_dyn_addr = 0;
  2487	
  2488		boardinfo = devm_kzalloc(dev, sizeof(*boardinfo), GFP_KERNEL);
  2489		if (!boardinfo)
  2490			return -ENOMEM;
  2491	
  2492		if (reg[0]) {
  2493			if (reg[0] > I3C_MAX_ADDR)
  2494				return -EINVAL;
  2495	
  2496			addrstatus = i3c_bus_get_addr_slot_status(&master->bus,
  2497								  reg[0]);
  2498			if (addrstatus != I3C_ADDR_SLOT_FREE)
  2499				return -EINVAL;
  2500		}
  2501	
  2502		boardinfo->static_addr = reg[0];
  2503	
  2504		if (!fwnode_property_read_u32(fwnode, "assigned-address", &init_dyn_addr)) {
  2505			if (init_dyn_addr > I3C_MAX_ADDR)
  2506				return -EINVAL;
  2507	
  2508			addrstatus = i3c_bus_get_addr_slot_status(&master->bus,
  2509								  init_dyn_addr);
  2510			if (addrstatus != I3C_ADDR_SLOT_FREE)
  2511				return -EINVAL;
  2512		}
  2513	
  2514		boardinfo->pid = ((u64)reg[1] << 32) | reg[2];
  2515	
  2516		if ((boardinfo->pid & GENMASK_ULL(63, 48)) ||
  2517		    I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
  2518			return -EINVAL;
  2519	
  2520		boardinfo->init_dyn_addr = init_dyn_addr;
  2521		boardinfo->fwnode = fwnode_handle_get(fwnode);
  2522		list_add_tail(&boardinfo->node, &master->boardinfo.i3c);
  2523	
  2524		return 0;
  2525	}
  2526	
  2527	static int i3c_master_add_of_dev(struct i3c_master_controller *master,
  2528					 struct fwnode_handle *fwnode)
  2529	{
  2530		u32 reg[3];
  2531		int ret;
  2532	
  2533		if (!master)
  2534			return -EINVAL;
  2535	
  2536		ret = fwnode_property_read_u32_array(fwnode, "reg", reg, ARRAY_SIZE(reg));
  2537		if (ret)
  2538			return ret;
  2539	
  2540		/*
  2541		 * The manufacturer ID can't be 0. If reg[1] == 0 that means we're
  2542		 * dealing with an I2C device.
  2543		 */
  2544		if (!reg[1])
  2545			ret = i3c_master_add_i2c_boardinfo(master, fwnode, reg);
  2546		else
  2547			ret = i3c_master_add_i3c_boardinfo(master, fwnode, reg);
  2548	
  2549		return ret;
  2550	}
  2551	
  2552	static int i3c_master_add_acpi_dev(struct i3c_master_controller *master,
  2553					   struct fwnode_handle *fwnode)
  2554	{
  2555		struct acpi_device *adev = to_acpi_device_node(fwnode);
> 2556		acpi_bus_address adr;
  2557		u32 reg[3] = { 0 };
  2558	
  2559		/*
  2560		 * If the ACPI table entry does not have _ADR method, it's an I2C device
  2561		 * If the ACPI table entry has _ADR method, it's an I3C device
  2562		 */
> 2563		if (!acpi_has_method(adev->handle, "_ADR"))
  2564			return i3c_master_add_i2c_boardinfo(master, fwnode, reg);
  2565	
> 2566		adr = acpi_device_adr(adev);
  2567	
  2568		/* For I3C devices, _ADR will have the 48 bit PID of the device  */
  2569		reg[1] = upper_32_bits(adr);
  2570		reg[2] = lower_32_bits(adr);
  2571	
  2572		fwnode_property_read_u32(fwnode, "mipi-i3c-static-address", &reg[0]);
  2573	
  2574		return i3c_master_add_i3c_boardinfo(master, fwnode, reg);
  2575	}
  2576	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Frank Li 2 weeks, 4 days ago
On Wed, Mar 18, 2026 at 10:57:17PM +0530, Akhil R wrote:
> Support ACPI enumeration for I2C and I3C devices on an I3C bus.
> Read _ADR and LVR from the ACPI resources and extract the data

ADR have _, but not _ before LVR, I am not familary with ACPI.

> 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.
>
> Although the existing subsystem allows host controllers to register
> through the ACPI table, it was not possible to describe I3C or I2C
> devices there.

why?

> This change enables describing the I3C or I2C devices

Don't use "This commit/change/" just Enable ...

Frank
> in the ACPI table, which is required if the device is using a static
> address or if it needs some specific properties to be attached to it.
>
> [1] https://www.mipi.org/specifications/disco
>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> ---
>  drivers/i3c/master.c | 101 +++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 93 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 2c479fecbfdf..15a356a2b3c8 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -2404,12 +2404,31 @@ EXPORT_SYMBOL_GPL(i3c_master_add_i3c_dev_locked);
>
>  #define OF_I3C_REG1_IS_I2C_DEV			BIT(31)
>
> +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 (!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 0;
> +}
> +
>  static int
>  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;
> +	struct acpi_device *adev;
> +	LIST_HEAD(resources);
>  	int ret;
>
>  	boardinfo = devm_kzalloc(dev, sizeof(*boardinfo), GFP_KERNEL);
> @@ -2420,6 +2439,23 @@ 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)) {
> +		adev = to_acpi_device_node(fwnode);
> +		boardinfo->base.fwnode = acpi_fwnode_handle(adev);
> +
> +		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;
>  	} else {
>  		return -EINVAL;
>  	}
> @@ -2434,9 +2470,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);
>
> @@ -2491,8 +2524,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;
> @@ -2516,6 +2549,31 @@ static int i3c_master_add_dev(struct i3c_master_controller *master,
>  	return ret;
>  }
>
> +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 };
> +
> +	/*
> +	 * If the ACPI table entry does not have _ADR method, it's an I2C device
> +	 * If the ACPI table entry has _ADR method, it's an I3C device
> +	 */
> +	if (!acpi_has_method(adev->handle, "_ADR"))
> +		return i3c_master_add_i2c_boardinfo(master, fwnode, reg);
> +
> +	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", &reg[0]);
> +
> +	return i3c_master_add_i3c_boardinfo(master, fwnode, reg);
> +}
> +
>  static int fwnode_populate_i3c_bus(struct i3c_master_controller *master)
>  {
>  	struct device *dev = &master->dev;
> @@ -2527,7 +2585,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;
>  	}
> @@ -2593,10 +2657,31 @@ static u8 i3c_master_i2c_get_lvr(struct i2c_client *client)
>  {
>  	/* Fall back to no spike filters and FM bus mode. */
>  	u8 lvr = I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE;
> +	struct i2c_dev_boardinfo boardinfo;
> +	struct acpi_device *adev;
> +	LIST_HEAD(resources);
>  	u32 reg[3];
> +	int ret;
> +
> +	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)) {
> +		adev = to_acpi_device_node(client->dev.fwnode);
> +		memset(&boardinfo, 0, sizeof(boardinfo));
> +
> +		ret = acpi_dev_get_resources(adev, &resources,
> +					     i3c_acpi_get_i2c_resource, &boardinfo);
>
> -	if (!fwnode_property_read_u32_array(client->dev.fwnode, "reg", reg, ARRAY_SIZE(reg)))
> -		lvr = reg[2];
> +		if (ret < 0)
> +			return lvr;
> +
> +		if (boardinfo.base.addr)
> +			lvr = boardinfo.lvr;
> +
> +		acpi_dev_free_resource_list(&resources);
> +	}
>
>  	return lvr;
>  }
> --
> 2.50.1
>
Re: [PATCH 04/12] i3c: master: Support ACPI enumeration
Posted by Akhil R 2 weeks, 3 days ago
On Thu, 19 Mar 2026 10:29:38 -0400, Frank Li wrote:
> On Wed, Mar 18, 2026 at 10:57:17PM +0530, Akhil R wrote:
>> Support ACPI enumeration for I2C and I3C devices on an I3C bus.
>> Read _ADR and LVR from the ACPI resources and extract the data
> 
> ADR have _, but not _ before LVR, I am not familary with ACPI.

'_ADR' is a static ACPI object (or method), but LVR is not.
LVR (Legacy Virtual Register) has to be read by parsing the
ACPI I2C serial resource.

> 
>> 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.
>>
>> Although the existing subsystem allows host controllers to register
>> through the ACPI table, it was not possible to describe I3C or I2C
>> devices there.
> 
> why?

The existing code relied on the 'reg' property to get PID, static address etc.
ACPI table entries do not use reg property, instead use _ADR or other resource
objects. Also for ACPI, MIPI recommends a different format which encodes the
details in the _ADR object. The specification also includes a few additional
properties like mipi-i3c-static-address, mipi-i3c-static-method etc. which
the new code follows.

> 
>> This change enables describing the I3C or I2C devices
> 
> Don't use "This commit/change/" just Enable ...

Ack. Will update.

Best Regards,
Akhil