[PATCH] ACPI: platform: Assign names to MEM resources from _DSD "reg-names"

Bowen Yu posted 1 patch 2 hours ago
drivers/acpi/acpi_platform.c | 37 ++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
[PATCH] ACPI: platform: Assign names to MEM resources from _DSD "reg-names"
Posted by Bowen Yu 2 hours ago
ACPI _CRS resources carry no names, so platform_get_resource_byname()
always fails for ACPI-created platform devices -- it skips any resource
whose name is NULL. This prevents drivers shared between Device Tree
and ACPI (via PRP0001) from using byname resource lookup.

Add a new helper, acpi_platform_set_resource_names(), that reads the
"reg-names" string array from _DSD and assigns names to MEM resources
in the order they appear in _CRS. This mirrors the Device Tree
"reg-names" property semantics. This property is optional, if absent
the behavior will be unchanged.

Tested on arm64 by injecting an SSDT through the initrd table upgrade
mechanism that describes a PRP0001 test device with three MMIO
resources and a matching "reg-names" package: a test driver using
platform_get_resource_byname() resolved all three regions, and
/proc/iomem shows the assigned names:

  f0000000-f0000fff : reg0
  f0001000-f0001fff : reg1
  f0002000-f0002fff : reg2

Signed-off-by: Bowen Yu <yubowen8@huawei.com>
---
 drivers/acpi/acpi_platform.c | 37 ++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 80ea7121744d..61f04eacc2f0 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -108,6 +108,39 @@ static unsigned int acpi_platform_adjust_resources(struct acpi_device *adev,
 	return count;
 }
 
+static void acpi_platform_set_resource_names(struct acpi_device *adev,
+					     struct resource *resources,
+					     int count)
+{
+	const char **names;
+	int mem_count = 0, mem_idx = 0;
+	int i, num;
+
+	/* reg-names is optional; skip entirely if not present in _DSD */
+	if (!fwnode_property_present(acpi_fwnode_handle(adev), "reg-names"))
+		return;
+
+	for (i = 0; i < count; i++)
+		if (resource_type(&resources[i]) == IORESOURCE_MEM)
+			mem_count++;
+	if (mem_count == 0)
+		return;
+
+	names = kcalloc(mem_count, sizeof(*names), GFP_KERNEL);
+	if (!names)
+		return;
+
+	num = fwnode_property_read_string_array(acpi_fwnode_handle(adev),
+						"reg-names", names, mem_count);
+	if (num == mem_count) {
+		for (i = 0; i < count; i++) {
+			if (resource_type(&resources[i]) == IORESOURCE_MEM)
+				resources[i].name = names[mem_idx++];
+		}
+	}
+	kfree(names);
+}
+
 static void acpi_platform_fill_resource(struct device *parent,
 					const struct resource *src,
 					struct resource *dest)
@@ -194,6 +227,10 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
 				acpi_platform_fill_resource(parent, rentry->res,
 							    &resources[count++]);
 			}
+
+			acpi_platform_set_resource_names(adev, resources,
+							 count);
+
 			acpi_dev_free_resource_list(&resource_list);
 		}
 	}
-- 
2.33.0