From: Sergio Melas <sergiomelas@gmail.com>
To: linux-hwmon@vger.kernel.org, groeck@gmail.com, sergiomelas@gmail.com
Cc: platform-driver-x86@vger.kernel.org, jdelvare@suse.com
Subject: [PATCH 1/1] hwmon: (yogafan) Add universal Lenovo Yoga/Legion fan driver
Date: Thu, 19 Mar 2026 14:29:20 +0100 [thread overview]
Message-ID: <20260319132920.275755-2-sergiomelas@gmail.com> (raw)
In-Reply-To: <20260319132920.275755-1-sergiomelas@gmail.com>
- Support universal ACPI fan monitoring for up to 8 fans.
- Support various ACPI path naming conventions (FANS, FA2S, FANX).
- Implement a passive RLLag (Rate Limited Lag) filter for jumpy EC data.
- Use dt-based scaling for physical consistency across read intervals.
- Filter parameters verified via tachometer and FOPTD identification.
- Use 10-bit fixed-point integer math to avoid floating-point registers.
- Support KDE 6 Plasma Sensor compatibility and stable S3 sleep cycles.
Signed-off-by: Sergio Melas <sergiomelas@gmail.com>
---
Documentation/hwmon/yoga_fan.rst | 36 +++++
auto_compile_rust_lenovo_drivers.sh | 196 -----------------------
drivers/hwmon/Kconfig | 14 ++
drivers/hwmon/Makefile | 1 +
drivers/hwmon/yoga_fan.c | 237 ++++++++++++++++++++++++++++
5 files changed, 288 insertions(+), 196 deletions(-)
create mode 100644 Documentation/hwmon/yoga_fan.rst
delete mode 100755 auto_compile_rust_lenovo_drivers.sh
create mode 100644 drivers/hwmon/yoga_fan.c
diff --git a/Documentation/hwmon/yoga_fan.rst b/Documentation/hwmon/yoga_fan.rst
new file mode 100644
index 000000000..37eec7647
--- /dev/null
+++ b/Documentation/hwmon/yoga_fan.rst
@@ -0,0 +1,36 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+Kernel driver yogafan
+=====================
+
+Supported chips:
+ * Lenovo Yoga / Legion / IdeaPad Embedded Controllers
+ Prefix: 'yogafan'
+ Addresses: ACPI (Dynamic probing of FANS, FA2S, FANX, etc.)
+
+Description
+-----------
+
+This driver provides fan speed monitoring for modern Lenovo laptops.
+It interfaces with the Lenovo Embedded Controller (EC) via ACPI to
+retrieve fan tachometer data.
+
+Many Lenovo ECs report RPM values that oscillate rapidly due to
+low-resolution internal sampling. To provide a stable reading in
+userspace (e.g., KDE Plasma, MangoHud), this driver implements a
+"Passive RLLag" (Rate Limited Lag) filter.
+
+Filter Logic:
+The filter is "passive," meaning it performs no background work.
+It calculates the state transition based on the ktime delta (dt)
+between read requests. This ensures physical model consistency
+while maximizing CPU sleep states and battery life.
+
+Probing:
+The driver dynamically searches for common Lenovo ACPI fan handles.
+It does not assume a fixed number of fans, making it compatible
+across various Yoga and Legion generations.
+
+Usage Note:
+If your device shows more fans than physically present, the EC is likely
+exposing a virtual or secondary hardware channel.
diff --git a/auto_compile_rust_lenovo_drivers.sh b/auto_compile_rust_lenovo_drivers.sh
deleted file mode 100755
index a3df04f65..000000000
--- a/auto_compile_rust_lenovo_drivers.sh
+++ /dev/null
@@ -1,196 +0,0 @@
-#!/bin/bash
-# auto_compile_rust_lenovo_drivers.sh
-
-##################################################################"
-# #"
-# Kernel Compile Script #"
-# Developed by Sergio Melas 2021-26 #"
-# #"
-# Email: sergiomelas@gmail.com #"
-# Released under GPL V2.0 #"
-# #"
-##################################################################"
-
-
-
-# Fix for dpkg-source email warning
-export DEBFULLNAME="Sergio Melas"
-export DEBEMAIL="sergiomelas@gmail.com"
-
-
-# Your kernel personalization string
-postfix="yoga"
-
-# ANSI Color Codes
-CYAN='\033[0;36m'
-GOLD='\033[1;33m'
-GREEN='\033[0;32m'
-BLUE='\033[1;34m'
-NC='\033[0m'
-
-echo -e "${GOLD} "
-echo -e " ##################################################################"
-echo -e " # #"
-echo -e " # ${CYAN} Kernel Compile Script ${GOLD} #"
-echo -e " # ${CYAN} Developed by Sergio Melas 2021-26 ${GOLD} #"
-echo -e " # #"
-echo -e " # ${BLUE} Email: ${GREEN}sergiomelas@gmail.com ${GOLD} #"
-echo -e " # ${BLUE} Released under GPL V2.0 ${GOLD} #"
-echo -e " # #"
-echo -e " ##################################################################"
-echo -e " ${NC}"
-
-
-
-# 1. Change to local directory
-VAR=$0
-DIR="$(dirname "${VAR}")"
-cd "${DIR}"
-
-# 2. Automated Architecture Detection
-ARCH_TYPE=$(uname -m)
-case "$ARCH_TYPE" in
- x86_64) ARCH_SUFFIX="amd64" ;;
- aarch64) ARCH_SUFFIX="arm64" ;;
- armv7l) ARCH_SUFFIX="armhf" ;;
- i386|i686) ARCH_SUFFIX="i386" ;;
- *) ARCH_SUFFIX="$ARCH_TYPE" ;;
-esac
-
-# 3. Combine for the final string
-full_postfix="${postfix}-${ARCH_SUFFIX}"
-
-
-# Admin login
-sudo ls >/dev/null
-
-# Install libs
-sudo apt-get install -y build-essential libncurses-dev bison flex libssl-dev libelf-dev dwarves debhelper rustc rust-src bindgen rustfmt rust-clippy clang libdw-dev:native bc
-
-# Configure kernel base
-LATEST_CONFIG=$(ls -v /boot/config-* 2>/dev/null | grep -v "$postfix" | tail -n 1)
-if [ -n "$LATEST_CONFIG" ]; then
- cp -v "$LATEST_CONFIG" .config
-else
- cp -v /boot/config-$(uname -r) .config
-fi
-
-# --- DRIVER INJECTION (Yoga Fan v4.3) ---
-echo -e "${BLUE}Injecting Yoga Fan Driver v4.3...${NC}"
-SOURCE_CODE="../../Lenovo Drivers/yoga_fan.c"
-TARGET_FILE="./drivers/hwmon/yoga_fan.c"
-
-if [ -f "$SOURCE_CODE" ]; then
- cp "$SOURCE_CODE" "$TARGET_FILE"
-else
- echo -e "${GOLD}Error: Source not found!${NC}"
- exit 1
-fi
-
-if ! grep -q "yoga_fan.o" ./drivers/hwmon/Makefile; then
- echo "obj-\$(CONFIG_SENSORS_YOGA_FAN) += yoga_fan.o" >> ./drivers/hwmon/Makefile
-fi
-
-if ! grep -q "config SENSORS_YOGA_FAN" ./drivers/hwmon/Kconfig; then
- cat <<EOF >> ./drivers/hwmon/Kconfig
-config SENSORS_YOGA_FAN
- tristate "Lenovo Yoga Fan Hardware Monitoring"
- depends on ACPI && HWMON
- help
- Support for fan RPM on modern Lenovo laptops.
-EOF
-fi
-
-# --- START OF OPTIMIZED MODULE CONFIGURATION (YOGA 14c ACN) ---
-
-# 1. AMD Zen 3 & Power (For Ryzen 5800U)
-scripts/config --set-val CONFIG_MZEN3 y # Zen 3 microarchitecture optimization
-scripts/config --enable CONFIG_X86_AMD_PSTATE # Modern AMD P-State driver
-scripts/config --set-val CONFIG_X86_AMD_PSTATE_DEFAULT_MODE 3 # "Active" mode for performance/watt balance
-scripts/config --enable CONFIG_AMD_PMC # Vital for s2idle (Modern Standby) sleep support
-scripts/config --enable CONFIG_SENSORS_K10TEMP # Accurate CPU temperature monitoring
-scripts/config --enable CONFIG_PINCTRL_AMD # Crucial for Touchpad/GPIO interrupts
-
-# 2. Graphics (AMD Radeon Vega/Cezanne)
-scripts/config --enable CONFIG_DRM_AMDGPU # Main Radeon driver
-scripts/config --enable CONFIG_DRM_AMDGPU_USERPTR # Support for OpenCL/ROCm
-scripts/config --enable CONFIG_DRM_DISPLAY_HDMI_HELPER # Essential for HDMI/HDR
-scripts/config --enable CONFIG_DRM_DISPLAY_DP_HELPER # Essential for DisplayPort/USB-C Alt Mode
-
-# 3. Lenovo Yoga 14c Hardware Logic (The Fan & Sensor Fix)
-scripts/config --set-val CONFIG_HWMON y # REQUIRED: Base framework for all sensors
-scripts/config --set-val CONFIG_ACPI_WMI y # REQUIRED: Bridge for Lenovo BIOS
-scripts/config --enable CONFIG_WMI_BMOF # REQUIRED: Interpret ACPI binary data
-scripts/config --set-val CONFIG_SENSORS_YOGA_FAN m # Compiles Yoga Fan driver as module
-scripts/config --enable CONFIG_LEDS_CLASS # Needed for status LEDs
-scripts/config --enable CONFIG_LEDS_TRIGGERS # Allows hardware events to trigger LEDs
-scripts/config --set-val CONFIG_IDEAPAD_LAPTOP y # Main driver for Yoga Fn keys
-scripts/config --enable CONFIG_LENOVO_YMC # Yoga Mode Control (Tablet mode)
-scripts/config --enable CONFIG_ACPI_PLATFORM_PROFILE # Enables Fn+Q power modes
-scripts/config --enable CONFIG_AMD_SFH_HID # Needed for screen auto-rotation
-scripts/config --enable CONFIG_HID_WACOM # Supports the internal stylus
-scripts/config --enable CONFIG_HID_MULTITOUCH # Enables 10-point touch screen
-
-# 4. Enable Rust (2026 Toolchain)
-scripts/config --set-val CONFIG_RUST y # Enables Rust infrastructure
-scripts/config --set-val MODVERSIONS n # Required for Rust compatibility
-scripts/config --set-val GENDWARFKSYMS y # Safe Rust module loading
-scripts/config --set-val RANDSTRUCT n # Prevents C-to-Rust memory mismatches
-scripts/config --set-val DEBUG_INFO_BTF n # Prevents Rust symbol length conflicts
-
-# 5. Rust-Powered "Blue Screen" (DRM Panic)
-scripts/config --enable CONFIG_DRM_PANIC # Graphical panic core
-scripts/config --enable CONFIG_DRM_PANIC_SCREEN_USER # Blue background
-scripts/config --enable CONFIG_DRM_PANIC_SCREEN_QR_CODE # Rust-generated scannable QR code
-
-# 6. Build Tweaks & Strict Debug Stripping
-scripts/config --set-str CONFIG_LOCALVERSION "-$full_postfix" # Identifies as -yoga-amd64
-scripts/config --set-val CONFIG_LOCALVERSION_AUTO n # Cleaner versioning
-scripts/config --undefine CONFIG_DEBUG_INFO # Strip primary debug symbols
-scripts/config --undefine CONFIG_DEBUG_INFO_BTF # Disable BPF Type Format bloat
-scripts/config --set-val CONFIG_DEBUG_INFO_NONE y # Explicitly select 'None'
-scripts/config --disable CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT # Kills bloated symbols
-scripts/config --disable CONFIG_DEBUG_INFO_DWARF4 # Disables old DWARF v4
-scripts/config --disable CONFIG_DEBUG_INFO_DWARF5 # Disables heavy DWARF v5
-scripts/config --disable CONFIG_GDB_SCRIPTS # No Python helpers
-
-# --- END OF OPTIMIZED MODULE CONFIGURATION ---
-
-make olddefconfig
-
-# Get kernel version (e.g., 7.0.0-rc4)
-VERSION_BASE=$(make kernelversion)
-FULL_VER="${VERSION_BASE}-${full_postfix}"
-PKG_VER="${VERSION_BASE}-${full_postfix}"
-
-echo -e "${BLUE}Starting Kernel Build (uname -r: ${FULL_VER})${NC}"
-
-# Compile using your naming logic
-make -j$(nproc) bindeb-pkg \
- KDEB_PKGVERSION="${PKG_VER}" \
- KDEB_SOURCENAME=linux-upstream \
- DEBUG_INFO=n \
- NO_VMLINUX_DEBUG=1
-
-# Change to parent directory
-cd ../
-
-echo -e "${BLUE}Post-Processing: Cleaning up filenames...${NC}"
-
-# Perform the exact renaming to remove the redundant version_arch string
-# e.g., linux-image-VER_VER_amd64.deb -> linux-image-VER.deb
-mv "linux-image-${FULL_VER}_${PKG_VER}_${ARCH_SUFFIX}.deb" "linux-image-${FULL_VER}.deb"
-mv "linux-headers-${FULL_VER}_${PKG_VER}_${ARCH_SUFFIX}.deb" "linux-headers-${FULL_VER}.deb"
-mv "linux-libc-dev_${PKG_VER}_${ARCH_SUFFIX}.deb" "linux-libc-dev_${FULL_VER}.deb"
-
-# Clean up
-rm -f *.buildinfo *.changes
-
-# Install the cleaned packages
-sudo apt-mark unhold linux-libc-dev
-sudo dpkg -i "linux-image-${FULL_VER}.deb" \
- "linux-headers-${FULL_VER}.deb" \
- "linux-libc-dev_${FULL_VER}.deb"
-sudo apt-mark hold linux-libc-dev
-
-echo -e "${CYAN}Success! kernel ${FULL_VER} installed.${NC}"
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 342aa97bf..7d938308d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2454,6 +2454,20 @@ config SENSORS_VEXPRESS
the ARM Ltd's Versatile Express platform. It can provide wide
range of information like temperature, power, energy.
+config SENSORS_YOGAFAN
+ tristate "Lenovo Yoga/Legion Fan Monitor"
+ depends on ACPI && DMI
+ help
+ If you say yes here you get support for the fan sensors on
+ modern Lenovo Yoga, Legion, and IdeaPad laptops.
+
+ This driver implements a passive RLLag filter to smooth out
+ oscillating RPM data reported by the Embedded Controller without
+ the power overhead of a background worker.
+
+ This driver can also be built as a module. If so, the module
+ will be called yoga_fan.
+
config SENSORS_VIA_CPUTEMP
tristate "VIA CPU temperature sensor"
depends on X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 7ac7711f9..d8d4ff834 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -252,3 +252,4 @@ obj-$(CONFIG_PMBUS) += pmbus/
ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG
obj-$(CONFIG_SENSORS_YOGA_FAN) += yoga_fan.o
+
diff --git a/drivers/hwmon/yoga_fan.c b/drivers/hwmon/yoga_fan.c
new file mode 100644
index 000000000..31e657146
--- /dev/null
+++ b/drivers/hwmon/yoga_fan.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/**
+ * yoga_fan.c - Lenovo Yoga/Legion Fan Hardware Monitoring Driver
+ *
+ * Provides fan speed monitoring for Lenovo Yoga, Legion, and IdeaPad
+ * laptops by interfacing with the Embedded Controller (EC) via ACPI.
+ *
+ * The driver implements a passive discrete-time first-order lag filter
+ * with slew-rate limiting (RLLag). This filter addresses low-resolution
+ * tachometer sampling in the EC by smoothing RPM readings based on
+ * the time delta (dt) between userspace requests, ensuring physical
+ * consistency without background task overhead.
+ *
+ * Copyright (C) 2021-2026 Sergio Melas <sergiomelas@gmail.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/init.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define DRVNAME "yogafan"
+#define MAX_FANS 8
+
+/* Filter Configuration Constants */
+#define TAU_MS 3000 /* Time constant for the first-order lag (ms) */
+#define MAX_SLEW_RPM_S 100 /* Maximum allowed change in RPM per second */
+
+struct yoga_fan_data {
+ const char *active_paths[MAX_FANS];
+ long filtered_val[MAX_FANS];
+ ktime_t last_update[MAX_FANS];
+ int fan_count;
+};
+
+/**
+ * apply_rllag_filter - Discrete-time filter update (Passive)
+ * @data: pointer to driver data
+ * @idx: fan index
+ * @raw_rpm: new raw value from ACPI
+ */
+static void apply_rllag_filter(struct yoga_fan_data *data, int idx, long raw_rpm)
+{
+ ktime_t now = ktime_get();
+ s64 dt_ms;
+ long delta, step, limit, alpha;
+
+ if (data->last_update[idx] == 0) {
+ data->filtered_val[idx] = raw_rpm;
+ data->last_update[idx] = now;
+ return;
+ }
+
+ dt_ms = ktime_to_ms(ktime_sub(now, data->last_update[idx]));
+
+ if (dt_ms > 5000) {
+ data->filtered_val[idx] = raw_rpm;
+ data->last_update[idx] = now;
+ return;
+ }
+
+ if (dt_ms < 1)
+ return;
+
+ delta = raw_rpm - data->filtered_val[idx];
+
+ /* Alpha = dt / (Tau + dt) using 10-bit fixed point math */
+ alpha = (dt_ms << 10) / (TAU_MS + dt_ms);
+ step = (delta * alpha) >> 10;
+
+ /* Slew Limit = (MaxSlew * dt) / 1000 */
+ limit = (MAX_SLEW_RPM_S * (long)dt_ms) / 1000;
+
+ if (step > limit)
+ step = limit;
+ else if (step < -limit)
+ step = -limit;
+
+ data->filtered_val[idx] += step;
+
+ if (data->filtered_val[idx] < 50)
+ data->filtered_val[idx] = 0;
+
+ data->last_update[idx] = now;
+}
+
+static int yoga_fan_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ struct yoga_fan_data *data = dev_get_drvdata(dev);
+ unsigned long long raw_acpi;
+ acpi_status status;
+ long rpm;
+
+ if (type != hwmon_fan || attr != hwmon_fan_input)
+ return -EOPNOTSUPP;
+
+ status = acpi_evaluate_integer(NULL, (char *)data->active_paths[channel], NULL, &raw_acpi);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ rpm = (raw_acpi > 0 && raw_acpi <= 255) ? ((long)raw_acpi * 100) : (long)raw_acpi;
+
+ apply_rllag_filter(data, channel, rpm);
+
+ *val = data->filtered_val[channel];
+ return 0;
+}
+
+static umode_t yoga_fan_is_visible(const void *data, enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ const struct yoga_fan_data *fan_data = data;
+
+ if (type == hwmon_fan && channel < fan_data->fan_count)
+ return 0444;
+
+ return 0;
+}
+
+static const struct hwmon_ops yoga_fan_hwmon_ops = {
+ .is_visible = yoga_fan_is_visible,
+ .read = yoga_fan_read,
+};
+
+static const struct hwmon_channel_info *yoga_fan_info[] = {
+ HWMON_CHANNEL_INFO(fan,
+ HWMON_F_INPUT, HWMON_F_INPUT, HWMON_F_INPUT, HWMON_F_INPUT,
+ HWMON_F_INPUT, HWMON_F_INPUT, HWMON_F_INPUT, HWMON_F_INPUT),
+ NULL
+};
+
+static const struct hwmon_chip_info yoga_fan_chip_info = {
+ .ops = &yoga_fan_hwmon_ops,
+ .info = yoga_fan_info,
+};
+
+static int yoga_fan_probe(struct platform_device *pdev)
+{
+ struct yoga_fan_data *data;
+ struct device *hwmon_dev;
+ acpi_handle handle;
+ int i;
+
+ static const char * const fan_paths[] = {
+ "\\_SB.PCI0.LPC0.EC0.FANS", // Primary Fan (Yoga 14c)
+ "\\_SB.PCI0.LPC0.EC0.FA2S", // Secondary Fan (Legion)
+ "\\_SB.PCI0.LPC0.EC0.FAN0", // IdeaPad / Slim
+ "\\_SB.PCI0.LPC.EC.FAN0", // Legacy
+ "\\_SB.PCI0.LPC0.EC.FAN0", // Alternate
+ };
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->fan_count = 0;
+
+ for (i = 0; i < ARRAY_SIZE(fan_paths); i++) {
+ if (ACPI_SUCCESS(acpi_get_handle(NULL, (char *)fan_paths[i], &handle))) {
+ data->active_paths[data->fan_count] = fan_paths[i];
+ data->fan_count++;
+
+ if (data->fan_count >= MAX_FANS)
+ break;
+ }
+ }
+
+ if (data->fan_count == 0)
+ return -ENODEV;
+
+ dev_set_drvdata(&pdev->dev, data);
+
+ hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, DRVNAME,
+ data, &yoga_fan_chip_info, NULL);
+
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+
+static struct platform_driver yoga_fan_driver = {
+ .driver = {
+ .name = DRVNAME,
+ },
+ .probe = yoga_fan_probe,
+};
+
+static struct platform_device *yoga_fan_device;
+
+static const struct dmi_system_id yoga_dmi_table[] __initconst = {
+ {
+ .ident = "Lenovo",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ },
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(dmi, yoga_dmi_table);
+
+static int __init yoga_fan_init(void)
+{
+ int ret;
+
+ if (!dmi_check_system(yoga_dmi_table))
+ return -ENODEV;
+
+ ret = platform_driver_register(&yoga_fan_driver);
+ if (ret)
+ return ret;
+
+ yoga_fan_device = platform_device_register_simple(DRVNAME, 0, NULL, 0);
+ if (IS_ERR(yoga_fan_device)) {
+ platform_driver_unregister(&yoga_fan_driver);
+ return PTR_ERR(yoga_fan_device);
+ }
+
+ return 0;
+}
+
+static void __exit yoga_fan_exit(void)
+{
+ platform_device_unregister(yoga_fan_device);
+ platform_driver_unregister(&yoga_fan_driver);
+}
+
+module_init(yoga_fan_init);
+module_exit(yoga_fan_exit);
+
+MODULE_AUTHOR("Sergio Melas <sergiomelas@gmail.com>");
+MODULE_DESCRIPTION("Lenovo Yoga/Legion Fan Monitor Driver");
+MODULE_LICENSE("GPL");
--
2.53.0
next prev parent reply other threads:[~2026-03-19 13:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-19 13:29 [PATCH 0/1] Sergio Melas
2026-03-19 13:29 ` Sergio Melas [this message]
2026-03-19 15:59 ` [PATCH 1/1] hwmon: (yogafan) Add universal Lenovo Yoga/Legion fan driver Guenter Roeck
2026-03-19 17:03 ` Guenter Roeck
2026-03-19 19:37 ` [PATCH 0/1] Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260319132920.275755-2-sergiomelas@gmail.com \
--to=sergiomelas@gmail.com \
--cc=groeck@gmail.com \
--cc=jdelvare@suse.com \
--cc=linux-hwmon@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox