ACPI: property: Move property ref argument parsing into a new function
Split out property reference argument parsing out of the __acpi_node_get_property_reference() function into a new one, acpi_get_ref_args(). The new function will be needed also for parsing string references soon. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
5ee772883a
commit
1aef25d9d1
@ -673,6 +673,58 @@ acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int acpi_get_ref_args(struct fwnode_reference_args *args,
|
||||||
|
struct fwnode_handle *ref_fwnode,
|
||||||
|
const union acpi_object **element,
|
||||||
|
const union acpi_object *end, size_t num_args)
|
||||||
|
{
|
||||||
|
u32 nargs = 0, i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the referred data extension node under the
|
||||||
|
* referred device node.
|
||||||
|
*/
|
||||||
|
for (; *element < end && (*element)->type == ACPI_TYPE_STRING;
|
||||||
|
(*element)++) {
|
||||||
|
const char *child_name = (*element)->string.pointer;
|
||||||
|
|
||||||
|
ref_fwnode = acpi_fwnode_get_named_child_node(ref_fwnode, child_name);
|
||||||
|
if (!ref_fwnode)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assume the following integer elements are all args. Stop counting on
|
||||||
|
* the first reference or end of the package arguments. In case of
|
||||||
|
* neither reference, nor integer, return an error, we can't parse it.
|
||||||
|
*/
|
||||||
|
for (i = 0; (*element) + i < end && i < num_args; i++) {
|
||||||
|
acpi_object_type type = (*element)[i].type;
|
||||||
|
|
||||||
|
if (type == ACPI_TYPE_LOCAL_REFERENCE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (type == ACPI_TYPE_INTEGER)
|
||||||
|
nargs++;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nargs > NR_FWNODE_REFERENCE_ARGS)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (args) {
|
||||||
|
args->fwnode = ref_fwnode;
|
||||||
|
args->nargs = nargs;
|
||||||
|
for (i = 0; i < nargs; i++)
|
||||||
|
args->args[i] = (*element)[i].integer.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*element) += nargs;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __acpi_node_get_property_reference - returns handle to the referenced object
|
* __acpi_node_get_property_reference - returns handle to the referenced object
|
||||||
* @fwnode: Firmware node to get the property from
|
* @fwnode: Firmware node to get the property from
|
||||||
@ -761,61 +813,22 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
|
|||||||
end = element + obj->package.count;
|
end = element + obj->package.count;
|
||||||
|
|
||||||
while (element < end) {
|
while (element < end) {
|
||||||
u32 nargs, i;
|
|
||||||
|
|
||||||
if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
|
if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
|
||||||
struct fwnode_handle *ref_fwnode;
|
|
||||||
|
|
||||||
device = acpi_fetch_acpi_dev(element->reference.handle);
|
device = acpi_fetch_acpi_dev(element->reference.handle);
|
||||||
if (!device)
|
if (!device)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
nargs = 0;
|
|
||||||
element++;
|
element++;
|
||||||
|
|
||||||
/*
|
ret = acpi_get_ref_args(idx == index ? args : NULL,
|
||||||
* Find the referred data extension node under the
|
acpi_fwnode_handle(device),
|
||||||
* referred device node.
|
&element, end, num_args);
|
||||||
*/
|
if (ret < 0)
|
||||||
for (ref_fwnode = acpi_fwnode_handle(device);
|
return ret;
|
||||||
element < end && element->type == ACPI_TYPE_STRING;
|
|
||||||
element++) {
|
|
||||||
ref_fwnode = acpi_fwnode_get_named_child_node(
|
|
||||||
ref_fwnode, element->string.pointer);
|
|
||||||
if (!ref_fwnode)
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Assume the following integer elements are all args.
|
|
||||||
* Stop counting on the first reference or end of the
|
|
||||||
* package arguments. In case of neither reference,
|
|
||||||
* nor integer, return an error, we can't parse it.
|
|
||||||
*/
|
|
||||||
for (i = 0; element + i < end && i < num_args; i++) {
|
|
||||||
acpi_object_type type = element[i].type;
|
|
||||||
|
|
||||||
if (type == ACPI_TYPE_LOCAL_REFERENCE)
|
|
||||||
break;
|
|
||||||
if (type == ACPI_TYPE_INTEGER)
|
|
||||||
nargs++;
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nargs > NR_FWNODE_REFERENCE_ARGS)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (idx == index) {
|
|
||||||
args->fwnode = ref_fwnode;
|
|
||||||
args->nargs = nargs;
|
|
||||||
for (i = 0; i < nargs; i++)
|
|
||||||
args->args[i] = element[i].integer.value;
|
|
||||||
|
|
||||||
|
if (idx == index)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
element += nargs;
|
|
||||||
} else if (element->type == ACPI_TYPE_INTEGER) {
|
} else if (element->type == ACPI_TYPE_INTEGER) {
|
||||||
if (idx == index)
|
if (idx == index)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user