]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/acpi/hardware/hwregs.c
[ACPI] ACPICA 20051216
[mv-sheeva.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 - 2005, R. Byron Moore
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 <linux/module.h>
47
48 #include <acpi/acpi.h>
49 #include <acpi/acnamesp.h>
50 #include <acpi/acevents.h>
51
52 #define _COMPONENT          ACPI_HARDWARE
53 ACPI_MODULE_NAME("hwregs")
54
55 /*******************************************************************************
56  *
57  * FUNCTION:    acpi_hw_clear_acpi_status
58  *
59  * PARAMETERS:  Flags           - Lock the hardware or not
60  *
61  * RETURN:      none
62  *
63  * DESCRIPTION: Clears all fixed and general purpose status bits
64  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
65  *
66  ******************************************************************************/
67 acpi_status acpi_hw_clear_acpi_status(u32 flags)
68 {
69         acpi_status status;
70
71         ACPI_FUNCTION_TRACE("hw_clear_acpi_status");
72
73         ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
74                           ACPI_BITMASK_ALL_FIXED_STATUS,
75                           (u16) acpi_gbl_FADT->xpm1a_evt_blk.address));
76
77         if (flags & ACPI_MTX_LOCK) {
78                 status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
79                 if (ACPI_FAILURE(status)) {
80                         return_ACPI_STATUS(status);
81                 }
82         }
83
84         status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
85                                         ACPI_REGISTER_PM1_STATUS,
86                                         ACPI_BITMASK_ALL_FIXED_STATUS);
87         if (ACPI_FAILURE(status)) {
88                 goto unlock_and_exit;
89         }
90
91         /* Clear the fixed events */
92
93         if (acpi_gbl_FADT->xpm1b_evt_blk.address) {
94                 status =
95                     acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS,
96                                             &acpi_gbl_FADT->xpm1b_evt_blk);
97                 if (ACPI_FAILURE(status)) {
98                         goto unlock_and_exit;
99                 }
100         }
101
102         /* Clear the GPE Bits in all GPE registers in all GPE blocks */
103
104         status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block);
105
106       unlock_and_exit:
107         if (flags & ACPI_MTX_LOCK) {
108                 (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
109         }
110         return_ACPI_STATUS(status);
111 }
112
113 /*******************************************************************************
114  *
115  * FUNCTION:    acpi_get_sleep_type_data
116  *
117  * PARAMETERS:  sleep_state         - Numeric sleep state
118  *              *sleep_type_a        - Where SLP_TYPa is returned
119  *              *sleep_type_b        - Where SLP_TYPb is returned
120  *
121  * RETURN:      Status - ACPI status
122  *
123  * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
124  *              state.
125  *
126  ******************************************************************************/
127
128 acpi_status
129 acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b)
130 {
131         acpi_status status = AE_OK;
132         struct acpi_parameter_info info;
133         char *sleep_state_name;
134
135         ACPI_FUNCTION_TRACE("acpi_get_sleep_type_data");
136
137         /* Validate parameters */
138
139         if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) {
140                 return_ACPI_STATUS(AE_BAD_PARAMETER);
141         }
142
143         /* Evaluate the namespace object containing the values for this state */
144
145         info.parameters = NULL;
146         info.return_object = NULL;
147         sleep_state_name =
148             ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
149
150         status = acpi_ns_evaluate_by_name(sleep_state_name, &info);
151         if (ACPI_FAILURE(status)) {
152                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
153                                   "%s while evaluating sleep_state [%s]\n",
154                                   acpi_format_exception(status),
155                                   sleep_state_name));
156
157                 return_ACPI_STATUS(status);
158         }
159
160         /* Must have a return object */
161
162         if (!info.return_object) {
163                 ACPI_REPORT_ERROR(("No Sleep State object returned from [%s]\n",
164                                    sleep_state_name));
165                 status = AE_NOT_EXIST;
166         }
167
168         /* It must be of type Package */
169
170         else if (ACPI_GET_OBJECT_TYPE(info.return_object) != ACPI_TYPE_PACKAGE) {
171                 ACPI_REPORT_ERROR(("Sleep State return object is not a Package\n"));
172                 status = AE_AML_OPERAND_TYPE;
173         }
174
175         /*
176          * The package must have at least two elements.  NOTE (March 2005): This
177          * goes against the current ACPI spec which defines this object as a
178          * package with one encoded DWORD element.  However, existing practice
179          * by BIOS vendors seems to be to have 2 or more elements, at least
180          * one per sleep type (A/B).
181          */
182         else if (info.return_object->package.count < 2) {
183                 ACPI_REPORT_ERROR(("Sleep State return package does not have at least two elements\n"));
184                 status = AE_AML_NO_OPERAND;
185         }
186
187         /* The first two elements must both be of type Integer */
188
189         else if ((ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[0])
190                   != ACPI_TYPE_INTEGER) ||
191                  (ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[1])
192                   != ACPI_TYPE_INTEGER)) {
193                 ACPI_REPORT_ERROR(("Sleep State return package elements are not both Integers (%s, %s)\n", acpi_ut_get_object_type_name(info.return_object->package.elements[0]), acpi_ut_get_object_type_name(info.return_object->package.elements[1])));
194                 status = AE_AML_OPERAND_TYPE;
195         } else {
196                 /* Valid _Sx_ package size, type, and value */
197
198                 *sleep_type_a = (u8)
199                     (info.return_object->package.elements[0])->integer.value;
200                 *sleep_type_b = (u8)
201                     (info.return_object->package.elements[1])->integer.value;
202         }
203
204         if (ACPI_FAILURE(status)) {
205                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
206                                   "%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
207                                   acpi_format_exception(status),
208                                   sleep_state_name, info.return_object,
209                                   acpi_ut_get_object_type_name(info.
210                                                                return_object)));
211         }
212
213         acpi_ut_remove_reference(info.return_object);
214         return_ACPI_STATUS(status);
215 }
216
217 EXPORT_SYMBOL(acpi_get_sleep_type_data);
218
219 /*******************************************************************************
220  *
221  * FUNCTION:    acpi_hw_get_register_bit_mask
222  *
223  * PARAMETERS:  register_id         - Index of ACPI Register to access
224  *
225  * RETURN:      The bitmask to be used when accessing the register
226  *
227  * DESCRIPTION: Map register_id into a register bitmask.
228  *
229  ******************************************************************************/
230
231 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
232 {
233         ACPI_FUNCTION_NAME("hw_get_bit_register_info");
234
235         if (register_id > ACPI_BITREG_MAX) {
236                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
237                                   "Invalid bit_register ID: %X\n",
238                                   register_id));
239                 return (NULL);
240         }
241
242         return (&acpi_gbl_bit_register_info[register_id]);
243 }
244
245 /*******************************************************************************
246  *
247  * FUNCTION:    acpi_get_register
248  *
249  * PARAMETERS:  register_id     - ID of ACPI bit_register to access
250  *              return_value    - Value that was read from the register
251  *              Flags           - Lock the hardware or not
252  *
253  * RETURN:      Status and the value read from specified Register.  Value
254  *              returned is normalized to bit0 (is shifted all the way right)
255  *
256  * DESCRIPTION: ACPI bit_register read function.
257  *
258  ******************************************************************************/
259
260 acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags)
261 {
262         u32 register_value = 0;
263         struct acpi_bit_register_info *bit_reg_info;
264         acpi_status status;
265
266         ACPI_FUNCTION_TRACE("acpi_get_register");
267
268         /* Get the info structure corresponding to the requested ACPI Register */
269
270         bit_reg_info = acpi_hw_get_bit_register_info(register_id);
271         if (!bit_reg_info) {
272                 return_ACPI_STATUS(AE_BAD_PARAMETER);
273         }
274
275         if (flags & ACPI_MTX_LOCK) {
276                 status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
277                 if (ACPI_FAILURE(status)) {
278                         return_ACPI_STATUS(status);
279                 }
280         }
281
282         /* Read from the register */
283
284         status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
285                                        bit_reg_info->parent_register,
286                                        &register_value);
287
288         if (flags & ACPI_MTX_LOCK) {
289                 (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
290         }
291
292         if (ACPI_SUCCESS(status)) {
293                 /* Normalize the value that was read */
294
295                 register_value =
296                     ((register_value & bit_reg_info->access_bit_mask)
297                      >> bit_reg_info->bit_position);
298
299                 *return_value = register_value;
300
301                 ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
302                                   register_value,
303                                   bit_reg_info->parent_register));
304         }
305
306         return_ACPI_STATUS(status);
307 }
308
309 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  *              Flags           - Lock the hardware or not
319  *
320  * RETURN:      Status
321  *
322  * DESCRIPTION: ACPI Bit Register write function.
323  *
324  ******************************************************************************/
325
326 acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
327 {
328         u32 register_value = 0;
329         struct acpi_bit_register_info *bit_reg_info;
330         acpi_status status;
331
332         ACPI_FUNCTION_TRACE_U32("acpi_set_register", register_id);
333
334         /* Get the info structure corresponding to the requested ACPI Register */
335
336         bit_reg_info = acpi_hw_get_bit_register_info(register_id);
337         if (!bit_reg_info) {
338                 ACPI_REPORT_ERROR(("Bad ACPI HW register_id: %X\n",
339                                    register_id));
340                 return_ACPI_STATUS(AE_BAD_PARAMETER);
341         }
342
343         if (flags & ACPI_MTX_LOCK) {
344                 status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
345                 if (ACPI_FAILURE(status)) {
346                         return_ACPI_STATUS(status);
347                 }
348         }
349
350         /* Always do a register read first so we can insert the new bits  */
351
352         status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
353                                        bit_reg_info->parent_register,
354                                        &register_value);
355         if (ACPI_FAILURE(status)) {
356                 goto unlock_and_exit;
357         }
358
359         /*
360          * Decode the Register ID
361          * Register ID = [Register block ID] | [bit ID]
362          *
363          * Check bit ID to fine locate Register offset.
364          * Check Mask to determine Register offset, and then read-write.
365          */
366         switch (bit_reg_info->parent_register) {
367         case ACPI_REGISTER_PM1_STATUS:
368
369                 /*
370                  * Status Registers are different from the rest.  Clear by
371                  * writing 1, and writing 0 has no effect.  So, the only relevant
372                  * information is the single bit we're interested in, all others should
373                  * be written as 0 so they will be left unchanged.
374                  */
375                 value = ACPI_REGISTER_PREPARE_BITS(value,
376                                                    bit_reg_info->bit_position,
377                                                    bit_reg_info->
378                                                    access_bit_mask);
379                 if (value) {
380                         status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
381                                                         ACPI_REGISTER_PM1_STATUS,
382                                                         (u16) value);
383                         register_value = 0;
384                 }
385                 break;
386
387         case ACPI_REGISTER_PM1_ENABLE:
388
389                 ACPI_REGISTER_INSERT_VALUE(register_value,
390                                            bit_reg_info->bit_position,
391                                            bit_reg_info->access_bit_mask,
392                                            value);
393
394                 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
395                                                 ACPI_REGISTER_PM1_ENABLE,
396                                                 (u16) register_value);
397                 break;
398
399         case ACPI_REGISTER_PM1_CONTROL:
400
401                 /*
402                  * Write the PM1 Control register.
403                  * Note that at this level, the fact that there are actually TWO
404                  * registers (A and B - and B may not exist) is abstracted.
405                  */
406                 ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
407                                   register_value));
408
409                 ACPI_REGISTER_INSERT_VALUE(register_value,
410                                            bit_reg_info->bit_position,
411                                            bit_reg_info->access_bit_mask,
412                                            value);
413
414                 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
415                                                 ACPI_REGISTER_PM1_CONTROL,
416                                                 (u16) register_value);
417                 break;
418
419         case ACPI_REGISTER_PM2_CONTROL:
420
421                 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
422                                                ACPI_REGISTER_PM2_CONTROL,
423                                                &register_value);
424                 if (ACPI_FAILURE(status)) {
425                         goto unlock_and_exit;
426                 }
427
428                 ACPI_DEBUG_PRINT((ACPI_DB_IO,
429                                   "PM2 control: Read %X from %8.8X%8.8X\n",
430                                   register_value,
431                                   ACPI_FORMAT_UINT64(acpi_gbl_FADT->
432                                                      xpm2_cnt_blk.address)));
433
434                 ACPI_REGISTER_INSERT_VALUE(register_value,
435                                            bit_reg_info->bit_position,
436                                            bit_reg_info->access_bit_mask,
437                                            value);
438
439                 ACPI_DEBUG_PRINT((ACPI_DB_IO,
440                                   "About to write %4.4X to %8.8X%8.8X\n",
441                                   register_value,
442                                   ACPI_FORMAT_UINT64(acpi_gbl_FADT->
443                                                      xpm2_cnt_blk.address)));
444
445                 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
446                                                 ACPI_REGISTER_PM2_CONTROL,
447                                                 (u8) (register_value));
448                 break;
449
450         default:
451                 break;
452         }
453
454       unlock_and_exit:
455
456         if (flags & ACPI_MTX_LOCK) {
457                 (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
458         }
459
460         /* Normalize the value that was read */
461
462         ACPI_DEBUG_EXEC(register_value =
463                         ((register_value & bit_reg_info->access_bit_mask) >>
464                          bit_reg_info->bit_position));
465
466         ACPI_DEBUG_PRINT((ACPI_DB_IO,
467                           "Set bits: %8.8X actual %8.8X register %X\n", value,
468                           register_value, bit_reg_info->parent_register));
469         return_ACPI_STATUS(status);
470 }
471
472 EXPORT_SYMBOL(acpi_set_register);
473
474 /******************************************************************************
475  *
476  * FUNCTION:    acpi_hw_register_read
477  *
478  * PARAMETERS:  use_lock            - Mutex hw access
479  *              register_id         - register_iD + Offset
480  *              return_value        - Where the register value is returned
481  *
482  * RETURN:      Status and the value read.
483  *
484  * DESCRIPTION: Acpi register read function.  Registers are read at the
485  *              given offset.
486  *
487  ******************************************************************************/
488
489 acpi_status
490 acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
491 {
492         u32 value1 = 0;
493         u32 value2 = 0;
494         acpi_status status;
495
496         ACPI_FUNCTION_TRACE("hw_register_read");
497
498         if (ACPI_MTX_LOCK == use_lock) {
499                 status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
500                 if (ACPI_FAILURE(status)) {
501                         return_ACPI_STATUS(status);
502                 }
503         }
504
505         switch (register_id) {
506         case ACPI_REGISTER_PM1_STATUS:  /* 16-bit access */
507
508                 status =
509                     acpi_hw_low_level_read(16, &value1,
510                                            &acpi_gbl_FADT->xpm1a_evt_blk);
511                 if (ACPI_FAILURE(status)) {
512                         goto unlock_and_exit;
513                 }
514
515                 /* PM1B is optional */
516
517                 status =
518                     acpi_hw_low_level_read(16, &value2,
519                                            &acpi_gbl_FADT->xpm1b_evt_blk);
520                 value1 |= value2;
521                 break;
522
523         case ACPI_REGISTER_PM1_ENABLE:  /* 16-bit access */
524
525                 status =
526                     acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
527                 if (ACPI_FAILURE(status)) {
528                         goto unlock_and_exit;
529                 }
530
531                 /* PM1B is optional */
532
533                 status =
534                     acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable);
535                 value1 |= value2;
536                 break;
537
538         case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
539
540                 status =
541                     acpi_hw_low_level_read(16, &value1,
542                                            &acpi_gbl_FADT->xpm1a_cnt_blk);
543                 if (ACPI_FAILURE(status)) {
544                         goto unlock_and_exit;
545                 }
546
547                 status =
548                     acpi_hw_low_level_read(16, &value2,
549                                            &acpi_gbl_FADT->xpm1b_cnt_blk);
550                 value1 |= value2;
551                 break;
552
553         case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
554
555                 status =
556                     acpi_hw_low_level_read(8, &value1,
557                                            &acpi_gbl_FADT->xpm2_cnt_blk);
558                 break;
559
560         case ACPI_REGISTER_PM_TIMER:    /* 32-bit access */
561
562                 status =
563                     acpi_hw_low_level_read(32, &value1,
564                                            &acpi_gbl_FADT->xpm_tmr_blk);
565                 break;
566
567         case ACPI_REGISTER_SMI_COMMAND_BLOCK:   /* 8-bit access */
568
569                 status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8);
570                 break;
571
572         default:
573                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown Register ID: %X\n",
574                                   register_id));
575                 status = AE_BAD_PARAMETER;
576                 break;
577         }
578
579       unlock_and_exit:
580         if (ACPI_MTX_LOCK == use_lock) {
581                 (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
582         }
583
584         if (ACPI_SUCCESS(status)) {
585                 *return_value = value1;
586         }
587
588         return_ACPI_STATUS(status);
589 }
590
591 /******************************************************************************
592  *
593  * FUNCTION:    acpi_hw_register_write
594  *
595  * PARAMETERS:  use_lock            - Mutex hw access
596  *              register_id         - register_iD + Offset
597  *              Value               - The value to write
598  *
599  * RETURN:      Status
600  *
601  * DESCRIPTION: Acpi register Write function.  Registers are written at the
602  *              given offset.
603  *
604  ******************************************************************************/
605
606 acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
607 {
608         acpi_status status;
609
610         ACPI_FUNCTION_TRACE("hw_register_write");
611
612         if (ACPI_MTX_LOCK == use_lock) {
613                 status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE);
614                 if (ACPI_FAILURE(status)) {
615                         return_ACPI_STATUS(status);
616                 }
617         }
618
619         switch (register_id) {
620         case ACPI_REGISTER_PM1_STATUS:  /* 16-bit access */
621
622                 status =
623                     acpi_hw_low_level_write(16, value,
624                                             &acpi_gbl_FADT->xpm1a_evt_blk);
625                 if (ACPI_FAILURE(status)) {
626                         goto unlock_and_exit;
627                 }
628
629                 /* PM1B is optional */
630
631                 status =
632                     acpi_hw_low_level_write(16, value,
633                                             &acpi_gbl_FADT->xpm1b_evt_blk);
634                 break;
635
636         case ACPI_REGISTER_PM1_ENABLE:  /* 16-bit access */
637
638                 status =
639                     acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
640                 if (ACPI_FAILURE(status)) {
641                         goto unlock_and_exit;
642                 }
643
644                 /* PM1B is optional */
645
646                 status =
647                     acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable);
648                 break;
649
650         case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
651
652                 status =
653                     acpi_hw_low_level_write(16, value,
654                                             &acpi_gbl_FADT->xpm1a_cnt_blk);
655                 if (ACPI_FAILURE(status)) {
656                         goto unlock_and_exit;
657                 }
658
659                 status =
660                     acpi_hw_low_level_write(16, value,
661                                             &acpi_gbl_FADT->xpm1b_cnt_blk);
662                 break;
663
664         case ACPI_REGISTER_PM1A_CONTROL:        /* 16-bit access */
665
666                 status =
667                     acpi_hw_low_level_write(16, value,
668                                             &acpi_gbl_FADT->xpm1a_cnt_blk);
669                 break;
670
671         case ACPI_REGISTER_PM1B_CONTROL:        /* 16-bit access */
672
673                 status =
674                     acpi_hw_low_level_write(16, value,
675                                             &acpi_gbl_FADT->xpm1b_cnt_blk);
676                 break;
677
678         case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
679
680                 status =
681                     acpi_hw_low_level_write(8, value,
682                                             &acpi_gbl_FADT->xpm2_cnt_blk);
683                 break;
684
685         case ACPI_REGISTER_PM_TIMER:    /* 32-bit access */
686
687                 status =
688                     acpi_hw_low_level_write(32, value,
689                                             &acpi_gbl_FADT->xpm_tmr_blk);
690                 break;
691
692         case ACPI_REGISTER_SMI_COMMAND_BLOCK:   /* 8-bit access */
693
694                 /* SMI_CMD is currently always in IO space */
695
696                 status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, value, 8);
697                 break;
698
699         default:
700                 status = AE_BAD_PARAMETER;
701                 break;
702         }
703
704       unlock_and_exit:
705         if (ACPI_MTX_LOCK == use_lock) {
706                 (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE);
707         }
708
709         return_ACPI_STATUS(status);
710 }
711
712 /******************************************************************************
713  *
714  * FUNCTION:    acpi_hw_low_level_read
715  *
716  * PARAMETERS:  Width               - 8, 16, or 32
717  *              Value               - Where the value is returned
718  *              Reg                 - GAS register structure
719  *
720  * RETURN:      Status
721  *
722  * DESCRIPTION: Read from either memory or IO space.
723  *
724  ******************************************************************************/
725
726 acpi_status
727 acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
728 {
729         u64 address;
730         acpi_status status;
731
732         ACPI_FUNCTION_NAME("hw_low_level_read");
733
734         /*
735          * Must have a valid pointer to a GAS structure, and
736          * a non-zero address within. However, don't return an error
737          * because the PM1A/B code must not fail if B isn't present.
738          */
739         if (!reg) {
740                 return (AE_OK);
741         }
742
743         /* Get a local copy of the address.  Handles possible alignment issues */
744
745         ACPI_MOVE_64_TO_64(&address, &reg->address);
746         if (!address) {
747                 return (AE_OK);
748         }
749         *value = 0;
750
751         /*
752          * Two address spaces supported: Memory or IO.
753          * PCI_Config is not supported here because the GAS struct is insufficient
754          */
755         switch (reg->address_space_id) {
756         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
757
758                 status = acpi_os_read_memory((acpi_physical_address) address,
759                                              value, width);
760                 break;
761
762         case ACPI_ADR_SPACE_SYSTEM_IO:
763
764                 status = acpi_os_read_port((acpi_io_address) address,
765                                            value, width);
766                 break;
767
768         default:
769                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
770                                   "Unsupported address space: %X\n",
771                                   reg->address_space_id));
772                 return (AE_BAD_PARAMETER);
773         }
774
775         ACPI_DEBUG_PRINT((ACPI_DB_IO,
776                           "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
777                           *value, width,
778                           ACPI_FORMAT_UINT64(address),
779                           acpi_ut_get_region_name(reg->address_space_id)));
780
781         return (status);
782 }
783
784 /******************************************************************************
785  *
786  * FUNCTION:    acpi_hw_low_level_write
787  *
788  * PARAMETERS:  Width               - 8, 16, or 32
789  *              Value               - To be written
790  *              Reg                 - GAS register structure
791  *
792  * RETURN:      Status
793  *
794  * DESCRIPTION: Write to either memory or IO space.
795  *
796  ******************************************************************************/
797
798 acpi_status
799 acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
800 {
801         u64 address;
802         acpi_status status;
803
804         ACPI_FUNCTION_NAME("hw_low_level_write");
805
806         /*
807          * Must have a valid pointer to a GAS structure, and
808          * a non-zero address within. However, don't return an error
809          * because the PM1A/B code must not fail if B isn't present.
810          */
811         if (!reg) {
812                 return (AE_OK);
813         }
814
815         /* Get a local copy of the address.  Handles possible alignment issues */
816
817         ACPI_MOVE_64_TO_64(&address, &reg->address);
818         if (!address) {
819                 return (AE_OK);
820         }
821
822         /*
823          * Two address spaces supported: Memory or IO.
824          * PCI_Config is not supported here because the GAS struct is insufficient
825          */
826         switch (reg->address_space_id) {
827         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
828
829                 status = acpi_os_write_memory((acpi_physical_address) address,
830                                               value, width);
831                 break;
832
833         case ACPI_ADR_SPACE_SYSTEM_IO:
834
835                 status = acpi_os_write_port((acpi_io_address) address,
836                                             value, width);
837                 break;
838
839         default:
840                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
841                                   "Unsupported address space: %X\n",
842                                   reg->address_space_id));
843                 return (AE_BAD_PARAMETER);
844         }
845
846         ACPI_DEBUG_PRINT((ACPI_DB_IO,
847                           "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
848                           value, width,
849                           ACPI_FORMAT_UINT64(address),
850                           acpi_ut_get_region_name(reg->address_space_id)));
851
852         return (status);
853 }