aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/hwregs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/hwregs.c')
-rw-r--r--drivers/acpi/acpica/hwregs.c206
1 files changed, 194 insertions, 12 deletions
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 23d5505cb1f7..15c9ed2be853 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -62,6 +62,184 @@ acpi_hw_write_multiple(u32 value,
62 struct acpi_generic_address *register_a, 62 struct acpi_generic_address *register_a,
63 struct acpi_generic_address *register_b); 63 struct acpi_generic_address *register_b);
64 64
65/******************************************************************************
66 *
67 * FUNCTION: acpi_hw_validate_register
68 *
69 * PARAMETERS: Reg - GAS register structure
70 * max_bit_width - Max bit_width supported (32 or 64)
71 * Address - Pointer to where the gas->address
72 * is returned
73 *
74 * RETURN: Status
75 *
76 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
77 * pointer, Address, space_id, bit_width, and bit_offset.
78 *
79 ******************************************************************************/
80
81acpi_status
82acpi_hw_validate_register(struct acpi_generic_address *reg,
83 u8 max_bit_width, u64 *address)
84{
85
86 /* Must have a valid pointer to a GAS structure */
87
88 if (!reg) {
89 return (AE_BAD_PARAMETER);
90 }
91
92 /*
93 * Copy the target address. This handles possible alignment issues.
94 * Address must not be null. A null address also indicates an optional
95 * ACPI register that is not supported, so no error message.
96 */
97 ACPI_MOVE_64_TO_64(address, &reg->address);
98 if (!(*address)) {
99 return (AE_BAD_ADDRESS);
100 }
101
102 /* Validate the space_iD */
103
104 if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
105 (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
106 ACPI_ERROR((AE_INFO,
107 "Unsupported address space: 0x%X", reg->space_id));
108 return (AE_SUPPORT);
109 }
110
111 /* Validate the bit_width */
112
113 if ((reg->bit_width != 8) &&
114 (reg->bit_width != 16) &&
115 (reg->bit_width != 32) && (reg->bit_width != max_bit_width)) {
116 ACPI_ERROR((AE_INFO,
117 "Unsupported register bit width: 0x%X",
118 reg->bit_width));
119 return (AE_SUPPORT);
120 }
121
122 /* Validate the bit_offset. Just a warning for now. */
123
124 if (reg->bit_offset != 0) {
125 ACPI_WARNING((AE_INFO,
126 "Unsupported register bit offset: 0x%X",
127 reg->bit_offset));
128 }
129
130 return (AE_OK);
131}
132
133/******************************************************************************
134 *
135 * FUNCTION: acpi_hw_read
136 *
137 * PARAMETERS: Value - Where the value is returned
138 * Reg - GAS register structure
139 *
140 * RETURN: Status
141 *
142 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
143 * version of acpi_read, used internally since the overhead of
144 * 64-bit values is not needed.
145 *
146 * LIMITATIONS: <These limitations also apply to acpi_hw_write>
147 * bit_width must be exactly 8, 16, or 32.
148 * space_iD must be system_memory or system_iO.
149 * bit_offset and access_width are currently ignored, as there has
150 * not been a need to implement these.
151 *
152 ******************************************************************************/
153
154acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
155{
156 u64 address;
157 acpi_status status;
158
159 ACPI_FUNCTION_NAME(hw_read);
160
161 /* Validate contents of the GAS register */
162
163 status = acpi_hw_validate_register(reg, 32, &address);
164 if (ACPI_FAILURE(status)) {
165 return (status);
166 }
167
168 /* Initialize entire 32-bit return value to zero */
169
170 *value = 0;
171
172 /*
173 * Two address spaces supported: Memory or IO. PCI_Config is
174 * not supported here because the GAS structure is insufficient
175 */
176 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
177 status = acpi_os_read_memory((acpi_physical_address)
178 address, value, reg->bit_width);
179 } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
180
181 status = acpi_hw_read_port((acpi_io_address)
182 address, value, reg->bit_width);
183 }
184
185 ACPI_DEBUG_PRINT((ACPI_DB_IO,
186 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
187 *value, reg->bit_width, ACPI_FORMAT_UINT64(address),
188 acpi_ut_get_region_name(reg->space_id)));
189
190 return (status);
191}
192
193/******************************************************************************
194 *
195 * FUNCTION: acpi_hw_write
196 *
197 * PARAMETERS: Value - Value to be written
198 * Reg - GAS register structure
199 *
200 * RETURN: Status
201 *
202 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
203 * version of acpi_write, used internally since the overhead of
204 * 64-bit values is not needed.
205 *
206 ******************************************************************************/
207
208acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
209{
210 u64 address;
211 acpi_status status;
212
213 ACPI_FUNCTION_NAME(hw_write);
214
215 /* Validate contents of the GAS register */
216
217 status = acpi_hw_validate_register(reg, 32, &address);
218 if (ACPI_FAILURE(status)) {
219 return (status);
220 }
221
222 /*
223 * Two address spaces supported: Memory or IO. PCI_Config is
224 * not supported here because the GAS structure is insufficient
225 */
226 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
227 status = acpi_os_write_memory((acpi_physical_address)
228 address, value, reg->bit_width);
229 } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
230
231 status = acpi_hw_write_port((acpi_io_address)
232 address, value, reg->bit_width);
233 }
234
235 ACPI_DEBUG_PRINT((ACPI_DB_IO,
236 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
237 value, reg->bit_width, ACPI_FORMAT_UINT64(address),
238 acpi_ut_get_region_name(reg->space_id)));
239
240 return (status);
241}
242
65/******************************************************************************* 243/*******************************************************************************
66 * 244 *
67 * FUNCTION: acpi_hw_clear_acpi_status 245 * FUNCTION: acpi_hw_clear_acpi_status
@@ -152,15 +330,16 @@ acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
152 330
153 ACPI_FUNCTION_TRACE(hw_write_pm1_control); 331 ACPI_FUNCTION_TRACE(hw_write_pm1_control);
154 332
155 status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); 333 status =
334 acpi_hw_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
156 if (ACPI_FAILURE(status)) { 335 if (ACPI_FAILURE(status)) {
157 return_ACPI_STATUS(status); 336 return_ACPI_STATUS(status);
158 } 337 }
159 338
160 if (acpi_gbl_FADT.xpm1b_control_block.address) { 339 if (acpi_gbl_FADT.xpm1b_control_block.address) {
161 status = 340 status =
162 acpi_write(pm1b_control, 341 acpi_hw_write(pm1b_control,
163 &acpi_gbl_FADT.xpm1b_control_block); 342 &acpi_gbl_FADT.xpm1b_control_block);
164 } 343 }
165 return_ACPI_STATUS(status); 344 return_ACPI_STATUS(status);
166} 345}
@@ -218,12 +397,13 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
218 397
219 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 398 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
220 399
221 status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block); 400 status =
401 acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block);
222 break; 402 break;
223 403
224 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 404 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
225 405
226 status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block); 406 status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block);
227 break; 407 break;
228 408
229 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 409 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
@@ -340,7 +520,8 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
340 * as per the ACPI spec. 520 * as per the ACPI spec.
341 */ 521 */
342 status = 522 status =
343 acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block); 523 acpi_hw_read(&read_value,
524 &acpi_gbl_FADT.xpm2_control_block);
344 if (ACPI_FAILURE(status)) { 525 if (ACPI_FAILURE(status)) {
345 goto exit; 526 goto exit;
346 } 527 }
@@ -350,12 +531,13 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
350 ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, 531 ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
351 read_value); 532 read_value);
352 533
353 status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block); 534 status =
535 acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block);
354 break; 536 break;
355 537
356 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 538 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
357 539
358 status = acpi_write(value, &acpi_gbl_FADT.xpm_timer_block); 540 status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block);
359 break; 541 break;
360 542
361 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 543 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
@@ -401,7 +583,7 @@ acpi_hw_read_multiple(u32 *value,
401 583
402 /* The first register is always required */ 584 /* The first register is always required */
403 585
404 status = acpi_read(&value_a, register_a); 586 status = acpi_hw_read(&value_a, register_a);
405 if (ACPI_FAILURE(status)) { 587 if (ACPI_FAILURE(status)) {
406 return (status); 588 return (status);
407 } 589 }
@@ -409,7 +591,7 @@ acpi_hw_read_multiple(u32 *value,
409 /* Second register is optional */ 591 /* Second register is optional */
410 592
411 if (register_b->address) { 593 if (register_b->address) {
412 status = acpi_read(&value_b, register_b); 594 status = acpi_hw_read(&value_b, register_b);
413 if (ACPI_FAILURE(status)) { 595 if (ACPI_FAILURE(status)) {
414 return (status); 596 return (status);
415 } 597 }
@@ -452,7 +634,7 @@ acpi_hw_write_multiple(u32 value,
452 634
453 /* The first register is always required */ 635 /* The first register is always required */
454 636
455 status = acpi_write(value, register_a); 637 status = acpi_hw_write(value, register_a);
456 if (ACPI_FAILURE(status)) { 638 if (ACPI_FAILURE(status)) {
457 return (status); 639 return (status);
458 } 640 }
@@ -470,7 +652,7 @@ acpi_hw_write_multiple(u32 value,
470 * and writes have no side effects" 652 * and writes have no side effects"
471 */ 653 */
472 if (register_b->address) { 654 if (register_b->address) {
473 status = acpi_write(value, register_b); 655 status = acpi_hw_write(value, register_b);
474 } 656 }
475 657
476 return (status); 658 return (status);