diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-10-31 15:28:37 -1000 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-10-31 15:28:37 -1000 |
commit | 4ac4677fdb76f644e09a6331bab65919b85f617d (patch) | |
tree | 99be7c9b47742ee0ef53fc0bd4c8f9ce98caaacf /tools/testing | |
parent | 89ed67ef126c4160349c1b96fdb775ea6170ac90 (diff) | |
parent | 607218deac6e29c52f4ce521ed467a0d75090a0d (diff) | |
download | lwn-4ac4677fdb76f644e09a6331bab65919b85f617d.tar.gz lwn-4ac4677fdb76f644e09a6331bab65919b85f617d.zip |
Merge tag 'thermal-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull thermal control updates from Rafael Wysocki:
"These further rework the ACPI thermal driver, after the changes made
to it in the previous cycle, to make it easier to grasp, get rid of
redundant pieces of internal data structures and eliminate its
reliance on a specific ordering of trip point objects in the thermal
core, make thermal core adjustments needed for the ACPI thermal driver
rework, modify the thermal governor interface so as to use trip
pointers for representing trip points in it, switch over multiple
thermal drivers to using void platform driver remove callbacks, add
support for 2 hardware features to the Intel int340x thermal driver,
add support for new hardware on ARM platforms, update documentation,
fix problems, clean up code and update the MAINTAINERS record for
thermal control.
Specifics:
- Untangle the initialization and updates of passive and active trip
points in the ACPI thermal driver (Rafael Wysocki)
- Reduce code duplication related to the initialization and updates
of trip points in the ACPI thermal driver (Rafael Wysocki)
- Use trip pointers for cooling device binding in the ACPI thermal
driver (Rafael Wysocki)
- Simplify critical and hot trips representation in the ACPI thermal
driver (Rafael Wysocki)
- Use trip pointers in thermal governors and in the related part of
the thermal core (Rafael Wysocki)
- Drop the trips_disabled bitmask that has become redundant from the
thermal core (Rafael Wysocki)
- Avoid updating trip points when the thermal zone temperature falls
into a trip point's hysteresis range (ícolas F. R. A. Prado)
- Add power floor notifications support to the int340x thermal
control driver (Srinivas Pandruvada)
- Rework updating trip points in the int340x thermal driver so that
it does not access thermal zone internals directly (Rafael
Wysocki)
- Use param_get_byte() instead of param_get_int() as the max_idle
module parameter .get() callback in the Intel powerclamp thermal
driver to avoid possible out-of-bounds access (David Arcari)
- Add workload hints support to the int340x thermal driver (Srinivas
Pandruvada)
- Add support for Mediatek LVTS MT8192 along with suspend/resume
routines (Balsam Chihi)
- Fix probe for THERMAL_V2 in the Mediatek LVTS driver (Markus
Schneider-Pargmann)
- Remove duplicate error message from the max76620 driver when
thermal_of_zone_register() fails (Thierry Reding)
- Add i.MX7D compatible bindings to fix a warning from dtbs_check for
the imx6ul platform (Alexander Stein)
- Add sa8775p compatible to the QCom tsens driver (Priyansh Jain)
- Fix error check in lvts_debugfs_init() to be against PTR_ERR() in
the LVTS Mediatek driver (Minjie Du)
- Remove unused variable in thermal/tools (Kuan-Wei Chiu)
- Document the imx8dl thermal sensor (Fabio Estevam)
- Add variable names in callback prototypes to prevent warning from
checkpatch.pl in the imx8mm driver (Bragatheswaran Manickavel)
- Add missing unevaluatedProperties on child node schemas for
tegra124 (Rob Herring)
- Add mt7988 support to the Mediatek LVTS driver (Frank Wunderlich)"
* tag 'thermal-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (111 commits)
thermal: ACPI: Include the right header file
thermal: core: Don't update trip points inside the hysteresis range
thermal: core: Pass trip pointer to governor throttle callback
thermal: gov_step_wise: Fold update_passive_instance() into its caller
thermal: gov_power_allocator: Use trip pointers instead of trip indices
thermal: gov_fair_share: Rearrange get_trip_level()
thermal: trip: Define for_each_trip() macro
thermal: trip: Simplify computing trip indices
thermal/qcom/tsens: Drop ops_v0_1
thermal/drivers/mediatek/lvts_thermal: Update calibration data documentation
thermal/drivers/mediatek/lvts_thermal: Add mt8192 support
thermal/drivers/mediatek/lvts_thermal: Add suspend and resume
dt-bindings: thermal: mediatek: Add LVTS thermal controller definition for mt8192
thermal/drivers/mediatek: Fix probe for THERMAL_V2
thermal/drivers/max77620: Remove duplicate error message
dt-bindings: timer: add imx7d compatible
dt-bindings: net: microchip: Allow nvmem-cell usage
dt-bindings: imx-thermal: Add #thermal-sensor-cells property
dt-bindings: thermal: tsens: Add sa8775p compatible
thermal/drivers/mediatek/lvts_thermal: Fix error check in lvts_debugfs_init()
...
Diffstat (limited to 'tools/testing')
5 files changed, 291 insertions, 0 deletions
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 1a21d6beebc6..e4e87997e091 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -85,6 +85,8 @@ TARGETS += syscall_user_dispatch TARGETS += sysctl TARGETS += tc-testing TARGETS += tdx +TARGETS += thermal/intel/power_floor +TARGETS += thermal/intel/workload_hint TARGETS += timens ifneq (1, $(quicktest)) TARGETS += timers diff --git a/tools/testing/selftests/thermal/intel/power_floor/Makefile b/tools/testing/selftests/thermal/intel/power_floor/Makefile new file mode 100644 index 000000000000..9b88e57dbba5 --- /dev/null +++ b/tools/testing/selftests/thermal/intel/power_floor/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +ifndef CROSS_COMPILE +uname_M := $(shell uname -m 2>/dev/null || echo not) +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) + +ifeq ($(ARCH),x86) +TEST_GEN_PROGS := power_floor_test + +include ../../../lib.mk + +endif +endif diff --git a/tools/testing/selftests/thermal/intel/power_floor/power_floor_test.c b/tools/testing/selftests/thermal/intel/power_floor/power_floor_test.c new file mode 100644 index 000000000000..0326b39a11b9 --- /dev/null +++ b/tools/testing/selftests/thermal/intel/power_floor/power_floor_test.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define _GNU_SOURCE + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <poll.h> +#include <signal.h> + +#define POWER_FLOOR_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/power_limits/power_floor_enable" +#define POWER_FLOOR_STATUS_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/power_limits/power_floor_status" + +void power_floor_exit(int signum) +{ + int fd; + + /* Disable feature via sysfs knob */ + + fd = open(POWER_FLOOR_ENABLE_ATTRIBUTE, O_RDWR); + if (fd < 0) { + perror("Unable to open power floor enable file\n"); + exit(1); + } + + if (write(fd, "0\n", 2) < 0) { + perror("Can' disable power floor notifications\n"); + exit(1); + } + + printf("Disabled power floor notifications\n"); + + close(fd); +} + +int main(int argc, char **argv) +{ + struct pollfd ufd; + char status_str[3]; + int fd, ret; + + if (signal(SIGINT, power_floor_exit) == SIG_IGN) + signal(SIGINT, SIG_IGN); + if (signal(SIGHUP, power_floor_exit) == SIG_IGN) + signal(SIGHUP, SIG_IGN); + if (signal(SIGTERM, power_floor_exit) == SIG_IGN) + signal(SIGTERM, SIG_IGN); + + /* Enable feature via sysfs knob */ + fd = open(POWER_FLOOR_ENABLE_ATTRIBUTE, O_RDWR); + if (fd < 0) { + perror("Unable to open power floor enable file\n"); + exit(1); + } + + if (write(fd, "1\n", 2) < 0) { + perror("Can' enable power floor notifications\n"); + exit(1); + } + + close(fd); + + printf("Enabled power floor notifications\n"); + + while (1) { + fd = open(POWER_FLOOR_STATUS_ATTRIBUTE, O_RDONLY); + if (fd < 0) { + perror("Unable to power floor status file\n"); + exit(1); + } + + if ((lseek(fd, 0L, SEEK_SET)) < 0) { + fprintf(stderr, "Failed to set pointer to beginning\n"); + exit(1); + } + + if (read(fd, status_str, sizeof(status_str)) < 0) { + fprintf(stderr, "Failed to read from:%s\n", + POWER_FLOOR_STATUS_ATTRIBUTE); + exit(1); + } + + ufd.fd = fd; + ufd.events = POLLPRI; + + ret = poll(&ufd, 1, -1); + if (ret < 0) { + perror("poll error"); + exit(1); + } else if (ret == 0) { + printf("Poll Timeout\n"); + } else { + if ((lseek(fd, 0L, SEEK_SET)) < 0) { + fprintf(stderr, "Failed to set pointer to beginning\n"); + exit(1); + } + + if (read(fd, status_str, sizeof(status_str)) < 0) + exit(0); + + printf("power floor status: %s\n", status_str); + } + + close(fd); + } +} diff --git a/tools/testing/selftests/thermal/intel/workload_hint/Makefile b/tools/testing/selftests/thermal/intel/workload_hint/Makefile new file mode 100644 index 000000000000..37ff3286283b --- /dev/null +++ b/tools/testing/selftests/thermal/intel/workload_hint/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +ifndef CROSS_COMPILE +uname_M := $(shell uname -m 2>/dev/null || echo not) +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) + +ifeq ($(ARCH),x86) +TEST_GEN_PROGS := workload_hint_test + +include ../../../lib.mk + +endif +endif diff --git a/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c b/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c new file mode 100644 index 000000000000..217c3a641c53 --- /dev/null +++ b/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define _GNU_SOURCE + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <poll.h> +#include <signal.h> + +#define WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/notification_delay_ms" +#define WORKLOAD_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_hint_enable" +#define WORKLOAD_TYPE_INDEX_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_type_index" + +static const char * const workload_types[] = { + "idle", + "battery_life", + "sustained", + "bursty", + NULL +}; + +#define WORKLOAD_TYPE_MAX_INDEX 3 + +void workload_hint_exit(int signum) +{ + int fd; + + /* Disable feature via sysfs knob */ + + fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR); + if (fd < 0) { + perror("Unable to open workload type feature enable file\n"); + exit(1); + } + + if (write(fd, "0\n", 2) < 0) { + perror("Can' disable workload hints\n"); + exit(1); + } + + printf("Disabled workload type prediction\n"); + + close(fd); +} + +int main(int argc, char **argv) +{ + struct pollfd ufd; + char index_str[4]; + int fd, ret, index; + char delay_str[64]; + int delay = 0; + + printf("Usage: workload_hint_test [notification delay in milli seconds]\n"); + + if (argc > 1) { + ret = sscanf(argv[1], "%d", &delay); + if (ret < 0) { + printf("Invalid delay\n"); + exit(1); + } + + printf("Setting notification delay to %d ms\n", delay); + if (delay < 0) + exit(1); + + sprintf(delay_str, "%s\n", argv[1]); + + sprintf(delay_str, "%s\n", argv[1]); + fd = open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE, O_RDWR); + if (fd < 0) { + perror("Unable to open workload notification delay\n"); + exit(1); + } + + if (write(fd, delay_str, strlen(delay_str)) < 0) { + perror("Can't set delay\n"); + exit(1); + } + + close(fd); + } + + if (signal(SIGINT, workload_hint_exit) == SIG_IGN) + signal(SIGINT, SIG_IGN); + if (signal(SIGHUP, workload_hint_exit) == SIG_IGN) + signal(SIGHUP, SIG_IGN); + if (signal(SIGTERM, workload_hint_exit) == SIG_IGN) + signal(SIGTERM, SIG_IGN); + + /* Enable feature via sysfs knob */ + fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR); + if (fd < 0) { + perror("Unable to open workload type feature enable file\n"); + exit(1); + } + + if (write(fd, "1\n", 2) < 0) { + perror("Can' enable workload hints\n"); + exit(1); + } + + close(fd); + + printf("Enabled workload type prediction\n"); + + while (1) { + fd = open(WORKLOAD_TYPE_INDEX_ATTRIBUTE, O_RDONLY); + if (fd < 0) { + perror("Unable to open workload type file\n"); + exit(1); + } + + if ((lseek(fd, 0L, SEEK_SET)) < 0) { + fprintf(stderr, "Failed to set pointer to beginning\n"); + exit(1); + } + + if (read(fd, index_str, sizeof(index_str)) < 0) { + fprintf(stderr, "Failed to read from:%s\n", + WORKLOAD_TYPE_INDEX_ATTRIBUTE); + exit(1); + } + + ufd.fd = fd; + ufd.events = POLLPRI; + + ret = poll(&ufd, 1, -1); + if (ret < 0) { + perror("poll error"); + exit(1); + } else if (ret == 0) { + printf("Poll Timeout\n"); + } else { + if ((lseek(fd, 0L, SEEK_SET)) < 0) { + fprintf(stderr, "Failed to set pointer to beginning\n"); + exit(1); + } + + if (read(fd, index_str, sizeof(index_str)) < 0) + exit(0); + + ret = sscanf(index_str, "%d", &index); + if (ret < 0) + break; + if (index > WORKLOAD_TYPE_MAX_INDEX) + printf("Invalid workload type index\n"); + else + printf("workload type:%s\n", workload_types[index]); + } + + close(fd); + } +} |