From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E60173AE187 for ; Fri, 22 May 2026 13:22:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.10 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779456126; cv=none; b=RBatUHj+qNoKLfU5+LAgmBCOKm5HPfr+ZvESMBGNIl1yYVEYNgBsT7LTyJTY3rsQfZFCYS24qfN5qHU03f5P1fDFnuOGOrzla6mwRvFrwYAKMu+oCX1AQIGnfMyrmbqgcMCoEIzS5k+vZYpXuNlmBkACpZaLihLxq+P1H5EPoE8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779456126; c=relaxed/simple; bh=tMxusWvO1slxEuXBe65PgVH/upo3TTC+kWfW/PeZYOI=; h=From:Date:To:cc:Subject:In-Reply-To:Message-ID:References: MIME-Version:Content-Type; b=MG3glyj3gjTw0ax/IpND6xcOvaispaqzG9wVefIXMNxEzxeF8ZiE/OGKIpCmCkhQ0nwLs76o9sHHxkKBQKyfbBARKkNdwRXd8t3Cd7eDZAOo1PAAAgo1dr5cuT9A1alI7Q7X0XRbaLU9JQ4MCUmX87KyunKwcmG0Y5/T3DNdAt0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=jy/pXUB4; arc=none smtp.client-ip=198.175.65.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="jy/pXUB4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1779456123; x=1810992123; h=from:date:to:cc:subject:in-reply-to:message-id: references:mime-version; bh=tMxusWvO1slxEuXBe65PgVH/upo3TTC+kWfW/PeZYOI=; b=jy/pXUB4TSMnw5sB+IBNN+BzQExILzq9r1fZ0wVcqj7MYT/SGgTr3r9q vw+r98AAPE8XqIcOQ+O3X8e0khYr++ZTIZk6WH9tQfnCuXblQ65tY8Aa8 CGVkStEHQ1SG64D7Uwg+WE/WXSMAJRXJQnZ1jR+3nHgVWqscRE7JzA+GS cv3IHBIqyVgCjt3jAeJKuN2x4mzJyUvX3QEvhEr9M7xkzR4RPGVe5ej0W kuiCpY+RTKVRTV3lpjGb7sl47zC8SmUhMuYXOgUJ38hyF8hoYi2AyxE+u ng7uquUq55rHhHY4yxFpp7tv1XsI2b8r06JY7nSoR4EXPqfcGPTsTnyGV g==; X-CSE-ConnectionGUID: /P32IU9fQHy2/P8XaCUkjg== X-CSE-MsgGUID: RyfzwIlKSeekqCjsEGA3pg== X-IronPort-AV: E=McAfee;i="6800,10657,11794"; a="97807048" X-IronPort-AV: E=Sophos;i="6.24,162,1774335600"; d="scan'208";a="97807048" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2026 06:22:01 -0700 X-CSE-ConnectionGUID: pp6aqz2aTG2ccsUDaNwrbg== X-CSE-MsgGUID: OvjnkOWmRRu1icypJSJN+A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.24,162,1774335600"; d="scan'208";a="238313370" Received: from ijarvine-mobl1.ger.corp.intel.com (HELO localhost) ([10.245.245.16]) by fmviesa008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2026 06:21:59 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Fri, 22 May 2026 16:21:55 +0300 (EEST) To: Shyam Sundar S K cc: Hans de Goede , platform-driver-x86@vger.kernel.org, mario.limonciello@amd.com, Sanket.Goswami@amd.com Subject: Re: [PATCH v5 1/8] platform/x86/amd/pmf: Add util layer and userspace character device interface In-Reply-To: <20260520185424.770772-2-Shyam-sundar.S-k@amd.com> Message-ID: <2a1643c1-919b-00f9-2f4d-91bbed9c7151@linux.intel.com> References: <20260520185424.770772-1-Shyam-sundar.S-k@amd.com> <20260520185424.770772-2-Shyam-sundar.S-k@amd.com> Precedence: bulk X-Mailing-List: platform-driver-x86@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII On Thu, 21 May 2026, Shyam Sundar S K wrote: > Add a util layer to AMD PMF that exposes a minimal userspace interface > via a character device for metrics monitoring and feature discovery. > > This creates /dev/amdpmf_interface with basic ioctl support to retrieve > PMF metrics such as: > * Power source and power slider position > * Platform type, lid state, and user presence > * Skin temperature and ambient light > * BIOS input parameters (1-10) > * Graphics workload metrics > * CPU C-state residency (average and maximum) > * Socket power consumption > > The interface enables smoother integration with userspace tools such as > AMD SystemDeck [1], which is widely used for monitoring and controlling > power and thermal behavior on AMD platforms. These tools help designers > keep major components within thermal limits to ensure proper operation > and enhance overall system stability and reliability. > > The feature is gated behind the CONFIG_AMD_PMF_UTIL_SUPPORT Kconfig > option, allowing it to be disabled if not needed. The implementation > uses existing PMF infrastructure to populate data from the TA (Trusted > Application) shared memory buffer. > > Link: https://docs.amd.com/v/u/en-US/68773_0.50 [1] > > Co-developed-by: Sanket Goswami > Signed-off-by: Sanket Goswami > Signed-off-by: Shyam Sundar S K > --- > drivers/platform/x86/amd/pmf/Kconfig | 10 ++++ > drivers/platform/x86/amd/pmf/Makefile | 2 + > drivers/platform/x86/amd/pmf/core.c | 5 ++ > drivers/platform/x86/amd/pmf/pmf.h | 9 ++++ > drivers/platform/x86/amd/pmf/util.c | 67 +++++++++++++++++++++++++++ > include/uapi/linux/amd-pmf.h | 60 ++++++++++++++++++++++++ > 6 files changed, 153 insertions(+) > create mode 100644 drivers/platform/x86/amd/pmf/util.c > create mode 100644 include/uapi/linux/amd-pmf.h > > diff --git a/drivers/platform/x86/amd/pmf/Kconfig b/drivers/platform/x86/amd/pmf/Kconfig > index 25b8f7ae3abd..ad4faf18de47 100644 > --- a/drivers/platform/x86/amd/pmf/Kconfig > +++ b/drivers/platform/x86/amd/pmf/Kconfig > @@ -30,3 +30,13 @@ config AMD_PMF_DEBUG > in the PMF config store. > > Say Y here to enable more debug logs and Say N here if you are not sure. > + > +config AMD_PMF_UTIL_SUPPORT > + bool "AMD PMF Util layer support" > + depends on AMD_PMF > + help > + Enabling this option provides a character device for userspace to capture > + PMF features (Smart PC Builder, Auto Mode, Static Power Slider, Dynamic > + Power Slider AC/DC) along with PMF metrics from the AMD PMF driver. > + > + Say Y here to enable it and Say N here if you are not sure. > diff --git a/drivers/platform/x86/amd/pmf/Makefile b/drivers/platform/x86/amd/pmf/Makefile > index 5978464e0eb7..bf7aad80b9e9 100644 > --- a/drivers/platform/x86/amd/pmf/Makefile > +++ b/drivers/platform/x86/amd/pmf/Makefile > @@ -8,3 +8,5 @@ obj-$(CONFIG_AMD_PMF) += amd-pmf.o > amd-pmf-y := core.o acpi.o sps.o \ > auto-mode.o cnqf.o \ > tee-if.o spc.o > +# Build util.c only when AMD_PMF_UTIL_SUPPORT is enabled > +amd-pmf-$(CONFIG_AMD_PMF_UTIL_SUPPORT) += util.o > diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c > index b9e5a2cf3aae..919d02f30aae 100644 > --- a/drivers/platform/x86/amd/pmf/core.c > +++ b/drivers/platform/x86/amd/pmf/core.c > @@ -634,6 +634,10 @@ static int amd_pmf_probe(struct platform_device *pdev) > > pmf_device = dev->dev; > > + err = amd_pmf_cdev_register(dev); > + if (err) > + dev_warn(dev->dev, "failed to register util interface: %d\n", err); > + > dev_info(dev->dev, "registered PMF device successfully\n"); > > return 0; > @@ -646,6 +650,7 @@ static void amd_pmf_remove(struct platform_device *pdev) > amd_pmf_deinit_features(dev); > if (is_apmf_func_supported(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) > amd_pmf_notify_sbios_heartbeat_event_v2(dev, ON_UNLOAD); > + amd_pmf_cdev_unregister(); Why is this not done in reverse order as in probe? > apmf_acpi_deinit(dev); > amd_pmf_dbgfs_unregister(dev); > } > diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h > index 69fef7448744..6f61076a9386 100644 > --- a/drivers/platform/x86/amd/pmf/pmf.h > +++ b/drivers/platform/x86/amd/pmf/pmf.h > @@ -928,4 +928,13 @@ int amd_pmf_tee_init(struct amd_pmf_dev *dev, const uuid_t *uuid); > void amd_pmf_tee_deinit(struct amd_pmf_dev *dev); > int amd_pmf_start_policy_engine(struct amd_pmf_dev *dev); > > +/* Util Layer */ > +#if IS_ENABLED(CONFIG_AMD_PMF_UTIL_SUPPORT) > +int amd_pmf_cdev_register(struct amd_pmf_dev *dev); > +void amd_pmf_cdev_unregister(void); > +#else > +static inline int amd_pmf_cdev_register(struct amd_pmf_dev *dev) { return 0; } > +static inline void amd_pmf_cdev_unregister(void) {} > +#endif > + > #endif /* PMF_H */ > diff --git a/drivers/platform/x86/amd/pmf/util.c b/drivers/platform/x86/amd/pmf/util.c > new file mode 100644 > index 000000000000..0052f0b6a7a5 > --- /dev/null > +++ b/drivers/platform/x86/amd/pmf/util.c > @@ -0,0 +1,67 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * AMD Platform Management Framework Util Layer > + * > + * Copyright (c) 2026, Advanced Micro Devices, Inc. > + * All Rights Reserved. > + * > + * Authors: Shyam Sundar S K > + * Sanket Goswami > + */ > + > +#include > +#include > +#include > +#include > + > +#include "pmf.h" > + > +static struct amd_pmf_dev *pmf_dev_handle; > +static DEFINE_MUTEX(pmf_util_lock); > + > +static long amd_pmf_set_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) > +{ > + return -ENOTTY; > +} > + > +static int amd_pmf_open(struct inode *inode, struct file *filp) > +{ > + guard(mutex)(&pmf_util_lock); > + if (!pmf_dev_handle) > + return -ENODEV; > + > + filp->private_data = pmf_dev_handle; > + return 0; > +} > + > +static const struct file_operations pmf_if_ops = { > + .owner = THIS_MODULE, > + .open = amd_pmf_open, > + .unlocked_ioctl = amd_pmf_set_ioctl, > +}; > + > +static struct miscdevice amd_pmf_util_if = { > + .minor = MISC_DYNAMIC_MINOR, > + .name = "amdpmf_interface", > + .fops = &pmf_if_ops, > +}; > + > +int amd_pmf_cdev_register(struct amd_pmf_dev *dev) > +{ > + int ret; > + > + guard(mutex)(&pmf_util_lock); > + pmf_dev_handle = dev; > + ret = misc_register(&amd_pmf_util_if); > + if (ret) > + pmf_dev_handle = NULL; > + > + return ret; > +} > + > +void amd_pmf_cdev_unregister(void) > +{ > + guard(mutex)(&pmf_util_lock); > + misc_deregister(&amd_pmf_util_if); sashiko noted that if misc_register() fails, deregister is called unconditionally. > + pmf_dev_handle = NULL; > +} > diff --git a/include/uapi/linux/amd-pmf.h b/include/uapi/linux/amd-pmf.h > new file mode 100644 > index 000000000000..c7099e7f463f > --- /dev/null > +++ b/include/uapi/linux/amd-pmf.h > @@ -0,0 +1,60 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */ > +/* > + * AMD Platform Management Framework (PMF) UAPI Header > + * > + * Copyright (c) 2026, Advanced Micro Devices, Inc. > + * All Rights Reserved. > + * > + * This file defines the user-space API for interacting with the AMD PMF > + * driver. It provides ioctl interfaces to query platform-specific metrics > + * such as power source, slider position, platform type, laptop placement, > + * and various BIOS input/output parameters. > + */ > + > +#ifndef _UAPI_LINUX_AMD_PMF_H > +#define _UAPI_LINUX_AMD_PMF_H > + > +#include > +#include > + > +/** > + * AMD_PMF_IOC_MAGIC - Magic number for AMD PMF ioctl commands > + * > + * This magic number uniquely identifies AMD PMF ioctl operations. > + */ > +#define AMD_PMF_IOC_MAGIC 'p' > + > +/** > + * IOCTL_AMD_PMF_POPULATE_DATA - ioctl command to retrieve PMF metrics data > + * > + * This ioctl command is used to populate the amd_pmf_info structure > + * with the requested PMF metrics information. > + */ > +#define IOCTL_AMD_PMF_POPULATE_DATA _IOWR(AMD_PMF_IOC_MAGIC, 0x00, struct amd_pmf_info) > + > +#define AMD_PMF_BIOS_PARAMS_MAX 10 > + > +struct amd_pmf_info { > + __u64 size; > + > + /* Power and state info */ > + __u32 platform_type; > + __u32 power_source; > + __u32 laptop_placement; > + __u32 lid_state; > + __u32 user_presence; > + __u32 slider_position; > + > + /* Thermal and power metrics */ > + __s32 skin_temp; > + __u32 gfx_busy; > + __s32 ambient_light; > + __u32 avg_c0_residency; > + __u32 max_c0_residency; > + __u32 socket_power; > + > + /* BIOS parameters */ > + __u32 bios_input[AMD_PMF_BIOS_PARAMS_MAX]; > +}; > + > +#endif /* _UAPI_LINUX_AMD_PMF_H */ > -- i.