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