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