xref: /openbmc/linux/drivers/acpi/property.c (revision 4a5f8ae5)
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 					   struct fwnode_handle *parent);
42 static bool acpi_extract_properties(const union acpi_object *desc,
43 				    struct acpi_device_data *data);
44 
45 static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
46 					acpi_handle handle,
47 					const union acpi_object *link,
48 					struct list_head *list,
49 					struct fwnode_handle *parent)
50 {
51 	struct acpi_data_node *dn;
52 	bool result;
53 
54 	dn = kzalloc(sizeof(*dn), GFP_KERNEL);
55 	if (!dn)
56 		return false;
57 
58 	dn->name = link->package.elements[0].string.pointer;
59 	dn->fwnode.type = FWNODE_ACPI_DATA;
60 	dn->parent = parent;
61 	INIT_LIST_HEAD(&dn->data.subnodes);
62 
63 	result = acpi_extract_properties(desc, &dn->data);
64 
65 	if (handle) {
66 		acpi_handle scope;
67 		acpi_status status;
68 
69 		/*
70 		 * The scope for the subnode object lookup is the one of the
71 		 * namespace node (device) containing the object that has
72 		 * returned the package.  That is, it's the scope of that
73 		 * object's parent.
74 		 */
75 		status = acpi_get_parent(handle, &scope);
76 		if (ACPI_SUCCESS(status)
77 		    && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data,
78 						      &dn->fwnode))
79 			result = true;
80 	} else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data,
81 						  &dn->fwnode)) {
82 		result = true;
83 	}
84 
85 	if (result) {
86 		dn->handle = handle;
87 		dn->data.pointer = desc;
88 		list_add_tail(&dn->sibling, list);
89 		return true;
90 	}
91 
92 	kfree(dn);
93 	acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
94 	return false;
95 }
96 
97 static bool acpi_nondev_subnode_data_ok(acpi_handle handle,
98 					const union acpi_object *link,
99 					struct list_head *list,
100 					struct fwnode_handle *parent)
101 {
102 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
103 	acpi_status status;
104 
105 	status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
106 					    ACPI_TYPE_PACKAGE);
107 	if (ACPI_FAILURE(status))
108 		return false;
109 
110 	if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list,
111 					parent))
112 		return true;
113 
114 	ACPI_FREE(buf.pointer);
115 	return false;
116 }
117 
118 static bool acpi_nondev_subnode_ok(acpi_handle scope,
119 				   const union acpi_object *link,
120 				   struct list_head *list,
121 				   struct fwnode_handle *parent)
122 {
123 	acpi_handle handle;
124 	acpi_status status;
125 
126 	if (!scope)
127 		return false;
128 
129 	status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
130 				 &handle);
131 	if (ACPI_FAILURE(status))
132 		return false;
133 
134 	return acpi_nondev_subnode_data_ok(handle, link, list, parent);
135 }
136 
137 static int acpi_add_nondev_subnodes(acpi_handle scope,
138 				    const union acpi_object *links,
139 				    struct list_head *list,
140 				    struct fwnode_handle *parent)
141 {
142 	bool ret = false;
143 	int i;
144 
145 	for (i = 0; i < links->package.count; i++) {
146 		const union acpi_object *link, *desc;
147 		acpi_handle handle;
148 		bool result;
149 
150 		link = &links->package.elements[i];
151 		/* Only two elements allowed. */
152 		if (link->package.count != 2)
153 			continue;
154 
155 		/* The first one must be a string. */
156 		if (link->package.elements[0].type != ACPI_TYPE_STRING)
157 			continue;
158 
159 		/* The second one may be a string, a reference or a package. */
160 		switch (link->package.elements[1].type) {
161 		case ACPI_TYPE_STRING:
162 			result = acpi_nondev_subnode_ok(scope, link, list,
163 							 parent);
164 			break;
165 		case ACPI_TYPE_LOCAL_REFERENCE:
166 			handle = link->package.elements[1].reference.handle;
167 			result = acpi_nondev_subnode_data_ok(handle, link, list,
168 							     parent);
169 			break;
170 		case ACPI_TYPE_PACKAGE:
171 			desc = &link->package.elements[1];
172 			result = acpi_nondev_subnode_extract(desc, NULL, link,
173 							     list, parent);
174 			break;
175 		default:
176 			result = false;
177 			break;
178 		}
179 		ret = ret || result;
180 	}
181 
182 	return ret;
183 }
184 
185 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
186 					   const union acpi_object *desc,
187 					   struct acpi_device_data *data,
188 					   struct fwnode_handle *parent)
189 {
190 	int i;
191 
192 	/* Look for the ACPI data subnodes UUID. */
193 	for (i = 0; i < desc->package.count; i += 2) {
194 		const union acpi_object *uuid, *links;
195 
196 		uuid = &desc->package.elements[i];
197 		links = &desc->package.elements[i + 1];
198 
199 		/*
200 		 * The first element must be a UUID and the second one must be
201 		 * a package.
202 		 */
203 		if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
204 		    || links->type != ACPI_TYPE_PACKAGE)
205 			break;
206 
207 		if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid)))
208 			continue;
209 
210 		return acpi_add_nondev_subnodes(scope, links, &data->subnodes,
211 						parent);
212 	}
213 
214 	return false;
215 }
216 
217 static bool acpi_property_value_ok(const union acpi_object *value)
218 {
219 	int j;
220 
221 	/*
222 	 * The value must be an integer, a string, a reference, or a package
223 	 * whose every element must be an integer, a string, or a reference.
224 	 */
225 	switch (value->type) {
226 	case ACPI_TYPE_INTEGER:
227 	case ACPI_TYPE_STRING:
228 	case ACPI_TYPE_LOCAL_REFERENCE:
229 		return true;
230 
231 	case ACPI_TYPE_PACKAGE:
232 		for (j = 0; j < value->package.count; j++)
233 			switch (value->package.elements[j].type) {
234 			case ACPI_TYPE_INTEGER:
235 			case ACPI_TYPE_STRING:
236 			case ACPI_TYPE_LOCAL_REFERENCE:
237 				continue;
238 
239 			default:
240 				return false;
241 			}
242 
243 		return true;
244 	}
245 	return false;
246 }
247 
248 static bool acpi_properties_format_valid(const union acpi_object *properties)
249 {
250 	int i;
251 
252 	for (i = 0; i < properties->package.count; i++) {
253 		const union acpi_object *property;
254 
255 		property = &properties->package.elements[i];
256 		/*
257 		 * Only two elements allowed, the first one must be a string and
258 		 * the second one has to satisfy certain conditions.
259 		 */
260 		if (property->package.count != 2
261 		    || property->package.elements[0].type != ACPI_TYPE_STRING
262 		    || !acpi_property_value_ok(&property->package.elements[1]))
263 			return false;
264 	}
265 	return true;
266 }
267 
268 static void acpi_init_of_compatible(struct acpi_device *adev)
269 {
270 	const union acpi_object *of_compatible;
271 	int ret;
272 
273 	ret = acpi_data_get_property_array(&adev->data, "compatible",
274 					   ACPI_TYPE_STRING, &of_compatible);
275 	if (ret) {
276 		ret = acpi_dev_get_property(adev, "compatible",
277 					    ACPI_TYPE_STRING, &of_compatible);
278 		if (ret) {
279 			if (adev->parent
280 			    && adev->parent->flags.of_compatible_ok)
281 				goto out;
282 
283 			return;
284 		}
285 	}
286 	adev->data.of_compatible = of_compatible;
287 
288  out:
289 	adev->flags.of_compatible_ok = 1;
290 }
291 
292 static bool acpi_extract_properties(const union acpi_object *desc,
293 				    struct acpi_device_data *data)
294 {
295 	int i;
296 
297 	if (desc->package.count % 2)
298 		return false;
299 
300 	/* Look for the device properties UUID. */
301 	for (i = 0; i < desc->package.count; i += 2) {
302 		const union acpi_object *uuid, *properties;
303 
304 		uuid = &desc->package.elements[i];
305 		properties = &desc->package.elements[i + 1];
306 
307 		/*
308 		 * The first element must be a UUID and the second one must be
309 		 * a package.
310 		 */
311 		if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
312 		    || properties->type != ACPI_TYPE_PACKAGE)
313 			break;
314 
315 		if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid)))
316 			continue;
317 
318 		/*
319 		 * We found the matching UUID. Now validate the format of the
320 		 * package immediately following it.
321 		 */
322 		if (!acpi_properties_format_valid(properties))
323 			break;
324 
325 		data->properties = properties;
326 		return true;
327 	}
328 
329 	return false;
330 }
331 
332 void acpi_init_properties(struct acpi_device *adev)
333 {
334 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
335 	struct acpi_hardware_id *hwid;
336 	acpi_status status;
337 	bool acpi_of = false;
338 
339 	INIT_LIST_HEAD(&adev->data.subnodes);
340 
341 	/*
342 	 * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
343 	 * Device Tree compatible properties for this device.
344 	 */
345 	list_for_each_entry(hwid, &adev->pnp.ids, list) {
346 		if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) {
347 			acpi_of = true;
348 			break;
349 		}
350 	}
351 
352 	status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
353 					    ACPI_TYPE_PACKAGE);
354 	if (ACPI_FAILURE(status))
355 		goto out;
356 
357 	if (acpi_extract_properties(buf.pointer, &adev->data)) {
358 		adev->data.pointer = buf.pointer;
359 		if (acpi_of)
360 			acpi_init_of_compatible(adev);
361 	}
362 	if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer,
363 					&adev->data, acpi_fwnode_handle(adev)))
364 		adev->data.pointer = buf.pointer;
365 
366 	if (!adev->data.pointer) {
367 		acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n");
368 		ACPI_FREE(buf.pointer);
369 	}
370 
371  out:
372 	if (acpi_of && !adev->flags.of_compatible_ok)
373 		acpi_handle_info(adev->handle,
374 			 ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n");
375 }
376 
377 static void acpi_destroy_nondev_subnodes(struct list_head *list)
378 {
379 	struct acpi_data_node *dn, *next;
380 
381 	if (list_empty(list))
382 		return;
383 
384 	list_for_each_entry_safe_reverse(dn, next, list, sibling) {
385 		acpi_destroy_nondev_subnodes(&dn->data.subnodes);
386 		wait_for_completion(&dn->kobj_done);
387 		list_del(&dn->sibling);
388 		ACPI_FREE((void *)dn->data.pointer);
389 		kfree(dn);
390 	}
391 }
392 
393 void acpi_free_properties(struct acpi_device *adev)
394 {
395 	acpi_destroy_nondev_subnodes(&adev->data.subnodes);
396 	ACPI_FREE((void *)adev->data.pointer);
397 	adev->data.of_compatible = NULL;
398 	adev->data.pointer = NULL;
399 	adev->data.properties = NULL;
400 }
401 
402 /**
403  * acpi_data_get_property - return an ACPI property with given name
404  * @data: ACPI device deta object to get the property from
405  * @name: Name of the property
406  * @type: Expected property type
407  * @obj: Location to store the property value (if not %NULL)
408  *
409  * Look up a property with @name and store a pointer to the resulting ACPI
410  * object at the location pointed to by @obj if found.
411  *
412  * Callers must not attempt to free the returned objects.  These objects will be
413  * freed by the ACPI core automatically during the removal of @data.
414  *
415  * Return: %0 if property with @name has been found (success),
416  *         %-EINVAL if the arguments are invalid,
417  *         %-EINVAL if the property doesn't exist,
418  *         %-EPROTO if the property value type doesn't match @type.
419  */
420 static int acpi_data_get_property(struct acpi_device_data *data,
421 				  const char *name, acpi_object_type type,
422 				  const union acpi_object **obj)
423 {
424 	const union acpi_object *properties;
425 	int i;
426 
427 	if (!data || !name)
428 		return -EINVAL;
429 
430 	if (!data->pointer || !data->properties)
431 		return -EINVAL;
432 
433 	properties = data->properties;
434 	for (i = 0; i < properties->package.count; i++) {
435 		const union acpi_object *propname, *propvalue;
436 		const union acpi_object *property;
437 
438 		property = &properties->package.elements[i];
439 
440 		propname = &property->package.elements[0];
441 		propvalue = &property->package.elements[1];
442 
443 		if (!strcmp(name, propname->string.pointer)) {
444 			if (type != ACPI_TYPE_ANY && propvalue->type != type)
445 				return -EPROTO;
446 			if (obj)
447 				*obj = propvalue;
448 
449 			return 0;
450 		}
451 	}
452 	return -EINVAL;
453 }
454 
455 /**
456  * acpi_dev_get_property - return an ACPI property with given name.
457  * @adev: ACPI device to get the property from.
458  * @name: Name of the property.
459  * @type: Expected property type.
460  * @obj: Location to store the property value (if not %NULL).
461  */
462 int acpi_dev_get_property(struct acpi_device *adev, const char *name,
463 			  acpi_object_type type, const union acpi_object **obj)
464 {
465 	return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL;
466 }
467 EXPORT_SYMBOL_GPL(acpi_dev_get_property);
468 
469 static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode)
470 {
471 	if (fwnode->type == FWNODE_ACPI) {
472 		struct acpi_device *adev = to_acpi_device_node(fwnode);
473 		return &adev->data;
474 	} else if (fwnode->type == FWNODE_ACPI_DATA) {
475 		struct acpi_data_node *dn = to_acpi_data_node(fwnode);
476 		return &dn->data;
477 	}
478 	return NULL;
479 }
480 
481 /**
482  * acpi_node_prop_get - return an ACPI property with given name.
483  * @fwnode: Firmware node to get the property from.
484  * @propname: Name of the property.
485  * @valptr: Location to store a pointer to the property value (if not %NULL).
486  */
487 int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
488 		       void **valptr)
489 {
490 	return acpi_data_get_property(acpi_device_data_of_node(fwnode),
491 				      propname, ACPI_TYPE_ANY,
492 				      (const union acpi_object **)valptr);
493 }
494 
495 /**
496  * acpi_data_get_property_array - return an ACPI array property with given name
497  * @adev: ACPI data object to get the property from
498  * @name: Name of the property
499  * @type: Expected type of array elements
500  * @obj: Location to store a pointer to the property value (if not NULL)
501  *
502  * Look up an array property with @name and store a pointer to the resulting
503  * ACPI object at the location pointed to by @obj if found.
504  *
505  * Callers must not attempt to free the returned objects.  Those objects will be
506  * freed by the ACPI core automatically during the removal of @data.
507  *
508  * Return: %0 if array property (package) with @name has been found (success),
509  *         %-EINVAL if the arguments are invalid,
510  *         %-EINVAL if the property doesn't exist,
511  *         %-EPROTO if the property is not a package or the type of its elements
512  *           doesn't match @type.
513  */
514 static int acpi_data_get_property_array(struct acpi_device_data *data,
515 					const char *name,
516 					acpi_object_type type,
517 					const union acpi_object **obj)
518 {
519 	const union acpi_object *prop;
520 	int ret, i;
521 
522 	ret = acpi_data_get_property(data, name, ACPI_TYPE_PACKAGE, &prop);
523 	if (ret)
524 		return ret;
525 
526 	if (type != ACPI_TYPE_ANY) {
527 		/* Check that all elements are of correct type. */
528 		for (i = 0; i < prop->package.count; i++)
529 			if (prop->package.elements[i].type != type)
530 				return -EPROTO;
531 	}
532 	if (obj)
533 		*obj = prop;
534 
535 	return 0;
536 }
537 
538 /**
539  * __acpi_node_get_property_reference - returns handle to the referenced object
540  * @fwnode: Firmware node to get the property from
541  * @propname: Name of the property
542  * @index: Index of the reference to return
543  * @num_args: Maximum number of arguments after each reference
544  * @args: Location to store the returned reference with optional arguments
545  *
546  * Find property with @name, verifify that it is a package containing at least
547  * one object reference and if so, store the ACPI device object pointer to the
548  * target object in @args->adev.  If the reference includes arguments, store
549  * them in the @args->args[] array.
550  *
551  * If there's more than one reference in the property value package, @index is
552  * used to select the one to return.
553  *
554  * It is possible to leave holes in the property value set like in the
555  * example below:
556  *
557  * Package () {
558  *     "cs-gpios",
559  *     Package () {
560  *        ^GPIO, 19, 0, 0,
561  *        ^GPIO, 20, 0, 0,
562  *        0,
563  *        ^GPIO, 21, 0, 0,
564  *     }
565  * }
566  *
567  * Calling this function with index %2 return %-ENOENT and with index %3
568  * returns the last entry. If the property does not contain any more values
569  * %-ENODATA is returned. The NULL entry must be single integer and
570  * preferably contain value %0.
571  *
572  * Return: %0 on success, negative error code on failure.
573  */
574 int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
575 	const char *propname, size_t index, size_t num_args,
576 	struct acpi_reference_args *args)
577 {
578 	const union acpi_object *element, *end;
579 	const union acpi_object *obj;
580 	struct acpi_device_data *data;
581 	struct acpi_device *device;
582 	int ret, idx = 0;
583 
584 	data = acpi_device_data_of_node(fwnode);
585 	if (!data)
586 		return -EINVAL;
587 
588 	ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
589 	if (ret)
590 		return ret;
591 
592 	/*
593 	 * The simplest case is when the value is a single reference.  Just
594 	 * return that reference then.
595 	 */
596 	if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
597 		if (index)
598 			return -EINVAL;
599 
600 		ret = acpi_bus_get_device(obj->reference.handle, &device);
601 		if (ret)
602 			return ret;
603 
604 		args->adev = device;
605 		args->nargs = 0;
606 		return 0;
607 	}
608 
609 	/*
610 	 * If it is not a single reference, then it is a package of
611 	 * references followed by number of ints as follows:
612 	 *
613 	 *  Package () { REF, INT, REF, INT, INT }
614 	 *
615 	 * The index argument is then used to determine which reference
616 	 * the caller wants (along with the arguments).
617 	 */
618 	if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
619 		return -EPROTO;
620 
621 	element = obj->package.elements;
622 	end = element + obj->package.count;
623 
624 	while (element < end) {
625 		u32 nargs, i;
626 
627 		if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
628 			ret = acpi_bus_get_device(element->reference.handle,
629 						  &device);
630 			if (ret)
631 				return -ENODEV;
632 
633 			nargs = 0;
634 			element++;
635 
636 			/* assume following integer elements are all args */
637 			for (i = 0; element + i < end && i < num_args; i++) {
638 				int type = element[i].type;
639 
640 				if (type == ACPI_TYPE_INTEGER)
641 					nargs++;
642 				else if (type == ACPI_TYPE_LOCAL_REFERENCE)
643 					break;
644 				else
645 					return -EPROTO;
646 			}
647 
648 			if (nargs > MAX_ACPI_REFERENCE_ARGS)
649 				return -EPROTO;
650 
651 			if (idx == index) {
652 				args->adev = device;
653 				args->nargs = nargs;
654 				for (i = 0; i < nargs; i++)
655 					args->args[i] = element[i].integer.value;
656 
657 				return 0;
658 			}
659 
660 			element += nargs;
661 		} else if (element->type == ACPI_TYPE_INTEGER) {
662 			if (idx == index)
663 				return -ENOENT;
664 			element++;
665 		} else {
666 			return -EPROTO;
667 		}
668 
669 		idx++;
670 	}
671 
672 	return -ENODATA;
673 }
674 EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);
675 
676 static int acpi_data_prop_read_single(struct acpi_device_data *data,
677 				      const char *propname,
678 				      enum dev_prop_type proptype, void *val)
679 {
680 	const union acpi_object *obj;
681 	int ret;
682 
683 	if (!val)
684 		return -EINVAL;
685 
686 	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
687 		ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj);
688 		if (ret)
689 			return ret;
690 
691 		switch (proptype) {
692 		case DEV_PROP_U8:
693 			if (obj->integer.value > U8_MAX)
694 				return -EOVERFLOW;
695 			*(u8 *)val = obj->integer.value;
696 			break;
697 		case DEV_PROP_U16:
698 			if (obj->integer.value > U16_MAX)
699 				return -EOVERFLOW;
700 			*(u16 *)val = obj->integer.value;
701 			break;
702 		case DEV_PROP_U32:
703 			if (obj->integer.value > U32_MAX)
704 				return -EOVERFLOW;
705 			*(u32 *)val = obj->integer.value;
706 			break;
707 		default:
708 			*(u64 *)val = obj->integer.value;
709 			break;
710 		}
711 	} else if (proptype == DEV_PROP_STRING) {
712 		ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj);
713 		if (ret)
714 			return ret;
715 
716 		*(char **)val = obj->string.pointer;
717 
718 		return 1;
719 	} else {
720 		ret = -EINVAL;
721 	}
722 	return ret;
723 }
724 
725 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
726 			      enum dev_prop_type proptype, void *val)
727 {
728 	int ret;
729 
730 	if (!adev)
731 		return -EINVAL;
732 
733 	ret = acpi_data_prop_read_single(&adev->data, propname, proptype, val);
734 	if (ret < 0 || proptype != ACPI_TYPE_STRING)
735 		return ret;
736 	return 0;
737 }
738 
739 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
740 				       size_t nval)
741 {
742 	int i;
743 
744 	for (i = 0; i < nval; i++) {
745 		if (items[i].type != ACPI_TYPE_INTEGER)
746 			return -EPROTO;
747 		if (items[i].integer.value > U8_MAX)
748 			return -EOVERFLOW;
749 
750 		val[i] = items[i].integer.value;
751 	}
752 	return 0;
753 }
754 
755 static int acpi_copy_property_array_u16(const union acpi_object *items,
756 					u16 *val, size_t nval)
757 {
758 	int i;
759 
760 	for (i = 0; i < nval; i++) {
761 		if (items[i].type != ACPI_TYPE_INTEGER)
762 			return -EPROTO;
763 		if (items[i].integer.value > U16_MAX)
764 			return -EOVERFLOW;
765 
766 		val[i] = items[i].integer.value;
767 	}
768 	return 0;
769 }
770 
771 static int acpi_copy_property_array_u32(const union acpi_object *items,
772 					u32 *val, size_t nval)
773 {
774 	int i;
775 
776 	for (i = 0; i < nval; i++) {
777 		if (items[i].type != ACPI_TYPE_INTEGER)
778 			return -EPROTO;
779 		if (items[i].integer.value > U32_MAX)
780 			return -EOVERFLOW;
781 
782 		val[i] = items[i].integer.value;
783 	}
784 	return 0;
785 }
786 
787 static int acpi_copy_property_array_u64(const union acpi_object *items,
788 					u64 *val, size_t nval)
789 {
790 	int i;
791 
792 	for (i = 0; i < nval; i++) {
793 		if (items[i].type != ACPI_TYPE_INTEGER)
794 			return -EPROTO;
795 
796 		val[i] = items[i].integer.value;
797 	}
798 	return 0;
799 }
800 
801 static int acpi_copy_property_array_string(const union acpi_object *items,
802 					   char **val, size_t nval)
803 {
804 	int i;
805 
806 	for (i = 0; i < nval; i++) {
807 		if (items[i].type != ACPI_TYPE_STRING)
808 			return -EPROTO;
809 
810 		val[i] = items[i].string.pointer;
811 	}
812 	return nval;
813 }
814 
815 static int acpi_data_prop_read(struct acpi_device_data *data,
816 			       const char *propname,
817 			       enum dev_prop_type proptype,
818 			       void *val, size_t nval)
819 {
820 	const union acpi_object *obj;
821 	const union acpi_object *items;
822 	int ret;
823 
824 	if (val && nval == 1) {
825 		ret = acpi_data_prop_read_single(data, propname, proptype, val);
826 		if (ret >= 0)
827 			return ret;
828 	}
829 
830 	ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj);
831 	if (ret)
832 		return ret;
833 
834 	if (!val)
835 		return obj->package.count;
836 
837 	if (proptype != DEV_PROP_STRING && nval > obj->package.count)
838 		return -EOVERFLOW;
839 	else if (nval <= 0)
840 		return -EINVAL;
841 
842 	items = obj->package.elements;
843 
844 	switch (proptype) {
845 	case DEV_PROP_U8:
846 		ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
847 		break;
848 	case DEV_PROP_U16:
849 		ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
850 		break;
851 	case DEV_PROP_U32:
852 		ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
853 		break;
854 	case DEV_PROP_U64:
855 		ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
856 		break;
857 	case DEV_PROP_STRING:
858 		ret = acpi_copy_property_array_string(
859 			items, (char **)val,
860 			min_t(u32, nval, obj->package.count));
861 		break;
862 	default:
863 		ret = -EINVAL;
864 		break;
865 	}
866 	return ret;
867 }
868 
869 int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
870 		       enum dev_prop_type proptype, void *val, size_t nval)
871 {
872 	return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL;
873 }
874 
875 /**
876  * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
877  * @fwnode: Firmware node to get the property from.
878  * @propname: Name of the property.
879  * @proptype: Expected property type.
880  * @val: Location to store the property value (if not %NULL).
881  * @nval: Size of the array pointed to by @val.
882  *
883  * If @val is %NULL, return the number of array elements comprising the value
884  * of the property.  Otherwise, read at most @nval values to the array at the
885  * location pointed to by @val.
886  */
887 int acpi_node_prop_read(struct fwnode_handle *fwnode,  const char *propname,
888 		        enum dev_prop_type proptype, void *val, size_t nval)
889 {
890 	return acpi_data_prop_read(acpi_device_data_of_node(fwnode),
891 				   propname, proptype, val, nval);
892 }
893 
894 /**
895  * acpi_get_next_subnode - Return the next child node handle for a fwnode
896  * @fwnode: Firmware node to find the next child node for.
897  * @child: Handle to one of the device's child nodes or a null handle.
898  */
899 struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode,
900 					    struct fwnode_handle *child)
901 {
902 	struct acpi_device *adev = to_acpi_device_node(fwnode);
903 	struct list_head *head, *next;
904 
905 	if (!child || child->type == FWNODE_ACPI) {
906 		if (adev)
907 			head = &adev->children;
908 		else
909 			goto nondev;
910 
911 		if (list_empty(head))
912 			goto nondev;
913 
914 		if (child) {
915 			adev = to_acpi_device_node(child);
916 			next = adev->node.next;
917 			if (next == head) {
918 				child = NULL;
919 				goto nondev;
920 			}
921 			adev = list_entry(next, struct acpi_device, node);
922 		} else {
923 			adev = list_first_entry(head, struct acpi_device, node);
924 		}
925 		return acpi_fwnode_handle(adev);
926 	}
927 
928  nondev:
929 	if (!child || child->type == FWNODE_ACPI_DATA) {
930 		struct acpi_data_node *data = to_acpi_data_node(fwnode);
931 		struct acpi_data_node *dn;
932 
933 		if (adev)
934 			head = &adev->data.subnodes;
935 		else if (data)
936 			head = &data->data.subnodes;
937 		else
938 			return NULL;
939 
940 		if (list_empty(head))
941 			return NULL;
942 
943 		if (child) {
944 			dn = to_acpi_data_node(child);
945 			next = dn->sibling.next;
946 			if (next == head)
947 				return NULL;
948 
949 			dn = list_entry(next, struct acpi_data_node, sibling);
950 		} else {
951 			dn = list_first_entry(head, struct acpi_data_node, sibling);
952 		}
953 		return &dn->fwnode;
954 	}
955 	return NULL;
956 }
957 
958 /**
959  * acpi_node_get_parent - Return parent fwnode of this fwnode
960  * @fwnode: Firmware node whose parent to get
961  *
962  * Returns parent node of an ACPI device or data firmware node or %NULL if
963  * not available.
964  */
965 struct fwnode_handle *acpi_node_get_parent(struct fwnode_handle *fwnode)
966 {
967 	if (is_acpi_data_node(fwnode)) {
968 		/* All data nodes have parent pointer so just return that */
969 		return to_acpi_data_node(fwnode)->parent;
970 	} else if (is_acpi_device_node(fwnode)) {
971 		acpi_handle handle, parent_handle;
972 
973 		handle = to_acpi_device_node(fwnode)->handle;
974 		if (ACPI_SUCCESS(acpi_get_parent(handle, &parent_handle))) {
975 			struct acpi_device *adev;
976 
977 			if (!acpi_bus_get_device(parent_handle, &adev))
978 				return acpi_fwnode_handle(adev);
979 		}
980 	}
981 
982 	return NULL;
983 }
984 
985 /**
986  * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node
987  * @fwnode: Pointer to the parent firmware node
988  * @prev: Previous endpoint node or %NULL to get the first
989  *
990  * Looks up next endpoint ACPI firmware node below a given @fwnode. Returns
991  * %NULL if there is no next endpoint, ERR_PTR() in case of error. In case
992  * of success the next endpoint is returned.
993  */
994 struct fwnode_handle *acpi_graph_get_next_endpoint(struct fwnode_handle *fwnode,
995 						   struct fwnode_handle *prev)
996 {
997 	struct fwnode_handle *port = NULL;
998 	struct fwnode_handle *endpoint;
999 
1000 	if (!prev) {
1001 		do {
1002 			port = fwnode_get_next_child_node(fwnode, port);
1003 			/* Ports must have port property */
1004 			if (fwnode_property_present(port, "port"))
1005 				break;
1006 		} while (port);
1007 	} else {
1008 		port = fwnode_get_parent(prev);
1009 	}
1010 
1011 	if (!port)
1012 		return NULL;
1013 
1014 	endpoint = fwnode_get_next_child_node(port, prev);
1015 	while (!endpoint) {
1016 		port = fwnode_get_next_child_node(fwnode, port);
1017 		if (!port)
1018 			break;
1019 		if (fwnode_property_present(port, "port"))
1020 			endpoint = fwnode_get_next_child_node(port, NULL);
1021 	}
1022 
1023 	if (endpoint) {
1024 		/* Endpoints must have "endpoint" property */
1025 		if (!fwnode_property_present(endpoint, "endpoint"))
1026 			return ERR_PTR(-EPROTO);
1027 	}
1028 
1029 	return endpoint;
1030 }
1031 
1032 /**
1033  * acpi_graph_get_child_prop_value - Return a child with a given property value
1034  * @fwnode: device fwnode
1035  * @prop_name: The name of the property to look for
1036  * @val: the desired property value
1037  *
1038  * Return the port node corresponding to a given port number. Returns
1039  * the child node on success, NULL otherwise.
1040  */
1041 static struct fwnode_handle *acpi_graph_get_child_prop_value(
1042 	struct fwnode_handle *fwnode, const char *prop_name, unsigned int val)
1043 {
1044 	struct fwnode_handle *child;
1045 
1046 	fwnode_for_each_child_node(fwnode, child) {
1047 		u32 nr;
1048 
1049 		if (!fwnode_property_read_u32(fwnode, prop_name, &nr))
1050 			continue;
1051 
1052 		if (val == nr)
1053 			return child;
1054 	}
1055 
1056 	return NULL;
1057 }
1058 
1059 
1060 /**
1061  * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint
1062  * @fwnode: Endpoint firmware node pointing to a remote device
1063  * @parent: Firmware node of remote port parent is filled here if not %NULL
1064  * @port: Firmware node of remote port is filled here if not %NULL
1065  * @endpoint: Firmware node of remote endpoint is filled here if not %NULL
1066  *
1067  * Function parses remote end of ACPI firmware remote endpoint and fills in
1068  * fields requested by the caller. Returns %0 in case of success and
1069  * negative errno otherwise.
1070  */
1071 int acpi_graph_get_remote_endpoint(struct fwnode_handle *fwnode,
1072 				   struct fwnode_handle **parent,
1073 				   struct fwnode_handle **port,
1074 				   struct fwnode_handle **endpoint)
1075 {
1076 	unsigned int port_nr, endpoint_nr;
1077 	struct acpi_reference_args args;
1078 	int ret;
1079 
1080 	memset(&args, 0, sizeof(args));
1081 	ret = acpi_node_get_property_reference(fwnode, "remote-endpoint", 0,
1082 					       &args);
1083 	if (ret)
1084 		return ret;
1085 
1086 	/*
1087 	 * Always require two arguments with the reference: port and
1088 	 * endpoint indices.
1089 	 */
1090 	if (args.nargs != 2)
1091 		return -EPROTO;
1092 
1093 	fwnode = acpi_fwnode_handle(args.adev);
1094 	port_nr = args.args[0];
1095 	endpoint_nr = args.args[1];
1096 
1097 	if (parent)
1098 		*parent = fwnode;
1099 
1100 	if (!port && !endpoint)
1101 		return 0;
1102 
1103 	fwnode = acpi_graph_get_child_prop_value(fwnode, "port", port_nr);
1104 	if (!fwnode)
1105 		return -EPROTO;
1106 
1107 	if (port)
1108 		*port = fwnode;
1109 
1110 	if (!endpoint)
1111 		return 0;
1112 
1113 	fwnode = acpi_graph_get_child_prop_value(fwnode, "endpoint",
1114 						 endpoint_nr);
1115 	if (!fwnode)
1116 		return -EPROTO;
1117 
1118 	*endpoint = fwnode;
1119 
1120 	return 0;
1121 }
1122