drivers/acpi/acpi_platform.c | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
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
© 2016 - 2026 Red Hat, Inc.