leds: leds-gpio: Convert gpio_blink_set() to use GPIO descriptors
[linux-block.git] / drivers / acpi / property.c
CommitLineData
ffdcd955
MW
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/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
23static const u8 prp_uuid[16] = {
24 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
25 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
26};
27
28static bool acpi_property_value_ok(const union acpi_object *value)
29{
30 int j;
31
32 /*
33 * The value must be an integer, a string, a reference, or a package
34 * whose every element must be an integer, a string, or a reference.
35 */
36 switch (value->type) {
37 case ACPI_TYPE_INTEGER:
38 case ACPI_TYPE_STRING:
39 case ACPI_TYPE_LOCAL_REFERENCE:
40 return true;
41
42 case ACPI_TYPE_PACKAGE:
43 for (j = 0; j < value->package.count; j++)
44 switch (value->package.elements[j].type) {
45 case ACPI_TYPE_INTEGER:
46 case ACPI_TYPE_STRING:
47 case ACPI_TYPE_LOCAL_REFERENCE:
48 continue;
49
50 default:
51 return false;
52 }
53
54 return true;
55 }
56 return false;
57}
58
59static bool acpi_properties_format_valid(const union acpi_object *properties)
60{
61 int i;
62
63 for (i = 0; i < properties->package.count; i++) {
64 const union acpi_object *property;
65
66 property = &properties->package.elements[i];
67 /*
68 * Only two elements allowed, the first one must be a string and
69 * the second one has to satisfy certain conditions.
70 */
71 if (property->package.count != 2
72 || property->package.elements[0].type != ACPI_TYPE_STRING
73 || !acpi_property_value_ok(&property->package.elements[1]))
74 return false;
75 }
76 return true;
77}
78
733e6251
MW
79static void acpi_init_of_compatible(struct acpi_device *adev)
80{
81 const union acpi_object *of_compatible;
82 struct acpi_hardware_id *hwid;
83 bool acpi_of = false;
84 int ret;
85
86 /*
87 * Check if the special PRP0001 ACPI ID is present and in that
88 * case we fill in Device Tree compatible properties for this
89 * device.
90 */
91 list_for_each_entry(hwid, &adev->pnp.ids, list) {
92 if (!strcmp(hwid->id, "PRP0001")) {
93 acpi_of = true;
94 break;
95 }
96 }
97
98 if (!acpi_of)
99 return;
100
101 ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
102 &of_compatible);
103 if (ret) {
104 ret = acpi_dev_get_property(adev, "compatible",
105 ACPI_TYPE_STRING, &of_compatible);
106 if (ret) {
107 acpi_handle_warn(adev->handle,
108 "PRP0001 requires compatible property\n");
109 return;
110 }
111 }
112 adev->data.of_compatible = of_compatible;
113}
114
ffdcd955
MW
115void acpi_init_properties(struct acpi_device *adev)
116{
117 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
118 const union acpi_object *desc;
119 acpi_status status;
120 int i;
121
122 status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
123 ACPI_TYPE_PACKAGE);
124 if (ACPI_FAILURE(status))
125 return;
126
127 desc = buf.pointer;
128 if (desc->package.count % 2)
129 goto fail;
130
131 /* Look for the device properties UUID. */
132 for (i = 0; i < desc->package.count; i += 2) {
133 const union acpi_object *uuid, *properties;
134
135 uuid = &desc->package.elements[i];
136 properties = &desc->package.elements[i + 1];
137
138 /*
139 * The first element must be a UUID and the second one must be
140 * a package.
141 */
142 if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
143 || properties->type != ACPI_TYPE_PACKAGE)
144 break;
145
146 if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid)))
147 continue;
148
149 /*
150 * We found the matching UUID. Now validate the format of the
151 * package immediately following it.
152 */
153 if (!acpi_properties_format_valid(properties))
154 break;
155
156 adev->data.pointer = buf.pointer;
157 adev->data.properties = properties;
733e6251
MW
158
159 acpi_init_of_compatible(adev);
ffdcd955
MW
160 return;
161 }
162
163 fail:
164 dev_warn(&adev->dev, "Returned _DSD data is not valid, skipping\n");
165 ACPI_FREE(buf.pointer);
166}
167
168void acpi_free_properties(struct acpi_device *adev)
169{
170 ACPI_FREE((void *)adev->data.pointer);
733e6251 171 adev->data.of_compatible = NULL;
ffdcd955
MW
172 adev->data.pointer = NULL;
173 adev->data.properties = NULL;
174}
175
176/**
177 * acpi_dev_get_property - return an ACPI property with given name
178 * @adev: ACPI device to get property
179 * @name: Name of the property
180 * @type: Expected property type
181 * @obj: Location to store the property value (if not %NULL)
182 *
183 * Look up a property with @name and store a pointer to the resulting ACPI
184 * object at the location pointed to by @obj if found.
185 *
186 * Callers must not attempt to free the returned objects. These objects will be
187 * freed by the ACPI core automatically during the removal of @adev.
188 *
189 * Return: %0 if property with @name has been found (success),
190 * %-EINVAL if the arguments are invalid,
191 * %-ENODATA if the property doesn't exist,
192 * %-EPROTO if the property value type doesn't match @type.
193 */
194int acpi_dev_get_property(struct acpi_device *adev, const char *name,
195 acpi_object_type type, const union acpi_object **obj)
196{
197 const union acpi_object *properties;
198 int i;
199
200 if (!adev || !name)
201 return -EINVAL;
202
203 if (!adev->data.pointer || !adev->data.properties)
204 return -ENODATA;
205
206 properties = adev->data.properties;
207 for (i = 0; i < properties->package.count; i++) {
208 const union acpi_object *propname, *propvalue;
209 const union acpi_object *property;
210
211 property = &properties->package.elements[i];
212
213 propname = &property->package.elements[0];
214 propvalue = &property->package.elements[1];
215
216 if (!strcmp(name, propname->string.pointer)) {
217 if (type != ACPI_TYPE_ANY && propvalue->type != type)
218 return -EPROTO;
219 else if (obj)
220 *obj = propvalue;
221
222 return 0;
223 }
224 }
225 return -ENODATA;
226}
227EXPORT_SYMBOL_GPL(acpi_dev_get_property);
228
229/**
230 * acpi_dev_get_property_array - return an ACPI array property with given name
231 * @adev: ACPI device to get property
232 * @name: Name of the property
233 * @type: Expected type of array elements
234 * @obj: Location to store a pointer to the property value (if not NULL)
235 *
236 * Look up an array property with @name and store a pointer to the resulting
237 * ACPI object at the location pointed to by @obj if found.
238 *
239 * Callers must not attempt to free the returned objects. Those objects will be
240 * freed by the ACPI core automatically during the removal of @adev.
241 *
242 * Return: %0 if array property (package) with @name has been found (success),
243 * %-EINVAL if the arguments are invalid,
244 * %-ENODATA if the property doesn't exist,
245 * %-EPROTO if the property is not a package or the type of its elements
246 * doesn't match @type.
247 */
248int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
249 acpi_object_type type,
250 const union acpi_object **obj)
251{
252 const union acpi_object *prop;
253 int ret, i;
254
255 ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop);
256 if (ret)
257 return ret;
258
259 if (type != ACPI_TYPE_ANY) {
260 /* Check that all elements are of correct type. */
261 for (i = 0; i < prop->package.count; i++)
262 if (prop->package.elements[i].type != type)
263 return -EPROTO;
264 }
265 if (obj)
266 *obj = prop;
267
268 return 0;
269}
270EXPORT_SYMBOL_GPL(acpi_dev_get_property_array);
271
272/**
273 * acpi_dev_get_property_reference - returns handle to the referenced object
274 * @adev: ACPI device to get property
275 * @name: Name of the property
276 * @size_prop: Name of the "size" property in referenced object
277 * @index: Index of the reference to return
278 * @args: Location to store the returned reference with optional arguments
279 *
280 * Find property with @name, verifify that it is a package containing at least
281 * one object reference and if so, store the ACPI device object pointer to the
282 * target object in @args->adev.
283 *
284 * If the reference includes arguments (@size_prop is not %NULL) follow the
285 * reference and check whether or not there is an integer property @size_prop
286 * under the target object and if so, whether or not its value matches the
287 * number of arguments that follow the reference. If there's more than one
288 * reference in the property value package, @index is used to select the one to
289 * return.
290 *
291 * Return: %0 on success, negative error code on failure.
292 */
293int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
294 const char *size_prop, size_t index,
295 struct acpi_reference_args *args)
296{
297 const union acpi_object *element, *end;
298 const union acpi_object *obj;
299 struct acpi_device *device;
300 int ret, idx = 0;
301
302 ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj);
303 if (ret)
304 return ret;
305
306 /*
307 * The simplest case is when the value is a single reference. Just
308 * return that reference then.
309 */
310 if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
311 if (size_prop || index)
312 return -EINVAL;
313
314 ret = acpi_bus_get_device(obj->reference.handle, &device);
315 if (ret)
316 return ret;
317
318 args->adev = device;
319 args->nargs = 0;
320 return 0;
321 }
322
323 /*
324 * If it is not a single reference, then it is a package of
325 * references followed by number of ints as follows:
326 *
327 * Package () { REF, INT, REF, INT, INT }
328 *
329 * The index argument is then used to determine which reference
330 * the caller wants (along with the arguments).
331 */
332 if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
333 return -EPROTO;
334
335 element = obj->package.elements;
336 end = element + obj->package.count;
337
338 while (element < end) {
339 u32 nargs, i;
340
341 if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
342 return -EPROTO;
343
344 ret = acpi_bus_get_device(element->reference.handle, &device);
345 if (ret)
346 return -ENODEV;
347
348 element++;
349 nargs = 0;
350
351 if (size_prop) {
352 const union acpi_object *prop;
353
354 /*
355 * Find out how many arguments the refenced object
356 * expects by reading its size_prop property.
357 */
358 ret = acpi_dev_get_property(device, size_prop,
359 ACPI_TYPE_INTEGER, &prop);
360 if (ret)
361 return ret;
362
363 nargs = prop->integer.value;
364 if (nargs > MAX_ACPI_REFERENCE_ARGS
365 || element + nargs > end)
366 return -EPROTO;
367
368 /*
369 * Skip to the start of the arguments and verify
370 * that they all are in fact integers.
371 */
372 for (i = 0; i < nargs; i++)
373 if (element[i].type != ACPI_TYPE_INTEGER)
374 return -EPROTO;
375 } else {
376 /* assume following integer elements are all args */
377 for (i = 0; element + i < end; i++) {
378 int type = element[i].type;
379
380 if (type == ACPI_TYPE_INTEGER)
381 nargs++;
382 else if (type == ACPI_TYPE_LOCAL_REFERENCE)
383 break;
384 else
385 return -EPROTO;
386 }
387 }
388
389 if (idx++ == index) {
390 args->adev = device;
391 args->nargs = nargs;
392 for (i = 0; i < nargs; i++)
393 args->args[i] = element[i].integer.value;
394
395 return 0;
396 }
397
398 element += nargs;
399 }
400
401 return -EPROTO;
402}
403EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
b31384fa
RW
404
405int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
406 void **valptr)
407{
408 return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY,
409 (const union acpi_object **)valptr);
410}
411
412int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
413 enum dev_prop_type proptype, void *val)
414{
415 const union acpi_object *obj;
416 int ret;
417
418 if (!val)
419 return -EINVAL;
420
421 if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
422 ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj);
423 if (ret)
424 return ret;
425
426 switch (proptype) {
427 case DEV_PROP_U8:
428 if (obj->integer.value > U8_MAX)
429 return -EOVERFLOW;
430 *(u8 *)val = obj->integer.value;
431 break;
432 case DEV_PROP_U16:
433 if (obj->integer.value > U16_MAX)
434 return -EOVERFLOW;
435 *(u16 *)val = obj->integer.value;
436 break;
437 case DEV_PROP_U32:
438 if (obj->integer.value > U32_MAX)
439 return -EOVERFLOW;
440 *(u32 *)val = obj->integer.value;
441 break;
442 default:
443 *(u64 *)val = obj->integer.value;
444 break;
445 }
446 } else if (proptype == DEV_PROP_STRING) {
447 ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj);
448 if (ret)
449 return ret;
450
451 *(char **)val = obj->string.pointer;
452 } else {
453 ret = -EINVAL;
454 }
455 return ret;
456}
457
458static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
459 size_t nval)
460{
461 int i;
462
463 for (i = 0; i < nval; i++) {
464 if (items[i].type != ACPI_TYPE_INTEGER)
465 return -EPROTO;
466 if (items[i].integer.value > U8_MAX)
467 return -EOVERFLOW;
468
469 val[i] = items[i].integer.value;
470 }
471 return 0;
472}
473
474static int acpi_copy_property_array_u16(const union acpi_object *items,
475 u16 *val, size_t nval)
476{
477 int i;
478
479 for (i = 0; i < nval; i++) {
480 if (items[i].type != ACPI_TYPE_INTEGER)
481 return -EPROTO;
482 if (items[i].integer.value > U16_MAX)
483 return -EOVERFLOW;
484
485 val[i] = items[i].integer.value;
486 }
487 return 0;
488}
489
490static int acpi_copy_property_array_u32(const union acpi_object *items,
491 u32 *val, size_t nval)
492{
493 int i;
494
495 for (i = 0; i < nval; i++) {
496 if (items[i].type != ACPI_TYPE_INTEGER)
497 return -EPROTO;
498 if (items[i].integer.value > U32_MAX)
499 return -EOVERFLOW;
500
501 val[i] = items[i].integer.value;
502 }
503 return 0;
504}
505
506static int acpi_copy_property_array_u64(const union acpi_object *items,
507 u64 *val, size_t nval)
508{
509 int i;
510
511 for (i = 0; i < nval; i++) {
512 if (items[i].type != ACPI_TYPE_INTEGER)
513 return -EPROTO;
514
515 val[i] = items[i].integer.value;
516 }
517 return 0;
518}
519
520static int acpi_copy_property_array_string(const union acpi_object *items,
521 char **val, size_t nval)
522{
523 int i;
524
525 for (i = 0; i < nval; i++) {
526 if (items[i].type != ACPI_TYPE_STRING)
527 return -EPROTO;
528
529 val[i] = items[i].string.pointer;
530 }
531 return 0;
532}
533
534int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
535 enum dev_prop_type proptype, void *val, size_t nval)
536{
537 const union acpi_object *obj;
538 const union acpi_object *items;
539 int ret;
540
541 if (val && nval == 1) {
542 ret = acpi_dev_prop_read_single(adev, propname, proptype, val);
543 if (!ret)
544 return ret;
545 }
546
547 ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj);
548 if (ret)
549 return ret;
550
551 if (!val)
552 return obj->package.count;
553 else if (nval <= 0)
554 return -EINVAL;
555
556 if (nval > obj->package.count)
557 return -EOVERFLOW;
558
559 items = obj->package.elements;
560 switch (proptype) {
561 case DEV_PROP_U8:
562 ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
563 break;
564 case DEV_PROP_U16:
565 ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
566 break;
567 case DEV_PROP_U32:
568 ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
569 break;
570 case DEV_PROP_U64:
571 ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
572 break;
573 case DEV_PROP_STRING:
574 ret = acpi_copy_property_array_string(items, (char **)val, nval);
575 break;
576 default:
577 ret = -EINVAL;
578 break;
579 }
580 return ret;
581}