Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 - 2007, 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 <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 }
858 
  This page was automatically generated by the LXR engine.