Blame view

drivers/acpi/utils.c 23.7 KB
c942fddf8   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
  /*
   *  acpi_utils.c - ACPI Utility Functions ($Revision: 10 $)
   *
   *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
   *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
11
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
  #include <linux/init.h>
  #include <linux/types.h>
fbfddae69   Toshi Kani   ACPI: Add acpi_ha...
14
15
  #include <linux/hardirq.h>
  #include <linux/acpi.h>
45fef5b88   Bjørn Mork   ACPI: add dynamic...
16
  #include <linux/dynamic_debug.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17

a192a9580   Len Brown   ACPI: Move defini...
18
  #include "internal.h"
2d12b6b38   Lukas Wunner   ACPI / utils: Add...
19
  #include "sleep.h"
a192a9580   Len Brown   ACPI: Move defini...
20

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  #define _COMPONENT		ACPI_BUS_COMPONENT
f52fd66d2   Len Brown   ACPI: clean up AC...
22
  ACPI_MODULE_NAME("utils");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
  
  /* --------------------------------------------------------------------------
                              Object Evaluation Helpers
     -------------------------------------------------------------------------- */
4fd7f5188   Harvey Harrison   ACPI: sparse fix,...
27
28
29
  static void
  acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  #ifdef ACPI_DEBUG_OUTPUT
4fd7f5188   Harvey Harrison   ACPI: sparse fix,...
31
32
33
34
35
36
  	char prefix[80] = {'\0'};
  	struct acpi_buffer buffer = {sizeof(prefix), prefix};
  	acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);
  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s
  ",
  		(char *) prefix, p, acpi_format_exception(s)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
  #else
4fd7f5188   Harvey Harrison   ACPI: sparse fix,...
38
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
  #endif
4fd7f5188   Harvey Harrison   ACPI: sparse fix,...
40
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
42
43
  acpi_extract_package(union acpi_object *package,
  		     struct acpi_buffer *format, struct acpi_buffer *buffer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
45
46
47
48
49
50
51
  	u32 size_required = 0;
  	u32 tail_offset = 0;
  	char *format_string = NULL;
  	u32 format_count = 0;
  	u32 i = 0;
  	u8 *head = NULL;
  	u8 *tail = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53

4be44fcd3   Len Brown   [ACPI] Lindent al...
54
55
  	if (!package || (package->type != ACPI_TYPE_PACKAGE)
  	    || (package->package.count < 1)) {
cece92969   Len Brown   ACPI: un-export A...
56
57
  		printk(KERN_WARNING PREFIX "Invalid package argument
  ");
d550d98d3   Patrick Mochel   ACPI: delete trac...
58
  		return AE_BAD_PARAMETER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
  	}
  
  	if (!format || !format->pointer || (format->length < 1)) {
cece92969   Len Brown   ACPI: un-export A...
62
63
  		printk(KERN_WARNING PREFIX "Invalid format argument
  ");
d550d98d3   Patrick Mochel   ACPI: delete trac...
64
  		return AE_BAD_PARAMETER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
  	}
  
  	if (!buffer) {
cece92969   Len Brown   ACPI: un-export A...
68
69
  		printk(KERN_WARNING PREFIX "Invalid buffer argument
  ");
d550d98d3   Patrick Mochel   ACPI: delete trac...
70
  		return AE_BAD_PARAMETER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  	}
4be44fcd3   Len Brown   [ACPI] Lindent al...
72
  	format_count = (format->length / sizeof(char)) - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  	if (format_count > package->package.count) {
cece92969   Len Brown   ACPI: un-export A...
74
75
76
77
  		printk(KERN_WARNING PREFIX "Format specifies more objects [%d]"
  			      " than exist in package [%d].
  ",
  			      format_count, package->package.count);
d550d98d3   Patrick Mochel   ACPI: delete trac...
78
  		return AE_BAD_DATA;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  	}
50dd09697   Jan Engelhardt   ACPI: Remove unne...
80
  	format_string = format->pointer;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
83
84
  
  	/*
  	 * Calculate size_required.
  	 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
85
  	for (i = 0; i < format_count; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
  
  		union acpi_object *element = &(package->package.elements[i]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
  		switch (element->type) {
  
  		case ACPI_TYPE_INTEGER:
  			switch (format_string[i]) {
  			case 'N':
439913fff   Lin Ming   ACPI: replace acp...
93
94
  				size_required += sizeof(u64);
  				tail_offset += sizeof(u64);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
  				break;
  			case 'S':
4be44fcd3   Len Brown   [ACPI] Lindent al...
97
  				size_required +=
439913fff   Lin Ming   ACPI: replace acp...
98
  				    sizeof(char *) + sizeof(u64) +
4be44fcd3   Len Brown   [ACPI] Lindent al...
99
100
  				    sizeof(char);
  				tail_offset += sizeof(char *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
  				break;
  			default:
cece92969   Len Brown   ACPI: un-export A...
103
  				printk(KERN_WARNING PREFIX "Invalid package element"
e7e92ec93   Colin Ian King   ACPI: Fix spellin...
104
  					      " [%d]: got number, expecting"
cece92969   Len Brown   ACPI: un-export A...
105
106
107
  					      " [%c]
  ",
  					      i, format_string[i]);
d550d98d3   Patrick Mochel   ACPI: delete trac...
108
  				return AE_BAD_DATA;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
111
112
113
114
115
  			}
  			break;
  
  		case ACPI_TYPE_STRING:
  		case ACPI_TYPE_BUFFER:
  			switch (format_string[i]) {
  			case 'S':
4be44fcd3   Len Brown   [ACPI] Lindent al...
116
117
118
119
120
  				size_required +=
  				    sizeof(char *) +
  				    (element->string.length * sizeof(char)) +
  				    sizeof(char);
  				tail_offset += sizeof(char *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
  				break;
  			case 'B':
4be44fcd3   Len Brown   [ACPI] Lindent al...
123
  				size_required +=
d93de3455   Fabian Frederick   ACPI: remove unne...
124
  				    sizeof(u8 *) + element->buffer.length;
4be44fcd3   Len Brown   [ACPI] Lindent al...
125
  				tail_offset += sizeof(u8 *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
127
  				break;
  			default:
cece92969   Len Brown   ACPI: un-export A...
128
  				printk(KERN_WARNING PREFIX "Invalid package element"
a6fc67202   Thomas Renninger   ACPI: Enable ACPI...
129
  					      " [%d] got string/buffer,"
e7e92ec93   Colin Ian King   ACPI: Fix spellin...
130
131
  					      " expecting [%c]
  ",
cece92969   Len Brown   ACPI: un-export A...
132
  					      i, format_string[i]);
d550d98d3   Patrick Mochel   ACPI: delete trac...
133
  				return AE_BAD_DATA;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
  			}
  			break;
e3ec483a7   Zhang Rui   ACPI: add ACPI_TY...
136
137
138
139
140
141
142
143
144
145
146
147
148
  		case ACPI_TYPE_LOCAL_REFERENCE:
  			switch (format_string[i]) {
  			case 'R':
  				size_required += sizeof(void *);
  				tail_offset += sizeof(void *);
  				break;
  			default:
  				printk(KERN_WARNING PREFIX "Invalid package element"
  					      " [%d] got reference,"
  					      " expecting [%c]
  ",
  					      i, format_string[i]);
  				return AE_BAD_DATA;
e3ec483a7   Zhang Rui   ACPI: add ACPI_TY...
149
150
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
  
  		case ACPI_TYPE_PACKAGE:
  		default:
4be44fcd3   Len Brown   [ACPI] Lindent al...
154
155
156
157
  			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  					  "Found unsupported element at index=%d
  ",
  					  i));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  			/* TBD: handle nested packages... */
d550d98d3   Patrick Mochel   ACPI: delete trac...
159
  			return AE_SUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
164
165
  		}
  	}
  
  	/*
  	 * Validate output buffer.
  	 */
e83dda062   Al Stone   ACPI: improve acp...
166
  	if (buffer->length == ACPI_ALLOCATE_BUFFER) {
2d0acb4af   jhbird.choi@samsung.com   ACPI: Clean up me...
167
  		buffer->pointer = ACPI_ALLOCATE_ZEROED(size_required);
e83dda062   Al Stone   ACPI: improve acp...
168
169
  		if (!buffer->pointer)
  			return AE_NO_MEMORY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
  		buffer->length = size_required;
e83dda062   Al Stone   ACPI: improve acp...
171
172
173
174
175
176
177
178
  	} else {
  		if (buffer->length < size_required) {
  			buffer->length = size_required;
  			return AE_BUFFER_OVERFLOW;
  		} else if (buffer->length != size_required ||
  			   !buffer->pointer) {
  			return AE_BAD_PARAMETER;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
181
182
183
184
185
186
  	}
  
  	head = buffer->pointer;
  	tail = buffer->pointer + tail_offset;
  
  	/*
  	 * Extract package data.
  	 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
187
  	for (i = 0; i < format_count; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
190
  
  		u8 **pointer = NULL;
  		union acpi_object *element = &(package->package.elements[i]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
194
195
  		switch (element->type) {
  
  		case ACPI_TYPE_INTEGER:
  			switch (format_string[i]) {
  			case 'N':
439913fff   Lin Ming   ACPI: replace acp...
196
  				*((u64 *) head) =
4be44fcd3   Len Brown   [ACPI] Lindent al...
197
  				    element->integer.value;
439913fff   Lin Ming   ACPI: replace acp...
198
  				head += sizeof(u64);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
  				break;
  			case 'S':
4be44fcd3   Len Brown   [ACPI] Lindent al...
201
  				pointer = (u8 **) head;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  				*pointer = tail;
439913fff   Lin Ming   ACPI: replace acp...
203
  				*((u64 *) tail) =
4be44fcd3   Len Brown   [ACPI] Lindent al...
204
  				    element->integer.value;
439913fff   Lin Ming   ACPI: replace acp...
205
206
  				head += sizeof(u64 *);
  				tail += sizeof(u64);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  				/* NULL terminate string */
  				*tail = (char)0;
  				tail += sizeof(char);
  				break;
  			default:
  				/* Should never get here */
  				break;
  			}
  			break;
  
  		case ACPI_TYPE_STRING:
  		case ACPI_TYPE_BUFFER:
  			switch (format_string[i]) {
  			case 'S':
4be44fcd3   Len Brown   [ACPI] Lindent al...
221
  				pointer = (u8 **) head;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  				*pointer = tail;
4be44fcd3   Len Brown   [ACPI] Lindent al...
223
224
225
  				memcpy(tail, element->string.pointer,
  				       element->string.length);
  				head += sizeof(char *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
227
228
229
230
231
  				tail += element->string.length * sizeof(char);
  				/* NULL terminate string */
  				*tail = (char)0;
  				tail += sizeof(char);
  				break;
  			case 'B':
4be44fcd3   Len Brown   [ACPI] Lindent al...
232
  				pointer = (u8 **) head;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
  				*pointer = tail;
4be44fcd3   Len Brown   [ACPI] Lindent al...
234
235
236
  				memcpy(tail, element->buffer.pointer,
  				       element->buffer.length);
  				head += sizeof(u8 *);
d93de3455   Fabian Frederick   ACPI: remove unne...
237
  				tail += element->buffer.length;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
239
240
241
242
243
  				break;
  			default:
  				/* Should never get here */
  				break;
  			}
  			break;
e3ec483a7   Zhang Rui   ACPI: add ACPI_TY...
244
245
246
247
248
249
250
251
252
253
254
255
  		case ACPI_TYPE_LOCAL_REFERENCE:
  			switch (format_string[i]) {
  			case 'R':
  				*(void **)head =
  				    (void *)element->reference.handle;
  				head += sizeof(void *);
  				break;
  			default:
  				/* Should never get here */
  				break;
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
257
258
259
260
261
262
  		case ACPI_TYPE_PACKAGE:
  			/* TBD: handle nested packages... */
  		default:
  			/* Should never get here */
  			break;
  		}
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
263
  	return AE_OK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265

4be44fcd3   Len Brown   [ACPI] Lindent al...
266
  EXPORT_SYMBOL(acpi_extract_package);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
268
  
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
269
270
  acpi_evaluate_integer(acpi_handle handle,
  		      acpi_string pathname,
27663c585   Matthew Wilcox   ACPI: Change acpi...
271
  		      struct acpi_object_list *arguments, unsigned long long *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
273
  	acpi_status status = AE_OK;
40599072d   Pavel Machek   ACPI: scheduling ...
274
  	union acpi_object element;
4be44fcd3   Len Brown   [ACPI] Lindent al...
275
  	struct acpi_buffer buffer = { 0, NULL };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
  	if (!data)
d550d98d3   Patrick Mochel   ACPI: delete trac...
278
  		return AE_BAD_PARAMETER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  	buffer.length = sizeof(union acpi_object);
40599072d   Pavel Machek   ACPI: scheduling ...
281
  	buffer.pointer = &element;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
284
  	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
  	if (ACPI_FAILURE(status)) {
  		acpi_util_eval_error(handle, pathname, status);
d550d98d3   Patrick Mochel   ACPI: delete trac...
285
  		return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
  	}
40599072d   Pavel Machek   ACPI: scheduling ...
287
  	if (element.type != ACPI_TYPE_INTEGER) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  		acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
d550d98d3   Patrick Mochel   ACPI: delete trac...
289
  		return AE_BAD_DATA;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
  	}
40599072d   Pavel Machek   ACPI: scheduling ...
291
  	*data = element.integer.value;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292

27663c585   Matthew Wilcox   ACPI: Change acpi...
293
294
  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]
  ", *data));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295

d550d98d3   Patrick Mochel   ACPI: delete trac...
296
  	return AE_OK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298

4be44fcd3   Len Brown   [ACPI] Lindent al...
299
  EXPORT_SYMBOL(acpi_evaluate_integer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
302
303
304
305
  acpi_evaluate_reference(acpi_handle handle,
  			acpi_string pathname,
  			struct acpi_object_list *arguments,
  			struct acpi_handle_list *list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
307
308
309
310
311
  	acpi_status status = AE_OK;
  	union acpi_object *package = NULL;
  	union acpi_object *element = NULL;
  	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  	u32 i = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
314
  
  	if (!list) {
d550d98d3   Patrick Mochel   ACPI: delete trac...
315
  		return AE_BAD_PARAMETER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
317
318
319
320
321
322
  	}
  
  	/* Evaluate object. */
  
  	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
  	if (ACPI_FAILURE(status))
  		goto end;
50dd09697   Jan Engelhardt   ACPI: Remove unne...
323
  	package = buffer.pointer;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
325
  
  	if ((buffer.length == 0) || !package) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
327
328
329
330
  		status = AE_BAD_DATA;
  		acpi_util_eval_error(handle, pathname, status);
  		goto end;
  	}
  	if (package->type != ACPI_TYPE_PACKAGE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
334
335
  		status = AE_BAD_DATA;
  		acpi_util_eval_error(handle, pathname, status);
  		goto end;
  	}
  	if (!package->package.count) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
338
339
340
341
  		status = AE_BAD_DATA;
  		acpi_util_eval_error(handle, pathname, status);
  		goto end;
  	}
  
  	if (package->package.count > ACPI_MAX_HANDLES) {
09e150869   Xiongfeng Wang   ACPI / utils: Fix...
342
  		kfree(package);
d550d98d3   Patrick Mochel   ACPI: delete trac...
343
  		return AE_NO_MEMORY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
347
348
349
350
351
  	}
  	list->count = package->package.count;
  
  	/* Extract package data. */
  
  	for (i = 0; i < list->count; i++) {
  
  		element = &(package->package.elements[i]);
cd0b22482   Bob Moore   ACPICA: Fixes for...
352
  		if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
  			status = AE_BAD_DATA;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
355
356
  			acpi_util_eval_error(handle, pathname, status);
  			break;
  		}
b6a163875   Thomas Renninger   ACPICA: Warn if p...
357
  		if (!element->reference.handle) {
b6a163875   Thomas Renninger   ACPICA: Warn if p...
358
  			status = AE_NULL_ENTRY;
c48cf1b9d   Rafael J. Wysocki   ACPI / utils: Dro...
359
  			acpi_util_eval_error(handle, pathname, status);
b6a163875   Thomas Renninger   ACPICA: Warn if p...
360
361
  			break;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
363
364
365
366
  		/* Get the  acpi_handle. */
  
  		list->handles[i] = element->reference.handle;
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]
  ",
4be44fcd3   Len Brown   [ACPI] Lindent al...
367
  				  list->handles[i]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
  	}
4be44fcd3   Len Brown   [ACPI] Lindent al...
369
        end:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
371
372
373
  	if (ACPI_FAILURE(status)) {
  		list->count = 0;
  		//kfree(list->handles);
  	}
02438d877   Len Brown   ACPI: delete acpi...
374
  	kfree(buffer.pointer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375

d550d98d3   Patrick Mochel   ACPI: delete trac...
376
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378

4be44fcd3   Len Brown   [ACPI] Lindent al...
379
  EXPORT_SYMBOL(acpi_evaluate_reference);
38ac0f1b9   Matthew Garrett   ACPI: Add _PLD su...
380
381
  
  acpi_status
8ede06aba   Feng Tang   ACPI: Use ACPICA ...
382
  acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
38ac0f1b9   Matthew Garrett   ACPI: Add _PLD su...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  {
  	acpi_status status;
  	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  	union acpi_object *output;
  
  	status = acpi_evaluate_object(handle, "_PLD", NULL, &buffer);
  
  	if (ACPI_FAILURE(status))
  		return status;
  
  	output = buffer.pointer;
  
  	if (!output || output->type != ACPI_TYPE_PACKAGE
  	    || !output->package.count
  	    || output->package.elements[0].type != ACPI_TYPE_BUFFER
8ede06aba   Feng Tang   ACPI: Use ACPICA ...
398
  	    || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) {
38ac0f1b9   Matthew Garrett   ACPI: Add _PLD su...
399
400
401
  		status = AE_TYPE;
  		goto out;
  	}
8ede06aba   Feng Tang   ACPI: Use ACPICA ...
402
403
404
405
  	status = acpi_decode_pld_buffer(
  			output->package.elements[0].buffer.pointer,
  			output->package.elements[0].buffer.length,
  			pld);
38ac0f1b9   Matthew Garrett   ACPI: Add _PLD su...
406
407
408
409
410
  out:
  	kfree(buffer.pointer);
  	return status;
  }
  EXPORT_SYMBOL(acpi_get_physical_device_location);
275c58d77   Toshi Kani   ACPI: Add an inte...
411
412
  
  /**
700b8422f   Rafael J. Wysocki   ACPI: Drop acpi_e...
413
   * acpi_evaluate_ost: Evaluate _OST for hotplug operations
275c58d77   Toshi Kani   ACPI: Add an inte...
414
415
416
417
418
419
420
421
422
423
   * @handle: ACPI device handle
   * @source_event: source event code
   * @status_code: status code
   * @status_buf: optional detailed information (NULL if none)
   *
   * Evaluate _OST for hotplug operations. All ACPI hotplug handlers
   * must call this function when evaluating _OST for hotplug operations.
   * When the platform does not support _OST, this function has no effect.
   */
  acpi_status
05730c195   Jiang Liu   ACPI: rename acpi...
424
425
  acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code,
  		  struct acpi_buffer *status_buf)
275c58d77   Toshi Kani   ACPI: Add an inte...
426
  {
275c58d77   Toshi Kani   ACPI: Add an inte...
427
428
429
430
431
432
  	union acpi_object params[3] = {
  		{.type = ACPI_TYPE_INTEGER,},
  		{.type = ACPI_TYPE_INTEGER,},
  		{.type = ACPI_TYPE_BUFFER,}
  	};
  	struct acpi_object_list arg_list = {3, params};
275c58d77   Toshi Kani   ACPI: Add an inte...
433
434
435
436
437
438
439
440
441
442
  
  	params[0].integer.value = source_event;
  	params[1].integer.value = status_code;
  	if (status_buf != NULL) {
  		params[2].buffer.pointer = status_buf->pointer;
  		params[2].buffer.length = status_buf->length;
  	} else {
  		params[2].buffer.pointer = NULL;
  		params[2].buffer.length = 0;
  	}
05730c195   Jiang Liu   ACPI: rename acpi...
443
  	return acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
275c58d77   Toshi Kani   ACPI: Add an inte...
444
  }
05730c195   Jiang Liu   ACPI: rename acpi...
445
  EXPORT_SYMBOL(acpi_evaluate_ost);
fbfddae69   Toshi Kani   ACPI: Add acpi_ha...
446
447
  
  /**
45fef5b88   Bjørn Mork   ACPI: add dynamic...
448
   * acpi_handle_path: Return the object path of handle
8373f8c6a   Andy Shevchenko   ACPI / utils: Des...
449
   * @handle: ACPI device handle
45fef5b88   Bjørn Mork   ACPI: add dynamic...
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
   *
   * Caller must free the returned buffer
   */
  static char *acpi_handle_path(acpi_handle handle)
  {
  	struct acpi_buffer buffer = {
  		.length = ACPI_ALLOCATE_BUFFER,
  		.pointer = NULL
  	};
  
  	if (in_interrupt() ||
  	    acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK)
  		return NULL;
  	return buffer.pointer;
  }
  
  /**
fbfddae69   Toshi Kani   ACPI: Add acpi_ha...
467
   * acpi_handle_printk: Print message with ACPI prefix and object path
8373f8c6a   Andy Shevchenko   ACPI / utils: Des...
468
469
470
   * @level: log level
   * @handle: ACPI device handle
   * @fmt: format string
fbfddae69   Toshi Kani   ACPI: Add acpi_ha...
471
472
473
474
475
476
477
478
479
480
481
   *
   * This function is called through acpi_handle_<level> macros and prints
   * a message with ACPI prefix and object path.  This function acquires
   * the global namespace mutex to obtain an object path.  In interrupt
   * context, it shows the object path as <n/a>.
   */
  void
  acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...)
  {
  	struct va_format vaf;
  	va_list args;
fbfddae69   Toshi Kani   ACPI: Add acpi_ha...
482
483
484
485
486
  	const char *path;
  
  	va_start(args, fmt);
  	vaf.fmt = fmt;
  	vaf.va = &args;
45fef5b88   Bjørn Mork   ACPI: add dynamic...
487
488
  	path = acpi_handle_path(handle);
  	printk("%sACPI: %s: %pV", level, path ? path : "<n/a>" , &vaf);
fbfddae69   Toshi Kani   ACPI: Add acpi_ha...
489
490
  
  	va_end(args);
45fef5b88   Bjørn Mork   ACPI: add dynamic...
491
  	kfree(path);
fbfddae69   Toshi Kani   ACPI: Add acpi_ha...
492
493
  }
  EXPORT_SYMBOL(acpi_handle_printk);
952c63e95   Jiang Liu   ACPI: introduce h...
494

45fef5b88   Bjørn Mork   ACPI: add dynamic...
495
496
497
  #if defined(CONFIG_DYNAMIC_DEBUG)
  /**
   * __acpi_handle_debug: pr_debug with ACPI prefix and object path
8373f8c6a   Andy Shevchenko   ACPI / utils: Des...
498
499
500
   * @descriptor: Dynamic Debug descriptor
   * @handle: ACPI device handle
   * @fmt: format string
45fef5b88   Bjørn Mork   ACPI: add dynamic...
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
   *
   * This function is called through acpi_handle_debug macro and debug
   * prints a message with ACPI prefix and object path. This function
   * acquires the global namespace mutex to obtain an object path.  In
   * interrupt context, it shows the object path as <n/a>.
   */
  void
  __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle,
  		    const char *fmt, ...)
  {
  	struct va_format vaf;
  	va_list args;
  	const char *path;
  
  	va_start(args, fmt);
  	vaf.fmt = fmt;
  	vaf.va = &args;
  
  	path = acpi_handle_path(handle);
  	__dynamic_pr_debug(descriptor, "ACPI: %s: %pV", path ? path : "<n/a>", &vaf);
  
  	va_end(args);
  	kfree(path);
  }
  EXPORT_SYMBOL(__acpi_handle_debug);
  #endif
952c63e95   Jiang Liu   ACPI: introduce h...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
  /**
   * acpi_has_method: Check whether @handle has a method named @name
   * @handle: ACPI device handle
   * @name: name of object or method
   *
   * Check whether @handle has a method named @name.
   */
  bool acpi_has_method(acpi_handle handle, char *name)
  {
  	acpi_handle tmp;
  
  	return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp));
  }
  EXPORT_SYMBOL(acpi_has_method);
0db982026   Jiang Liu   ACPI: introduce h...
541
542
543
544
545
546
547
548
549
550
551
552
  
  acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
  				       u64 arg)
  {
  	union acpi_object obj = { .type = ACPI_TYPE_INTEGER };
  	struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, };
  
  	obj.integer.value = arg;
  
  	return acpi_evaluate_object(handle, method, &arg_list, NULL);
  }
  EXPORT_SYMBOL(acpi_execute_simple_method);
7d2421f84   Jiang Liu   ACPI: introduce t...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
  
  /**
   * acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations
   * @handle: ACPI device handle
   *
   * Evaluate device's _EJ0 method for hotplug operations.
   */
  acpi_status acpi_evaluate_ej0(acpi_handle handle)
  {
  	acpi_status status;
  
  	status = acpi_execute_simple_method(handle, "_EJ0", 1);
  	if (status == AE_NOT_FOUND)
  		acpi_handle_warn(handle, "No _EJ0 support for device
  ");
  	else if (ACPI_FAILURE(status))
  		acpi_handle_warn(handle, "Eject failed (0x%x)
  ", status);
  
  	return status;
  }
  
  /**
   * acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device
   * @handle: ACPI device handle
   * @lock: lock device if non-zero, otherwise unlock device
   *
   * Evaluate device's _LCK method if present to lock/unlock device
   */
  acpi_status acpi_evaluate_lck(acpi_handle handle, int lock)
  {
  	acpi_status status;
  
  	status = acpi_execute_simple_method(handle, "_LCK", !!lock);
  	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
  		if (lock)
  			acpi_handle_warn(handle,
  				"Locking device failed (0x%x)
  ", status);
  		else
  			acpi_handle_warn(handle,
  				"Unlocking device failed (0x%x)
  ", status);
  	}
  
  	return status;
  }
a65ac5204   Jiang Liu   ACPI: introduce h...
600
601
  
  /**
132565d8e   Hans de Goede   ACPI: utils: Add ...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
   * acpi_evaluate_reg: Evaluate _REG method to register OpRegion presence
   * @handle: ACPI device handle
   * @space_id: ACPI address space id to register OpRegion presence for
   * @function: Parameter to pass to _REG one of ACPI_REG_CONNECT or
   *            ACPI_REG_DISCONNECT
   *
   * Evaluate device's _REG method to register OpRegion presence.
   */
  acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function)
  {
  	struct acpi_object_list arg_list;
  	union acpi_object params[2];
  
  	params[0].type = ACPI_TYPE_INTEGER;
  	params[0].integer.value = space_id;
  	params[1].type = ACPI_TYPE_INTEGER;
  	params[1].integer.value = function;
  	arg_list.count = 2;
  	arg_list.pointer = params;
  
  	return acpi_evaluate_object(handle, "_REG", &arg_list, NULL);
  }
  EXPORT_SYMBOL(acpi_evaluate_reg);
  
  /**
a65ac5204   Jiang Liu   ACPI: introduce h...
627
628
   * acpi_evaluate_dsm - evaluate device's _DSM method
   * @handle: ACPI device handle
94116f812   Andy Shevchenko   ACPI: Switch to u...
629
   * @guid: GUID of requested functions, should be 16 bytes
a65ac5204   Jiang Liu   ACPI: introduce h...
630
631
632
633
   * @rev: revision number of requested function
   * @func: requested function number
   * @argv4: the function specific parameter
   *
94116f812   Andy Shevchenko   ACPI: Switch to u...
634
   * Evaluate device's _DSM method with specified GUID, revision id and
a65ac5204   Jiang Liu   ACPI: introduce h...
635
636
637
638
639
640
   * function number. Caller needs to free the returned object.
   *
   * Though ACPI defines the fourth parameter for _DSM should be a package,
   * some old BIOSes do expect a buffer or an integer etc.
   */
  union acpi_object *
94116f812   Andy Shevchenko   ACPI: Switch to u...
641
  acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 func,
a65ac5204   Jiang Liu   ACPI: introduce h...
642
643
644
645
646
647
648
649
650
651
652
653
  		  union acpi_object *argv4)
  {
  	acpi_status ret;
  	struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
  	union acpi_object params[4];
  	struct acpi_object_list input = {
  		.count = 4,
  		.pointer = params,
  	};
  
  	params[0].type = ACPI_TYPE_BUFFER;
  	params[0].buffer.length = 16;
94116f812   Andy Shevchenko   ACPI: Switch to u...
654
  	params[0].buffer.pointer = (u8 *)guid;
a65ac5204   Jiang Liu   ACPI: introduce h...
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  	params[1].type = ACPI_TYPE_INTEGER;
  	params[1].integer.value = rev;
  	params[2].type = ACPI_TYPE_INTEGER;
  	params[2].integer.value = func;
  	if (argv4) {
  		params[3] = *argv4;
  	} else {
  		params[3].type = ACPI_TYPE_PACKAGE;
  		params[3].package.count = 0;
  		params[3].package.elements = NULL;
  	}
  
  	ret = acpi_evaluate_object(handle, "_DSM", &input, &buf);
  	if (ACPI_SUCCESS(ret))
  		return (union acpi_object *)buf.pointer;
  
  	if (ret != AE_NOT_FOUND)
  		acpi_handle_warn(handle,
  				"failed to evaluate _DSM (0x%x)
  ", ret);
  
  	return NULL;
  }
  EXPORT_SYMBOL(acpi_evaluate_dsm);
  
  /**
   * acpi_check_dsm - check if _DSM method supports requested functions.
   * @handle: ACPI device handle
94116f812   Andy Shevchenko   ACPI: Switch to u...
683
   * @guid: GUID of requested functions, should be 16 bytes at least
a65ac5204   Jiang Liu   ACPI: introduce h...
684
685
   * @rev: revision number of requested functions
   * @funcs: bitmap of requested functions
a65ac5204   Jiang Liu   ACPI: introduce h...
686
687
688
689
690
   *
   * Evaluate device's _DSM method to check whether it supports requested
   * functions. Currently only support 64 functions at maximum, should be
   * enough for now.
   */
94116f812   Andy Shevchenko   ACPI: Switch to u...
691
  bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs)
a65ac5204   Jiang Liu   ACPI: introduce h...
692
693
694
695
  {
  	int i;
  	u64 mask = 0;
  	union acpi_object *obj;
a72255983   Dan Williams   nfit: make DIMM D...
696
697
  	if (funcs == 0)
  		return false;
94116f812   Andy Shevchenko   ACPI: Switch to u...
698
  	obj = acpi_evaluate_dsm(handle, guid, rev, 0, NULL);
a65ac5204   Jiang Liu   ACPI: introduce h...
699
700
701
702
703
704
705
706
  	if (!obj)
  		return false;
  
  	/* For compatibility, old BIOSes may return an integer */
  	if (obj->type == ACPI_TYPE_INTEGER)
  		mask = obj->integer.value;
  	else if (obj->type == ACPI_TYPE_BUFFER)
  		for (i = 0; i < obj->buffer.length && i < 8; i++)
4a798f508   Colin Ian King   ACPI / util: cast...
707
  			mask |= (((u64)obj->buffer.pointer[i]) << (i * 8));
a65ac5204   Jiang Liu   ACPI: introduce h...
708
709
710
711
  	ACPI_FREE(obj);
  
  	/*
  	 * Bit 0 indicates whether there's support for any functions other than
94116f812   Andy Shevchenko   ACPI: Switch to u...
712
  	 * function 0 for the specified GUID and revision.
a65ac5204   Jiang Liu   ACPI: introduce h...
713
714
715
716
717
718
719
  	 */
  	if ((mask & 0x1) && (mask & funcs) == funcs)
  		return true;
  
  	return false;
  }
  EXPORT_SYMBOL(acpi_check_dsm);
14ca7a47d   Hans de Goede   acpi-video-detect...
720

2d12b6b38   Lukas Wunner   ACPI / utils: Add...
721
  /**
35009c807   Andy Shevchenko   ACPI / utils: Int...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
   * acpi_dev_hid_uid_match - Match device by supplied HID and UID
   * @adev: ACPI device to match.
   * @hid2: Hardware ID of the device.
   * @uid2: Unique ID of the device, pass NULL to not check _UID.
   *
   * Matches HID and UID in @adev with given @hid2 and @uid2.
   * Returns true if matches.
   */
  bool acpi_dev_hid_uid_match(struct acpi_device *adev,
  			    const char *hid2, const char *uid2)
  {
  	const char *hid1 = acpi_device_hid(adev);
  	const char *uid1 = acpi_device_uid(adev);
  
  	if (strcmp(hid1, hid2))
  		return false;
  
  	if (!uid2)
  		return true;
  
  	return uid1 && !strcmp(uid1, uid2);
  }
  EXPORT_SYMBOL(acpi_dev_hid_uid_match);
  
  /**
c68ae33e7   Lukas Wunner   ACPI / utils: Ren...
747
   * acpi_dev_found - Detect presence of a given ACPI device in the namespace.
2d12b6b38   Lukas Wunner   ACPI / utils: Add...
748
749
750
751
752
753
754
755
756
757
758
   * @hid: Hardware ID of the device.
   *
   * Return %true if the device was present at the moment of invocation.
   * Note that if the device is pluggable, it may since have disappeared.
   *
   * For this function to work, acpi_bus_scan() must have been executed
   * which happens in the subsys_initcall() subsection. Hence, do not
   * call from a subsys_initcall() or earlier (use acpi_get_devices()
   * instead). Calling from module_init() is fine (which is synonymous
   * with device_initcall()).
   */
c68ae33e7   Lukas Wunner   ACPI / utils: Ren...
759
  bool acpi_dev_found(const char *hid)
2d12b6b38   Lukas Wunner   ACPI / utils: Add...
760
761
762
763
764
765
766
767
768
769
770
771
772
773
  {
  	struct acpi_device_bus_id *acpi_device_bus_id;
  	bool found = false;
  
  	mutex_lock(&acpi_device_lock);
  	list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
  		if (!strcmp(acpi_device_bus_id->bus_id, hid)) {
  			found = true;
  			break;
  		}
  	mutex_unlock(&acpi_device_lock);
  
  	return found;
  }
c68ae33e7   Lukas Wunner   ACPI / utils: Ren...
774
  EXPORT_SYMBOL(acpi_dev_found);
2d12b6b38   Lukas Wunner   ACPI / utils: Add...
775

67dcf8a3e   Andy Shevchenko   ACPI: utils: Intr...
776
  struct acpi_dev_match_info {
8661423ee   Hans de Goede   ACPI / utils: Add...
777
778
779
780
  	struct acpi_device_id hid[2];
  	const char *uid;
  	s64 hrv;
  };
418e3ea15   Suzuki K Poulose   bus_find_device: ...
781
  static int acpi_dev_match_cb(struct device *dev, const void *data)
8661423ee   Hans de Goede   ACPI / utils: Add...
782
783
  {
  	struct acpi_device *adev = to_acpi_device(dev);
418e3ea15   Suzuki K Poulose   bus_find_device: ...
784
  	const struct acpi_dev_match_info *match = data;
8661423ee   Hans de Goede   ACPI / utils: Add...
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
  	unsigned long long hrv;
  	acpi_status status;
  
  	if (acpi_match_device_ids(adev, match->hid))
  		return 0;
  
  	if (match->uid && (!adev->pnp.unique_id ||
  	    strcmp(adev->pnp.unique_id, match->uid)))
  		return 0;
  
  	if (match->hrv == -1)
  		return 1;
  
  	status = acpi_evaluate_integer(adev->handle, "_HRV", NULL, &hrv);
  	if (ACPI_FAILURE(status))
  		return 0;
  
  	return hrv == match->hrv;
  }
  
  /**
   * acpi_dev_present - Detect that a given ACPI device is present
   * @hid: Hardware ID of the device.
   * @uid: Unique ID of the device, pass NULL to not check _UID
   * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
   *
   * Return %true if a matching device was present at the moment of invocation.
   * Note that if the device is pluggable, it may since have disappeared.
   *
   * Note that unlike acpi_dev_found() this function checks the status
   * of the device. So for devices which are present in the dsdt, but
   * which are disabled (their _STA callback returns 0) this function
   * will return false.
   *
   * For this function to work, acpi_bus_scan() must have been executed
   * which happens in the subsys_initcall() subsection. Hence, do not
   * call from a subsys_initcall() or earlier (use acpi_get_devices()
   * instead). Calling from module_init() is fine (which is synonymous
   * with device_initcall()).
   */
  bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
  {
67dcf8a3e   Andy Shevchenko   ACPI: utils: Intr...
827
  	struct acpi_dev_match_info match = {};
8661423ee   Hans de Goede   ACPI / utils: Add...
828
829
830
831
832
  	struct device *dev;
  
  	strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
  	match.uid = uid;
  	match.hrv = hrv;
67dcf8a3e   Andy Shevchenko   ACPI: utils: Intr...
833
  	dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb);
54e3aca84   Andy Shevchenko   ACPI / utils: Dro...
834
  	put_device(dev);
8661423ee   Hans de Goede   ACPI / utils: Add...
835
836
837
  	return !!dev;
  }
  EXPORT_SYMBOL(acpi_dev_present);
67dcf8a3e   Andy Shevchenko   ACPI: utils: Intr...
838
  /**
817b4d64d   Andy Shevchenko   ACPI / utils: Int...
839
   * acpi_dev_get_first_match_dev - Return the first match of ACPI device
67dcf8a3e   Andy Shevchenko   ACPI: utils: Intr...
840
841
842
843
   * @hid: Hardware ID of the device.
   * @uid: Unique ID of the device, pass NULL to not check _UID
   * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
   *
817b4d64d   Andy Shevchenko   ACPI / utils: Int...
844
   * Return the first match of ACPI device if a matching device was present
67dcf8a3e   Andy Shevchenko   ACPI: utils: Intr...
845
846
   * at the moment of invocation, or NULL otherwise.
   *
817b4d64d   Andy Shevchenko   ACPI / utils: Int...
847
848
   * The caller is responsible to call put_device() on the returned device.
   *
67dcf8a3e   Andy Shevchenko   ACPI: utils: Intr...
849
850
   * See additional information in acpi_dev_present() as well.
   */
817b4d64d   Andy Shevchenko   ACPI / utils: Int...
851
852
853
854
855
856
857
858
859
860
861
  struct acpi_device *
  acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
  {
  	struct acpi_dev_match_info match = {};
  	struct device *dev;
  
  	strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
  	match.uid = uid;
  	match.hrv = hrv;
  
  	dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb);
e6374f6b2   Suzuki K Poulose   acpi: utils: Clea...
862
  	return dev ? to_acpi_device(dev) : NULL;
817b4d64d   Andy Shevchenko   ACPI / utils: Int...
863
864
  }
  EXPORT_SYMBOL(acpi_dev_get_first_match_dev);
14ca7a47d   Hans de Goede   acpi-video-detect...
865
866
867
868
869
870
871
872
873
874
875
876
877
878
  /*
   * acpi_backlight= handling, this is done here rather then in video_detect.c
   * because __setup cannot be used in modules.
   */
  char acpi_video_backlight_string[16];
  EXPORT_SYMBOL(acpi_video_backlight_string);
  
  static int __init acpi_backlight(char *str)
  {
  	strlcpy(acpi_video_backlight_string, str,
  		sizeof(acpi_video_backlight_string));
  	return 1;
  }
  __setup("acpi_backlight=", acpi_backlight);
5aa5911a0   Toshi Kani   ACPI / blacklist:...
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
  
  /**
   * acpi_match_platform_list - Check if the system matches with a given list
   * @plat: pointer to acpi_platform_list table terminated by a NULL entry
   *
   * Return the matched index if the system is found in the platform list.
   * Otherwise, return a negative error code.
   */
  int acpi_match_platform_list(const struct acpi_platform_list *plat)
  {
  	struct acpi_table_header hdr;
  	int idx = 0;
  
  	if (acpi_disabled)
  		return -ENODEV;
  
  	for (; plat->oem_id[0]; plat++, idx++) {
  		if (ACPI_FAILURE(acpi_get_table_header(plat->table, 0, &hdr)))
  			continue;
  
  		if (strncmp(plat->oem_id, hdr.oem_id, ACPI_OEM_ID_SIZE))
  			continue;
  
  		if (strncmp(plat->oem_table_id, hdr.oem_table_id, ACPI_OEM_TABLE_ID_SIZE))
  			continue;
  
  		if ((plat->pred == all_versions) ||
  		    (plat->pred == less_than_or_equal && hdr.oem_revision <= plat->oem_revision) ||
  		    (plat->pred == greater_than_or_equal && hdr.oem_revision >= plat->oem_revision) ||
  		    (plat->pred == equal && hdr.oem_revision == plat->oem_revision))
  			return idx;
  	}
  
  	return -ENODEV;
  }
  EXPORT_SYMBOL(acpi_match_platform_list);