Commit 00a2b433 authored by Len Brown's avatar Len Brown

Pull acpica into test branch

parents de85871a 2d571b33
...@@ -239,10 +239,8 @@ u32 acpi_ev_fixed_event_detect(void) ...@@ -239,10 +239,8 @@ u32 acpi_ev_fixed_event_detect(void)
* Read the fixed feature status and enable registers, as all the cases * Read the fixed feature status and enable registers, as all the cases
* depend on their values. Ignore errors here. * depend on their values. Ignore errors here.
*/ */
(void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
ACPI_REGISTER_PM1_STATUS, &fixed_status); (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
(void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
"Fixed Event Block: Enable %08X Status %08X\n", "Fixed Event Block: Enable %08X Status %08X\n",
......
...@@ -75,8 +75,7 @@ acpi_status acpi_hw_clear_acpi_status(void) ...@@ -75,8 +75,7 @@ acpi_status acpi_hw_clear_acpi_status(void)
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
ACPI_REGISTER_PM1_STATUS,
ACPI_BITMASK_ALL_FIXED_STATUS); ACPI_BITMASK_ALL_FIXED_STATUS);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto unlock_and_exit;
...@@ -259,7 +258,7 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) ...@@ -259,7 +258,7 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_get_register(u32 register_id, u32 * return_value) acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
{ {
u32 register_value = 0; u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info; struct acpi_bit_register_info *bit_reg_info;
...@@ -276,8 +275,7 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value) ...@@ -276,8 +275,7 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value)
/* Read from the register */ /* Read from the register */
status = acpi_hw_register_read(ACPI_MTX_LOCK, status = acpi_hw_register_read(bit_reg_info->parent_register,
bit_reg_info->parent_register,
&register_value); &register_value);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
...@@ -298,6 +296,16 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value) ...@@ -298,6 +296,16 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value)
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
acpi_status acpi_get_register(u32 register_id, u32 * return_value)
{
acpi_status status;
acpi_cpu_flags flags;
flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
status = acpi_get_register_unlocked(register_id, return_value);
acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
return status;
}
ACPI_EXPORT_SYMBOL(acpi_get_register) ACPI_EXPORT_SYMBOL(acpi_get_register)
/******************************************************************************* /*******************************************************************************
...@@ -335,8 +343,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ...@@ -335,8 +343,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
/* Always do a register read first so we can insert the new bits */ /* Always do a register read first so we can insert the new bits */
status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_read(bit_reg_info->parent_register,
bit_reg_info->parent_register,
&register_value); &register_value);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto unlock_and_exit;
...@@ -363,8 +370,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ...@@ -363,8 +370,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info-> bit_reg_info->
access_bit_mask); access_bit_mask);
if (value) { if (value) {
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
ACPI_REGISTER_PM1_STATUS,
(u16) value); (u16) value);
register_value = 0; register_value = 0;
} }
...@@ -377,8 +383,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ...@@ -377,8 +383,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info->access_bit_mask, bit_reg_info->access_bit_mask,
value); value);
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
ACPI_REGISTER_PM1_ENABLE,
(u16) register_value); (u16) register_value);
break; break;
...@@ -397,15 +402,13 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ...@@ -397,15 +402,13 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info->access_bit_mask, bit_reg_info->access_bit_mask,
value); value);
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
ACPI_REGISTER_PM1_CONTROL,
(u16) register_value); (u16) register_value);
break; break;
case ACPI_REGISTER_PM2_CONTROL: case ACPI_REGISTER_PM2_CONTROL:
status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
ACPI_REGISTER_PM2_CONTROL,
&register_value); &register_value);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto unlock_and_exit;
...@@ -430,8 +433,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value) ...@@ -430,8 +433,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
xpm2_control_block. xpm2_control_block.
address))); address)));
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
ACPI_REGISTER_PM2_CONTROL,
(u8) (register_value)); (u8) (register_value));
break; break;
...@@ -461,8 +463,7 @@ ACPI_EXPORT_SYMBOL(acpi_set_register) ...@@ -461,8 +463,7 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
* *
* FUNCTION: acpi_hw_register_read * FUNCTION: acpi_hw_register_read
* *
* PARAMETERS: use_lock - Lock hardware? True/False * PARAMETERS: register_id - ACPI Register ID
* register_id - ACPI Register ID
* return_value - Where the register value is returned * return_value - Where the register value is returned
* *
* RETURN: Status and the value read. * RETURN: Status and the value read.
...@@ -471,19 +472,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_register) ...@@ -471,19 +472,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) acpi_hw_register_read(u32 register_id, u32 * return_value)
{ {
u32 value1 = 0; u32 value1 = 0;
u32 value2 = 0; u32 value2 = 0;
acpi_status status; acpi_status status;
acpi_cpu_flags lock_flags = 0;
ACPI_FUNCTION_TRACE(hw_register_read); ACPI_FUNCTION_TRACE(hw_register_read);
if (ACPI_MTX_LOCK == use_lock) {
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
}
switch (register_id) { switch (register_id) {
case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
...@@ -491,7 +487,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) ...@@ -491,7 +487,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
acpi_hw_low_level_read(16, &value1, acpi_hw_low_level_read(16, &value1,
&acpi_gbl_FADT.xpm1a_event_block); &acpi_gbl_FADT.xpm1a_event_block);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto exit;
} }
/* PM1B is optional */ /* PM1B is optional */
...@@ -507,7 +503,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) ...@@ -507,7 +503,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
status = status =
acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable); acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto exit;
} }
/* PM1B is optional */ /* PM1B is optional */
...@@ -523,7 +519,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) ...@@ -523,7 +519,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
acpi_hw_low_level_read(16, &value1, acpi_hw_low_level_read(16, &value1,
&acpi_gbl_FADT.xpm1a_control_block); &acpi_gbl_FADT.xpm1a_control_block);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto exit;
} }
status = status =
...@@ -558,10 +554,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) ...@@ -558,10 +554,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
break; break;
} }
unlock_and_exit: exit:
if (ACPI_MTX_LOCK == use_lock) {
acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
}
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
*return_value = value1; *return_value = value1;
...@@ -574,8 +567,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) ...@@ -574,8 +567,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
* *
* FUNCTION: acpi_hw_register_write * FUNCTION: acpi_hw_register_write
* *
* PARAMETERS: use_lock - Lock hardware? True/False * PARAMETERS: register_id - ACPI Register ID
* register_id - ACPI Register ID
* Value - The value to write * Value - The value to write
* *
* RETURN: Status * RETURN: Status
...@@ -597,28 +589,22 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) ...@@ -597,28 +589,22 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) acpi_status acpi_hw_register_write(u32 register_id, u32 value)
{ {
acpi_status status; acpi_status status;
acpi_cpu_flags lock_flags = 0;
u32 read_value; u32 read_value;
ACPI_FUNCTION_TRACE(hw_register_write); ACPI_FUNCTION_TRACE(hw_register_write);
if (ACPI_MTX_LOCK == use_lock) {
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
}
switch (register_id) { switch (register_id) {
case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
/* Perform a read first to preserve certain bits (per ACPI spec) */ /* Perform a read first to preserve certain bits (per ACPI spec) */
status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
ACPI_REGISTER_PM1_STATUS,
&read_value); &read_value);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto exit;
} }
/* Insert the bits to be preserved */ /* Insert the bits to be preserved */
...@@ -632,7 +618,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) ...@@ -632,7 +618,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
acpi_hw_low_level_write(16, value, acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT.xpm1a_event_block); &acpi_gbl_FADT.xpm1a_event_block);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto exit;
} }
/* PM1B is optional */ /* PM1B is optional */
...@@ -647,7 +633,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) ...@@ -647,7 +633,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
status = status =
acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable); acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto exit;
} }
/* PM1B is optional */ /* PM1B is optional */
...@@ -661,11 +647,10 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) ...@@ -661,11 +647,10 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
/* /*
* Perform a read first to preserve certain bits (per ACPI spec) * Perform a read first to preserve certain bits (per ACPI spec)
*/ */
status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
ACPI_REGISTER_PM1_CONTROL,
&read_value); &read_value);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto exit;
} }
/* Insert the bits to be preserved */ /* Insert the bits to be preserved */
...@@ -679,7 +664,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) ...@@ -679,7 +664,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
acpi_hw_low_level_write(16, value, acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT.xpm1a_control_block); &acpi_gbl_FADT.xpm1a_control_block);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto unlock_and_exit; goto exit;
} }
status = status =
...@@ -728,11 +713,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) ...@@ -728,11 +713,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
break; break;
} }
unlock_and_exit: exit:
if (ACPI_MTX_LOCK == use_lock) {
acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
...@@ -309,8 +309,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) ...@@ -309,8 +309,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */ /* Get current value of PM1A control */
status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -337,15 +336,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) ...@@ -337,15 +336,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Write #1: fill in SLP_TYP data */ /* Write #1: fill in SLP_TYP data */
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol); PM1Acontrol);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol); PM1Bcontrol);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -360,15 +357,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) ...@@ -360,15 +357,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
ACPI_FLUSH_CPU_CACHE(); ACPI_FLUSH_CPU_CACHE();
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol); PM1Acontrol);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol); PM1Bcontrol);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -388,8 +383,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) ...@@ -388,8 +383,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
*/ */
acpi_os_stall(10000000); acpi_os_stall(10000000);
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
ACPI_REGISTER_PM1_CONTROL,
sleep_enable_reg_info-> sleep_enable_reg_info->
access_bit_mask); access_bit_mask);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
...@@ -400,7 +394,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) ...@@ -400,7 +394,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Wait until we enter sleep state */ /* Wait until we enter sleep state */
do { do {
status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
&in_value);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -516,8 +511,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) ...@@ -516,8 +511,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */ /* Get current value of PM1A control */
status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
ACPI_REGISTER_PM1_CONTROL,
&PM1Acontrol); &PM1Acontrol);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
...@@ -539,11 +533,9 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) ...@@ -539,11 +533,9 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
/* Just ignore any errors */ /* Just ignore any errors */
(void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol); PM1Acontrol);
(void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol); PM1Bcontrol);
} }
} }
......
...@@ -71,9 +71,9 @@ u32 acpi_hw_get_mode(void); ...@@ -71,9 +71,9 @@ u32 acpi_hw_get_mode(void);
struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
acpi_status acpi_status
acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value); acpi_hw_register_read(u32 register_id, u32 * return_value);
acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value); acpi_status acpi_hw_register_write(u32 register_id, u32 value);
acpi_status acpi_status
acpi_hw_low_level_read(u32 width, acpi_hw_low_level_read(u32 width,
......
...@@ -314,6 +314,8 @@ acpi_resource_to_address64(struct acpi_resource *resource, ...@@ -314,6 +314,8 @@ acpi_resource_to_address64(struct acpi_resource *resource,
*/ */
acpi_status acpi_get_register(u32 register_id, u32 * return_value); acpi_status acpi_get_register(u32 register_id, u32 * return_value);
acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value);
acpi_status acpi_set_register(u32 register_id, u32 value); acpi_status acpi_set_register(u32 register_id, u32 value);
acpi_status acpi_status
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment