Merge branches 'thermal-powerclamp', 'thermal-int340x' and 'thermal-docs'
Merge powerclamp thermal driver changes, int340x thermal driver changes and thermal documentation changes for 5.18-rc1: - Don't use bitmap_weight() in end_power_clamp() in the powerclamp driver (Yury Norov). - Update the OS policy capabilities handshake in the int340x thermal driver (Srinivas Pandruvada). - Increase the policies bitmap size in int340x (Srinivas Pandruvada). - Replace acpi_bus_get_device() with acpi_fetch_acpi_dev() in the int340x thermal driver (Rafael Wysocki). - Check for NULL after calling kmemdup() in int340x (Jiasheng Jiang). - Add Intel Dynamic Power and Thermal Framework (DPTF) kernel interface documentation (Srinivas Pandruvada). - Fix bullet list warning in the thermal documentation (Randy Dunlap). * thermal-powerclamp: thermal: intel_powerclamp: don't use bitmap_weight() in end_power_clamp() * thermal-int340x: thermal: int340x: Update OS policy capability handshake thermal: int340x: Increase bitmap size thermal: Replace acpi_bus_get_device() thermal: int340x: Check for NULL after calling kmemdup() * thermal-docs: Documentation: thermal: DPTF Documentation thermal: fix Documentation bullet list warning
This commit is contained in:
commit
2d6fc1455f
@ -203,7 +203,7 @@ Description:
|
||||
|
||||
- for generic ACPI: should be "Fan", "Processor" or "LCD"
|
||||
- for memory controller device on intel_menlow platform:
|
||||
should be "Memory controller".
|
||||
should be "Memory controller".
|
||||
|
||||
RO, Required
|
||||
|
||||
|
@ -17,3 +17,4 @@ Thermal
|
||||
intel_powerclamp
|
||||
nouveau_thermal
|
||||
x86_pkg_temperature_thermal
|
||||
intel_dptf
|
||||
|
272
Documentation/driver-api/thermal/intel_dptf.rst
Normal file
272
Documentation/driver-api/thermal/intel_dptf.rst
Normal file
@ -0,0 +1,272 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===============================================================
|
||||
Intel(R) Dynamic Platform and Thermal Framework Sysfs Interface
|
||||
===============================================================
|
||||
|
||||
:Copyright: |copy| 2022 Intel Corporation
|
||||
|
||||
:Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Intel(R) Dynamic Platform and Thermal Framework (DPTF) is a platform
|
||||
level hardware/software solution for power and thermal management.
|
||||
|
||||
As a container for multiple power/thermal technologies, DPTF provides
|
||||
a coordinated approach for different policies to effect the hardware
|
||||
state of a system.
|
||||
|
||||
Since it is a platform level framework, this has several components.
|
||||
Some parts of the technology is implemented in the firmware and uses
|
||||
ACPI and PCI devices to expose various features for monitoring and
|
||||
control. Linux has a set of kernel drivers exposing hardware interface
|
||||
to user space. This allows user space thermal solutions like
|
||||
"Linux Thermal Daemon" to read platform specific thermal and power
|
||||
tables to deliver adequate performance while keeping the system under
|
||||
thermal limits.
|
||||
|
||||
DPTF ACPI Drivers interface
|
||||
----------------------------
|
||||
|
||||
:file:`/sys/bus/platform/devices/<N>/uuids`, where <N>
|
||||
=INT3400|INTC1040|INTC1041|INTC10A0
|
||||
|
||||
``available_uuids`` (RO)
|
||||
A set of UUIDs strings presenting available policies
|
||||
which should be notified to the firmware when the
|
||||
user space can support those policies.
|
||||
|
||||
UUID strings:
|
||||
|
||||
"42A441D6-AE6A-462b-A84B-4A8CE79027D3" : Passive 1
|
||||
|
||||
"3A95C389-E4B8-4629-A526-C52C88626BAE" : Active
|
||||
|
||||
"97C68AE7-15FA-499c-B8C9-5DA81D606E0A" : Critical
|
||||
|
||||
"63BE270F-1C11-48FD-A6F7-3AF253FF3E2D" : Adaptive performance
|
||||
|
||||
"5349962F-71E6-431D-9AE8-0A635B710AEE" : Emergency call
|
||||
|
||||
"9E04115A-AE87-4D1C-9500-0F3E340BFE75" : Passive 2
|
||||
|
||||
"F5A35014-C209-46A4-993A-EB56DE7530A1" : Power Boss
|
||||
|
||||
"6ED722A7-9240-48A5-B479-31EEF723D7CF" : Virtual Sensor
|
||||
|
||||
"16CAF1B7-DD38-40ED-B1C1-1B8A1913D531" : Cooling mode
|
||||
|
||||
"BE84BABF-C4D4-403D-B495-3128FD44dAC1" : HDC
|
||||
|
||||
``current_uuid`` (RW)
|
||||
User space can write strings from available UUIDs, one at a
|
||||
time.
|
||||
|
||||
:file:`/sys/bus/platform/devices/<N>/`, where <N>
|
||||
=INT3400|INTC1040|INTC1041|INTC10A0
|
||||
|
||||
``imok`` (WO)
|
||||
User space daemon write 1 to respond to firmware event
|
||||
for sending keep alive notification. User space receives
|
||||
THERMAL_EVENT_KEEP_ALIVE kobject uevent notification when
|
||||
firmware calls for user space to respond with imok ACPI
|
||||
method.
|
||||
|
||||
``odvp*`` (RO)
|
||||
Firmware thermal status variable values. Thermal tables
|
||||
calls for different processing based on these variable
|
||||
values.
|
||||
|
||||
``data_vault`` (RO)
|
||||
Binary thermal table. Refer to
|
||||
https:/github.com/intel/thermal_daemon for decoding
|
||||
thermal table.
|
||||
|
||||
|
||||
ACPI Thermal Relationship table interface
|
||||
------------------------------------------
|
||||
|
||||
:file:`/dev/acpi_thermal_rel`
|
||||
|
||||
This device provides IOCTL interface to read standard ACPI
|
||||
thermal relationship tables via ACPI methods _TRT and _ART.
|
||||
These IOCTLs are defined in
|
||||
drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.h
|
||||
|
||||
IOCTLs:
|
||||
|
||||
ACPI_THERMAL_GET_TRT_LEN: Get length of TRT table
|
||||
|
||||
ACPI_THERMAL_GET_ART_LEN: Get length of ART table
|
||||
|
||||
ACPI_THERMAL_GET_TRT_COUNT: Number of records in TRT table
|
||||
|
||||
ACPI_THERMAL_GET_ART_COUNT: Number of records in ART table
|
||||
|
||||
ACPI_THERMAL_GET_TRT: Read binary TRT table, length to read is
|
||||
provided via argument to ioctl().
|
||||
|
||||
ACPI_THERMAL_GET_ART: Read binary ART table, length to read is
|
||||
provided via argument to ioctl().
|
||||
|
||||
DPTF ACPI Sensor drivers
|
||||
-------------------------
|
||||
|
||||
DPTF Sensor drivers are presented as standard thermal sysfs thermal_zone.
|
||||
|
||||
|
||||
DPTF ACPI Cooling drivers
|
||||
--------------------------
|
||||
|
||||
DPTF cooling drivers are presented as standard thermal sysfs cooling_device.
|
||||
|
||||
|
||||
DPTF Processor thermal PCI Driver interface
|
||||
--------------------------------------------
|
||||
|
||||
:file:`/sys/bus/pci/devices/0000\:00\:04.0/power_limits/`
|
||||
|
||||
Refer to Documentation/power/powercap/powercap.rst for powercap
|
||||
ABI.
|
||||
|
||||
``power_limit_0_max_uw`` (RO)
|
||||
Maximum powercap sysfs constraint_0_power_limit_uw for Intel RAPL
|
||||
|
||||
``power_limit_0_step_uw`` (RO)
|
||||
Power limit increment/decrements for Intel RAPL constraint 0 power limit
|
||||
|
||||
``power_limit_0_min_uw`` (RO)
|
||||
Minimum powercap sysfs constraint_0_power_limit_uw for Intel RAPL
|
||||
|
||||
``power_limit_0_tmin_us`` (RO)
|
||||
Minimum powercap sysfs constraint_0_time_window_us for Intel RAPL
|
||||
|
||||
``power_limit_0_tmax_us`` (RO)
|
||||
Maximum powercap sysfs constraint_0_time_window_us for Intel RAPL
|
||||
|
||||
``power_limit_1_max_uw`` (RO)
|
||||
Maximum powercap sysfs constraint_1_power_limit_uw for Intel RAPL
|
||||
|
||||
``power_limit_1_step_uw`` (RO)
|
||||
Power limit increment/decrements for Intel RAPL constraint 1 power limit
|
||||
|
||||
``power_limit_1_min_uw`` (RO)
|
||||
Minimum powercap sysfs constraint_1_power_limit_uw for Intel RAPL
|
||||
|
||||
``power_limit_1_tmin_us`` (RO)
|
||||
Minimum powercap sysfs constraint_1_time_window_us for Intel RAPL
|
||||
|
||||
``power_limit_1_tmax_us`` (RO)
|
||||
Maximum powercap sysfs constraint_1_time_window_us for Intel RAPL
|
||||
|
||||
:file:`/sys/bus/pci/devices/0000\:00\:04.0/`
|
||||
|
||||
``tcc_offset_degree_celsius`` (RW)
|
||||
TCC offset from the critical temperature where hardware will throttle
|
||||
CPU.
|
||||
|
||||
:file:`/sys/bus/pci/devices/0000\:00\:04.0/workload_request`
|
||||
|
||||
``workload_available_types`` (RO)
|
||||
Available workload types. User space can specify one of the workload type
|
||||
it is currently executing via workload_type. For example: idle, bursty,
|
||||
sustained etc.
|
||||
|
||||
``workload_type`` (RW)
|
||||
User space can specify any one of the available workload type using
|
||||
this interface.
|
||||
|
||||
DPTF Processor thermal RFIM interface
|
||||
--------------------------------------------
|
||||
|
||||
RFIM interface allows adjustment of FIVR (Fully Integrated Voltage Regulator)
|
||||
and DDR (Double Data Rate)frequencies to avoid RF interference with WiFi and 5G.
|
||||
|
||||
Switching voltage regulators (VR) generate radiated EMI or RFI at the
|
||||
fundamental frequency and its harmonics. Some harmonics may interfere
|
||||
with very sensitive wireless receivers such as Wi-Fi and cellular that
|
||||
are integrated into host systems like notebook PCs. One of mitigation
|
||||
methods is requesting SOC integrated VR (IVR) switching frequency to a
|
||||
small % and shift away the switching noise harmonic interference from
|
||||
radio channels. OEM or ODMs can use the driver to control SOC IVR
|
||||
operation within the range where it does not impact IVR performance.
|
||||
|
||||
DRAM devices of DDR IO interface and their power plane can generate EMI
|
||||
at the data rates. Similar to IVR control mechanism, Intel offers a
|
||||
mechanism by which DDR data rates can be changed if several conditions
|
||||
are met: there is strong RFI interference because of DDR; CPU power
|
||||
management has no other restriction in changing DDR data rates;
|
||||
PC ODMs enable this feature (real time DDR RFI Mitigation referred to as
|
||||
DDR-RFIM) for Wi-Fi from BIOS.
|
||||
|
||||
|
||||
FIVR attributes
|
||||
|
||||
:file:`/sys/bus/pci/devices/0000\:00\:04.0/fivr/`
|
||||
|
||||
``vco_ref_code_lo`` (RW)
|
||||
The VCO reference code is an 11-bit field and controls the FIVR
|
||||
switching frequency. This is the 3-bit LSB field.
|
||||
|
||||
``vco_ref_code_hi`` (RW)
|
||||
The VCO reference code is an 11-bit field and controls the FIVR
|
||||
switching frequency. This is the 8-bit MSB field.
|
||||
|
||||
``spread_spectrum_pct`` (RW)
|
||||
Set the FIVR spread spectrum clocking percentage
|
||||
|
||||
``spread_spectrum_clk_enable`` (RW)
|
||||
Enable/disable of the FIVR spread spectrum clocking feature
|
||||
|
||||
``rfi_vco_ref_code`` (RW)
|
||||
This field is a read only status register which reflects the
|
||||
current FIVR switching frequency
|
||||
|
||||
``fivr_fffc_rev`` (RW)
|
||||
This field indicated the revision of the FIVR HW.
|
||||
|
||||
|
||||
DVFS attributes
|
||||
|
||||
:file:`/sys/bus/pci/devices/0000\:00\:04.0/dvfs/`
|
||||
|
||||
``rfi_restriction_run_busy`` (RW)
|
||||
Request the restriction of specific DDR data rate and set this
|
||||
value 1. Self reset to 0 after operation.
|
||||
|
||||
``rfi_restriction_err_code`` (RW)
|
||||
0 :Request is accepted, 1:Feature disabled,
|
||||
2: the request restricts more points than it is allowed
|
||||
|
||||
``rfi_restriction_data_rate_Delta`` (RW)
|
||||
Restricted DDR data rate for RFI protection: Lower Limit
|
||||
|
||||
``rfi_restriction_data_rate_Base`` (RW)
|
||||
Restricted DDR data rate for RFI protection: Upper Limit
|
||||
|
||||
``ddr_data_rate_point_0`` (RO)
|
||||
DDR data rate selection 1st point
|
||||
|
||||
``ddr_data_rate_point_1`` (RO)
|
||||
DDR data rate selection 2nd point
|
||||
|
||||
``ddr_data_rate_point_2`` (RO)
|
||||
DDR data rate selection 3rd point
|
||||
|
||||
``ddr_data_rate_point_3`` (RO)
|
||||
DDR data rate selection 4th point
|
||||
|
||||
``rfi_disable (RW)``
|
||||
Disable DDR rate change feature
|
||||
|
||||
DPTF Power supply and Battery Interface
|
||||
----------------------------------------
|
||||
|
||||
Refer to Documentation/ABI/testing/sysfs-platform-dptf
|
||||
|
||||
DPTF Fan Control
|
||||
----------------------------------------
|
||||
|
||||
Refer to Documentation/admin-guide/acpi/fan_performance_states.rst
|
@ -72,7 +72,6 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
|
||||
int i;
|
||||
int nr_bad_entries = 0;
|
||||
struct trt *trts;
|
||||
struct acpi_device *adev;
|
||||
union acpi_object *p;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
struct acpi_buffer element = { 0, NULL };
|
||||
@ -112,12 +111,10 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
|
||||
if (!create_dev)
|
||||
continue;
|
||||
|
||||
result = acpi_bus_get_device(trt->source, &adev);
|
||||
if (result)
|
||||
if (!acpi_fetch_acpi_dev(trt->source))
|
||||
pr_warn("Failed to get source ACPI device\n");
|
||||
|
||||
result = acpi_bus_get_device(trt->target, &adev);
|
||||
if (result)
|
||||
if (!acpi_fetch_acpi_dev(trt->target))
|
||||
pr_warn("Failed to get target ACPI device\n");
|
||||
}
|
||||
|
||||
@ -149,7 +146,6 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
|
||||
int i;
|
||||
int nr_bad_entries = 0;
|
||||
struct art *arts;
|
||||
struct acpi_device *adev;
|
||||
union acpi_object *p;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
struct acpi_buffer element = { 0, NULL };
|
||||
@ -191,16 +187,11 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
|
||||
if (!create_dev)
|
||||
continue;
|
||||
|
||||
if (art->source) {
|
||||
result = acpi_bus_get_device(art->source, &adev);
|
||||
if (result)
|
||||
pr_warn("Failed to get source ACPI device\n");
|
||||
}
|
||||
if (art->target) {
|
||||
result = acpi_bus_get_device(art->target, &adev);
|
||||
if (result)
|
||||
pr_warn("Failed to get target ACPI device\n");
|
||||
}
|
||||
if (!acpi_fetch_acpi_dev(art->source))
|
||||
pr_warn("Failed to get source ACPI device\n");
|
||||
|
||||
if (!acpi_fetch_acpi_dev(art->target))
|
||||
pr_warn("Failed to get target ACPI device\n");
|
||||
}
|
||||
|
||||
*artp = arts;
|
||||
|
@ -17,8 +17,8 @@
|
||||
#define INT3400_KEEP_ALIVE 0xA0
|
||||
|
||||
enum int3400_thermal_uuid {
|
||||
INT3400_THERMAL_ACTIVE = 0,
|
||||
INT3400_THERMAL_PASSIVE_1,
|
||||
INT3400_THERMAL_ACTIVE,
|
||||
INT3400_THERMAL_CRITICAL,
|
||||
INT3400_THERMAL_ADAPTIVE_PERFORMANCE,
|
||||
INT3400_THERMAL_EMERGENCY_CALL_MODE,
|
||||
@ -31,8 +31,8 @@ enum int3400_thermal_uuid {
|
||||
};
|
||||
|
||||
static char *int3400_thermal_uuids[INT3400_THERMAL_MAXIMUM_UUID] = {
|
||||
"42A441D6-AE6A-462b-A84B-4A8CE79027D3",
|
||||
"3A95C389-E4B8-4629-A526-C52C88626BAE",
|
||||
"42A441D6-AE6A-462b-A84B-4A8CE79027D3",
|
||||
"97C68AE7-15FA-499c-B8C9-5DA81D606E0A",
|
||||
"63BE270F-1C11-48FD-A6F7-3AF253FF3E2D",
|
||||
"5349962F-71E6-431D-9AE8-0A635B710AEE",
|
||||
@ -53,12 +53,13 @@ struct int3400_thermal_priv {
|
||||
struct art *arts;
|
||||
int trt_count;
|
||||
struct trt *trts;
|
||||
u8 uuid_bitmap;
|
||||
u32 uuid_bitmap;
|
||||
int rel_misc_dev_res;
|
||||
int current_uuid_index;
|
||||
char *data_vault;
|
||||
int odvp_count;
|
||||
int *odvp;
|
||||
u32 os_uuid_mask;
|
||||
struct odvp_attr *odvp_attrs;
|
||||
};
|
||||
|
||||
@ -142,12 +143,55 @@ static ssize_t current_uuid_show(struct device *dev,
|
||||
struct device_attribute *devattr, char *buf)
|
||||
{
|
||||
struct int3400_thermal_priv *priv = dev_get_drvdata(dev);
|
||||
int i, length = 0;
|
||||
|
||||
if (priv->current_uuid_index == -1)
|
||||
return sprintf(buf, "INVALID\n");
|
||||
if (priv->current_uuid_index > 0)
|
||||
return sprintf(buf, "%s\n",
|
||||
int3400_thermal_uuids[priv->current_uuid_index]);
|
||||
|
||||
return sprintf(buf, "%s\n",
|
||||
int3400_thermal_uuids[priv->current_uuid_index]);
|
||||
for (i = 0; i <= INT3400_THERMAL_CRITICAL; i++) {
|
||||
if (priv->os_uuid_mask & BIT(i))
|
||||
length += scnprintf(&buf[length],
|
||||
PAGE_SIZE - length,
|
||||
"%s\n",
|
||||
int3400_thermal_uuids[i]);
|
||||
}
|
||||
|
||||
if (length)
|
||||
return length;
|
||||
|
||||
return sprintf(buf, "INVALID\n");
|
||||
}
|
||||
|
||||
static int int3400_thermal_run_osc(acpi_handle handle, char *uuid_str, int *enable)
|
||||
{
|
||||
u32 ret, buf[2];
|
||||
acpi_status status;
|
||||
int result = 0;
|
||||
struct acpi_osc_context context = {
|
||||
.uuid_str = NULL,
|
||||
.rev = 1,
|
||||
.cap.length = 8,
|
||||
};
|
||||
|
||||
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;
|
||||
} else
|
||||
result = -EPERM;
|
||||
|
||||
kfree(context.ret.pointer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t current_uuid_store(struct device *dev,
|
||||
@ -164,16 +208,47 @@ static ssize_t current_uuid_store(struct device *dev,
|
||||
* If we have a list of supported UUIDs, make sure
|
||||
* this one is supported.
|
||||
*/
|
||||
if (priv->uuid_bitmap &&
|
||||
!(priv->uuid_bitmap & (1 << i)))
|
||||
if (priv->uuid_bitmap & BIT(i)) {
|
||||
priv->current_uuid_index = i;
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is support of only 3 policies via the new
|
||||
* _OSC to inform OS capability:
|
||||
* INT3400_THERMAL_ACTIVE
|
||||
* INT3400_THERMAL_PASSIVE_1
|
||||
* INT3400_THERMAL_CRITICAL
|
||||
*/
|
||||
|
||||
if (i > INT3400_THERMAL_CRITICAL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->current_uuid_index = i;
|
||||
return count;
|
||||
priv->os_uuid_mask |= BIT(i);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
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);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(current_uuid);
|
||||
@ -236,41 +311,6 @@ end:
|
||||
return result;
|
||||
}
|
||||
|
||||
static int int3400_thermal_run_osc(acpi_handle handle,
|
||||
enum int3400_thermal_uuid uuid, bool enable)
|
||||
{
|
||||
u32 ret, buf[2];
|
||||
acpi_status status;
|
||||
int result = 0;
|
||||
struct acpi_osc_context context = {
|
||||
.uuid_str = NULL,
|
||||
.rev = 1,
|
||||
.cap.length = 8,
|
||||
};
|
||||
|
||||
if (uuid < 0 || uuid >= INT3400_THERMAL_MAXIMUM_UUID)
|
||||
return -EINVAL;
|
||||
|
||||
context.uuid_str = int3400_thermal_uuids[uuid];
|
||||
|
||||
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;
|
||||
} else
|
||||
result = -EPERM;
|
||||
|
||||
kfree(context.ret.pointer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t odvp_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
@ -426,10 +466,18 @@ static int int3400_thermal_change_mode(struct thermal_zone_device *thermal,
|
||||
if (!priv)
|
||||
return -EINVAL;
|
||||
|
||||
if (mode != thermal->mode)
|
||||
if (mode != thermal->mode) {
|
||||
int enabled;
|
||||
|
||||
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,
|
||||
priv->current_uuid_index,
|
||||
mode == THERMAL_DEVICE_ENABLED);
|
||||
int3400_thermal_uuids[priv->current_uuid_index],
|
||||
&enabled);
|
||||
}
|
||||
|
||||
|
||||
evaluate_odvp(priv);
|
||||
@ -468,6 +516,11 @@ static void int3400_setup_gddv(struct int3400_thermal_priv *priv)
|
||||
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;
|
||||
}
|
||||
|
||||
bin_attr_data_vault.private = priv->data_vault;
|
||||
bin_attr_data_vault.size = obj->package.elements[0].buffer.length;
|
||||
kfree(buffer.pointer);
|
||||
|
@ -556,12 +556,9 @@ static void end_power_clamp(void)
|
||||
* stop faster.
|
||||
*/
|
||||
clamping = false;
|
||||
if (bitmap_weight(cpu_clamping_mask, num_possible_cpus())) {
|
||||
for_each_set_bit(i, cpu_clamping_mask, num_possible_cpus()) {
|
||||
pr_debug("clamping worker for cpu %d alive, destroy\n",
|
||||
i);
|
||||
stop_power_clamp_worker(i);
|
||||
}
|
||||
for_each_set_bit(i, cpu_clamping_mask, num_possible_cpus()) {
|
||||
pr_debug("clamping worker for cpu %d alive, destroy\n", i);
|
||||
stop_power_clamp_worker(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user