public inbox for linux-hwmon@vger.kernel.org
 help / color / mirror / Atom feed
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


  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