]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/acpi/property.c
kvm: x86: hyperv: make VP_INDEX managed by userspace
[karo-tx-linux.git] / drivers / acpi / property.c
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 }