diff options
| -rw-r--r-- | drivers/acpi/property.c | 62 | ||||
| -rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 2 | ||||
| -rw-r--r-- | include/linux/acpi.h | 4 |
3 files changed, 19 insertions, 49 deletions
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 27add91bc270..0d083736e25b 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c | |||
| @@ -273,25 +273,21 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_property_array); | |||
| 273 | * acpi_dev_get_property_reference - returns handle to the referenced object | 273 | * acpi_dev_get_property_reference - returns handle to the referenced object |
| 274 | * @adev: ACPI device to get property | 274 | * @adev: ACPI device to get property |
| 275 | * @name: Name of the property | 275 | * @name: Name of the property |
| 276 | * @size_prop: Name of the "size" property in referenced object | ||
| 277 | * @index: Index of the reference to return | 276 | * @index: Index of the reference to return |
| 278 | * @args: Location to store the returned reference with optional arguments | 277 | * @args: Location to store the returned reference with optional arguments |
| 279 | * | 278 | * |
| 280 | * Find property with @name, verifify that it is a package containing at least | 279 | * Find property with @name, verifify that it is a package containing at least |
| 281 | * one object reference and if so, store the ACPI device object pointer to the | 280 | * one object reference and if so, store the ACPI device object pointer to the |
| 282 | * target object in @args->adev. | 281 | * target object in @args->adev. If the reference includes arguments, store |
| 282 | * them in the @args->args[] array. | ||
| 283 | * | 283 | * |
| 284 | * If the reference includes arguments (@size_prop is not %NULL) follow the | 284 | * If there's more than one reference in the property value package, @index is |
| 285 | * reference and check whether or not there is an integer property @size_prop | 285 | * used to select the one to return. |
| 286 | * under the target object and if so, whether or not its value matches the | ||
| 287 | * number of arguments that follow the reference. If there's more than one | ||
| 288 | * reference in the property value package, @index is used to select the one to | ||
| 289 | * return. | ||
| 290 | * | 286 | * |
| 291 | * Return: %0 on success, negative error code on failure. | 287 | * Return: %0 on success, negative error code on failure. |
| 292 | */ | 288 | */ |
| 293 | int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, | 289 | int acpi_dev_get_property_reference(struct acpi_device *adev, |
| 294 | const char *size_prop, size_t index, | 290 | const char *name, size_t index, |
| 295 | struct acpi_reference_args *args) | 291 | struct acpi_reference_args *args) |
| 296 | { | 292 | { |
| 297 | const union acpi_object *element, *end; | 293 | const union acpi_object *element, *end; |
| @@ -308,7 +304,7 @@ int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, | |||
| 308 | * return that reference then. | 304 | * return that reference then. |
| 309 | */ | 305 | */ |
| 310 | if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { | 306 | if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { |
| 311 | if (size_prop || index) | 307 | if (index) |
| 312 | return -EINVAL; | 308 | return -EINVAL; |
| 313 | 309 | ||
| 314 | ret = acpi_bus_get_device(obj->reference.handle, &device); | 310 | ret = acpi_bus_get_device(obj->reference.handle, &device); |
| @@ -348,42 +344,16 @@ int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, | |||
| 348 | element++; | 344 | element++; |
| 349 | nargs = 0; | 345 | nargs = 0; |
| 350 | 346 | ||
| 351 | if (size_prop) { | 347 | /* assume following integer elements are all args */ |
| 352 | const union acpi_object *prop; | 348 | for (i = 0; element + i < end; i++) { |
| 353 | 349 | int type = element[i].type; | |
| 354 | /* | ||
| 355 | * Find out how many arguments the refenced object | ||
| 356 | * expects by reading its size_prop property. | ||
| 357 | */ | ||
| 358 | ret = acpi_dev_get_property(device, size_prop, | ||
| 359 | ACPI_TYPE_INTEGER, &prop); | ||
| 360 | if (ret) | ||
| 361 | return ret; | ||
| 362 | |||
| 363 | nargs = prop->integer.value; | ||
| 364 | if (nargs > MAX_ACPI_REFERENCE_ARGS | ||
| 365 | || element + nargs > end) | ||
| 366 | return -EPROTO; | ||
| 367 | 350 | ||
| 368 | /* | 351 | if (type == ACPI_TYPE_INTEGER) |
| 369 | * Skip to the start of the arguments and verify | 352 | nargs++; |
| 370 | * that they all are in fact integers. | 353 | else if (type == ACPI_TYPE_LOCAL_REFERENCE) |
| 371 | */ | 354 | break; |
| 372 | for (i = 0; i < nargs; i++) | 355 | else |
| 373 | if (element[i].type != ACPI_TYPE_INTEGER) | 356 | return -EPROTO; |
| 374 | return -EPROTO; | ||
| 375 | } else { | ||
| 376 | /* assume following integer elements are all args */ | ||
| 377 | for (i = 0; element + i < end; i++) { | ||
| 378 | int type = element[i].type; | ||
| 379 | |||
| 380 | if (type == ACPI_TYPE_INTEGER) | ||
| 381 | nargs++; | ||
| 382 | else if (type == ACPI_TYPE_LOCAL_REFERENCE) | ||
| 383 | break; | ||
| 384 | else | ||
| 385 | return -EPROTO; | ||
| 386 | } | ||
| 387 | } | 357 | } |
| 388 | 358 | ||
| 389 | if (idx++ == index) { | 359 | if (idx++ == index) { |
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 5a4d061e787e..ba98bb59a58f 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c | |||
| @@ -405,7 +405,7 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, | |||
| 405 | dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname); | 405 | dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname); |
| 406 | 406 | ||
| 407 | memset(&args, 0, sizeof(args)); | 407 | memset(&args, 0, sizeof(args)); |
| 408 | ret = acpi_dev_get_property_reference(adev, propname, NULL, | 408 | ret = acpi_dev_get_property_reference(adev, propname, |
| 409 | index, &args); | 409 | index, &args); |
| 410 | if (ret) { | 410 | if (ret) { |
| 411 | bool found = acpi_get_driver_gpio_data(adev, propname, | 411 | bool found = acpi_get_driver_gpio_data(adev, propname, |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 0902426c4521..10f2ed95645c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
| @@ -718,8 +718,8 @@ int acpi_dev_get_property(struct acpi_device *adev, const char *name, | |||
| 718 | int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, | 718 | int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, |
| 719 | acpi_object_type type, | 719 | acpi_object_type type, |
| 720 | const union acpi_object **obj); | 720 | const union acpi_object **obj); |
| 721 | int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, | 721 | int acpi_dev_get_property_reference(struct acpi_device *adev, |
| 722 | const char *cells_name, size_t index, | 722 | const char *name, size_t index, |
| 723 | struct acpi_reference_args *args); | 723 | struct acpi_reference_args *args); |
| 724 | 724 | ||
| 725 | int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, | 725 | int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, |
