xref: /linux/drivers/acpi/property.c (revision 83bce9c2baa51e439480a713119a73d3c8b61083)
1 /*
2  * ACPI device specific properties support.
3  *
4  * Copyright (C) 2014, Intel Corporation
5  * All rights reserved.
6  *
7  * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
8  *          Darren Hart <dvhart@linux.intel.com>
9  *          Rafael J. Wysocki <rafael.j.wysocki@intel.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15 
16 #include <linux/acpi.h>
17 #include <linux/device.h>
18 #include <linux/export.h>
19 
20 #include "internal.h"
21 
22 static int acpi_data_get_property_array(struct acpi_device_data *data,
23 					const char *name,
24 					acpi_object_type type,
25 					const union acpi_object **obj);
26 
27 /* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
28 static const u8 prp_uuid[16] = {
29 	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
30 	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
31 };
32 /* ACPI _DSD data subnodes UUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
33 static const u8 ads_uuid[16] = {
34 	0xe6, 0xe3, 0xb8, 0xdb, 0x86, 0x58, 0xa6, 0x4b,
35 	0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b
36 };
37 
38 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
39 					   const union acpi_object *desc,
40 					   struct acpi_device_data *data);
41 static bool acpi_extract_properties(const union acpi_object *desc,
42 				    struct acpi_device_data *data);
43 
44 static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
45 					acpi_handle handle,
46 					const union acpi_object *link,
47 					struct list_head *list)
48 {
49 	struct acpi_data_node *dn;
50 	bool result;
51 
52 	dn = kzalloc(sizeof(*dn), GFP_KERNEL);
53 	if (!dn)
54 		return false;
55 
56 	dn->name = link->package.elements[0].string.pointer;
57 	dn->fwnode.type = FWNODE_ACPI_DATA;
58 	INIT_LIST_HEAD(&dn->data.subnodes);
59 
60 	result = acpi_extract_properties(desc, &dn->data);
61 
62 	if (handle) {
63 		acpi_handle scope;
64 		acpi_status status;
65 
66 		/*
67 		 * The scope for the subnode object lookup is the one of the
68 		 * namespace node (device) containing the object that has
69 		 * returned the package.  That is, it's the scope of that
70 		 * object's parent.
71 		 */
72 		status = acpi_get_parent(handle, &scope);
73 		if (ACPI_SUCCESS(status)
74 		    && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data))
75 			result = true;
76 	} else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data)) {
77 		result = true;
78 	}
79 
80 	if (result) {
81 		dn->handle = handle;
82 		dn->data.pointer = desc;
83 		list_add_tail(&dn->sibling, list);
84 		return true;
85 	}
86 
87 	kfree(dn);
88 	acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
89 	return false;
90 }
91 
92 static bool acpi_nondev_subnode_data_ok(acpi_handle handle,
93 					const union acpi_object *link,
94 					struct list_head *list)
95 {
96 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
97 	acpi_status status;
98 
99 	status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
100 					    ACPI_TYPE_PACKAGE);
101 	if (ACPI_FAILURE(status))
102 		return false;
103 
104 	if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list))
105 		return true;
106 
107 	ACPI_FREE(buf.pointer);
108 	return false;
109 }
110 
111 static bool acpi_nondev_subnode_ok(acpi_handle scope,
112 				   const union acpi_object *link,
113 				   struct list_head *list)
114 {
115 	acpi_handle handle;
116 	acpi_status status;
117 
118 	if (!scope)
119 		return false;
120 
121 	status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
122 				 &handle);
123 	if (ACPI_FAILURE(status))
124 		return false;
125 
126 	return acpi_nondev_subnode_data_ok(handle, link, list);
127 }
128 
129 static int acpi_add_nondev_subnodes(acpi_handle scope,
130 				    const union acpi_object *links,
131 				    struct list_head *list)
132 {
133 	bool ret = false;
134 	int i;
135 
136 	for (i = 0; i < links->package.count; i++) {
137 		const union acpi_object *link, *desc;
138 		acpi_handle handle;
139 		bool result;
140 
141 		link = &links->package.elements[i];
142 		/* Only two elements allowed. */
143 		if (link->package.count != 2)
144 			continue;
145 
146 		/* The first one must be a string. */
147 		if (link->package.elements[0].type != ACPI_TYPE_STRING)
148 			continue;
149 
150 		/* The second one may be a string, a reference or a package. */
151 		switch (link->package.elements[1].type) {
152 		case ACPI_TYPE_STRING:
153 			result = acpi_nondev_subnode_ok(scope, link, list);
154 			break;
155 		case ACPI_TYPE_LOCAL_REFERENCE:
156 			handle = link->package.elements[1].reference.handle;
157 			result = acpi_nondev_subnode_data_ok(handle, link, list);
158 			break;
159 		case ACPI_TYPE_PACKAGE:
160 			desc = &link->package.elements[1];
161 			result = acpi_nondev_subnode_extract(desc, NULL, link, list);
162 			break;
163 		default:
164 			result = false;
165 			break;
166 		}
167 		ret = ret || result;
168 	}
169 
170 	return ret;
171 }
172 
173 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
174 					   const union acpi_object *desc,
175 					   struct acpi_device_data *data)
176 {
177 	int i;
178 
179 	/* Look for the ACPI data subnodes UUID. */
180 	for (i = 0; i < desc->package.count; i += 2) {
181 		const union acpi_object *uuid, *links;
182 
183 		uuid = &desc->package.elements[i];
184 		links = &desc->package.elements[i + 1];
185 
186 		/*
187 		 * The first element must be a UUID and the second one must be
188 		 * a package.
189 		 */
190 		if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
191 		    || links->type != ACPI_TYPE_PACKAGE)
192 			break;
193 
194 		if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid)))
195 			continue;
196 
197 		return acpi_add_nondev_subnodes(scope, links, &data->subnodes);
198 	}
199 
200 	return false;
201 }
202 
203 static bool acpi_property_value_ok(const union acpi_object *value)
204 {
205 	int j;
206 
207 	/*
208 	 * The value must be an integer, a string, a reference, or a package
209 	 * whose every element must be an integer, a string, or a reference.
210 	 */
211 	switch (value->type) {
212 	case ACPI_TYPE_INTEGER:
213 	case ACPI_TYPE_STRING:
214 	case ACPI_TYPE_LOCAL_REFERENCE:
215 		return true;
216 
217 	case ACPI_TYPE_PACKAGE:
218 		for (j = 0; j < value->package.count; j++)
219 			switch (value->package.elements[j].type) {
220 			case ACPI_TYPE_INTEGER:
221 			case ACPI_TYPE_STRING:
222 			case ACPI_TYPE_LOCAL_REFERENCE:
223 				continue;
224 
225 			default:
226 				return false;
227 			}
228 
229 		return true;
230 	}
231 	return false;
232 }
233 
234 static bool acpi_properties_format_valid(const union acpi_object *properties)
235 {
236 	int i;
237 
238 	for (i = 0; i < properties->package.count; i++) {
239 		const union acpi_object *property;
240 
241 		property = &properties->package.elements[i];
242 		/*
243 		 * Only two elements allowed, the first one must be a string and
244 		 * the second one has to satisfy certain conditions.
245 		 */
246 		if (property->package.count != 2
247 		    || property->package.elements[0].type != ACPI_TYPE_STRING
248 		    || !acpi_property_value_ok(&property->package.elements[1]))
249 			return false;
250 	}
251 	return true;
252 }
253 
254 static void acpi_init_of_compatible(struct acpi_device *adev)
255 {
256 	const union acpi_object *of_compatible;
257 	int ret;
258 
259 	ret = acpi_data_get_property_array(&adev->data, "compatible",
260 					   ACPI_TYPE_STRING, &of_compatible);
261 	if (ret) {
262 		ret = acpi_dev_get_property(adev, "compatible",
263 					    ACPI_TYPE_STRING, &of_compatible);
264 		if (ret) {
265 			if (adev->parent
266 			    && adev->parent->flags.of_compatible_ok)
267 				goto out;
268 
269 			return;
270 		}
271 	}
272 	adev->data.of_compatible = of_compatible;
273 
274  out:
275 	adev->flags.of_compatible_ok = 1;
276 }
277 
278 static bool acpi_extract_properties(const union acpi_object *desc,
279 				    struct acpi_device_data *data)
280 {
281 	int i;
282 
283 	if (desc->package.count % 2)
284 		return false;
285 
286 	/* Look for the device properties UUID. */
287 	for (i = 0; i < desc->package.count; i += 2) {
288 		const union acpi_object *uuid, *properties;
289 
290 		uuid = &desc->package.elements[i];
291 		properties = &desc->package.elements[i + 1];
292 
293 		/*
294 		 * The first element must be a UUID and the second one must be
295 		 * a package.
296 		 */
297 		if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
298 		    || properties->type != ACPI_TYPE_PACKAGE)
299 			break;
300 
301 		if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid)))
302 			continue;
303 
304 		/*
305 		 * We found the matching UUID. Now validate the format of the
306 		 * package immediately following it.
307 		 */
308 		if (!acpi_properties_format_valid(properties))
309 			break;
310 
311 		data->properties = properties;
312 		return true;
313 	}
314 
315 	return false;
316 }
317 
318 void acpi_init_properties(struct acpi_device *adev)
319 {
320 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
321 	struct acpi_hardware_id *hwid;
322 	acpi_status status;
323 	bool acpi_of = false;
324 
325 	INIT_LIST_HEAD(&adev->data.subnodes);
326 
327 	/*
328 	 * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
329 	 * Device Tree compatible properties for this device.
330 	 */
331 	list_for_each_entry(hwid, &adev->pnp.ids, list) {
332 		if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) {
333 			acpi_of = true;
334 			break;
335 		}
336 	}
337 
338 	status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
339 					    ACPI_TYPE_PACKAGE);
340 	if (ACPI_FAILURE(status))
341 		goto out;
342 
343 	if (acpi_extract_properties(buf.pointer, &adev->data)) {
344 		adev->data.pointer = buf.pointer;
345 		if (acpi_of)
346 			acpi_init_of_compatible(adev);
347 	}
348 	if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, &adev->data))
349 		adev->data.pointer = buf.pointer;
350 
351 	if (!adev->data.pointer) {
352 		acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n");
353 		ACPI_FREE(buf.pointer);
354 	}
355 
356  out:
357 	if (acpi_of && !adev->flags.of_compatible_ok)
358 		acpi_handle_info(adev->handle,
359 			 ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n");
360 }
361 
362 static void acpi_destroy_nondev_subnodes(struct list_head *list)
363 {
364 	struct acpi_data_node *dn, *next;
365 
366 	if (list_empty(list))
367 		return;
368 
369 	list_for_each_entry_safe_reverse(dn, next, list, sibling) {
370 		acpi_destroy_nondev_subnodes(&dn->data.subnodes);
371 		wait_for_completion(&dn->kobj_done);
372 		list_del(&dn->sibling);
373 		ACPI_FREE((void *)dn->data.pointer);
374 		kfree(dn);
375 	}
376 }
377 
378 void acpi_free_properties(struct acpi_device *adev)
379 {
380 	acpi_destroy_nondev_subnodes(&adev->data.subnodes);
381 	ACPI_FREE((void *)adev->data.pointer);
382 	adev->data.of_compatible = NULL;
383 	adev->data.pointer = NULL;
384 	adev->data.properties = NULL;
385 }
386 
387 /**
388  * acpi_data_get_property - return an ACPI property with given name
389  * @data: ACPI device deta object to get the property from
390  * @name: Name of the property
391  * @type: Expected property type
392  * @obj: Location to store the property value (if not %NULL)
393  *
394  * Look up a property with @name and store a pointer to the resulting ACPI
395  * object at the location pointed to by @obj if found.
396  *
397  * Callers must not attempt to free the returned objects.  These objects will be
398  * freed by the ACPI core automatically during the removal of @data.
399  *
400  * Return: %0 if property with @name has been found (success),
401  *         %-EINVAL if the arguments are invalid,
402  *         %-EINVAL if the property doesn't exist,
403  *         %-EPROTO if the property value type doesn't match @type.
404  */
405 static int acpi_data_get_property(struct acpi_device_data *data,
406 				  const char *name, acpi_object_type type,
407 				  const union acpi_object **obj)
408 {
409 	const union acpi_object *properties;
410 	int i;
411 
412 	if (!data || !name)
413 		return -EINVAL;
414 
415 	if (!data->pointer || !data->properties)
416 		return -EINVAL;
417 
418 	properties = data->properties;
419 	for (i = 0; i < properties->package.count; i++) {
420 		const union acpi_object *propname, *propvalue;
421 		const union acpi_object *property;
422 
423 		property = &properties->package.elements[i];
424 
425 		propname = &property->package.elements[0];
426 		propvalue = &property->package.elements[1];
427 
428 		if (!strcmp(name, propname->string.pointer)) {
429 			if (type != ACPI_TYPE_ANY && propvalue->type != type)
430 				return -EPROTO;
431 			if (obj)
432 				*obj = propvalue;
433 
434 			return 0;
435 		}
436 	}
437 	return -EINVAL;
438 }
439 
440 /**
441  * acpi_dev_get_property - return an ACPI property with given name.
442  * @adev: ACPI device to get the property from.
443  * @name: Name of the property.
444  * @type: Expected property type.
445  * @obj: Location to store the property value (if not %NULL).
446  */
447 int acpi_dev_get_property(struct acpi_device *adev, const char *name,
448 			  acpi_object_type type, const union acpi_object **obj)
449 {
450 	return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL;
451 }
452 EXPORT_SYMBOL_GPL(acpi_dev_get_property);
453 
454 static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode)
455 {
456 	if (fwnode->type == FWNODE_ACPI) {
457 		struct acpi_device *adev = to_acpi_device_node(fwnode);
458 		return &adev->data;
459 	} else if (fwnode->type == FWNODE_ACPI_DATA) {
460 		struct acpi_data_node *dn = to_acpi_data_node(fwnode);
461 		return &dn->data;
462 	}
463 	return NULL;
464 }
465 
466 /**
467  * acpi_node_prop_get - return an ACPI property with given name.
468  * @fwnode: Firmware node to get the property from.
469  * @propname: Name of the property.
470  * @valptr: Location to store a pointer to the property value (if not %NULL).
471  */
472 int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
473 		       void **valptr)
474 {
475 	return acpi_data_get_property(acpi_device_data_of_node(fwnode),
476 				      propname, ACPI_TYPE_ANY,
477 				      (const union acpi_object **)valptr);
478 }
479 
480 /**
481  * acpi_data_get_property_array - return an ACPI array property with given name
482  * @adev: ACPI data object to get the property from
483  * @name: Name of the property
484  * @type: Expected type of array elements
485  * @obj: Location to store a pointer to the property value (if not NULL)
486  *
487  * Look up an array property with @name and store a pointer to the resulting
488  * ACPI object at the location pointed to by @obj if found.
489  *
490  * Callers must not attempt to free the returned objects.  Those objects will be
491  * freed by the ACPI core automatically during the removal of @data.
492  *
493  * Return: %0 if array property (package) with @name has been found (success),
494  *         %-EINVAL if the arguments are invalid,
495  *         %-EINVAL if the property doesn't exist,
496  *         %-EPROTO if the property is not a package or the type of its elements
497  *           doesn't match @type.
498  */
499 static int acpi_data_get_property_array(struct acpi_device_data *data,
500 					const char *name,
501 					acpi_object_type type,
502 					const union acpi_object **obj)
503 {
504 	const union acpi_object *prop;
505 	int ret, i;
506 
507 	ret = acpi_data_get_property(data, name, ACPI_TYPE_PACKAGE, &prop);
508 	if (ret)
509 		return ret;
510 
511 	if (type != ACPI_TYPE_ANY) {
512 		/* Check that all elements are of correct type. */
513 		for (i = 0; i < prop->package.count; i++)
514 			if (prop->package.elements[i].type != type)
515 				return -EPROTO;
516 	}
517 	if (obj)
518 		*obj = prop;
519 
520 	return 0;
521 }
522 
523 /**
524  * __acpi_node_get_property_reference - returns handle to the referenced object
525  * @fwnode: Firmware node to get the property from
526  * @propname: Name of the property
527  * @index: Index of the reference to return
528  * @num_args: Maximum number of arguments after each reference
529  * @args: Location to store the returned reference with optional arguments
530  *
531  * Find property with @name, verifify that it is a package containing at least
532  * one object reference and if so, store the ACPI device object pointer to the
533  * target object in @args->adev.  If the reference includes arguments, store
534  * them in the @args->args[] array.
535  *
536  * If there's more than one reference in the property value package, @index is
537  * used to select the one to return.
538  *
539  * It is possible to leave holes in the property value set like in the
540  * example below:
541  *
542  * Package () {
543  *     "cs-gpios",
544  *     Package () {
545  *        ^GPIO, 19, 0, 0,
546  *        ^GPIO, 20, 0, 0,
547  *        0,
548  *        ^GPIO, 21, 0, 0,
549  *     }
550  * }
551  *
552  * Calling this function with index %2 return %-ENOENT and with index %3
553  * returns the last entry. If the property does not contain any more values
554  * %-ENODATA is returned. The NULL entry must be single integer and
555  * preferably contain value %0.
556  *
557  * Return: %0 on success, negative error code on failure.
558  */
559 int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
560 	const char *propname, size_t index, size_t num_args,
561 	struct acpi_reference_args *args)
562 {
563 	const union acpi_object *element, *end;
564 	const union acpi_object *obj;
565 	struct acpi_device_data *data;
566 	struct acpi_device *device;
567 	int ret, idx = 0;
568 
569 	data = acpi_device_data_of_node(fwnode);
570 	if (!data)
571 		return -EINVAL;
572 
573 	ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
574 	if (ret)
575 		return ret;
576 
577 	/*
578 	 * The simplest case is when the value is a single reference.  Just
579 	 * return that reference then.
580 	 */
581 	if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
582 		if (index)
583 			return -EINVAL;
584 
585 		ret = acpi_bus_get_device(obj->reference.handle, &device);
586 		if (ret)
587 			return ret;
588 
589 		args->adev = device;
590 		args->nargs = 0;
591 		return 0;
592 	}
593 
594 	/*
595 	 * If it is not a single reference, then it is a package of
596 	 * references followed by number of ints as follows:
597 	 *
598 	 *  Package () { REF, INT, REF, INT, INT }
599 	 *
600 	 * The index argument is then used to determine which reference
601 	 * the caller wants (along with the arguments).
602 	 */
603 	if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
604 		return -EPROTO;
605 
606 	element = obj->package.elements;
607 	end = element + obj->package.count;
608 
609 	while (element < end) {
610 		u32 nargs, i;
611 
612 		if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
613 			ret = acpi_bus_get_device(element->reference.handle,
614 						  &device);
615 			if (ret)
616 				return -ENODEV;
617 
618 			nargs = 0;
619 			element++;
620 
621 			/* assume following integer elements are all args */
622 			for (i = 0; element + i < end && i < num_args; i++) {
623 				int type = element[i].type;
624 
625 				if (type == ACPI_TYPE_INTEGER)
626 					nargs++;
627 				else if (type == ACPI_TYPE_LOCAL_REFERENCE)
628 					break;
629 				else
630 					return -EPROTO;
631 			}
632 
633 			if (nargs > MAX_ACPI_REFERENCE_ARGS)
634 				return -EPROTO;
635 
636 			if (idx == index) {
637 				args->adev = device;
638 				args->nargs = nargs;
639 				for (i = 0; i < nargs; i++)
640 					args->args[i] = element[i].integer.value;
641 
642 				return 0;
643 			}
644 
645 			element += nargs;
646 		} else if (element->type == ACPI_TYPE_INTEGER) {
647 			if (idx == index)
648 				return -ENOENT;
649 			element++;
650 		} else {
651 			return -EPROTO;
652 		}
653 
654 		idx++;
655 	}
656 
657 	return -ENODATA;
658 }
659 EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);
660 
661 static int acpi_data_prop_read_single(struct acpi_device_data *data,
662 				      const char *propname,
663 				      enum dev_prop_type proptype, void *val)
664 {
665 	const union acpi_object *obj;
666 	int ret;
667 
668 	if (!val)
669 		return -EINVAL;
670 
671 	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
672 		ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj);
673 		if (ret)
674 			return ret;
675 
676 		switch (proptype) {
677 		case DEV_PROP_U8:
678 			if (obj->integer.value > U8_MAX)
679 				return -EOVERFLOW;
680 			*(u8 *)val = obj->integer.value;
681 			break;
682 		case DEV_PROP_U16:
683 			if (obj->integer.value > U16_MAX)
684 				return -EOVERFLOW;
685 			*(u16 *)val = obj->integer.value;
686 			break;
687 		case DEV_PROP_U32:
688 			if (obj->integer.value > U32_MAX)
689 				return -EOVERFLOW;
690 			*(u32 *)val = obj->integer.value;
691 			break;
692 		default:
693 			*(u64 *)val = obj->integer.value;
694 			break;
695 		}
696 	} else if (proptype == DEV_PROP_STRING) {
697 		ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj);
698 		if (ret)
699 			return ret;
700 
701 		*(char **)val = obj->string.pointer;
702 	} else {
703 		ret = -EINVAL;
704 	}
705 	return ret;
706 }
707 
708 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
709 			      enum dev_prop_type proptype, void *val)
710 {
711 	return adev ? acpi_data_prop_read_single(&adev->data, propname, proptype, val) : -EINVAL;
712 }
713 
714 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
715 				       size_t nval)
716 {
717 	int i;
718 
719 	for (i = 0; i < nval; i++) {
720 		if (items[i].type != ACPI_TYPE_INTEGER)
721 			return -EPROTO;
722 		if (items[i].integer.value > U8_MAX)
723 			return -EOVERFLOW;
724 
725 		val[i] = items[i].integer.value;
726 	}
727 	return 0;
728 }
729 
730 static int acpi_copy_property_array_u16(const union acpi_object *items,
731 					u16 *val, size_t nval)
732 {
733 	int i;
734 
735 	for (i = 0; i < nval; i++) {
736 		if (items[i].type != ACPI_TYPE_INTEGER)
737 			return -EPROTO;
738 		if (items[i].integer.value > U16_MAX)
739 			return -EOVERFLOW;
740 
741 		val[i] = items[i].integer.value;
742 	}
743 	return 0;
744 }
745 
746 static int acpi_copy_property_array_u32(const union acpi_object *items,
747 					u32 *val, size_t nval)
748 {
749 	int i;
750 
751 	for (i = 0; i < nval; i++) {
752 		if (items[i].type != ACPI_TYPE_INTEGER)
753 			return -EPROTO;
754 		if (items[i].integer.value > U32_MAX)
755 			return -EOVERFLOW;
756 
757 		val[i] = items[i].integer.value;
758 	}
759 	return 0;
760 }
761 
762 static int acpi_copy_property_array_u64(const union acpi_object *items,
763 					u64 *val, size_t nval)
764 {
765 	int i;
766 
767 	for (i = 0; i < nval; i++) {
768 		if (items[i].type != ACPI_TYPE_INTEGER)
769 			return -EPROTO;
770 
771 		val[i] = items[i].integer.value;
772 	}
773 	return 0;
774 }
775 
776 static int acpi_copy_property_array_string(const union acpi_object *items,
777 					   char **val, size_t nval)
778 {
779 	int i;
780 
781 	for (i = 0; i < nval; i++) {
782 		if (items[i].type != ACPI_TYPE_STRING)
783 			return -EPROTO;
784 
785 		val[i] = items[i].string.pointer;
786 	}
787 	return 0;
788 }
789 
790 static int acpi_data_prop_read(struct acpi_device_data *data,
791 			       const char *propname,
792 			       enum dev_prop_type proptype,
793 			       void *val, size_t nval)
794 {
795 	const union acpi_object *obj;
796 	const union acpi_object *items;
797 	int ret;
798 
799 	if (val && nval == 1) {
800 		ret = acpi_data_prop_read_single(data, propname, proptype, val);
801 		if (!ret)
802 			return ret;
803 	}
804 
805 	ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj);
806 	if (ret)
807 		return ret;
808 
809 	if (!val)
810 		return obj->package.count;
811 
812 	if (nval > obj->package.count)
813 		return -EOVERFLOW;
814 	else if (nval <= 0)
815 		return -EINVAL;
816 
817 	items = obj->package.elements;
818 
819 	switch (proptype) {
820 	case DEV_PROP_U8:
821 		ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
822 		break;
823 	case DEV_PROP_U16:
824 		ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
825 		break;
826 	case DEV_PROP_U32:
827 		ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
828 		break;
829 	case DEV_PROP_U64:
830 		ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
831 		break;
832 	case DEV_PROP_STRING:
833 		ret = acpi_copy_property_array_string(items, (char **)val, nval);
834 		break;
835 	default:
836 		ret = -EINVAL;
837 		break;
838 	}
839 	return ret;
840 }
841 
842 int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
843 		       enum dev_prop_type proptype, void *val, size_t nval)
844 {
845 	return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL;
846 }
847 
848 /**
849  * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
850  * @fwnode: Firmware node to get the property from.
851  * @propname: Name of the property.
852  * @proptype: Expected property type.
853  * @val: Location to store the property value (if not %NULL).
854  * @nval: Size of the array pointed to by @val.
855  *
856  * If @val is %NULL, return the number of array elements comprising the value
857  * of the property.  Otherwise, read at most @nval values to the array at the
858  * location pointed to by @val.
859  */
860 int acpi_node_prop_read(struct fwnode_handle *fwnode,  const char *propname,
861 		        enum dev_prop_type proptype, void *val, size_t nval)
862 {
863 	return acpi_data_prop_read(acpi_device_data_of_node(fwnode),
864 				   propname, proptype, val, nval);
865 }
866 
867 /**
868  * acpi_get_next_subnode - Return the next child node handle for a device.
869  * @dev: Device to find the next child node for.
870  * @child: Handle to one of the device's child nodes or a null handle.
871  */
872 struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
873 					    struct fwnode_handle *child)
874 {
875 	struct acpi_device *adev = ACPI_COMPANION(dev);
876 	struct list_head *head, *next;
877 
878 	if (!adev)
879 		return NULL;
880 
881 	if (!child || child->type == FWNODE_ACPI) {
882 		head = &adev->children;
883 		if (list_empty(head))
884 			goto nondev;
885 
886 		if (child) {
887 			adev = to_acpi_device_node(child);
888 			next = adev->node.next;
889 			if (next == head) {
890 				child = NULL;
891 				adev = ACPI_COMPANION(dev);
892 				goto nondev;
893 			}
894 			adev = list_entry(next, struct acpi_device, node);
895 		} else {
896 			adev = list_first_entry(head, struct acpi_device, node);
897 		}
898 		return acpi_fwnode_handle(adev);
899 	}
900 
901  nondev:
902 	if (!child || child->type == FWNODE_ACPI_DATA) {
903 		struct acpi_data_node *dn;
904 
905 		head = &adev->data.subnodes;
906 		if (list_empty(head))
907 			return NULL;
908 
909 		if (child) {
910 			dn = to_acpi_data_node(child);
911 			next = dn->sibling.next;
912 			if (next == head)
913 				return NULL;
914 
915 			dn = list_entry(next, struct acpi_data_node, sibling);
916 		} else {
917 			dn = list_first_entry(head, struct acpi_data_node, sibling);
918 		}
919 		return &dn->fwnode;
920 	}
921 	return NULL;
922 }
923