]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/acpi/hardware/hwregs.c
ACPICA: update Intel copyright
[linux-2.6-omap-h63xx.git] / drivers / acpi / hardware / hwregs.c
1
2 /*******************************************************************************
3  *
4  * Module Name: hwregs - Read/write access functions for the various ACPI
5  *                       control and status registers.
6  *
7  ******************************************************************************/
8
9 /*
10  * Copyright (C) 2000 - 2008, Intel Corp.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions, and the following disclaimer,
18  *    without modification.
19  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
20  *    substantially similar to the "NO WARRANTY" disclaimer below
21  *    ("Disclaimer") and any redistribution must be conditioned upon
22  *    including a substantially similar Disclaimer requirement for further
23  *    binary redistribution.
24  * 3. Neither the names of the above-listed copyright holders nor the names
25  *    of any contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * Alternatively, this software may be distributed under the terms of the
29  * GNU General Public License ("GPL") version 2 as published by the Free
30  * Software Foundation.
31  *
32  * NO WARRANTY
33  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
36  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43  * POSSIBILITY OF SUCH DAMAGES.
44  */
45
46 #include <acpi/acpi.h>
47 #include <acpi/acnamesp.h>
48 #include <acpi/acevents.h>
49
50 #define _COMPONENT          ACPI_HARDWARE
51 ACPI_MODULE_NAME("hwregs")
52
53 /*******************************************************************************
54  *
55  * FUNCTION:    acpi_hw_clear_acpi_status
56  *
57  * PARAMETERS:  None
58  *
59  * RETURN:      None
60  *
61  * DESCRIPTION: Clears all fixed and general purpose status bits
62  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
63  *
64  ******************************************************************************/
65 acpi_status acpi_hw_clear_acpi_status(void)
66 {
67         acpi_status status;
68         acpi_cpu_flags lock_flags = 0;
69
70         ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
71
72         ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
73                           ACPI_BITMASK_ALL_FIXED_STATUS,
74                           (u16) acpi_gbl_FADT.xpm1a_event_block.address));
75
76         lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
77
78         status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
79                                         ACPI_BITMASK_ALL_FIXED_STATUS);
80         if (ACPI_FAILURE(status)) {
81                 goto unlock_and_exit;
82         }
83
84         /* Clear the fixed events */
85
86         if (acpi_gbl_FADT.xpm1b_event_block.address) {
87                 status =
88                     acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS,
89                                             &acpi_gbl_FADT.xpm1b_event_block);
90                 if (ACPI_FAILURE(status)) {
91                         goto unlock_and_exit;
92                 }
93         }
94
95         /* Clear the GPE Bits in all GPE registers in all GPE blocks */
96
97         status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block);
98
99       unlock_and_exit:
100         acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
101         return_ACPI_STATUS(status);
102 }
103
104 /*******************************************************************************
105  *
106  * FUNCTION:    acpi_get_sleep_type_data
107  *
108  * PARAMETERS:  sleep_state         - Numeric sleep state
109  *              *sleep_type_a        - Where SLP_TYPa is returned
110  *              *sleep_type_b        - Where SLP_TYPb is returned
111  *
112  * RETURN:      Status - ACPI status
113  *
114  * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
115  *              state.
116  *
117  ******************************************************************************/
118
119 acpi_status
120 acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b)
121 {
122         acpi_status status = AE_OK;
123         struct acpi_evaluate_info *info;
124
125         ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data);
126
127         /* Validate parameters */
128
129         if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) {
130                 return_ACPI_STATUS(AE_BAD_PARAMETER);
131         }
132
133         /* Allocate the evaluation information block */
134
135         info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
136         if (!info) {
137                 return_ACPI_STATUS(AE_NO_MEMORY);
138         }
139
140         info->pathname =
141             ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
142
143         /* Evaluate the namespace object containing the values for this state */
144
145         status = acpi_ns_evaluate(info);
146         if (ACPI_FAILURE(status)) {
147                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
148                                   "%s while evaluating SleepState [%s]\n",
149                                   acpi_format_exception(status),
150                                   info->pathname));
151
152                 goto cleanup;
153         }
154
155         /* Must have a return object */
156
157         if (!info->return_object) {
158                 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
159                             info->pathname));
160                 status = AE_NOT_EXIST;
161         }
162
163         /* It must be of type Package */
164
165         else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
166                 ACPI_ERROR((AE_INFO,
167                             "Sleep State return object is not a Package"));
168                 status = AE_AML_OPERAND_TYPE;
169         }
170
171         /*
172          * The package must have at least two elements. NOTE (March 2005): This
173          * goes against the current ACPI spec which defines this object as a
174          * package with one encoded DWORD element. However, existing practice
175          * by BIOS vendors seems to be to have 2 or more elements, at least
176          * one per sleep type (A/B).
177          */
178         else if (info->return_object->package.count < 2) {
179                 ACPI_ERROR((AE_INFO,
180                             "Sleep State return package does not have at least two elements"));
181                 status = AE_AML_NO_OPERAND;
182         }
183
184         /* The first two elements must both be of type Integer */
185
186         else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
187                   != ACPI_TYPE_INTEGER) ||
188                  (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
189                   != ACPI_TYPE_INTEGER)) {
190                 ACPI_ERROR((AE_INFO,
191                             "Sleep State return package elements are not both Integers (%s, %s)",
192                             acpi_ut_get_object_type_name(info->return_object->
193                                                          package.elements[0]),
194                             acpi_ut_get_object_type_name(info->return_object->
195                                                          package.elements[1])));
196                 status = AE_AML_OPERAND_TYPE;
197         } else {
198                 /* Valid _Sx_ package size, type, and value */
199
200                 *sleep_type_a = (u8)
201                     (info->return_object->package.elements[0])->integer.value;
202                 *sleep_type_b = (u8)
203                     (info->return_object->package.elements[1])->integer.value;
204         }
205
206         if (ACPI_FAILURE(status)) {
207                 ACPI_EXCEPTION((AE_INFO, status,
208                                 "While evaluating SleepState [%s], bad Sleep object %p type %s",
209                                 info->pathname, info->return_object,
210                                 acpi_ut_get_object_type_name(info->
211                                                              return_object)));
212         }
213
214         acpi_ut_remove_reference(info->return_object);
215
216       cleanup:
217         ACPI_FREE(info);
218         return_ACPI_STATUS(status);
219 }
220
221 ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data)
222
223 /*******************************************************************************
224  *
225  * FUNCTION:    acpi_hw_get_register_bit_mask
226  *
227  * PARAMETERS:  register_id         - Index of ACPI Register to access
228  *
229  * RETURN:      The bitmask to be used when accessing the register
230  *
231  * DESCRIPTION: Map register_id into a register bitmask.
232  *
233  ******************************************************************************/
234 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
235 {
236         ACPI_FUNCTION_ENTRY();
237
238         if (register_id > ACPI_BITREG_MAX) {
239                 ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X",
240                             register_id));
241                 return (NULL);
242         }
243
244         return (&acpi_gbl_bit_register_info[register_id]);
245 }
246
247 /*******************************************************************************
248  *
249  * FUNCTION:    acpi_get_register
250  *
251  * PARAMETERS:  register_id     - ID of ACPI bit_register to access
252  *              return_value    - Value that was read from the register
253  *
254  * RETURN:      Status and the value read from specified Register. Value
255  *              returned is normalized to bit0 (is shifted all the way right)
256  *
257  * DESCRIPTION: ACPI bit_register read function.
258  *
259  ******************************************************************************/
260
261 acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
262 {
263         u32 register_value = 0;
264         struct acpi_bit_register_info *bit_reg_info;
265         acpi_status status;
266
267         ACPI_FUNCTION_TRACE(acpi_get_register);
268
269         /* Get the info structure corresponding to the requested ACPI Register */
270
271         bit_reg_info = acpi_hw_get_bit_register_info(register_id);
272         if (!bit_reg_info) {
273                 return_ACPI_STATUS(AE_BAD_PARAMETER);
274         }
275
276         /* Read from the register */
277
278         status = acpi_hw_register_read(bit_reg_info->parent_register,
279                                        &register_value);
280
281         if (ACPI_SUCCESS(status)) {
282
283                 /* Normalize the value that was read */
284
285                 register_value =
286                     ((register_value & bit_reg_info->access_bit_mask)
287                      >> bit_reg_info->bit_position);
288
289                 *return_value = register_value;
290
291                 ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
292                                   register_value,
293                                   bit_reg_info->parent_register));
294         }
295
296         return_ACPI_STATUS(status);
297 }
298
299 acpi_status acpi_get_register(u32 register_id, u32 * return_value)
300 {
301         acpi_status status;
302         acpi_cpu_flags flags;
303         flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
304         status = acpi_get_register_unlocked(register_id, return_value);
305         acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
306         return status;
307 }
308
309 ACPI_EXPORT_SYMBOL(acpi_get_register)
310
311 /*******************************************************************************
312  *
313  * FUNCTION:    acpi_set_register
314  *
315  * PARAMETERS:  register_id     - ID of ACPI bit_register to access
316  *              Value           - (only used on write) value to write to the
317  *                                Register, NOT pre-normalized to the bit pos
318  *
319  * RETURN:      Status
320  *
321  * DESCRIPTION: ACPI Bit Register write function.
322  *
323  ******************************************************************************/
324 acpi_status acpi_set_register(u32 register_id, u32 value)
325 {
326         u32 register_value = 0;
327         struct acpi_bit_register_info *bit_reg_info;
328         acpi_status status;
329         acpi_cpu_flags lock_flags;
330
331         ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
332
333         /* Get the info structure corresponding to the requested ACPI Register */
334
335         bit_reg_info = acpi_hw_get_bit_register_info(register_id);
336         if (!bit_reg_info) {
337                 ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X",
338                             register_id));
339                 return_ACPI_STATUS(AE_BAD_PARAMETER);
340         }
341
342         lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
343
344         /* Always do a register read first so we can insert the new bits  */
345
346         status = acpi_hw_register_read(bit_reg_info->parent_register,
347                                        &register_value);
348         if (ACPI_FAILURE(status)) {
349                 goto unlock_and_exit;
350         }
351
352         /*
353          * Decode the Register ID
354          * Register ID = [Register block ID] | [bit ID]
355          *
356          * Check bit ID to fine locate Register offset.
357          * Check Mask to determine Register offset, and then read-write.
358          */
359         switch (bit_reg_info->parent_register) {
360         case ACPI_REGISTER_PM1_STATUS:
361
362                 /*
363                  * Status Registers are different from the rest. Clear by
364                  * writing 1, and writing 0 has no effect. So, the only relevant
365                  * information is the single bit we're interested in, all others should
366                  * be written as 0 so they will be left unchanged.
367                  */
368                 value = ACPI_REGISTER_PREPARE_BITS(value,
369                                                    bit_reg_info->bit_position,
370                                                    bit_reg_info->
371                                                    access_bit_mask);
372                 if (value) {
373                         status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
374                                                         (u16) value);
375                         register_value = 0;
376                 }
377                 break;
378
379         case ACPI_REGISTER_PM1_ENABLE:
380
381                 ACPI_REGISTER_INSERT_VALUE(register_value,
382                                            bit_reg_info->bit_position,
383                                            bit_reg_info->access_bit_mask,
384                                            value);
385
386                 status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
387                                                 (u16) register_value);
388                 break;
389
390         case ACPI_REGISTER_PM1_CONTROL:
391
392                 /*
393                  * Write the PM1 Control register.
394                  * Note that at this level, the fact that there are actually TWO
395                  * registers (A and B - and B may not exist) is abstracted.
396                  */
397                 ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
398                                   register_value));
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(ACPI_REGISTER_PM1_CONTROL,
406                                                 (u16) register_value);
407                 break;
408
409         case ACPI_REGISTER_PM2_CONTROL:
410
411                 status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
412                                                &register_value);
413                 if (ACPI_FAILURE(status)) {
414                         goto unlock_and_exit;
415                 }
416
417                 ACPI_DEBUG_PRINT((ACPI_DB_IO,
418                                   "PM2 control: Read %X from %8.8X%8.8X\n",
419                                   register_value,
420                                   ACPI_FORMAT_UINT64(acpi_gbl_FADT.
421                                                      xpm2_control_block.
422                                                      address)));
423
424                 ACPI_REGISTER_INSERT_VALUE(register_value,
425                                            bit_reg_info->bit_position,
426                                            bit_reg_info->access_bit_mask,
427                                            value);
428
429                 ACPI_DEBUG_PRINT((ACPI_DB_IO,
430                                   "About to write %4.4X to %8.8X%8.8X\n",
431                                   register_value,
432                                   ACPI_FORMAT_UINT64(acpi_gbl_FADT.
433                                                      xpm2_control_block.
434                                                      address)));
435
436                 status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
437                                                 (u8) (register_value));
438                 break;
439
440         default:
441                 break;
442         }
443
444       unlock_and_exit:
445
446         acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
447
448         /* Normalize the value that was read */
449
450         ACPI_DEBUG_EXEC(register_value =
451                         ((register_value & bit_reg_info->access_bit_mask) >>
452                          bit_reg_info->bit_position));
453
454         ACPI_DEBUG_PRINT((ACPI_DB_IO,
455                           "Set bits: %8.8X actual %8.8X register %X\n", value,
456                           register_value, bit_reg_info->parent_register));
457         return_ACPI_STATUS(status);
458 }
459
460 ACPI_EXPORT_SYMBOL(acpi_set_register)
461
462 /******************************************************************************
463  *
464  * FUNCTION:    acpi_hw_register_read
465  *
466  * PARAMETERS:  register_id         - ACPI Register ID
467  *              return_value        - Where the register value is returned
468  *
469  * RETURN:      Status and the value read.
470  *
471  * DESCRIPTION: Read from the specified ACPI register
472  *
473  ******************************************************************************/
474 acpi_status
475 acpi_hw_register_read(u32 register_id, u32 * return_value)
476 {
477         u32 value1 = 0;
478         u32 value2 = 0;
479         acpi_status status;
480
481         ACPI_FUNCTION_TRACE(hw_register_read);
482
483         switch (register_id) {
484         case ACPI_REGISTER_PM1_STATUS:  /* 16-bit access */
485
486                 status =
487                     acpi_hw_low_level_read(16, &value1,
488                                            &acpi_gbl_FADT.xpm1a_event_block);
489                 if (ACPI_FAILURE(status)) {
490                         goto exit;
491                 }
492
493                 /* PM1B is optional */
494
495                 status =
496                     acpi_hw_low_level_read(16, &value2,
497                                            &acpi_gbl_FADT.xpm1b_event_block);
498                 value1 |= value2;
499                 break;
500
501         case ACPI_REGISTER_PM1_ENABLE:  /* 16-bit access */
502
503                 status =
504                     acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
505                 if (ACPI_FAILURE(status)) {
506                         goto exit;
507                 }
508
509                 /* PM1B is optional */
510
511                 status =
512                     acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable);
513                 value1 |= value2;
514                 break;
515
516         case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
517
518                 status =
519                     acpi_hw_low_level_read(16, &value1,
520                                            &acpi_gbl_FADT.xpm1a_control_block);
521                 if (ACPI_FAILURE(status)) {
522                         goto exit;
523                 }
524
525                 status =
526                     acpi_hw_low_level_read(16, &value2,
527                                            &acpi_gbl_FADT.xpm1b_control_block);
528                 value1 |= value2;
529                 break;
530
531         case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
532
533                 status =
534                     acpi_hw_low_level_read(8, &value1,
535                                            &acpi_gbl_FADT.xpm2_control_block);
536                 break;
537
538         case ACPI_REGISTER_PM_TIMER:    /* 32-bit access */
539
540                 status =
541                     acpi_hw_low_level_read(32, &value1,
542                                            &acpi_gbl_FADT.xpm_timer_block);
543                 break;
544
545         case ACPI_REGISTER_SMI_COMMAND_BLOCK:   /* 8-bit access */
546
547                 status =
548                     acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
549                 break;
550
551         default:
552                 ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
553                 status = AE_BAD_PARAMETER;
554                 break;
555         }
556
557       exit:
558
559         if (ACPI_SUCCESS(status)) {
560                 *return_value = value1;
561         }
562
563         return_ACPI_STATUS(status);
564 }
565
566 /******************************************************************************
567  *
568  * FUNCTION:    acpi_hw_register_write
569  *
570  * PARAMETERS:  register_id         - ACPI Register ID
571  *              Value               - The value to write
572  *
573  * RETURN:      Status
574  *
575  * DESCRIPTION: Write to the specified ACPI register
576  *
577  * NOTE: In accordance with the ACPI specification, this function automatically
578  * preserves the value of the following bits, meaning that these bits cannot be
579  * changed via this interface:
580  *
581  * PM1_CONTROL[0] = SCI_EN
582  * PM1_CONTROL[9]
583  * PM1_STATUS[11]
584  *
585  * ACPI References:
586  * 1) Hardware Ignored Bits: When software writes to a register with ignored
587  *      bit fields, it preserves the ignored bit fields
588  * 2) SCI_EN: OSPM always preserves this bit position
589  *
590  ******************************************************************************/
591
592 acpi_status acpi_hw_register_write(u32 register_id, u32 value)
593 {
594         acpi_status status;
595         u32 read_value;
596
597         ACPI_FUNCTION_TRACE(hw_register_write);
598
599         switch (register_id) {
600         case ACPI_REGISTER_PM1_STATUS:  /* 16-bit access */
601
602                 /* Perform a read first to preserve certain bits (per ACPI spec) */
603
604                 status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
605                                                &read_value);
606                 if (ACPI_FAILURE(status)) {
607                         goto exit;
608                 }
609
610                 /* Insert the bits to be preserved */
611
612                 ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
613                                  read_value);
614
615                 /* Now we can write the data */
616
617                 status =
618                     acpi_hw_low_level_write(16, value,
619                                             &acpi_gbl_FADT.xpm1a_event_block);
620                 if (ACPI_FAILURE(status)) {
621                         goto exit;
622                 }
623
624                 /* PM1B is optional */
625
626                 status =
627                     acpi_hw_low_level_write(16, value,
628                                             &acpi_gbl_FADT.xpm1b_event_block);
629                 break;
630
631         case ACPI_REGISTER_PM1_ENABLE:  /* 16-bit access */
632
633                 status =
634                     acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
635                 if (ACPI_FAILURE(status)) {
636                         goto exit;
637                 }
638
639                 /* PM1B is optional */
640
641                 status =
642                     acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable);
643                 break;
644
645         case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
646
647                 /*
648                  * Perform a read first to preserve certain bits (per ACPI spec)
649                  */
650                 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
651                                                &read_value);
652                 if (ACPI_FAILURE(status)) {
653                         goto exit;
654                 }
655
656                 /* Insert the bits to be preserved */
657
658                 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS,
659                                  read_value);
660
661                 /* Now we can write the data */
662
663                 status =
664                     acpi_hw_low_level_write(16, value,
665                                             &acpi_gbl_FADT.xpm1a_control_block);
666                 if (ACPI_FAILURE(status)) {
667                         goto exit;
668                 }
669
670                 status =
671                     acpi_hw_low_level_write(16, value,
672                                             &acpi_gbl_FADT.xpm1b_control_block);
673                 break;
674
675         case ACPI_REGISTER_PM1A_CONTROL:        /* 16-bit access */
676
677                 status =
678                     acpi_hw_low_level_write(16, value,
679                                             &acpi_gbl_FADT.xpm1a_control_block);
680                 break;
681
682         case ACPI_REGISTER_PM1B_CONTROL:        /* 16-bit access */
683
684                 status =
685                     acpi_hw_low_level_write(16, value,
686                                             &acpi_gbl_FADT.xpm1b_control_block);
687                 break;
688
689         case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
690
691                 status =
692                     acpi_hw_low_level_write(8, value,
693                                             &acpi_gbl_FADT.xpm2_control_block);
694                 break;
695
696         case ACPI_REGISTER_PM_TIMER:    /* 32-bit access */
697
698                 status =
699                     acpi_hw_low_level_write(32, value,
700                                             &acpi_gbl_FADT.xpm_timer_block);
701                 break;
702
703         case ACPI_REGISTER_SMI_COMMAND_BLOCK:   /* 8-bit access */
704
705                 /* SMI_CMD is currently always in IO space */
706
707                 status =
708                     acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
709                 break;
710
711         default:
712                 status = AE_BAD_PARAMETER;
713                 break;
714         }
715
716       exit:
717         return_ACPI_STATUS(status);
718 }
719
720 /******************************************************************************
721  *
722  * FUNCTION:    acpi_hw_low_level_read
723  *
724  * PARAMETERS:  Width               - 8, 16, or 32
725  *              Value               - Where the value is returned
726  *              Reg                 - GAS register structure
727  *
728  * RETURN:      Status
729  *
730  * DESCRIPTION: Read from either memory or IO space.
731  *
732  ******************************************************************************/
733
734 acpi_status
735 acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
736 {
737         u64 address;
738         acpi_status status;
739
740         ACPI_FUNCTION_NAME(hw_low_level_read);
741
742         /*
743          * Must have a valid pointer to a GAS structure, and
744          * a non-zero address within. However, don't return an error
745          * because the PM1A/B code must not fail if B isn't present.
746          */
747         if (!reg) {
748                 return (AE_OK);
749         }
750
751         /* Get a local copy of the address. Handles possible alignment issues */
752
753         ACPI_MOVE_64_TO_64(&address, &reg->address);
754         if (!address) {
755                 return (AE_OK);
756         }
757         *value = 0;
758
759         /*
760          * Two address spaces supported: Memory or IO.
761          * PCI_Config is not supported here because the GAS struct is insufficient
762          */
763         switch (reg->space_id) {
764         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
765
766                 status = acpi_os_read_memory((acpi_physical_address) address,
767                                              value, width);
768                 break;
769
770         case ACPI_ADR_SPACE_SYSTEM_IO:
771
772                 status =
773                     acpi_os_read_port((acpi_io_address) address, value, width);
774                 break;
775
776         default:
777                 ACPI_ERROR((AE_INFO,
778                             "Unsupported address space: %X", reg->space_id));
779                 return (AE_BAD_PARAMETER);
780         }
781
782         ACPI_DEBUG_PRINT((ACPI_DB_IO,
783                           "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
784                           *value, width, ACPI_FORMAT_UINT64(address),
785                           acpi_ut_get_region_name(reg->space_id)));
786
787         return (status);
788 }
789
790 /******************************************************************************
791  *
792  * FUNCTION:    acpi_hw_low_level_write
793  *
794  * PARAMETERS:  Width               - 8, 16, or 32
795  *              Value               - To be written
796  *              Reg                 - GAS register structure
797  *
798  * RETURN:      Status
799  *
800  * DESCRIPTION: Write to either memory or IO space.
801  *
802  ******************************************************************************/
803
804 acpi_status
805 acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
806 {
807         u64 address;
808         acpi_status status;
809
810         ACPI_FUNCTION_NAME(hw_low_level_write);
811
812         /*
813          * Must have a valid pointer to a GAS structure, and
814          * a non-zero address within. However, don't return an error
815          * because the PM1A/B code must not fail if B isn't present.
816          */
817         if (!reg) {
818                 return (AE_OK);
819         }
820
821         /* Get a local copy of the address. Handles possible alignment issues */
822
823         ACPI_MOVE_64_TO_64(&address, &reg->address);
824         if (!address) {
825                 return (AE_OK);
826         }
827
828         /*
829          * Two address spaces supported: Memory or IO.
830          * PCI_Config is not supported here because the GAS struct is insufficient
831          */
832         switch (reg->space_id) {
833         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
834
835                 status = acpi_os_write_memory((acpi_physical_address) address,
836                                               value, width);
837                 break;
838
839         case ACPI_ADR_SPACE_SYSTEM_IO:
840
841                 status = acpi_os_write_port((acpi_io_address) address, value,
842                                             width);
843                 break;
844
845         default:
846                 ACPI_ERROR((AE_INFO,
847                             "Unsupported address space: %X", reg->space_id));
848                 return (AE_BAD_PARAMETER);
849         }
850
851         ACPI_DEBUG_PRINT((ACPI_DB_IO,
852                           "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
853                           value, width, ACPI_FORMAT_UINT64(address),
854                           acpi_ut_get_region_name(reg->space_id)));
855
856         return (status);
857 }