Add retries for ex write and move enable custom fan table to end because of possible external race condition

This commit is contained in:
Werner Sembach 2022-10-05 16:25:37 +02:00
parent a8b3cb6dc3
commit 19642a2496
3 changed files with 57 additions and 24 deletions

View file

@ -189,8 +189,8 @@ static bool fans_initialized = false;
static int uw_init_fan(void) { static int uw_init_fan(void) {
int i; int i;
u16 addr_use_custom_fan_table_0 = 0x07c5; u16 addr_use_custom_fan_table_0 = 0x07c5; // use different tables for both fans (0x0f00-0x0f2f and 0x0f30-0x0f5f respectivly)
u16 addr_use_custom_fan_table_1 = 0x07c6; u16 addr_use_custom_fan_table_1 = 0x07c6; // enable 0x0fxx fantables
u8 offset_use_custom_fan_table_0 = 7; u8 offset_use_custom_fan_table_0 = 7;
u8 offset_use_custom_fan_table_1 = 2; u8 offset_use_custom_fan_table_1 = 2;
u8 value_use_custom_fan_table_0; u8 value_use_custom_fan_table_0;
@ -206,28 +206,28 @@ static int uw_init_fan(void) {
set_full_fan_mode(false); set_full_fan_mode(false);
uniwill_read_ec_ram(addr_use_custom_fan_table_0, &value_use_custom_fan_table_0); uniwill_read_ec_ram(addr_use_custom_fan_table_0, &value_use_custom_fan_table_0);
uniwill_read_ec_ram(addr_use_custom_fan_table_1, &value_use_custom_fan_table_1);
if (!((value_use_custom_fan_table_0 >> offset_use_custom_fan_table_0) & 1)) { if (!((value_use_custom_fan_table_0 >> offset_use_custom_fan_table_0) & 1)) {
uniwill_write_ec_ram(addr_use_custom_fan_table_0, value_use_custom_fan_table_0 + (1 << offset_use_custom_fan_table_0)); uniwill_write_ec_ram_with_retry(addr_use_custom_fan_table_0, value_use_custom_fan_table_0 + (1 << offset_use_custom_fan_table_0), 3);
}
if (!((value_use_custom_fan_table_1 >> offset_use_custom_fan_table_1) & 1)) {
uniwill_write_ec_ram(addr_use_custom_fan_table_1, value_use_custom_fan_table_1 + (1 << offset_use_custom_fan_table_1));
} }
uniwill_write_ec_ram(addr_cpu_custom_fan_table_end_temp, 0xff); uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_end_temp, 0xff, 3);
uniwill_write_ec_ram(addr_cpu_custom_fan_table_start_temp, 0x00); uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_start_temp, 0x00, 3);
uniwill_write_ec_ram(addr_cpu_custom_fan_table_fan_speed, 0x00); uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_fan_speed, 0x00, 3);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_end_temp, 0xff); uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_end_temp, 0xff, 3);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_start_temp, 0x00); uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_start_temp, 0x00, 3);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_fan_speed, 0x00); uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_fan_speed, 0x00, 3);
for (i = 0x1; i <= 0xf; ++i) { for (i = 0x1; i <= 0xf; ++i) {
uniwill_write_ec_ram(addr_cpu_custom_fan_table_end_temp + i, 0xff); uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_end_temp + i, 0xff, 3);
uniwill_write_ec_ram(addr_cpu_custom_fan_table_start_temp + i, 0xff); uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_start_temp + i, 0xff, 3);
uniwill_write_ec_ram(addr_cpu_custom_fan_table_fan_speed + i, 0x00); uniwill_write_ec_ram_with_retry(addr_cpu_custom_fan_table_fan_speed + i, 0x00, 3);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_end_temp + i, 0xff); uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_end_temp + i, 0xff, 3);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_start_temp + i, 0xff); uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_start_temp + i, 0xff, 3);
uniwill_write_ec_ram(addr_gpu_custom_fan_table_fan_speed + i, 0x00); uniwill_write_ec_ram_with_retry(addr_gpu_custom_fan_table_fan_speed + i, 0x00, 3);
}
uniwill_read_ec_ram(addr_use_custom_fan_table_1, &value_use_custom_fan_table_1);
if (!((value_use_custom_fan_table_1 >> offset_use_custom_fan_table_1) & 1)) {
uniwill_write_ec_ram_with_retry(addr_use_custom_fan_table_1, value_use_custom_fan_table_1 + (1 << offset_use_custom_fan_table_1), 3);
} }
} }
@ -292,10 +292,15 @@ static u32 uw_set_fan(u32 fan_index, u8 fan_speed)
static u32 uw_set_fan_auto(void) static u32 uw_set_fan_auto(void)
{ {
u8 mode_data; u8 mode_data;
// Get current mode
uniwill_read_ec_ram(0x0751, &mode_data); if (has_universal_ec_fan_control() == 1) {
// Switch off "full fan mode" (i.e. unset 0x40 bit) }
uniwill_write_ec_ram(0x0751, mode_data & 0xbf); else {
// Get current mode
uniwill_read_ec_ram(0x0751, &mode_data);
// Switch off "full fan mode" (i.e. unset 0x40 bit)
uniwill_write_ec_ram(0x0751, mode_data & 0xbf);
}
return 0; return 0;
} }

View file

@ -37,6 +37,7 @@
typedef u32 (uniwill_read_ec_ram_t)(u16, u8*); typedef u32 (uniwill_read_ec_ram_t)(u16, u8*);
typedef u32 (uniwill_write_ec_ram_t)(u16, u8); typedef u32 (uniwill_write_ec_ram_t)(u16, u8);
typedef u32 (uniwill_write_ec_ram_with_retry_t)(u16, u8, int);
typedef void (uniwill_event_callb_t)(u32); typedef void (uniwill_event_callb_t)(u32);
struct uniwill_interface_t { struct uniwill_interface_t {
@ -50,6 +51,7 @@ u32 uniwill_add_interface(struct uniwill_interface_t *new_interface);
u32 uniwill_remove_interface(struct uniwill_interface_t *interface); u32 uniwill_remove_interface(struct uniwill_interface_t *interface);
uniwill_read_ec_ram_t uniwill_read_ec_ram; uniwill_read_ec_ram_t uniwill_read_ec_ram;
uniwill_write_ec_ram_t uniwill_write_ec_ram; uniwill_write_ec_ram_t uniwill_write_ec_ram;
uniwill_write_ec_ram_with_retry_t uniwill_write_ec_ram_with_retry;
u32 uniwill_get_active_interface_id(char **id_str); u32 uniwill_get_active_interface_id(char **id_str);
union uw_ec_read_return { union uw_ec_read_return {

View file

@ -124,6 +124,32 @@ u32 uniwill_write_ec_ram(u16 address, u8 data)
} }
EXPORT_SYMBOL(uniwill_write_ec_ram); EXPORT_SYMBOL(uniwill_write_ec_ram);
u32 uniwill_write_ec_ram_with_retry(u16 address, u8 data, int retries)
{
u32 status;
int i;
u8 control_data;
for (i = 0; i < retries; ++i) {
status = uniwill_write_ec_ram(address, data);
if (status != 0) {
msleep(50);
continue;
}
else {
status = uniwill_read_ec_ram(address, &control_data);
if (status != 0 || data != control_data) {
msleep(50);
continue;
}
break;
}
}
return status;
}
EXPORT_SYMBOL(uniwill_write_ec_ram_with_retry);
static DEFINE_MUTEX(uniwill_interface_modification_lock); static DEFINE_MUTEX(uniwill_interface_modification_lock);
u32 uniwill_add_interface(struct uniwill_interface_t *interface) u32 uniwill_add_interface(struct uniwill_interface_t *interface)