1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45#include <acpi/acpi.h>
46#include "accommon.h"
47#include "acnamesp.h"
48
49#define _COMPONENT ACPI_HARDWARE
50ACPI_MODULE_NAME("hwxface")
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65acpi_status acpi_reset(void)
66{
67 struct acpi_generic_address *reset_reg;
68 acpi_status status;
69
70 ACPI_FUNCTION_TRACE(acpi_reset);
71
72 reset_reg = &acpi_gbl_FADT.reset_register;
73
74
75
76 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
77 !reset_reg->address) {
78 return_ACPI_STATUS(AE_NOT_EXIST);
79 }
80
81 if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
82
83
84
85
86
87 status =
88 acpi_os_write_port((acpi_io_address) reset_reg->address,
89 acpi_gbl_FADT.reset_value,
90 reset_reg->bit_width);
91 } else {
92
93
94 status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg);
95 }
96
97 return_ACPI_STATUS(status);
98}
99
100ACPI_EXPORT_SYMBOL(acpi_reset)
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
121{
122 u32 value;
123 u32 width;
124 u64 address;
125 acpi_status status;
126
127 ACPI_FUNCTION_NAME(acpi_read);
128
129 if (!return_value) {
130 return (AE_BAD_PARAMETER);
131 }
132
133
134
135 status = acpi_hw_validate_register(reg, 64, &address);
136 if (ACPI_FAILURE(status)) {
137 return (status);
138 }
139
140 width = reg->bit_width;
141 if (width == 64) {
142 width = 32;
143 }
144
145
146
147 *return_value = 0;
148 value = 0;
149
150
151
152
153
154 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
155 status = acpi_os_read_memory((acpi_physical_address)
156 address, &value, width);
157 if (ACPI_FAILURE(status)) {
158 return (status);
159 }
160 *return_value = value;
161
162 if (reg->bit_width == 64) {
163
164
165
166 status = acpi_os_read_memory((acpi_physical_address)
167 (address + 4), &value, 32);
168 if (ACPI_FAILURE(status)) {
169 return (status);
170 }
171 *return_value |= ((u64)value << 32);
172 }
173 } else {
174
175 status = acpi_hw_read_port((acpi_io_address)
176 address, &value, width);
177 if (ACPI_FAILURE(status)) {
178 return (status);
179 }
180 *return_value = value;
181
182 if (reg->bit_width == 64) {
183
184
185
186 status = acpi_hw_read_port((acpi_io_address)
187 (address + 4), &value, 32);
188 if (ACPI_FAILURE(status)) {
189 return (status);
190 }
191 *return_value |= ((u64)value << 32);
192 }
193 }
194
195 ACPI_DEBUG_PRINT((ACPI_DB_IO,
196 "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
197 ACPI_FORMAT_UINT64(*return_value), reg->bit_width,
198 ACPI_FORMAT_UINT64(address),
199 acpi_ut_get_region_name(reg->space_id)));
200
201 return (status);
202}
203
204ACPI_EXPORT_SYMBOL(acpi_read)
205
206
207
208
209
210
211
212
213
214
215
216
217
218acpi_status acpi_write(u64 value, struct acpi_generic_address *reg)
219{
220 u32 width;
221 u64 address;
222 acpi_status status;
223
224 ACPI_FUNCTION_NAME(acpi_write);
225
226
227
228 status = acpi_hw_validate_register(reg, 64, &address);
229 if (ACPI_FAILURE(status)) {
230 return (status);
231 }
232
233 width = reg->bit_width;
234 if (width == 64) {
235 width = 32;
236 }
237
238
239
240
241
242 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
243 status = acpi_os_write_memory((acpi_physical_address)
244 address, ACPI_LODWORD(value),
245 width);
246 if (ACPI_FAILURE(status)) {
247 return (status);
248 }
249
250 if (reg->bit_width == 64) {
251 status = acpi_os_write_memory((acpi_physical_address)
252 (address + 4),
253 ACPI_HIDWORD(value), 32);
254 if (ACPI_FAILURE(status)) {
255 return (status);
256 }
257 }
258 } else {
259
260 status = acpi_hw_write_port((acpi_io_address)
261 address, ACPI_LODWORD(value),
262 width);
263 if (ACPI_FAILURE(status)) {
264 return (status);
265 }
266
267 if (reg->bit_width == 64) {
268 status = acpi_hw_write_port((acpi_io_address)
269 (address + 4),
270 ACPI_HIDWORD(value), 32);
271 if (ACPI_FAILURE(status)) {
272 return (status);
273 }
274 }
275 }
276
277 ACPI_DEBUG_PRINT((ACPI_DB_IO,
278 "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
279 ACPI_FORMAT_UINT64(value), reg->bit_width,
280 ACPI_FORMAT_UINT64(address),
281 acpi_ut_get_region_name(reg->space_id)));
282
283 return (status);
284}
285
286ACPI_EXPORT_SYMBOL(acpi_write)
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
313{
314 struct acpi_bit_register_info *bit_reg_info;
315 u32 register_value;
316 u32 value;
317 acpi_status status;
318
319 ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
320
321
322
323 bit_reg_info = acpi_hw_get_bit_register_info(register_id);
324 if (!bit_reg_info) {
325 return_ACPI_STATUS(AE_BAD_PARAMETER);
326 }
327
328
329
330 status = acpi_hw_register_read(bit_reg_info->parent_register,
331 ®ister_value);
332 if (ACPI_FAILURE(status)) {
333 return_ACPI_STATUS(status);
334 }
335
336
337
338 value = ((register_value & bit_reg_info->access_bit_mask)
339 >> bit_reg_info->bit_position);
340
341 ACPI_DEBUG_PRINT((ACPI_DB_IO,
342 "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
343 register_id, bit_reg_info->parent_register,
344 register_value, value));
345
346 *return_value = value;
347 return_ACPI_STATUS(AE_OK);
348}
349
350ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373acpi_status acpi_write_bit_register(u32 register_id, u32 value)
374{
375 struct acpi_bit_register_info *bit_reg_info;
376 acpi_cpu_flags lock_flags;
377 u32 register_value;
378 acpi_status status = AE_OK;
379
380 ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
381
382
383
384 bit_reg_info = acpi_hw_get_bit_register_info(register_id);
385 if (!bit_reg_info) {
386 return_ACPI_STATUS(AE_BAD_PARAMETER);
387 }
388
389 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
390
391
392
393
394
395 if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
396
397
398
399
400
401
402 status = acpi_hw_register_read(bit_reg_info->parent_register,
403 ®ister_value);
404 if (ACPI_FAILURE(status)) {
405 goto unlock_and_exit;
406 }
407
408
409
410
411
412 ACPI_REGISTER_INSERT_VALUE(register_value,
413 bit_reg_info->bit_position,
414 bit_reg_info->access_bit_mask,
415 value);
416
417 status = acpi_hw_register_write(bit_reg_info->parent_register,
418 register_value);
419 } else {
420
421
422
423
424
425
426
427
428 register_value = ACPI_REGISTER_PREPARE_BITS(value,
429 bit_reg_info->
430 bit_position,
431 bit_reg_info->
432 access_bit_mask);
433
434
435
436 if (register_value) {
437 status =
438 acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
439 register_value);
440 }
441 }
442
443 ACPI_DEBUG_PRINT((ACPI_DB_IO,
444 "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
445 register_id, bit_reg_info->parent_register, value,
446 register_value));
447
448unlock_and_exit:
449
450 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
451 return_ACPI_STATUS(status);
452}
453
454ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470acpi_status
471acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
472{
473 acpi_status status = AE_OK;
474 struct acpi_evaluate_info *info;
475
476 ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data);
477
478
479
480 if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) {
481 return_ACPI_STATUS(AE_BAD_PARAMETER);
482 }
483
484
485
486 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
487 if (!info) {
488 return_ACPI_STATUS(AE_NO_MEMORY);
489 }
490
491 info->pathname =
492 ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
493
494
495
496 status = acpi_ns_evaluate(info);
497 if (ACPI_FAILURE(status)) {
498 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
499 "%s while evaluating SleepState [%s]\n",
500 acpi_format_exception(status),
501 info->pathname));
502
503 goto cleanup;
504 }
505
506
507
508 if (!info->return_object) {
509 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
510 info->pathname));
511 status = AE_NOT_EXIST;
512 }
513
514
515
516 else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
517 ACPI_ERROR((AE_INFO,
518 "Sleep State return object is not a Package"));
519 status = AE_AML_OPERAND_TYPE;
520 }
521
522
523
524
525
526
527
528
529 else if (info->return_object->package.count < 2) {
530 ACPI_ERROR((AE_INFO,
531 "Sleep State return package does not have at least two elements"));
532 status = AE_AML_NO_OPERAND;
533 }
534
535
536
537 else if (((info->return_object->package.elements[0])->common.type
538 != ACPI_TYPE_INTEGER) ||
539 ((info->return_object->package.elements[1])->common.type
540 != ACPI_TYPE_INTEGER)) {
541 ACPI_ERROR((AE_INFO,
542 "Sleep State return package elements are not both Integers "
543 "(%s, %s)",
544 acpi_ut_get_object_type_name(info->return_object->
545 package.elements[0]),
546 acpi_ut_get_object_type_name(info->return_object->
547 package.elements[1])));
548 status = AE_AML_OPERAND_TYPE;
549 } else {
550
551
552 *sleep_type_a = (u8)
553 (info->return_object->package.elements[0])->integer.value;
554 *sleep_type_b = (u8)
555 (info->return_object->package.elements[1])->integer.value;
556 }
557
558 if (ACPI_FAILURE(status)) {
559 ACPI_EXCEPTION((AE_INFO, status,
560 "While evaluating SleepState [%s], bad Sleep object %p type %s",
561 info->pathname, info->return_object,
562 acpi_ut_get_object_type_name(info->
563 return_object)));
564 }
565
566 acpi_ut_remove_reference(info->return_object);
567
568 cleanup:
569 ACPI_FREE(info);
570 return_ACPI_STATUS(status);
571}
572
573ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data)
574