in hisi_lpc.c [393:466]
static int hisi_lpc_acpi_set_io_res(struct device *child,
struct device *hostdev,
const struct resource **res, int *num_res)
{
struct acpi_device *adev;
struct acpi_device *host;
struct resource_entry *rentry;
LIST_HEAD(resource_list);
struct resource *resources;
int count;
int i;
if (!child || !hostdev)
return -EINVAL;
host = to_acpi_device(hostdev);
adev = to_acpi_device(child);
if (!adev->status.present) {
dev_dbg(child, "device is not present\n");
return -EIO;
}
if (acpi_device_enumerated(adev)) {
dev_dbg(child, "has been enumerated\n");
return -EIO;
}
/*
* The following code segment to retrieve the resources is common to
* acpi_create_platform_device(), so consider a common helper function
* in future.
*/
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
if (count <= 0) {
dev_dbg(child, "failed to get resources\n");
return count ? count : -EIO;
}
resources = devm_kcalloc(hostdev, count, sizeof(*resources),
GFP_KERNEL);
if (!resources) {
dev_warn(hostdev, "could not allocate memory for %d resources\n",
count);
acpi_dev_free_resource_list(&resource_list);
return -ENOMEM;
}
count = 0;
list_for_each_entry(rentry, &resource_list, node) {
resources[count] = *rentry->res;
hisi_lpc_acpi_fixup_child_resource(hostdev, &resources[count]);
count++;
}
acpi_dev_free_resource_list(&resource_list);
/* translate the I/O resources */
for (i = 0; i < count; i++) {
int ret;
if (!(resources[i].flags & IORESOURCE_IO))
continue;
ret = hisi_lpc_acpi_xlat_io_res(adev, host, &resources[i]);
if (ret) {
dev_err(child, "translate IO range %pR failed (%d)\n",
&resources[i], ret);
return ret;
}
}
*res = resources;
*num_res = count;
return 0;
}