diff options
Diffstat (limited to 'drivers/thermal/intel/int340x_thermal/int3400_thermal.c')
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 72 |
1 files changed, 41 insertions, 31 deletions
diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c index d97f496bab9b..770d2b0299c3 100644 --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c @@ -169,37 +169,53 @@ static int int3400_thermal_run_osc(acpi_handle handle, char *uuid_str, int *enab acpi_status status; int result = 0; struct acpi_osc_context context = { - .uuid_str = NULL, + .uuid_str = uuid_str, .rev = 1, .cap.length = 8, + .cap.pointer = buf, }; - context.uuid_str = uuid_str; - buf[OSC_QUERY_DWORD] = 0; buf[OSC_SUPPORT_DWORD] = *enable; - context.cap.pointer = buf; - status = acpi_run_osc(handle, &context); if (ACPI_SUCCESS(status)) { ret = *((u32 *)(context.ret.pointer + 4)); if (ret != *enable) result = -EPERM; + + kfree(context.ret.pointer); } else result = -EPERM; - kfree(context.ret.pointer); - return result; } +static int set_os_uuid_mask(struct int3400_thermal_priv *priv, u32 mask) +{ + int cap = 0; + + /* + * Capability bits: + * Bit 0: set to 1 to indicate DPTF is active + * Bi1 1: set to 1 to active cooling is supported by user space daemon + * Bit 2: set to 1 to passive cooling is supported by user space daemon + * Bit 3: set to 1 to critical trip is handled by user space daemon + */ + if (mask) + cap = (priv->os_uuid_mask << 1) | 0x01; + + return int3400_thermal_run_osc(priv->adev->handle, + "b23ba85d-c8b7-3542-88de-8de2ffcfd698", + &cap); +} + static ssize_t current_uuid_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct int3400_thermal_priv *priv = dev_get_drvdata(dev); - int i; + int ret, i; for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; ++i) { if (!strncmp(buf, int3400_thermal_uuids[i], @@ -231,19 +247,7 @@ static ssize_t current_uuid_store(struct device *dev, } if (priv->os_uuid_mask) { - int cap, ret; - - /* - * Capability bits: - * Bit 0: set to 1 to indicate DPTF is active - * Bi1 1: set to 1 to active cooling is supported by user space daemon - * Bit 2: set to 1 to passive cooling is supported by user space daemon - * Bit 3: set to 1 to critical trip is handled by user space daemon - */ - cap = ((priv->os_uuid_mask << 1) | 0x01); - ret = int3400_thermal_run_osc(priv->adev->handle, - "b23ba85d-c8b7-3542-88de-8de2ffcfd698", - &cap); + ret = set_os_uuid_mask(priv, priv->os_uuid_mask); if (ret) return ret; } @@ -469,17 +473,26 @@ static int int3400_thermal_change_mode(struct thermal_zone_device *thermal, if (mode != thermal->mode) { int enabled; + enabled = mode == THERMAL_DEVICE_ENABLED; + + if (priv->os_uuid_mask) { + if (!enabled) { + priv->os_uuid_mask = 0; + result = set_os_uuid_mask(priv, priv->os_uuid_mask); + } + goto eval_odvp; + } + if (priv->current_uuid_index < 0 || priv->current_uuid_index >= INT3400_THERMAL_MAXIMUM_UUID) return -EINVAL; - enabled = (mode == THERMAL_DEVICE_ENABLED); result = int3400_thermal_run_osc(priv->adev->handle, int3400_thermal_uuids[priv->current_uuid_index], &enabled); } - +eval_odvp: evaluate_odvp(priv); return result; @@ -508,21 +521,18 @@ static void int3400_setup_gddv(struct int3400_thermal_priv *priv) obj = buffer.pointer; if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 1 - || obj->package.elements[0].type != ACPI_TYPE_BUFFER) { - kfree(buffer.pointer); - return; - } + || obj->package.elements[0].type != ACPI_TYPE_BUFFER) + goto out_free; priv->data_vault = kmemdup(obj->package.elements[0].buffer.pointer, obj->package.elements[0].buffer.length, GFP_KERNEL); - if (!priv->data_vault) { - kfree(buffer.pointer); - return; - } + if (!priv->data_vault) + goto out_free; bin_attr_data_vault.private = priv->data_vault; bin_attr_data_vault.size = obj->package.elements[0].buffer.length; +out_free: kfree(buffer.pointer); } |