File: /usr/src/linux/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      *              $Revision: 109 $
7      *
8      ******************************************************************************/
9     
10     /*
11      *  Copyright (C) 2000, 2001 R. Byron Moore
12      *
13      *  This program is free software; you can redistribute it and/or modify
14      *  it under the terms of the GNU General Public License as published by
15      *  the Free Software Foundation; either version 2 of the License, or
16      *  (at your option) any later version.
17      *
18      *  This program is distributed in the hope that it will be useful,
19      *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20      *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21      *  GNU General Public License for more details.
22      *
23      *  You should have received a copy of the GNU General Public License
24      *  along with this program; if not, write to the Free Software
25      *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26      */
27     
28     
29     #include "acpi.h"
30     #include "achware.h"
31     #include "acnamesp.h"
32     
33     #define _COMPONENT          ACPI_HARDWARE
34     	 MODULE_NAME         ("hwregs")
35     
36     
37     /*******************************************************************************
38      *
39      * FUNCTION:    Acpi_hw_get_bit_shift
40      *
41      * PARAMETERS:  Mask            - Input mask to determine bit shift from.
42      *                                Must have at least 1 bit set.
43      *
44      * RETURN:      Bit location of the lsb of the mask
45      *
46      * DESCRIPTION: Returns the bit number for the low order bit that's set.
47      *
48      ******************************************************************************/
49     
50     u32
51     acpi_hw_get_bit_shift (
52     	u32                     mask)
53     {
54     	u32                     shift;
55     
56     
57     	FUNCTION_TRACE ("Hw_get_bit_shift");
58     
59     
60     	for (shift = 0; ((mask >> shift) & 1) == 0; shift++) { ; }
61     
62     	return_VALUE (shift);
63     }
64     
65     
66     /*******************************************************************************
67      *
68      * FUNCTION:    Acpi_hw_clear_acpi_status
69      *
70      * PARAMETERS:  none
71      *
72      * RETURN:      none
73      *
74      * DESCRIPTION: Clears all fixed and general purpose status bits
75      *
76      ******************************************************************************/
77     
78     void
79     acpi_hw_clear_acpi_status (void)
80     {
81     	u16                     gpe_length;
82     	u16                     index;
83     
84     
85     	FUNCTION_TRACE ("Hw_clear_acpi_status");
86     
87     
88     	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
89     		ALL_FIXED_STS_BITS,
90     		(u16) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm1a_evt_blk.address)));
91     
92     
93     	acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
94     
95     	acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS);
96     
97     
98     	if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address)) {
99     		acpi_os_write_port ((ACPI_IO_ADDRESS)
100     			ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address),
101     			ALL_FIXED_STS_BITS, 16);
102     	}
103     
104     	/* now clear the GPE Bits */
105     
106     	if (acpi_gbl_FADT->gpe0blk_len) {
107     		gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len);
108     
109     		for (index = 0; index < gpe_length; index++) {
110     			acpi_os_write_port ((ACPI_IO_ADDRESS) (
111     				ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + index),
112     					0xFF, 8);
113     		}
114     	}
115     
116     	if (acpi_gbl_FADT->gpe1_blk_len) {
117     		gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len);
118     
119     		for (index = 0; index < gpe_length; index++) {
120     			acpi_os_write_port ((ACPI_IO_ADDRESS) (
121     				ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + index),
122     				0xFF, 8);
123     		}
124     	}
125     
126     	acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
127     	return_VOID;
128     }
129     
130     
131     /*******************************************************************************
132      *
133      * FUNCTION:    Acpi_hw_obtain_sleep_type_register_data
134      *
135      * PARAMETERS:  Sleep_state       - Numeric state requested
136      *              *Slp_Typ_a         - Pointer to byte to receive SLP_TYPa value
137      *              *Slp_Typ_b         - Pointer to byte to receive SLP_TYPb value
138      *
139      * RETURN:      Status - ACPI status
140      *
141      * DESCRIPTION: Acpi_hw_obtain_sleep_type_register_data() obtains the SLP_TYP and
142      *              SLP_TYPb values for the sleep state requested.
143      *
144      ******************************************************************************/
145     
146     acpi_status
147     acpi_hw_obtain_sleep_type_register_data (
148     	u8                      sleep_state,
149     	u8                      *slp_typ_a,
150     	u8                      *slp_typ_b)
151     {
152     	acpi_status             status = AE_OK;
153     	acpi_operand_object     *obj_desc;
154     
155     
156     	FUNCTION_TRACE ("Hw_obtain_sleep_type_register_data");
157     
158     
159     	/*
160     	 *  Validate parameters
161     	 */
162     	if ((sleep_state > ACPI_S_STATES_MAX) ||
163     		!slp_typ_a || !slp_typ_b) {
164     		return_ACPI_STATUS (AE_BAD_PARAMETER);
165     	}
166     
167     	/*
168     	 *  Acpi_evaluate the namespace object containing the values for this state
169     	 */
170     	status = acpi_ns_evaluate_by_name ((NATIVE_CHAR *) acpi_gbl_db_sleep_states[sleep_state],
171     			  NULL, &obj_desc);
172     	if (ACPI_FAILURE (status)) {
173     		return_ACPI_STATUS (status);
174     	}
175     
176     	if (!obj_desc) {
177     		REPORT_ERROR (("Missing Sleep State object\n"));
178     		return_ACPI_STATUS (AE_NOT_EXIST);
179     	}
180     
181     	/*
182     	 *  We got something, now ensure it is correct.  The object must
183     	 *  be a package and must have at least 2 numeric values as the
184     	 *  two elements
185     	 */
186     
187     	/* Even though Acpi_evaluate_object resolves package references,
188     	 * Ns_evaluate dpesn't. So, we do it here.
189     	 */
190     	status = acpi_ut_resolve_package_references(obj_desc);
191     
192     	if (obj_desc->package.count < 2) {
193     		/* Must have at least two elements */
194     
195     		REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
196     		status = AE_ERROR;
197     	}
198     
199     	else if (((obj_desc->package.elements[0])->common.type !=
200     			 ACPI_TYPE_INTEGER) ||
201     			 ((obj_desc->package.elements[1])->common.type !=
202     				ACPI_TYPE_INTEGER)) {
203     		/* Must have two  */
204     
205     		REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
206     		status = AE_ERROR;
207     	}
208     
209     	else {
210     		/*
211     		 *  Valid _Sx_ package size, type, and value
212     		 */
213     		*slp_typ_a = (u8) (obj_desc->package.elements[0])->integer.value;
214     
215     		*slp_typ_b = (u8) (obj_desc->package.elements[1])->integer.value;
216     	}
217     
218     
219     	if (ACPI_FAILURE (status)) {
220     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %X\n",
221     			obj_desc, obj_desc->common.type));
222     	}
223     
224     	acpi_ut_remove_reference (obj_desc);
225     
226     	return_ACPI_STATUS (status);
227     }
228     
229     
230     /*******************************************************************************
231      *
232      * FUNCTION:    Acpi_hw_register_bit_access
233      *
234      * PARAMETERS:  Read_write      - Either ACPI_READ or ACPI_WRITE.
235      *              Use_lock        - Lock the hardware
236      *              Register_id     - index of ACPI Register to access
237      *              Value           - (only used on write) value to write to the
238      *                                Register.  Shifted all the way right.
239      *
240      * RETURN:      Value written to or read from specified Register.  This value
241      *              is shifted all the way right.
242      *
243      * DESCRIPTION: Generic ACPI Register read/write function.
244      *
245      ******************************************************************************/
246     
247     u32
248     acpi_hw_register_bit_access (
249     	NATIVE_UINT             read_write,
250     	u8                      use_lock,
251     	u32                     register_id,
252     	...)                    /* Value (only used on write) */
253     {
254     	u32                     register_value = 0;
255     	u32                     mask = 0;
256     	u32                     value = 0;
257     	va_list                 marker;
258     
259     
260     	FUNCTION_TRACE ("Hw_register_bit_access");
261     
262     
263     	if (read_write == ACPI_WRITE) {
264     		va_start (marker, register_id);
265     		value = va_arg (marker, u32);
266     		va_end (marker);
267     	}
268     
269     	if (ACPI_MTX_LOCK == use_lock) {
270     		acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
271     	}
272     
273     	/*
274     	 * Decode the Register ID
275     	 * Register id = Register block id | bit id
276     	 *
277     	 * Check bit id to fine locate Register offset.
278     	 * Check Mask to determine Register offset, and then read-write.
279     	 */
280     	switch (REGISTER_BLOCK_ID (register_id)) {
281     	case PM1_STS:
282     
283     		switch (register_id) {
284     		case TMR_STS:
285     			mask = TMR_STS_MASK;
286     			break;
287     
288     		case BM_STS:
289     			mask = BM_STS_MASK;
290     			break;
291     
292     		case GBL_STS:
293     			mask = GBL_STS_MASK;
294     			break;
295     
296     		case PWRBTN_STS:
297     			mask = PWRBTN_STS_MASK;
298     			break;
299     
300     		case SLPBTN_STS:
301     			mask = SLPBTN_STS_MASK;
302     			break;
303     
304     		case RTC_STS:
305     			mask = RTC_STS_MASK;
306     			break;
307     
308     		case WAK_STS:
309     			mask = WAK_STS_MASK;
310     			break;
311     
312     		default:
313     			mask = 0;
314     			break;
315     		}
316     
317     		register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS);
318     
319     		if (read_write == ACPI_WRITE) {
320     			/*
321     			 * Status Registers are different from the rest.  Clear by
322     			 * writing 1, writing 0 has no effect.  So, the only relevent
323     			 * information is the single bit we're interested in, all
324     			 * others should be written as 0 so they will be left
325     			 * unchanged
326     			 */
327     			value <<= acpi_hw_get_bit_shift (mask);
328     			value &= mask;
329     
330     			if (value) {
331     				acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS,
332     					(u16) value);
333     				register_value = 0;
334     			}
335     		}
336     
337     		break;
338     
339     
340     	case PM1_EN:
341     
342     		switch (register_id) {
343     		case TMR_EN:
344     			mask = TMR_EN_MASK;
345     			break;
346     
347     		case GBL_EN:
348     			mask = GBL_EN_MASK;
349     			break;
350     
351     		case PWRBTN_EN:
352     			mask = PWRBTN_EN_MASK;
353     			break;
354     
355     		case SLPBTN_EN:
356     			mask = SLPBTN_EN_MASK;
357     			break;
358     
359     		case RTC_EN:
360     			mask = RTC_EN_MASK;
361     			break;
362     
363     		default:
364     			mask = 0;
365     			break;
366     		}
367     
368     		register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN);
369     
370     		if (read_write == ACPI_WRITE) {
371     			register_value &= ~mask;
372     			value          <<= acpi_hw_get_bit_shift (mask);
373     			value          &= mask;
374     			register_value |= value;
375     
376     			acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (u16) register_value);
377     		}
378     
379     		break;
380     
381     
382     	case PM1_CONTROL:
383     
384     		switch (register_id) {
385     		case SCI_EN:
386     			mask = SCI_EN_MASK;
387     			break;
388     
389     		case BM_RLD:
390     			mask = BM_RLD_MASK;
391     			break;
392     
393     		case GBL_RLS:
394     			mask = GBL_RLS_MASK;
395     			break;
396     
397     		case SLP_TYPE_A:
398     		case SLP_TYPE_B:
399     			mask = SLP_TYPE_X_MASK;
400     			break;
401     
402     		case SLP_EN:
403     			mask = SLP_EN_MASK;
404     			break;
405     
406     		default:
407     			mask = 0;
408     			break;
409     		}
410     
411     
412     		/*
413     		 * Read the PM1 Control register.
414     		 * Note that at this level, the fact that there are actually TWO
415     		 * registers (A and B) and that B may not exist, are abstracted.
416     		 */
417     		register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL);
418     
419     		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", register_value));
420     
421     		if (read_write == ACPI_WRITE) {
422     			register_value &= ~mask;
423     			value          <<= acpi_hw_get_bit_shift (mask);
424     			value          &= mask;
425     			register_value |= value;
426     
427     			/*
428     			 * SLP_TYPE_x Registers are written differently
429     			 * than any other control Registers with
430     			 * respect to A and B Registers.  The value
431     			 * for A may be different than the value for B
432     			 *
433     			 * Therefore, pass the Register_id, not just generic PM1_CONTROL,
434     			 * because we need to do different things. Yuck.
435     			 */
436     			acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id,
437     					(u16) register_value);
438     		}
439     		break;
440     
441     
442     	case PM2_CONTROL:
443     
444     		switch (register_id) {
445     		case ARB_DIS:
446     			mask = ARB_DIS_MASK;
447     			break;
448     
449     		default:
450     			mask = 0;
451     			break;
452     		}
453     
454     		register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
455     
456     		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %p\n",
457     			register_value, ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm2_cnt_blk.address)));
458     
459     		if (read_write == ACPI_WRITE) {
460     			register_value &= ~mask;
461     			value          <<= acpi_hw_get_bit_shift (mask);
462     			value          &= mask;
463     			register_value |= value;
464     
465     			ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %p\n", register_value,
466     				acpi_gbl_FADT->Xpm2_cnt_blk.address));
467     
468     			acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
469     					   PM2_CONTROL, (u8) (register_value));
470     		}
471     		break;
472     
473     
474     	case PM_TIMER:
475     
476     		mask = TMR_VAL_MASK;
477     		register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
478     				 PM_TIMER);
479     		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM_TIMER: Read %X from %p\n",
480     			register_value, ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address)));
481     
482     		break;
483     
484     
485     	case GPE1_EN_BLOCK:
486     	case GPE1_STS_BLOCK:
487     	case GPE0_EN_BLOCK:
488     	case GPE0_STS_BLOCK:
489     
490     		/* Determine the bit to be accessed
491     		 *
492     		 *  (u32) Register_id:
493     		 *      31      24       16       8        0
494     		 *      +--------+--------+--------+--------+
495     		 *      |  gpe_block_id   |  gpe_bit_number |
496     		 *      +--------+--------+--------+--------+
497     		 *
498     		 *     gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
499     		 *     gpe_bit_number is relative from the gpe_block (0x00~0xFF)
500     		 */
501     		mask = REGISTER_BIT_ID(register_id); /* gpe_bit_number */
502     		register_id = REGISTER_BLOCK_ID(register_id) | (mask >> 3);
503     		mask = acpi_gbl_decode_to8bit [mask % 8];
504     
505     		/*
506     		 * The base address of the GPE 0 Register Block
507     		 * Plus 1/2 the length of the GPE 0 Register Block
508     		 * The enable Register is the Register following the Status Register
509     		 * and each Register is defined as 1/2 of the total Register Block
510     		 */
511     
512     		/*
513     		 * This sets the bit within Enable_bit that needs to be written to
514     		 * the Register indicated in Mask to a 1, all others are 0
515     		 */
516     
517     		/* Now get the current Enable Bits in the selected Reg */
518     
519     		register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id);
520     		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "GPE Enable bits: Read %X from %X\n",
521     			register_value, register_id));
522     
523     		if (read_write == ACPI_WRITE) {
524     			register_value &= ~mask;
525     			value          <<= acpi_hw_get_bit_shift (mask);
526     			value          &= mask;
527     			register_value |= value;
528     
529     			/*
530     			 * This write will put the Action state into the General Purpose
531     			 * Enable Register indexed by the value in Mask
532     			 */
533     			ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
534     				register_value, register_id));
535     			acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id,
536     				(u8) register_value);
537     			register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
538     					   register_id);
539     		}
540     		break;
541     
542     
543     	case SMI_CMD_BLOCK:
544     	case PROCESSOR_BLOCK:
545     
546     		/* Not used by any callers at this time - therefore, not implemented */
547     
548     	default:
549     
550     		mask = 0;
551     		break;
552     	}
553     
554     	if (ACPI_MTX_LOCK == use_lock) {
555     		acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
556     	}
557     
558     
559     	register_value &= mask;
560     	register_value >>= acpi_hw_get_bit_shift (mask);
561     
562     	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Register I/O: returning %X\n", register_value));
563     	return_VALUE (register_value);
564     }
565     
566     
567     /******************************************************************************
568      *
569      * FUNCTION:    Acpi_hw_register_read
570      *
571      * PARAMETERS:  Use_lock               - Mutex hw access.
572      *              Register_id            - Register_iD + Offset.
573      *
574      * RETURN:      Value read or written.
575      *
576      * DESCRIPTION: Acpi register read function.  Registers are read at the
577      *              given offset.
578      *
579      ******************************************************************************/
580     
581     u32
582     acpi_hw_register_read (
583     	u8                      use_lock,
584     	u32                     register_id)
585     {
586     	u32                     value = 0;
587     	u32                     bank_offset;
588     
589     
590     	FUNCTION_TRACE ("Hw_register_read");
591     
592     
593     	if (ACPI_MTX_LOCK == use_lock) {
594     		acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
595     	}
596     
597     
598     	switch (REGISTER_BLOCK_ID(register_id)) {
599     	case PM1_STS: /* 16-bit access */
600     
601     		value =  acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, 0);
602     		value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, 0);
603     		break;
604     
605     
606     	case PM1_EN: /* 16-bit access*/
607     
608     		bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len);
609     		value =  acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset);
610     		value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset);
611     		break;
612     
613     
614     	case PM1_CONTROL: /* 16-bit access */
615     
616     		value =  acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
617     		value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
618     		break;
619     
620     
621     	case PM2_CONTROL: /* 8-bit access */
622     
623     		value =  acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xpm2_cnt_blk, 0);
624     		break;
625     
626     
627     	case PM_TIMER: /* 32-bit access */
628     
629     		value =  acpi_hw_low_level_read (32, &acpi_gbl_FADT->Xpm_tmr_blk, 0);
630     		break;
631     
632     
633     	/*
634     	 * For the GPE? Blocks, the lower word of Register_id contains the
635     	 * byte offset for which to read, as each part of each block may be
636     	 * several bytes long.
637     	 */
638     	case GPE0_STS_BLOCK: /* 8-bit access */
639     
640     		bank_offset = REGISTER_BIT_ID(register_id);
641     		value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset);
642     		break;
643     
644     	case GPE0_EN_BLOCK: /* 8-bit access */
645     
646     		bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len) + REGISTER_BIT_ID(register_id);
647     		value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset);
648     		break;
649     
650     	case GPE1_STS_BLOCK: /* 8-bit access */
651     
652     		bank_offset = REGISTER_BIT_ID(register_id);
653     		value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset);
654     		break;
655     
656     	case GPE1_EN_BLOCK: /* 8-bit access */
657     
658     		bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len) + REGISTER_BIT_ID(register_id);
659     		value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset);
660     		break;
661     
662     	case SMI_CMD_BLOCK: /* 8bit */
663     
664     		acpi_os_read_port (acpi_gbl_FADT->smi_cmd, &value, 8);
665     		break;
666     
667     	default:
668     		/* Value will be returned as 0 */
669     		break;
670     	}
671     
672     
673     	if (ACPI_MTX_LOCK == use_lock) {
674     		acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
675     	}
676     
677     	return_VALUE (value);
678     }
679     
680     
681     /******************************************************************************
682      *
683      * FUNCTION:    Acpi_hw_register_write
684      *
685      * PARAMETERS:  Use_lock               - Mutex hw access.
686      *              Register_id            - Register_iD + Offset.
687      *
688      * RETURN:      Value read or written.
689      *
690      * DESCRIPTION: Acpi register Write function.  Registers are written at the
691      *              given offset.
692      *
693      ******************************************************************************/
694     
695     void
696     acpi_hw_register_write (
697     	u8                      use_lock,
698     	u32                     register_id,
699     	u32                     value)
700     {
701     	u32                     bank_offset;
702     
703     
704     	FUNCTION_TRACE ("Hw_register_write");
705     
706     
707     	if (ACPI_MTX_LOCK == use_lock) {
708     		acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
709     	}
710     
711     
712     	switch (REGISTER_BLOCK_ID (register_id)) {
713     	case PM1_STS: /* 16-bit access */
714     
715     		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, 0);
716     		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, 0);
717     		break;
718     
719     
720     	case PM1_EN: /* 16-bit access*/
721     
722     		bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len);
723     		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset);
724     		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset);
725     		break;
726     
727     
728     	case PM1_CONTROL: /* 16-bit access */
729     
730     		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
731     		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
732     		break;
733     
734     
735     	case PM1_a_CONTROL: /* 16-bit access */
736     
737     		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
738     		break;
739     
740     
741     	case PM1_b_CONTROL: /* 16-bit access */
742     
743     		acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
744     		break;
745     
746     
747     	case PM2_CONTROL: /* 8-bit access */
748     
749     		acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xpm2_cnt_blk, 0);
750     		break;
751     
752     
753     	case PM_TIMER: /* 32-bit access */
754     
755     		acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->Xpm_tmr_blk, 0);
756     		break;
757     
758     
759     	case GPE0_STS_BLOCK: /* 8-bit access */
760     
761     		bank_offset = REGISTER_BIT_ID(register_id);
762     		acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset);
763     		break;
764     
765     
766     	case GPE0_EN_BLOCK: /* 8-bit access */
767     
768     		bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len) + REGISTER_BIT_ID(register_id);
769     		acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset);
770     		break;
771     
772     
773     	case GPE1_STS_BLOCK: /* 8-bit access */
774     
775     		bank_offset = REGISTER_BIT_ID(register_id);
776     		acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset);
777     		break;
778     
779     
780     	case GPE1_EN_BLOCK: /* 8-bit access */
781     
782     		bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len) + REGISTER_BIT_ID(register_id);
783     		acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset);
784     		break;
785     
786     
787     	case SMI_CMD_BLOCK: /* 8bit */
788     
789     		/* For 2.0, SMI_CMD is always in IO space */
790     		/* TBD: what about 1.0? 0.71? */
791     
792     		acpi_os_write_port (acpi_gbl_FADT->smi_cmd, value, 8);
793     		break;
794     
795     
796     	default:
797     		value = 0;
798     		break;
799     	}
800     
801     
802     	if (ACPI_MTX_LOCK == use_lock) {
803     		acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
804     	}
805     
806     	return_VOID;
807     }
808     
809     
810     /******************************************************************************
811      *
812      * FUNCTION:    Acpi_hw_low_level_read
813      *
814      * PARAMETERS:  Register            - GAS register structure
815      *              Offset              - Offset from the base address in the GAS
816      *              Width               - 8, 16, or 32
817      *
818      * RETURN:      Value read
819      *
820      * DESCRIPTION: Read from either memory, IO, or PCI config space.
821      *
822      ******************************************************************************/
823     
824     u32
825     acpi_hw_low_level_read (
826     	u32                     width,
827     	acpi_generic_address    *reg,
828     	u32                     offset)
829     {
830     	u32                     value = 0;
831     	ACPI_PHYSICAL_ADDRESS   mem_address;
832     	ACPI_IO_ADDRESS         io_address;
833     	acpi_pci_id             pci_id;
834     	u16                     pci_register;
835     
836     
837     	FUNCTION_ENTRY ();
838     
839     
840     	/*
841     	 * Must have a valid pointer to a GAS structure, and
842     	 * a non-zero address within
843     	 */
844     	if ((!reg) ||
845     		(!ACPI_VALID_ADDRESS (reg->address))) {
846     		return 0;
847     	}
848     
849     
850     	/*
851     	 * Three address spaces supported:
852     	 * Memory, Io, or PCI config.
853     	 */
854     	switch (reg->address_space_id) {
855     	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
856     
857     		mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
858     
859     		acpi_os_read_memory (mem_address, &value, width);
860     		break;
861     
862     
863     	case ACPI_ADR_SPACE_SYSTEM_IO:
864     
865     		io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
866     
867     		acpi_os_read_port (io_address, &value, width);
868     		break;
869     
870     
871     	case ACPI_ADR_SPACE_PCI_CONFIG:
872     
873     		pci_id.segment = 0;
874     		pci_id.bus     = 0;
875     		pci_id.device  = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (reg->address));
876     		pci_id.function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (reg->address));
877     		pci_register   = (u16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset);
878     
879     		acpi_os_read_pci_configuration (&pci_id, pci_register, &value, width);
880     		break;
881     	}
882     
883     	return value;
884     }
885     
886     
887     /******************************************************************************
888      *
889      * FUNCTION:    Acpi_hw_low_level_write
890      *
891      * PARAMETERS:  Width               - 8, 16, or 32
892      *              Value               - To be written
893      *              Register            - GAS register structure
894      *              Offset              - Offset from the base address in the GAS
895      *
896      *
897      * RETURN:      Value read
898      *
899      * DESCRIPTION: Read from either memory, IO, or PCI config space.
900      *
901      ******************************************************************************/
902     
903     void
904     acpi_hw_low_level_write (
905     	u32                     width,
906     	u32                     value,
907     	acpi_generic_address    *reg,
908     	u32                     offset)
909     {
910     	ACPI_PHYSICAL_ADDRESS   mem_address;
911     	ACPI_IO_ADDRESS         io_address;
912     	acpi_pci_id             pci_id;
913     	u16                     pci_register;
914     
915     
916     	FUNCTION_ENTRY ();
917     
918     
919     	/*
920     	 * Must have a valid pointer to a GAS structure, and
921     	 * a non-zero address within
922     	 */
923     	if ((!reg) ||
924     		(!ACPI_VALID_ADDRESS (reg->address))) {
925     		return;
926     	}
927     
928     
929     	/*
930     	 * Three address spaces supported:
931     	 * Memory, Io, or PCI config.
932     	 */
933     	switch (reg->address_space_id) {
934     	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
935     
936     		mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
937     
938     		acpi_os_write_memory (mem_address, value, width);
939     		break;
940     
941     
942     	case ACPI_ADR_SPACE_SYSTEM_IO:
943     
944     		io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
945     
946     		acpi_os_write_port (io_address, value, width);
947     		break;
948     
949     
950     	case ACPI_ADR_SPACE_PCI_CONFIG:
951     
952     		pci_id.segment = 0;
953     		pci_id.bus     = 0;
954     		pci_id.device  = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (reg->address));
955     		pci_id.function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (reg->address));
956     		pci_register   = (u16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset);
957     
958     		acpi_os_write_pci_configuration (&pci_id, pci_register, value, width);
959     		break;
960     	}
961     }
962