* [PATCH 01/22] platform/x86/intel/vsec: Refactor base_addr handling
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 02/22] platform/x86/intel/vsec: Make driver_data info const David E. Box
` (21 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86,
Michael J . Ruhl
The base_addr field in intel_vsec_platform_info was originally added to
support devices that emulate PCI VSEC capabilities in MMIO. Previously,
the code would check at registration time whether base_addr was set,
falling back to the PCI BAR if not.
Refactor this by making base_addr an explicit function parameter. This
clarifies ownership of the value and removes conditional logic from
intel_vsec_add_dev(). It also enables making intel_vsec_platform_info
const in a later patch, since the function no longer needs to write to
info->base_addr.
No functional change intended.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
Previous change log:
Changes in v7:
- No change
Changes in v6:
- No change
Changes in v5:
- No change
Changes in v4:
- No change
Changes in v3:
- No change
Changes in v2:
- Use pci_resource_start() macro instead of direct pdev->resource array
access (suggested by Ilpo)
drivers/platform/x86/intel/vsec.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c
index 5059d320edf8..46966edca03b 100644
--- a/drivers/platform/x86/intel/vsec.c
+++ b/drivers/platform/x86/intel/vsec.c
@@ -271,14 +271,13 @@ EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, "INTEL_VSEC");
static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header,
struct intel_vsec_platform_info *info,
- unsigned long cap_id)
+ unsigned long cap_id, u64 base_addr)
{
struct intel_vsec_device __free(kfree) *intel_vsec_dev = NULL;
struct resource __free(kfree) *res = NULL;
struct resource *tmp;
struct device *parent;
unsigned long quirks = info->quirks;
- u64 base_addr;
int i;
if (info->parent)
@@ -310,11 +309,6 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he
if (quirks & VSEC_QUIRK_TABLE_SHIFT)
header->offset >>= TABLE_OFFSET_SHIFT;
- if (info->base_addr)
- base_addr = info->base_addr;
- else
- base_addr = pdev->resource[header->tbir].start;
-
/*
* The DVSEC/VSEC contains the starting offset and count for a block of
* discovery tables. Create a resource array of these tables to the
@@ -412,7 +406,8 @@ static int get_cap_id(u32 header_id, unsigned long *cap_id)
static int intel_vsec_register_device(struct pci_dev *pdev,
struct intel_vsec_header *header,
- struct intel_vsec_platform_info *info)
+ struct intel_vsec_platform_info *info,
+ u64 base_addr)
{
const struct vsec_feature_dependency *consumer_deps;
struct vsec_priv *priv;
@@ -428,7 +423,7 @@ static int intel_vsec_register_device(struct pci_dev *pdev,
* For others using the exported APIs, add the device directly.
*/
if (!pci_match_id(intel_vsec_pci_ids, pdev))
- return intel_vsec_add_dev(pdev, header, info, cap_id);
+ return intel_vsec_add_dev(pdev, header, info, cap_id, base_addr);
priv = pci_get_drvdata(pdev);
if (priv->state[cap_id] == STATE_REGISTERED ||
@@ -444,7 +439,7 @@ static int intel_vsec_register_device(struct pci_dev *pdev,
consumer_deps = get_consumer_dependencies(priv, cap_id);
if (!consumer_deps || suppliers_ready(priv, consumer_deps, cap_id)) {
- ret = intel_vsec_add_dev(pdev, header, info, cap_id);
+ ret = intel_vsec_add_dev(pdev, header, info, cap_id, base_addr);
if (ret)
priv->state[cap_id] = STATE_SKIP;
else
@@ -464,7 +459,7 @@ static bool intel_vsec_walk_header(struct pci_dev *pdev,
int ret;
for ( ; *header; header++) {
- ret = intel_vsec_register_device(pdev, *header, info);
+ ret = intel_vsec_register_device(pdev, *header, info, info->base_addr);
if (!ret)
have_devices = true;
}
@@ -512,7 +507,8 @@ static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER2, &hdr);
header.id = PCI_DVSEC_HEADER2_ID(hdr);
- ret = intel_vsec_register_device(pdev, &header, info);
+ ret = intel_vsec_register_device(pdev, &header, info,
+ pci_resource_start(pdev, header.tbir));
if (ret)
continue;
@@ -557,7 +553,8 @@ static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
header.tbir = INTEL_DVSEC_TABLE_BAR(table);
header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
- ret = intel_vsec_register_device(pdev, &header, info);
+ ret = intel_vsec_register_device(pdev, &header, info,
+ pci_resource_start(pdev, header.tbir));
if (ret)
continue;
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 02/22] platform/x86/intel/vsec: Make driver_data info const
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
2026-03-13 1:51 ` [PATCH 01/22] platform/x86/intel/vsec: Refactor base_addr handling David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 03/22] platform/x86/intel/vsec: Decouple add/link helpers from PCI David E. Box
` (20 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86,
Michael J . Ruhl
Treat PCI id->driver_data (intel_vsec_platform_info) as read-only by making
vsec_priv->info a const pointer and updating all function signatures to
accept const intel_vsec_platform_info *.
This improves const-correctness and clarifies that the platform info data
from the driver_data table is not meant to be modified at runtime.
No functional changes intended.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
Previous changelog:
Changes in v7:
- No change
Changes in v6:
- No change
Changes in v5:
- No change
Changes in v4:
- No change
Changes in v3:
- No change
Changes in v2:
- New patch
drivers/platform/x86/intel/vsec.c | 20 ++++++++++----------
include/linux/intel_vsec.h | 4 ++--
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c
index 46966edca03b..e0096be605d9 100644
--- a/drivers/platform/x86/intel/vsec.c
+++ b/drivers/platform/x86/intel/vsec.c
@@ -42,7 +42,7 @@ enum vsec_device_state {
};
struct vsec_priv {
- struct intel_vsec_platform_info *info;
+ const struct intel_vsec_platform_info *info;
struct device *suppliers[VSEC_FEATURE_COUNT];
struct oobmsm_plat_info plat_info;
enum vsec_device_state state[VSEC_FEATURE_COUNT];
@@ -270,7 +270,7 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, "INTEL_VSEC");
static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header,
- struct intel_vsec_platform_info *info,
+ const struct intel_vsec_platform_info *info,
unsigned long cap_id, u64 base_addr)
{
struct intel_vsec_device __free(kfree) *intel_vsec_dev = NULL;
@@ -406,7 +406,7 @@ static int get_cap_id(u32 header_id, unsigned long *cap_id)
static int intel_vsec_register_device(struct pci_dev *pdev,
struct intel_vsec_header *header,
- struct intel_vsec_platform_info *info,
+ const struct intel_vsec_platform_info *info,
u64 base_addr)
{
const struct vsec_feature_dependency *consumer_deps;
@@ -452,7 +452,7 @@ static int intel_vsec_register_device(struct pci_dev *pdev,
}
static bool intel_vsec_walk_header(struct pci_dev *pdev,
- struct intel_vsec_platform_info *info)
+ const struct intel_vsec_platform_info *info)
{
struct intel_vsec_header **header = info->headers;
bool have_devices = false;
@@ -468,7 +468,7 @@ static bool intel_vsec_walk_header(struct pci_dev *pdev,
}
static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
- struct intel_vsec_platform_info *info)
+ const struct intel_vsec_platform_info *info)
{
bool have_devices = false;
int pos = 0;
@@ -519,7 +519,7 @@ static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
}
static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
- struct intel_vsec_platform_info *info)
+ const struct intel_vsec_platform_info *info)
{
bool have_devices = false;
int pos = 0;
@@ -565,7 +565,7 @@ static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
}
int intel_vsec_register(struct pci_dev *pdev,
- struct intel_vsec_platform_info *info)
+ const struct intel_vsec_platform_info *info)
{
if (!pdev || !info || !info->headers)
return -EINVAL;
@@ -578,7 +578,7 @@ int intel_vsec_register(struct pci_dev *pdev,
EXPORT_SYMBOL_NS_GPL(intel_vsec_register, "INTEL_VSEC");
static bool intel_vsec_get_features(struct pci_dev *pdev,
- struct intel_vsec_platform_info *info)
+ const struct intel_vsec_platform_info *info)
{
bool found = false;
@@ -622,7 +622,7 @@ static void intel_vsec_skip_missing_dependencies(struct pci_dev *pdev)
static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
- struct intel_vsec_platform_info *info;
+ const struct intel_vsec_platform_info *info;
struct vsec_priv *priv;
int num_caps, ret;
int run_once = 0;
@@ -633,7 +633,7 @@ static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id
return ret;
pci_save_state(pdev);
- info = (struct intel_vsec_platform_info *)id->driver_data;
+ info = (const struct intel_vsec_platform_info *)id->driver_data;
if (!info)
return -EINVAL;
diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index 1a0f357c2427..d551174b0049 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -200,13 +200,13 @@ static inline struct intel_vsec_device *auxdev_to_ivdev(struct auxiliary_device
#if IS_ENABLED(CONFIG_INTEL_VSEC)
int intel_vsec_register(struct pci_dev *pdev,
- struct intel_vsec_platform_info *info);
+ const struct intel_vsec_platform_info *info);
int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info,
struct intel_vsec_device *vsec_dev);
struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pdev);
#else
static inline int intel_vsec_register(struct pci_dev *pdev,
- struct intel_vsec_platform_info *info)
+ const struct intel_vsec_platform_info *info)
{
return -ENODEV;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 03/22] platform/x86/intel/vsec: Decouple add/link helpers from PCI
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
2026-03-13 1:51 ` [PATCH 01/22] platform/x86/intel/vsec: Refactor base_addr handling David E. Box
2026-03-13 1:51 ` [PATCH 02/22] platform/x86/intel/vsec: Make driver_data info const David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 04/22] platform/x86/intel/vsec: Switch exported helpers from pci_dev to device David E. Box
` (19 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86,
Michael J . Ruhl
This refactor prepares for adding ACPI-enumerated PMT endpoints. While
intel_vsec is bound to PCI today, some helpers are used by code that will
also register PMT endpoints from non-PCI (ACPI) paths. Clean up
PCI-specific plumbing where it isn’t strictly required and rely on generic
struct device where possible.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
Previous changelog:
Changes in v7:
- Correct the remaining struct device * argument to intel_vsec_add_aux().
When dropping the unused first argument in v6, the device parameter was
inadvertently changed from &vsec_dev->auxdev.dev to the PCI device.
Restore the aux device.
Changes in v6:
- No change
Changes in v5:
- No change
Changes in v4:
- No change
Changes in v3:
- No change
Changes in v2:
- No change (previous patch 1)
drivers/platform/x86/intel/vsec.c | 13 +++++++++----
drivers/platform/x86/intel/vsec_tpmi.c | 2 +-
include/linux/intel_vsec.h | 2 +-
3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c
index e0096be605d9..938648b9ef09 100644
--- a/drivers/platform/x86/intel/vsec.c
+++ b/drivers/platform/x86/intel/vsec.c
@@ -158,18 +158,23 @@ static bool vsec_driver_present(int cap_id)
*/
static const struct pci_device_id intel_vsec_pci_ids[];
-static int intel_vsec_link_devices(struct pci_dev *pdev, struct device *dev,
+static int intel_vsec_link_devices(struct device *parent, struct device *dev,
int consumer_id)
{
const struct vsec_feature_dependency *deps;
enum vsec_device_state *state;
struct device **suppliers;
struct vsec_priv *priv;
+ struct pci_dev *pdev;
int supplier_id;
if (!consumer_id)
return 0;
+ if (!dev_is_pci(parent))
+ return 0;
+
+ pdev = to_pci_dev(parent);
if (!pci_match_id(intel_vsec_pci_ids, pdev))
return 0;
@@ -204,7 +209,7 @@ static int intel_vsec_link_devices(struct pci_dev *pdev, struct device *dev,
return 0;
}
-int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
+int intel_vsec_add_aux(struct device *parent,
struct intel_vsec_device *intel_vsec_dev,
const char *name)
{
@@ -252,7 +257,7 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
if (ret)
goto cleanup_aux;
- ret = intel_vsec_link_devices(pdev, &auxdev->dev, intel_vsec_dev->cap_id);
+ ret = intel_vsec_link_devices(parent, &auxdev->dev, intel_vsec_dev->cap_id);
if (ret)
goto cleanup_aux;
@@ -343,7 +348,7 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he
* Pass the ownership of intel_vsec_dev and resource within it to
* intel_vsec_add_aux()
*/
- return intel_vsec_add_aux(pdev, parent, no_free_ptr(intel_vsec_dev),
+ return intel_vsec_add_aux(parent, no_free_ptr(intel_vsec_dev),
intel_vsec_name(header->id));
}
diff --git a/drivers/platform/x86/intel/vsec_tpmi.c b/drivers/platform/x86/intel/vsec_tpmi.c
index 98846e88d3d0..2298b6361094 100644
--- a/drivers/platform/x86/intel/vsec_tpmi.c
+++ b/drivers/platform/x86/intel/vsec_tpmi.c
@@ -655,7 +655,7 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info,
* feature_vsec_dev and res memory are also freed as part of
* device deletion.
*/
- return intel_vsec_add_aux(vsec_dev->pcidev, &vsec_dev->auxdev.dev,
+ return intel_vsec_add_aux(&vsec_dev->auxdev.dev,
feature_vsec_dev, feature_id_name);
}
diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index d551174b0049..49a746ec0128 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -184,7 +184,7 @@ struct pmt_feature_group {
struct telemetry_region regions[];
};
-int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
+int intel_vsec_add_aux(struct device *parent,
struct intel_vsec_device *intel_vsec_dev,
const char *name);
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 04/22] platform/x86/intel/vsec: Switch exported helpers from pci_dev to device
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (2 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 03/22] platform/x86/intel/vsec: Decouple add/link helpers from PCI David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 05/22] platform/x86/intel/vsec: Return real error codes from registration path David E. Box
` (18 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Preparatory refactor for ACPI-enumerated PMT endpoints. Several exported
PMT/VSEC interfaces and structs carried struct pci_dev * even though
callers only need a generic struct device. Move those to struct device * so
the same APIs work for PCI and ACPI parents.
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
Previous changelog:
Changes in v7:
- Drop the change in this patch that converted the intel_vsec_add_aux()
device argument to vsec_dev->dev (PCI device). Patch 3 fixes a prior
regression where the argument was mistakenly changed from the auxdev
device to the PCI device. Keep the auxdev (&vsec_dev->auxdev.dev) as
intended.
Changes in v6:
- No change
Changes in v5:
- xe_vsec.h: Remove forward declaration for pci_dev and add for device
Changes in v4:
- No change
Changes in v3:
- No change
Changes in v2:
- Add forward declarations for struct device in class.h, telemetry.h
- Restore struct pci_dev forward declaration in intel_vsec.h that was removed
- Remove base_addr parameter changes (moved to separate patch)
- Remove erroneous hunk in intel_vsec_pci_probe()
(review comments by Ilpo Järvinen)
drivers/gpu/drm/xe/xe_debugfs.c | 2 +-
drivers/gpu/drm/xe/xe_hwmon.c | 2 +-
drivers/gpu/drm/xe/xe_vsec.c | 7 ++-
drivers/gpu/drm/xe/xe_vsec.h | 4 +-
drivers/platform/x86/intel/pmc/core.c | 4 +-
.../platform/x86/intel/pmc/ssram_telemetry.c | 2 +-
drivers/platform/x86/intel/pmt/class.c | 8 ++--
drivers/platform/x86/intel/pmt/class.h | 5 ++-
drivers/platform/x86/intel/pmt/discovery.c | 4 +-
drivers/platform/x86/intel/pmt/telemetry.c | 13 +++---
drivers/platform/x86/intel/pmt/telemetry.h | 12 ++---
drivers/platform/x86/intel/sdsi.c | 5 ++-
drivers/platform/x86/intel/vsec.c | 44 +++++++++++--------
drivers/platform/x86/intel/vsec_tpmi.c | 6 +--
include/linux/intel_vsec.h | 13 +++---
15 files changed, 71 insertions(+), 60 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_debugfs.c b/drivers/gpu/drm/xe/xe_debugfs.c
index 844cfafe1ec7..ad2d8f179eb6 100644
--- a/drivers/gpu/drm/xe/xe_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_debugfs.c
@@ -45,7 +45,7 @@ static void read_residency_counter(struct xe_device *xe, struct xe_mmio *mmio,
u64 residency = 0;
int ret;
- ret = xe_pmt_telem_read(to_pci_dev(xe->drm.dev),
+ ret = xe_pmt_telem_read(xe->drm.dev,
xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID),
&residency, offset, sizeof(residency));
if (ret != sizeof(residency)) {
diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
index 0fd4d4f1014a..92e423a339f1 100644
--- a/drivers/gpu/drm/xe/xe_hwmon.c
+++ b/drivers/gpu/drm/xe/xe_hwmon.c
@@ -506,7 +506,7 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy)
if (hwmon->xe->info.platform == XE_BATTLEMAGE) {
u64 pmt_val;
- ret = xe_pmt_telem_read(to_pci_dev(hwmon->xe->drm.dev),
+ ret = xe_pmt_telem_read(hwmon->xe->drm.dev,
xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID),
&pmt_val, BMG_ENERGY_STATUS_PMT_OFFSET, sizeof(pmt_val));
if (ret != sizeof(pmt_val)) {
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index 4ebb4dbe1c9b..a9baf0bfe572 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -140,10 +140,10 @@ static int xe_guid_decode(u32 guid, int *index, u32 *offset)
return 0;
}
-int xe_pmt_telem_read(struct pci_dev *pdev, u32 guid, u64 *data, loff_t user_offset,
+int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offset,
u32 count)
{
- struct xe_device *xe = pdev_to_xe_device(pdev);
+ struct xe_device *xe = kdev_to_xe_device(dev);
void __iomem *telem_addr = xe->mmio.regs + BMG_TELEMETRY_OFFSET;
u32 mem_region;
u32 offset;
@@ -198,7 +198,6 @@ void xe_vsec_init(struct xe_device *xe)
{
struct intel_vsec_platform_info *info;
struct device *dev = xe->drm.dev;
- struct pci_dev *pdev = to_pci_dev(dev);
enum xe_vsec platform;
platform = get_platform_info(xe);
@@ -221,6 +220,6 @@ void xe_vsec_init(struct xe_device *xe)
* Register a VSEC. Cleanup is handled using device managed
* resources.
*/
- intel_vsec_register(pdev, info);
+ intel_vsec_register(dev, info);
}
MODULE_IMPORT_NS("INTEL_VSEC");
diff --git a/drivers/gpu/drm/xe/xe_vsec.h b/drivers/gpu/drm/xe/xe_vsec.h
index dabfb4e02d70..a25b4e6e681b 100644
--- a/drivers/gpu/drm/xe/xe_vsec.h
+++ b/drivers/gpu/drm/xe/xe_vsec.h
@@ -6,10 +6,10 @@
#include <linux/types.h>
-struct pci_dev;
+struct device;
struct xe_device;
void xe_vsec_init(struct xe_device *xe);
-int xe_pmt_telem_read(struct pci_dev *pdev, u32 guid, u64 *data, loff_t user_offset, u32 count);
+int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offset, u32 count);
#endif
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 02b303418d18..d91e1ab842d6 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -1315,7 +1315,7 @@ static struct telem_endpoint *pmc_core_register_endpoint(struct pci_dev *pcidev,
unsigned int i;
for (i = 0; guids[i]; i++) {
- ep = pmt_telem_find_and_register_endpoint(pcidev, guids[i], 0);
+ ep = pmt_telem_find_and_register_endpoint(&pcidev->dev, guids[i], 0);
if (!IS_ERR(ep))
return ep;
}
@@ -1600,7 +1600,7 @@ static int pmc_core_get_telem_info(struct pmc_dev *pmcdev, struct pmc_dev_info *
if (!pmc->map->lpm_req_guid)
return -ENXIO;
- ep = pmt_telem_find_and_register_endpoint(pcidev, pmc->map->lpm_req_guid, 0);
+ ep = pmt_telem_find_and_register_endpoint(&pcidev->dev, pmc->map->lpm_req_guid, 0);
if (IS_ERR(ep)) {
dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %pe", ep);
return -EPROBE_DEFER;
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 03fad9331fc0..6f6e83e70fc5 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -60,7 +60,7 @@ pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, u64 ssram_base, void __iomem
info.base_addr = ssram_base;
info.parent = &pcidev->dev;
- return intel_vsec_register(pcidev, &info);
+ return intel_vsec_register(&pcidev->dev, &info);
}
static inline u64 get_base(void __iomem *addr, u32 offset)
diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index be3c8d9e4fff..b4c9964df807 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -60,11 +60,11 @@ pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count)
return count;
}
-int pmt_telem_read_mmio(struct pci_dev *pdev, struct pmt_callbacks *cb, u32 guid, void *buf,
+int pmt_telem_read_mmio(struct device *dev, struct pmt_callbacks *cb, u32 guid, void *buf,
void __iomem *addr, loff_t off, u32 count)
{
if (cb && cb->read_telem)
- return cb->read_telem(pdev, guid, buf, off, count);
+ return cb->read_telem(dev, guid, buf, off, count);
addr += off;
@@ -99,7 +99,7 @@ intel_pmt_read(struct file *filp, struct kobject *kobj,
if (count > entry->size - off)
count = entry->size - off;
- count = pmt_telem_read_mmio(entry->pcidev, entry->cb, entry->header.guid, buf,
+ count = pmt_telem_read_mmio(entry->ep->dev, entry->cb, entry->header.guid, buf,
entry->base, off, count);
return count;
@@ -208,7 +208,7 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
struct intel_vsec_device *ivdev,
struct resource *disc_res)
{
- struct pci_dev *pci_dev = ivdev->pcidev;
+ struct pci_dev *pci_dev = to_pci_dev(ivdev->dev);
struct device *dev = &ivdev->auxdev.dev;
struct intel_pmt_header *header = &entry->header;
u8 bir;
diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
index 3c5ad5f52bca..1ae56a5baad2 100644
--- a/drivers/platform/x86/intel/pmt/class.h
+++ b/drivers/platform/x86/intel/pmt/class.h
@@ -19,11 +19,12 @@
#define GET_BIR(v) ((v) & GENMASK(2, 0))
#define GET_ADDRESS(v) ((v) & GENMASK(31, 3))
+struct device;
struct pci_dev;
extern struct class intel_pmt_class;
struct telem_endpoint {
- struct pci_dev *pcidev;
+ struct device *dev;
struct telem_header header;
struct pmt_callbacks *cb;
void __iomem *base;
@@ -65,7 +66,7 @@ struct intel_pmt_namespace {
struct intel_pmt_entry *entry);
};
-int pmt_telem_read_mmio(struct pci_dev *pdev, struct pmt_callbacks *cb, u32 guid, void *buf,
+int pmt_telem_read_mmio(struct device *dev, struct pmt_callbacks *cb, u32 guid, void *buf,
void __iomem *addr, loff_t off, u32 count);
bool intel_pmt_is_early_client_hw(struct device *dev);
int intel_pmt_dev_create(struct intel_pmt_entry *entry,
diff --git a/drivers/platform/x86/intel/pmt/discovery.c b/drivers/platform/x86/intel/pmt/discovery.c
index e500aa327d23..c482368bfaae 100644
--- a/drivers/platform/x86/intel/pmt/discovery.c
+++ b/drivers/platform/x86/intel/pmt/discovery.c
@@ -542,7 +542,7 @@ static int pmt_features_probe(struct auxiliary_device *auxdev, const struct auxi
if (!priv)
return -ENOMEM;
- priv->parent = &ivdev->pcidev->dev;
+ priv->parent = ivdev->dev;
auxiliary_set_drvdata(auxdev, priv);
priv->dev = device_create(&intel_pmt_class, &auxdev->dev, MKDEV(0, 0), priv,
@@ -609,7 +609,7 @@ void intel_pmt_get_features(struct intel_pmt_entry *entry)
mutex_lock(&feature_list_lock);
list_for_each_entry(feature, &pmt_feature_list, list) {
- if (feature->priv->parent != &entry->ep->pcidev->dev)
+ if (feature->priv->parent != entry->ep->dev)
continue;
pmt_get_features(entry, feature);
diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
index a52803bfe124..bdc7c24a3678 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.c
+++ b/drivers/platform/x86/intel/pmt/telemetry.c
@@ -112,7 +112,7 @@ static int pmt_telem_add_endpoint(struct intel_vsec_device *ivdev,
return -ENOMEM;
ep = entry->ep;
- ep->pcidev = ivdev->pcidev;
+ ep->dev = ivdev->dev;
ep->header.access_type = entry->header.access_type;
ep->header.guid = entry->header.guid;
ep->header.base_offset = entry->header.base_offset;
@@ -204,7 +204,7 @@ int pmt_telem_get_endpoint_info(int devid, struct telem_endpoint_info *info)
goto unlock;
}
- info->pdev = entry->ep->pcidev;
+ info->dev = entry->ep->dev;
info->header = entry->ep->header;
unlock:
@@ -218,9 +218,10 @@ static int pmt_copy_region(struct telemetry_region *region,
struct intel_pmt_entry *entry)
{
+ struct pci_dev *pdev = to_pci_dev(entry->ep->dev);
struct oobmsm_plat_info *plat_info;
- plat_info = intel_vsec_get_mapping(entry->ep->pcidev);
+ plat_info = intel_vsec_get_mapping(pdev);
if (IS_ERR(plat_info))
return PTR_ERR(plat_info);
@@ -308,7 +309,7 @@ int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count)
if (offset + NUM_BYTES_QWORD(count) > size)
return -EINVAL;
- pmt_telem_read_mmio(ep->pcidev, ep->cb, ep->header.guid, data, ep->base, offset,
+ pmt_telem_read_mmio(ep->dev, ep->cb, ep->header.guid, data, ep->base, offset,
NUM_BYTES_QWORD(count));
return ep->present ? 0 : -EPIPE;
@@ -335,7 +336,7 @@ int pmt_telem_read32(struct telem_endpoint *ep, u32 id, u32 *data, u32 count)
EXPORT_SYMBOL_NS_GPL(pmt_telem_read32, "INTEL_PMT_TELEMETRY");
struct telem_endpoint *
-pmt_telem_find_and_register_endpoint(struct pci_dev *pcidev, u32 guid, u16 pos)
+pmt_telem_find_and_register_endpoint(struct device *dev, u32 guid, u16 pos)
{
int devid = 0;
int inst = 0;
@@ -348,7 +349,7 @@ pmt_telem_find_and_register_endpoint(struct pci_dev *pcidev, u32 guid, u16 pos)
if (err)
return ERR_PTR(err);
- if (ep_info.header.guid == guid && ep_info.pdev == pcidev) {
+ if (ep_info.header.guid == guid && ep_info.dev == dev) {
if (inst == pos)
return pmt_telem_register_endpoint(devid);
++inst;
diff --git a/drivers/platform/x86/intel/pmt/telemetry.h b/drivers/platform/x86/intel/pmt/telemetry.h
index d45af5512b4e..0f88c5e7d90e 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.h
+++ b/drivers/platform/x86/intel/pmt/telemetry.h
@@ -6,8 +6,8 @@
#define PMT_TELEM_TELEMETRY 0
#define PMT_TELEM_CRASHLOG 1
+struct device;
struct telem_endpoint;
-struct pci_dev;
struct telem_header {
u8 access_type;
@@ -17,7 +17,7 @@ struct telem_header {
};
struct telem_endpoint_info {
- struct pci_dev *pdev;
+ struct device *dev;
struct telem_header header;
};
@@ -71,8 +71,8 @@ int pmt_telem_get_endpoint_info(int devid, struct telem_endpoint_info *info);
/**
* pmt_telem_find_and_register_endpoint() - Get a telemetry endpoint from
- * pci_dev device, guid and pos
- * @pdev: PCI device inside the Intel vsec
+ * device, guid and pos
+ * @dev: device inside the Intel vsec
* @guid: GUID of the telemetry space
* @pos: Instance of the guid
*
@@ -80,8 +80,8 @@ int pmt_telem_get_endpoint_info(int devid, struct telem_endpoint_info *info);
* * endpoint - On success returns pointer to the telemetry endpoint
* * -ENXIO - telemetry endpoint not found
*/
-struct telem_endpoint *pmt_telem_find_and_register_endpoint(struct pci_dev *pcidev,
- u32 guid, u16 pos);
+struct telem_endpoint *
+pmt_telem_find_and_register_endpoint(struct device *dev, u32 guid, u16 pos);
/**
* pmt_telem_read() - Read qwords from counter sram using sample id
diff --git a/drivers/platform/x86/intel/sdsi.c b/drivers/platform/x86/intel/sdsi.c
index da75f53d0bcc..d7e37d4ace23 100644
--- a/drivers/platform/x86/intel/sdsi.c
+++ b/drivers/platform/x86/intel/sdsi.c
@@ -599,13 +599,14 @@ static int sdsi_get_layout(struct sdsi_priv *priv, struct disc_table *table)
return 0;
}
-static int sdsi_map_mbox_registers(struct sdsi_priv *priv, struct pci_dev *parent,
+static int sdsi_map_mbox_registers(struct sdsi_priv *priv, struct device *dev,
struct disc_table *disc_table, struct resource *disc_res)
{
u32 access_type = FIELD_GET(DT_ACCESS_TYPE, disc_table->access_info);
u32 size = FIELD_GET(DT_SIZE, disc_table->access_info);
u32 tbir = FIELD_GET(DT_TBIR, disc_table->offset);
u32 offset = DT_OFFSET(disc_table->offset);
+ struct pci_dev *parent = to_pci_dev(dev);
struct resource res = {};
/* Starting location of SDSi MMIO region based on access type */
@@ -681,7 +682,7 @@ static int sdsi_probe(struct auxiliary_device *auxdev, const struct auxiliary_de
return ret;
/* Map the SDSi mailbox registers */
- ret = sdsi_map_mbox_registers(priv, intel_cap_dev->pcidev, &disc_table, disc_res);
+ ret = sdsi_map_mbox_registers(priv, intel_cap_dev->dev, &disc_table, disc_res);
if (ret)
return ret;
diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c
index 938648b9ef09..a547e4b98245 100644
--- a/drivers/platform/x86/intel/vsec.c
+++ b/drivers/platform/x86/intel/vsec.c
@@ -274,7 +274,7 @@ int intel_vsec_add_aux(struct device *parent,
}
EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, "INTEL_VSEC");
-static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header,
+static int intel_vsec_add_dev(struct device *dev, struct intel_vsec_header *header,
const struct intel_vsec_platform_info *info,
unsigned long cap_id, u64 base_addr)
{
@@ -288,18 +288,18 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he
if (info->parent)
parent = info->parent;
else
- parent = &pdev->dev;
+ parent = dev;
if (!intel_vsec_supported(header->id, info->caps))
return -EINVAL;
if (!header->num_entries) {
- dev_dbg(&pdev->dev, "Invalid 0 entry count for header id %d\n", header->id);
+ dev_dbg(dev, "Invalid 0 entry count for header id %d\n", header->id);
return -EINVAL;
}
if (!header->entry_size) {
- dev_dbg(&pdev->dev, "Invalid 0 entry size for header id %d\n", header->id);
+ dev_dbg(dev, "Invalid 0 entry size for header id %d\n", header->id);
return -EINVAL;
}
@@ -331,7 +331,7 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he
release_mem_region(tmp->start, resource_size(tmp));
}
- intel_vsec_dev->pcidev = pdev;
+ intel_vsec_dev->dev = dev;
intel_vsec_dev->resource = no_free_ptr(res);
intel_vsec_dev->num_resources = header->num_entries;
intel_vsec_dev->quirks = info->quirks;
@@ -409,13 +409,14 @@ static int get_cap_id(u32 header_id, unsigned long *cap_id)
return 0;
}
-static int intel_vsec_register_device(struct pci_dev *pdev,
+static int intel_vsec_register_device(struct device *dev,
struct intel_vsec_header *header,
const struct intel_vsec_platform_info *info,
u64 base_addr)
{
const struct vsec_feature_dependency *consumer_deps;
struct vsec_priv *priv;
+ struct pci_dev *pdev;
unsigned long cap_id;
int ret;
@@ -427,8 +428,12 @@ static int intel_vsec_register_device(struct pci_dev *pdev,
* Only track dependencies for devices probed by the VSEC driver.
* For others using the exported APIs, add the device directly.
*/
+ if (!dev_is_pci(dev))
+ return intel_vsec_add_dev(dev, header, info, cap_id, base_addr);
+
+ pdev = to_pci_dev(dev);
if (!pci_match_id(intel_vsec_pci_ids, pdev))
- return intel_vsec_add_dev(pdev, header, info, cap_id, base_addr);
+ return intel_vsec_add_dev(dev, header, info, cap_id, base_addr);
priv = pci_get_drvdata(pdev);
if (priv->state[cap_id] == STATE_REGISTERED ||
@@ -444,7 +449,7 @@ static int intel_vsec_register_device(struct pci_dev *pdev,
consumer_deps = get_consumer_dependencies(priv, cap_id);
if (!consumer_deps || suppliers_ready(priv, consumer_deps, cap_id)) {
- ret = intel_vsec_add_dev(pdev, header, info, cap_id, base_addr);
+ ret = intel_vsec_add_dev(dev, header, info, cap_id, base_addr);
if (ret)
priv->state[cap_id] = STATE_SKIP;
else
@@ -456,7 +461,7 @@ static int intel_vsec_register_device(struct pci_dev *pdev,
return -EAGAIN;
}
-static bool intel_vsec_walk_header(struct pci_dev *pdev,
+static bool intel_vsec_walk_header(struct device *dev,
const struct intel_vsec_platform_info *info)
{
struct intel_vsec_header **header = info->headers;
@@ -464,7 +469,7 @@ static bool intel_vsec_walk_header(struct pci_dev *pdev,
int ret;
for ( ; *header; header++) {
- ret = intel_vsec_register_device(pdev, *header, info, info->base_addr);
+ ret = intel_vsec_register_device(dev, *header, info, info->base_addr);
if (!ret)
have_devices = true;
}
@@ -512,7 +517,7 @@ static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER2, &hdr);
header.id = PCI_DVSEC_HEADER2_ID(hdr);
- ret = intel_vsec_register_device(pdev, &header, info,
+ ret = intel_vsec_register_device(&pdev->dev, &header, info,
pci_resource_start(pdev, header.tbir));
if (ret)
continue;
@@ -558,7 +563,7 @@ static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
header.tbir = INTEL_DVSEC_TABLE_BAR(table);
header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
- ret = intel_vsec_register_device(pdev, &header, info,
+ ret = intel_vsec_register_device(&pdev->dev, &header, info,
pci_resource_start(pdev, header.tbir));
if (ret)
continue;
@@ -569,13 +574,13 @@ static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
return have_devices;
}
-int intel_vsec_register(struct pci_dev *pdev,
+int intel_vsec_register(struct device *dev,
const struct intel_vsec_platform_info *info)
{
- if (!pdev || !info || !info->headers)
+ if (!dev || !info || !info->headers)
return -EINVAL;
- if (!intel_vsec_walk_header(pdev, info))
+ if (!intel_vsec_walk_header(dev, info))
return -ENODEV;
else
return 0;
@@ -601,7 +606,7 @@ static bool intel_vsec_get_features(struct pci_dev *pdev,
found = true;
if (info && (info->quirks & VSEC_QUIRK_NO_DVSEC) &&
- intel_vsec_walk_header(pdev, info))
+ intel_vsec_walk_header(&pdev->dev, info))
found = true;
return found;
@@ -673,7 +678,10 @@ int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info,
{
struct vsec_priv *priv;
- priv = pci_get_drvdata(vsec_dev->pcidev);
+ if (!dev_is_pci(vsec_dev->dev))
+ return -ENODEV;
+
+ priv = pci_get_drvdata(to_pci_dev(vsec_dev->dev));
if (!priv)
return -EINVAL;
@@ -821,7 +829,7 @@ static pci_ers_result_t intel_vsec_pci_slot_reset(struct pci_dev *pdev)
xa_for_each(&auxdev_array, index, intel_vsec_dev) {
/* check if pdev doesn't match */
- if (pdev != intel_vsec_dev->pcidev)
+ if (&pdev->dev != intel_vsec_dev->dev)
continue;
devm_release_action(&pdev->dev, intel_vsec_remove_aux,
&intel_vsec_dev->auxdev);
diff --git a/drivers/platform/x86/intel/vsec_tpmi.c b/drivers/platform/x86/intel/vsec_tpmi.c
index 2298b6361094..9dddf4e5863e 100644
--- a/drivers/platform/x86/intel/vsec_tpmi.c
+++ b/drivers/platform/x86/intel/vsec_tpmi.c
@@ -530,7 +530,7 @@ static const struct file_operations mem_write_ops = {
.release = single_release,
};
-#define tpmi_to_dev(info) (&info->vsec_dev->pcidev->dev)
+#define tpmi_to_dev(info) ((info)->vsec_dev->dev)
static void tpmi_dbgfs_register(struct intel_tpmi_info *tpmi_info)
{
@@ -642,7 +642,7 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info,
tmp->flags = IORESOURCE_MEM;
}
- feature_vsec_dev->pcidev = vsec_dev->pcidev;
+ feature_vsec_dev->dev = vsec_dev->dev;
feature_vsec_dev->resource = res;
feature_vsec_dev->num_resources = pfs->pfs_header.num_entries;
feature_vsec_dev->priv_data = &tpmi_info->plat_info;
@@ -742,7 +742,7 @@ static int tpmi_fetch_pfs_header(struct intel_tpmi_pm_feature *pfs, u64 start, i
static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev)
{
struct intel_vsec_device *vsec_dev = auxdev_to_ivdev(auxdev);
- struct pci_dev *pci_dev = vsec_dev->pcidev;
+ struct pci_dev *pci_dev = to_pci_dev(vsec_dev->dev);
struct intel_tpmi_info *tpmi_info;
u64 pfs_start = 0;
int ret, i;
diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index 49a746ec0128..4eecb2a6bac4 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -29,6 +29,7 @@
#define INTEL_DVSEC_TABLE_OFFSET(x) ((x) & GENMASK(31, 3))
#define TABLE_OFFSET_SHIFT 3
+struct device;
struct pci_dev;
struct resource;
@@ -82,14 +83,14 @@ enum intel_vsec_quirks {
* struct pmt_callbacks - Callback infrastructure for PMT devices
* @read_telem: when specified, called by client driver to access PMT
* data (instead of direct copy).
- * * pdev: PCI device reference for the callback's use
+ * * dev: device reference for the callback's use
* * guid: ID of data to acccss
* * data: buffer for the data to be copied
* * off: offset into the requested buffer
* * count: size of buffer
*/
struct pmt_callbacks {
- int (*read_telem)(struct pci_dev *pdev, u32 guid, u64 *data, loff_t off, u32 count);
+ int (*read_telem)(struct device *dev, u32 guid, u64 *data, loff_t off, u32 count);
};
struct vsec_feature_dependency {
@@ -122,7 +123,7 @@ struct intel_vsec_platform_info {
/**
* struct intel_vsec_device - Auxbus specific device information
* @auxdev: auxbus device struct for auxbus access
- * @pcidev: pci device associated with the device
+ * @dev: struct device associated with the device
* @resource: any resources shared by the parent
* @ida: id reference
* @num_resources: number of resources
@@ -135,7 +136,7 @@ struct intel_vsec_platform_info {
*/
struct intel_vsec_device {
struct auxiliary_device auxdev;
- struct pci_dev *pcidev;
+ struct device *dev;
struct resource *resource;
struct ida *ida;
int num_resources;
@@ -199,13 +200,13 @@ static inline struct intel_vsec_device *auxdev_to_ivdev(struct auxiliary_device
}
#if IS_ENABLED(CONFIG_INTEL_VSEC)
-int intel_vsec_register(struct pci_dev *pdev,
+int intel_vsec_register(struct device *dev,
const struct intel_vsec_platform_info *info);
int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info,
struct intel_vsec_device *vsec_dev);
struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pdev);
#else
-static inline int intel_vsec_register(struct pci_dev *pdev,
+static inline int intel_vsec_register(struct device *dev,
const struct intel_vsec_platform_info *info)
{
return -ENODEV;
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 05/22] platform/x86/intel/vsec: Return real error codes from registration path
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (3 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 04/22] platform/x86/intel/vsec: Switch exported helpers from pci_dev to device David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 06/22] platform/x86/intel/vsec: Plumb ACPI PMT discovery tables through vsec David E. Box
` (17 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Stop collapsing registration results into booleans. Make
intel_vsec_walk_header() return int and propagate the first non-zero error
from intel_vsec_register_device(). intel_vsec_register() now returns that
error directly and 0 on success.
This preserves success behavior while surfacing meaningful errors instead
of hiding them behind a bool/-ENODEV, which makes debugging and probe
ordering issues clearer.
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
Previous changelog:
Changes in v7:
- No change
Changes in v6:
- No change
Changes in v5:
- No change
Changes in v4:
- No change
Changes in v3:
- No change
Changes in v2:
- No change (previous patch 3)
drivers/platform/x86/intel/vsec.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c
index a547e4b98245..34b2c19ecff0 100644
--- a/drivers/platform/x86/intel/vsec.c
+++ b/drivers/platform/x86/intel/vsec.c
@@ -461,20 +461,19 @@ static int intel_vsec_register_device(struct device *dev,
return -EAGAIN;
}
-static bool intel_vsec_walk_header(struct device *dev,
- const struct intel_vsec_platform_info *info)
+static int intel_vsec_walk_header(struct device *dev,
+ const struct intel_vsec_platform_info *info)
{
struct intel_vsec_header **header = info->headers;
- bool have_devices = false;
int ret;
for ( ; *header; header++) {
ret = intel_vsec_register_device(dev, *header, info, info->base_addr);
- if (!ret)
- have_devices = true;
+ if (ret)
+ return ret;
}
- return have_devices;
+ return 0;
}
static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
@@ -580,10 +579,7 @@ int intel_vsec_register(struct device *dev,
if (!dev || !info || !info->headers)
return -EINVAL;
- if (!intel_vsec_walk_header(dev, info))
- return -ENODEV;
- else
- return 0;
+ return intel_vsec_walk_header(dev, info);
}
EXPORT_SYMBOL_NS_GPL(intel_vsec_register, "INTEL_VSEC");
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 06/22] platform/x86/intel/vsec: Plumb ACPI PMT discovery tables through vsec
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (4 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 05/22] platform/x86/intel/vsec: Return real error codes from registration path David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 16:54 ` Ilpo Järvinen
2026-03-13 1:51 ` [PATCH 07/22] platform/x86/intel/pmt: Add pre/post decode hooks around header parsing David E. Box
` (16 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Some platforms expose PMT discovery via ACPI instead of PCI BARs. Add a
generic discovery source flag and carry ACPI discovery entries alongside
the existing PCI resource path so PMT clients can consume either.
Changes:
- Add enum intel_vsec_disc_source { _PCI, _ACPI }.
- Extend intel_vsec_platform_info and intel_vsec_device with source enum
and ACPI discovery table pointer/
- When src==ACPI, skip BAR resource setup and copy the ACPI discovery
entries into the aux device.
No user-visible behavior change yet; this only wires ACPI data through vsec
in preparation for ACPI-enumerated PMT clients.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
Previous changelog:
Changes in v7:
- No change
Changes in v6:
- Fix checkpatch parens alignment warning
Changes in v5:
- No change
Changes in v4:
- Use check_mul_overflow() instead of array_size() which was
incorrectly checking for 0 anyway.
Changes in v3:
- Re-send with all changes intended for v2 which was sent without them
being applied.
Changes in v2:
- Improve comment to clarify BAR resource setup doesn't apply to ACPI
discovery
- Add missing #include for kmemdup()
- Use array_size() for overflow protection
(review comments by Ilpo Järvinen)
drivers/platform/x86/intel/vsec.c | 23 +++++++++++++++++++++++
include/linux/intel_vsec.h | 20 +++++++++++++++++++-
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c
index 34b2c19ecff0..7d5dbc1c1d05 100644
--- a/drivers/platform/x86/intel/vsec.c
+++ b/drivers/platform/x86/intel/vsec.c
@@ -24,7 +24,9 @@
#include <linux/intel_vsec.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/overflow.h>
#include <linux/pci.h>
+#include <linux/string.h>
#include <linux/types.h>
#define PMT_XA_START 0
@@ -109,6 +111,7 @@ static void intel_vsec_dev_release(struct device *dev)
ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id);
+ kfree(intel_vsec_dev->acpi_disc);
kfree(intel_vsec_dev->resource);
kfree(intel_vsec_dev);
}
@@ -320,6 +323,13 @@ static int intel_vsec_add_dev(struct device *dev, struct intel_vsec_header *head
* auxiliary device driver.
*/
for (i = 0, tmp = res; i < header->num_entries; i++, tmp++) {
+ /*
+ * Skip resource mapping check for ACPI-based discovery
+ * since those tables are read from _DSD, not MMIO.
+ */
+ if (info->src == INTEL_VSEC_DISC_ACPI)
+ break;
+
tmp->start = base_addr + header->offset + i * (header->entry_size * sizeof(u32));
tmp->end = tmp->start + (header->entry_size * sizeof(u32)) - 1;
tmp->flags = IORESOURCE_MEM;
@@ -338,6 +348,19 @@ static int intel_vsec_add_dev(struct device *dev, struct intel_vsec_header *head
intel_vsec_dev->base_addr = info->base_addr;
intel_vsec_dev->priv_data = info->priv_data;
intel_vsec_dev->cap_id = cap_id;
+ intel_vsec_dev->src = info->src;
+
+ if (info->src == INTEL_VSEC_DISC_ACPI) {
+ size_t bytes;
+
+ if (check_mul_overflow(intel_vsec_dev->num_resources,
+ sizeof(*info->acpi_disc), &bytes))
+ return -EOVERFLOW;
+
+ intel_vsec_dev->acpi_disc = kmemdup(info->acpi_disc, bytes, GFP_KERNEL);
+ if (!intel_vsec_dev->acpi_disc)
+ return -ENOMEM;
+ }
if (header->id == VSEC_ID_SDSI)
intel_vsec_dev->ida = &intel_vsec_sdsi_ida;
diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index 4eecb2a6bac4..1fe5665a9d02 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -33,6 +33,11 @@ struct device;
struct pci_dev;
struct resource;
+enum intel_vsec_disc_source {
+ INTEL_VSEC_DISC_PCI, /* PCI, default */
+ INTEL_VSEC_DISC_ACPI, /* ACPI */
+};
+
enum intel_vsec_id {
VSEC_ID_TELEMETRY = 2,
VSEC_ID_WATCHER = 3,
@@ -103,6 +108,10 @@ struct vsec_feature_dependency {
* @parent: parent device in the auxbus chain
* @headers: list of headers to define the PMT client devices to create
* @deps: array of feature dependencies
+ * @acpi_disc: ACPI discovery tables, each entry is two QWORDs
+ * in little-endian format as defined by the PMT ACPI spec.
+ * Valid only when @provider == INTEL_VSEC_DISC_ACPI.
+ * @src: source of discovery table data
* @priv_data: private data, usable by parent devices, currently a callback
* @caps: bitmask of PMT capabilities for the given headers
* @quirks: bitmask of VSEC device quirks
@@ -113,6 +122,8 @@ struct intel_vsec_platform_info {
struct device *parent;
struct intel_vsec_header **headers;
const struct vsec_feature_dependency *deps;
+ u32 (*acpi_disc)[4];
+ enum intel_vsec_disc_source src;
void *priv_data;
unsigned long caps;
unsigned long quirks;
@@ -124,7 +135,12 @@ struct intel_vsec_platform_info {
* struct intel_vsec_device - Auxbus specific device information
* @auxdev: auxbus device struct for auxbus access
* @dev: struct device associated with the device
- * @resource: any resources shared by the parent
+ * @resource: PCI discovery resources (BAR windows), one per discovery
+ * instance. Valid only when @src == INTEL_VSEC_DISC_PCI
+ * @acpi_disc: ACPI discovery tables, each entry is two QWORDs
+ * in little-endian format as defined by the PMT ACPI spec.
+ * Valid only when @src == INTEL_VSEC_DISC_ACPI.
+ * @src: source of discovery table data
* @ida: id reference
* @num_resources: number of resources
* @id: xarray id
@@ -138,6 +154,8 @@ struct intel_vsec_device {
struct auxiliary_device auxdev;
struct device *dev;
struct resource *resource;
+ u32 (*acpi_disc)[4];
+ enum intel_vsec_disc_source src;
struct ida *ida;
int num_resources;
int id; /* xa */
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 06/22] platform/x86/intel/vsec: Plumb ACPI PMT discovery tables through vsec
2026-03-13 1:51 ` [PATCH 06/22] platform/x86/intel/vsec: Plumb ACPI PMT discovery tables through vsec David E. Box
@ 2026-03-17 16:54 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 16:54 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> Some platforms expose PMT discovery via ACPI instead of PCI BARs. Add a
> generic discovery source flag and carry ACPI discovery entries alongside
> the existing PCI resource path so PMT clients can consume either.
>
> Changes:
> - Add enum intel_vsec_disc_source { _PCI, _ACPI }.
> - Extend intel_vsec_platform_info and intel_vsec_device with source enum
> and ACPI discovery table pointer/
> - When src==ACPI, skip BAR resource setup and copy the ACPI discovery
> entries into the aux device.
>
> No user-visible behavior change yet; this only wires ACPI data through vsec
> in preparation for ACPI-enumerated PMT clients.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
I took patches up to this one to the review-ilpo-next branch as those are
basically ready and have seen enough version by now.
--
i.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 07/22] platform/x86/intel/pmt: Add pre/post decode hooks around header parsing
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (5 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 06/22] platform/x86/intel/vsec: Plumb ACPI PMT discovery tables through vsec David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 08/22] platform/x86/intel/pmt/crashlog: Split init into pre-decode David E. Box
` (15 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Add optional pre- and post-decode callbacks to the PMT class so namespaces
can perform setup and cleanup steps around header parsing.
- Add pmt_pre_decode() and pmt_post_decode() to struct
intel_pmt_namespace.
- Update intel_pmt_dev_create() to invoke, in order:
pre → header_decode() → post.
- Keep the existing pmt_header_decode() callback unchanged.
No functional changes. This adds flexibility for upcoming decoders while
preserving current behavior.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmt/class.c | 12 ++++++++++++
drivers/platform/x86/intel/pmt/class.h | 4 ++++
2 files changed, 16 insertions(+)
diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index b4c9964df807..9b315334a69b 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -381,10 +381,22 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespa
if (IS_ERR(entry->disc_table))
return PTR_ERR(entry->disc_table);
+ if (ns->pmt_pre_decode) {
+ ret = ns->pmt_pre_decode(intel_vsec_dev, entry);
+ if (ret)
+ return ret;
+ }
+
ret = ns->pmt_header_decode(entry, dev);
if (ret)
return ret;
+ if (ns->pmt_post_decode) {
+ ret = ns->pmt_post_decode(intel_vsec_dev, entry);
+ if (ret)
+ return ret;
+ }
+
ret = intel_pmt_populate_entry(entry, intel_vsec_dev, disc_res);
if (ret)
return ret;
diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
index 1ae56a5baad2..ff39014b208c 100644
--- a/drivers/platform/x86/intel/pmt/class.h
+++ b/drivers/platform/x86/intel/pmt/class.h
@@ -62,6 +62,10 @@ struct intel_pmt_namespace {
struct xarray *xa;
int (*pmt_header_decode)(struct intel_pmt_entry *entry,
struct device *dev);
+ int (*pmt_pre_decode)(struct intel_vsec_device *ivdev,
+ struct intel_pmt_entry *entry);
+ int (*pmt_post_decode)(struct intel_vsec_device *ivdev,
+ struct intel_pmt_entry *entry);
int (*pmt_add_endpoint)(struct intel_vsec_device *ivdev,
struct intel_pmt_entry *entry);
};
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 08/22] platform/x86/intel/pmt/crashlog: Split init into pre-decode
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (6 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 07/22] platform/x86/intel/pmt: Add pre/post decode hooks around header parsing David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 09/22] platform/x86/intel/pmt/telemetry: Move overlap check to post-decode hook David E. Box
` (14 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Refactor crashlog initialization to use the PMT namespace pre-decode hook:
- Add pmt_crashlog_pre_decode() to parse type/version, select the
crashlog_info, initialize the control mutex, and set entry->attr_grp.
- Simplify pmt_crashlog_header_decode() to only read header fields from
the discovery table.
- Wire the namespace with .pmt_pre_decode = pmt_crashlog_pre_decode.
This separates structural initialization from header parsing, aligning
crashlog with the PMT class pre/post decode flow.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmt/crashlog.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
index b0393c9c5b4b..f936daf99e4d 100644
--- a/drivers/platform/x86/intel/pmt/crashlog.c
+++ b/drivers/platform/x86/intel/pmt/crashlog.c
@@ -496,11 +496,9 @@ static const struct crashlog_info *select_crashlog_info(u32 type, u32 version)
return &crashlog_type1_ver2;
}
-static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
- struct device *dev)
+static int pmt_crashlog_pre_decode(struct intel_vsec_device *ivdev,
+ struct intel_pmt_entry *entry)
{
- void __iomem *disc_table = entry->disc_table;
- struct intel_pmt_header *header = &entry->header;
struct crashlog_entry *crashlog;
u32 version;
u32 type;
@@ -513,6 +511,16 @@ static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
mutex_init(&crashlog->control_mutex);
crashlog->info = select_crashlog_info(type, version);
+ entry->attr_grp = crashlog->info->attr_grp;
+
+ return 0;
+}
+
+static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
+ struct device *dev)
+{
+ void __iomem *disc_table = entry->disc_table;
+ struct intel_pmt_header *header = &entry->header;
header->access_type = GET_ACCESS(readl(disc_table));
header->guid = readl(disc_table + GUID_OFFSET);
@@ -521,8 +529,6 @@ static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
/* Size is measured in DWORDS, but accessor returns bytes */
header->size = GET_SIZE(readl(disc_table + SIZE_OFFSET));
- entry->attr_grp = crashlog->info->attr_grp;
-
return 0;
}
@@ -530,6 +536,7 @@ static DEFINE_XARRAY_ALLOC(crashlog_array);
static struct intel_pmt_namespace pmt_crashlog_ns = {
.name = "crashlog",
.xa = &crashlog_array,
+ .pmt_pre_decode = pmt_crashlog_pre_decode,
.pmt_header_decode = pmt_crashlog_header_decode,
};
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 09/22] platform/x86/intel/pmt/telemetry: Move overlap check to post-decode hook
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (7 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 08/22] platform/x86/intel/pmt/crashlog: Split init into pre-decode David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 10/22] platform/x86/intel/pmt: Move header decode into common helper David E. Box
` (13 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Update the telemetry namespace to use the new PMT class pre/post decode
interface. The overlap check, which previously occurred during header
decode, is now performed in the post-decode hook once header fields are
populated. This preserves existing behavior while reusing the same header
decode logic across PMT drivers.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmt/class.h | 1 +
drivers/platform/x86/intel/pmt/telemetry.c | 24 ++++++++++++++--------
2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
index ff39014b208c..8a0db0ef58c1 100644
--- a/drivers/platform/x86/intel/pmt/class.h
+++ b/drivers/platform/x86/intel/pmt/class.h
@@ -37,6 +37,7 @@ struct intel_pmt_header {
u32 size;
u32 guid;
u8 access_type;
+ u8 telem_type;
};
struct intel_pmt_entry {
diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
index bdc7c24a3678..d22f633638be 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.c
+++ b/drivers/platform/x86/intel/pmt/telemetry.c
@@ -58,14 +58,9 @@ struct pmt_telem_priv {
struct intel_pmt_entry entry[];
};
-static bool pmt_telem_region_overlaps(struct intel_pmt_entry *entry,
- struct device *dev)
+static bool pmt_telem_region_overlaps(struct device *dev, u32 guid, u32 type)
{
- u32 guid = readl(entry->disc_table + TELEM_GUID_OFFSET);
-
if (intel_pmt_is_early_client_hw(dev)) {
- u32 type = TELEM_TYPE(readl(entry->disc_table));
-
if ((type == TELEM_TYPE_PUNIT_FIXED) ||
(guid == TELEM_CLIENT_FIXED_BLOCK_GUID))
return true;
@@ -80,15 +75,25 @@ static int pmt_telem_header_decode(struct intel_pmt_entry *entry,
void __iomem *disc_table = entry->disc_table;
struct intel_pmt_header *header = &entry->header;
- if (pmt_telem_region_overlaps(entry, dev))
- return 1;
-
header->access_type = TELEM_ACCESS(readl(disc_table));
header->guid = readl(disc_table + TELEM_GUID_OFFSET);
header->base_offset = readl(disc_table + TELEM_BASE_OFFSET);
/* Size is measured in DWORDS, but accessor returns bytes */
header->size = TELEM_SIZE(readl(disc_table));
+ header->telem_type = TELEM_TYPE(readl(entry->disc_table));
+
+ return 0;
+}
+
+static int pmt_telem_post_decode(struct intel_vsec_device *ivdev,
+ struct intel_pmt_entry *entry)
+{
+ struct intel_pmt_header *header = &entry->header;
+ struct device *dev = &ivdev->auxdev.dev;
+
+ if (pmt_telem_region_overlaps(dev, header->guid, header->telem_type))
+ return 1;
/*
* Some devices may expose non-functioning entries that are
@@ -131,6 +136,7 @@ static struct intel_pmt_namespace pmt_telem_ns = {
.name = "telem",
.xa = &telem_array,
.pmt_header_decode = pmt_telem_header_decode,
+ .pmt_post_decode = pmt_telem_post_decode,
.pmt_add_endpoint = pmt_telem_add_endpoint,
};
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 10/22] platform/x86/intel/pmt: Move header decode into common helper
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (8 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 09/22] platform/x86/intel/pmt/telemetry: Move overlap check to post-decode hook David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 15:42 ` Ilpo Järvinen
2026-03-13 1:51 ` [PATCH 11/22] platform/x86/intel/pmt: Pass discovery index instead of resource David E. Box
` (12 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Unify PMT discovery table parsing by moving header decode logic into the
class driver. A new helper, pmt_read_header(), now fills in the standard
header fields from the discovery table, replacing the per-namespace
pmt_header_decode callbacks in telemetry and crashlog.
This centralizes the discovery table bit-field definitions in class.h,
removes duplicate decode code from telemetry and crashlog, and prepares the
PMT class for additional discovery sources.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmt/class.c | 38 +++++++++++++++-------
drivers/platform/x86/intel/pmt/class.h | 15 +++++++--
drivers/platform/x86/intel/pmt/crashlog.c | 17 ----------
drivers/platform/x86/intel/pmt/telemetry.c | 26 ---------------
4 files changed, 40 insertions(+), 56 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index 9b315334a69b..a4d6ffed2fed 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -8,6 +8,7 @@
* Author: "Alexander Duyck" <alexander.h.duyck@linux.intel.com>
*/
+#include <linux/bitfield.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/intel_vsec.h>
@@ -368,26 +369,41 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
return ret;
}
-int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns,
- struct intel_vsec_device *intel_vsec_dev, int idx)
+static int pmt_read_header(struct intel_vsec_device *ivdev, int idx,
+ struct intel_pmt_entry *entry)
{
- struct device *dev = &intel_vsec_dev->auxdev.dev;
- struct resource *disc_res;
- int ret;
+ struct intel_pmt_header *header = &entry->header;
+ struct device *dev = &ivdev->auxdev.dev;
+ u64 headers[2];
- disc_res = &intel_vsec_dev->resource[idx];
-
- entry->disc_table = devm_ioremap_resource(dev, disc_res);
+ entry->disc_table = devm_ioremap_resource(dev, &ivdev->resource[idx]);
if (IS_ERR(entry->disc_table))
return PTR_ERR(entry->disc_table);
+ memcpy_fromio(headers, entry->disc_table, 2 * sizeof(u64));
+
+ header->access_type = FIELD_GET(PMT_ACCESS_TYPE, headers[0]);
+ header->telem_type = FIELD_GET(PMT_TELEM_TYPE, headers[0]);
+ /* Size is measured in DWORDS, but accessor returns bytes */
+ header->size = PMT_GET_SIZE(FIELD_GET(PMT_SIZE, headers[0]));
+ header->guid = FIELD_GET(PMT_GUID32, headers[0]);
+ header->base_offset = FIELD_GET(PMT_BASE_OFFSET, headers[1]);
+
+ return 0;
+}
+
+int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns,
+ struct intel_vsec_device *intel_vsec_dev, int idx)
+{
+ int ret;
+
if (ns->pmt_pre_decode) {
ret = ns->pmt_pre_decode(intel_vsec_dev, entry);
if (ret)
return ret;
}
- ret = ns->pmt_header_decode(entry, dev);
+ ret = pmt_read_header(intel_vsec_dev, idx, entry);
if (ret)
return ret;
@@ -397,11 +413,11 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespa
return ret;
}
- ret = intel_pmt_populate_entry(entry, intel_vsec_dev, disc_res);
+ ret = intel_pmt_populate_entry(entry, intel_vsec_dev, &intel_vsec_dev->resource[idx]);
if (ret)
return ret;
- return intel_pmt_dev_register(entry, ns, dev);
+ return intel_pmt_dev_register(entry, ns, &intel_vsec_dev->auxdev.dev);
}
EXPORT_SYMBOL_NS_GPL(intel_pmt_dev_create, "INTEL_PMT");
diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
index 8a0db0ef58c1..06f90c7ce6b3 100644
--- a/drivers/platform/x86/intel/pmt/class.h
+++ b/drivers/platform/x86/intel/pmt/class.h
@@ -11,6 +11,19 @@
#include "telemetry.h"
+/* PMT Discovery Table DWORD 1 */
+#define PMT_ACCESS_TYPE GENMASK_ULL(3, 0)
+#define PMT_TELEM_TYPE GENMASK_ULL(7, 4)
+#define PMT_SIZE GENMASK_ULL(27, 12)
+#define PMT_GUID32 GENMASK_ULL(63, 32)
+
+/* PMT Discovery Table DWORD 2 */
+#define PMT_BASE_OFFSET GENMASK_ULL(31, 0)
+#define PMT_TELE_ID GENMASK_ULL(63, 32)
+
+/* Get size bytes from DWORDs */
+#define PMT_GET_SIZE(v) ((v) << 2)
+
/* PMT access types */
#define ACCESS_BARID 2
#define ACCESS_LOCAL 3
@@ -61,8 +74,6 @@ struct intel_pmt_entry {
struct intel_pmt_namespace {
const char *name;
struct xarray *xa;
- int (*pmt_header_decode)(struct intel_pmt_entry *entry,
- struct device *dev);
int (*pmt_pre_decode)(struct intel_vsec_device *ivdev,
struct intel_pmt_entry *entry);
int (*pmt_post_decode)(struct intel_vsec_device *ivdev,
diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
index f936daf99e4d..67795e2cb1ed 100644
--- a/drivers/platform/x86/intel/pmt/crashlog.c
+++ b/drivers/platform/x86/intel/pmt/crashlog.c
@@ -516,28 +516,11 @@ static int pmt_crashlog_pre_decode(struct intel_vsec_device *ivdev,
return 0;
}
-static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
- struct device *dev)
-{
- void __iomem *disc_table = entry->disc_table;
- struct intel_pmt_header *header = &entry->header;
-
- header->access_type = GET_ACCESS(readl(disc_table));
- header->guid = readl(disc_table + GUID_OFFSET);
- header->base_offset = readl(disc_table + BASE_OFFSET);
-
- /* Size is measured in DWORDS, but accessor returns bytes */
- header->size = GET_SIZE(readl(disc_table + SIZE_OFFSET));
-
- return 0;
-}
-
static DEFINE_XARRAY_ALLOC(crashlog_array);
static struct intel_pmt_namespace pmt_crashlog_ns = {
.name = "crashlog",
.xa = &crashlog_array,
.pmt_pre_decode = pmt_crashlog_pre_decode,
- .pmt_header_decode = pmt_crashlog_header_decode,
};
/*
diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
index d22f633638be..80773e3c3efa 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.c
+++ b/drivers/platform/x86/intel/pmt/telemetry.c
@@ -27,14 +27,6 @@
#include "class.h"
-#define TELEM_SIZE_OFFSET 0x0
-#define TELEM_GUID_OFFSET 0x4
-#define TELEM_BASE_OFFSET 0x8
-#define TELEM_ACCESS(v) ((v) & GENMASK(3, 0))
-#define TELEM_TYPE(v) (((v) & GENMASK(7, 4)) >> 4)
-/* size is in bytes */
-#define TELEM_SIZE(v) (((v) & GENMASK(27, 12)) >> 10)
-
/* Used by client hardware to identify a fixed telemetry entry*/
#define TELEM_CLIENT_FIXED_BLOCK_GUID 0x10000000
@@ -69,23 +61,6 @@ static bool pmt_telem_region_overlaps(struct device *dev, u32 guid, u32 type)
return false;
}
-static int pmt_telem_header_decode(struct intel_pmt_entry *entry,
- struct device *dev)
-{
- void __iomem *disc_table = entry->disc_table;
- struct intel_pmt_header *header = &entry->header;
-
- header->access_type = TELEM_ACCESS(readl(disc_table));
- header->guid = readl(disc_table + TELEM_GUID_OFFSET);
- header->base_offset = readl(disc_table + TELEM_BASE_OFFSET);
-
- /* Size is measured in DWORDS, but accessor returns bytes */
- header->size = TELEM_SIZE(readl(disc_table));
- header->telem_type = TELEM_TYPE(readl(entry->disc_table));
-
- return 0;
-}
-
static int pmt_telem_post_decode(struct intel_vsec_device *ivdev,
struct intel_pmt_entry *entry)
{
@@ -135,7 +110,6 @@ static DEFINE_XARRAY_ALLOC(telem_array);
static struct intel_pmt_namespace pmt_telem_ns = {
.name = "telem",
.xa = &telem_array,
- .pmt_header_decode = pmt_telem_header_decode,
.pmt_post_decode = pmt_telem_post_decode,
.pmt_add_endpoint = pmt_telem_add_endpoint,
};
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 10/22] platform/x86/intel/pmt: Move header decode into common helper
2026-03-13 1:51 ` [PATCH 10/22] platform/x86/intel/pmt: Move header decode into common helper David E. Box
@ 2026-03-17 15:42 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 15:42 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> Unify PMT discovery table parsing by moving header decode logic into the
> class driver. A new helper, pmt_read_header(), now fills in the standard
> header fields from the discovery table, replacing the per-namespace
> pmt_header_decode callbacks in telemetry and crashlog.
>
> This centralizes the discovery table bit-field definitions in class.h,
> removes duplicate decode code from telemetry and crashlog, and prepares the
> PMT class for additional discovery sources.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmt/class.c | 38 +++++++++++++++-------
> drivers/platform/x86/intel/pmt/class.h | 15 +++++++--
> drivers/platform/x86/intel/pmt/crashlog.c | 17 ----------
> drivers/platform/x86/intel/pmt/telemetry.c | 26 ---------------
> 4 files changed, 40 insertions(+), 56 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
> index 9b315334a69b..a4d6ffed2fed 100644
> --- a/drivers/platform/x86/intel/pmt/class.c
> +++ b/drivers/platform/x86/intel/pmt/class.c
> @@ -8,6 +8,7 @@
> * Author: "Alexander Duyck" <alexander.h.duyck@linux.intel.com>
> */
>
> +#include <linux/bitfield.h>
> #include <linux/kernel.h>
> #include <linux/log2.h>
> #include <linux/intel_vsec.h>
> @@ -368,26 +369,41 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
> return ret;
> }
>
> -int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns,
> - struct intel_vsec_device *intel_vsec_dev, int idx)
> +static int pmt_read_header(struct intel_vsec_device *ivdev, int idx,
> + struct intel_pmt_entry *entry)
> {
> - struct device *dev = &intel_vsec_dev->auxdev.dev;
> - struct resource *disc_res;
> - int ret;
> + struct intel_pmt_header *header = &entry->header;
> + struct device *dev = &ivdev->auxdev.dev;
> + u64 headers[2];
>
> - disc_res = &intel_vsec_dev->resource[idx];
> -
> - entry->disc_table = devm_ioremap_resource(dev, disc_res);
> + entry->disc_table = devm_ioremap_resource(dev, &ivdev->resource[idx]);
> if (IS_ERR(entry->disc_table))
> return PTR_ERR(entry->disc_table);
>
> + memcpy_fromio(headers, entry->disc_table, 2 * sizeof(u64));
> +
> + header->access_type = FIELD_GET(PMT_ACCESS_TYPE, headers[0]);
> + header->telem_type = FIELD_GET(PMT_TELEM_TYPE, headers[0]);
> + /* Size is measured in DWORDS, but accessor returns bytes */
> + header->size = PMT_GET_SIZE(FIELD_GET(PMT_SIZE, headers[0]));
IMO, the FIELD_GET() could be done within the macro as the macro itself
is PMT SIZE specific.
Perhaps name it such that the name indicates unit as you currently end up
using comments to explain that.
> + header->guid = FIELD_GET(PMT_GUID32, headers[0]);
> + header->base_offset = FIELD_GET(PMT_BASE_OFFSET, headers[1]);
> +
> + return 0;
> +}
> +
> +int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns,
> + struct intel_vsec_device *intel_vsec_dev, int idx)
> +{
> + int ret;
> +
> if (ns->pmt_pre_decode) {
> ret = ns->pmt_pre_decode(intel_vsec_dev, entry);
> if (ret)
> return ret;
> }
>
> - ret = ns->pmt_header_decode(entry, dev);
> + ret = pmt_read_header(intel_vsec_dev, idx, entry);
> if (ret)
> return ret;
>
> @@ -397,11 +413,11 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespa
> return ret;
> }
>
> - ret = intel_pmt_populate_entry(entry, intel_vsec_dev, disc_res);
> + ret = intel_pmt_populate_entry(entry, intel_vsec_dev, &intel_vsec_dev->resource[idx]);
> if (ret)
> return ret;
>
> - return intel_pmt_dev_register(entry, ns, dev);
> + return intel_pmt_dev_register(entry, ns, &intel_vsec_dev->auxdev.dev);
> }
> EXPORT_SYMBOL_NS_GPL(intel_pmt_dev_create, "INTEL_PMT");
>
> diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
> index 8a0db0ef58c1..06f90c7ce6b3 100644
> --- a/drivers/platform/x86/intel/pmt/class.h
> +++ b/drivers/platform/x86/intel/pmt/class.h
> @@ -11,6 +11,19 @@
>
> #include "telemetry.h"
>
> +/* PMT Discovery Table DWORD 1 */
> +#define PMT_ACCESS_TYPE GENMASK_ULL(3, 0)
> +#define PMT_TELEM_TYPE GENMASK_ULL(7, 4)
> +#define PMT_SIZE GENMASK_ULL(27, 12)
> +#define PMT_GUID32 GENMASK_ULL(63, 32)
> +
> +/* PMT Discovery Table DWORD 2 */
> +#define PMT_BASE_OFFSET GENMASK_ULL(31, 0)
> +#define PMT_TELE_ID GENMASK_ULL(63, 32)
> +
> +/* Get size bytes from DWORDs */
> +#define PMT_GET_SIZE(v) ((v) << 2)
Use (v) * sizeof(u32) or something along those lines.
> +
> /* PMT access types */
> #define ACCESS_BARID 2
> #define ACCESS_LOCAL 3
> @@ -61,8 +74,6 @@ struct intel_pmt_entry {
> struct intel_pmt_namespace {
> const char *name;
> struct xarray *xa;
> - int (*pmt_header_decode)(struct intel_pmt_entry *entry,
> - struct device *dev);
> int (*pmt_pre_decode)(struct intel_vsec_device *ivdev,
> struct intel_pmt_entry *entry);
> int (*pmt_post_decode)(struct intel_vsec_device *ivdev,
> diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
> index f936daf99e4d..67795e2cb1ed 100644
> --- a/drivers/platform/x86/intel/pmt/crashlog.c
> +++ b/drivers/platform/x86/intel/pmt/crashlog.c
> @@ -516,28 +516,11 @@ static int pmt_crashlog_pre_decode(struct intel_vsec_device *ivdev,
> return 0;
> }
>
> -static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
> - struct device *dev)
> -{
> - void __iomem *disc_table = entry->disc_table;
> - struct intel_pmt_header *header = &entry->header;
> -
> - header->access_type = GET_ACCESS(readl(disc_table));
> - header->guid = readl(disc_table + GUID_OFFSET);
> - header->base_offset = readl(disc_table + BASE_OFFSET);
> -
> - /* Size is measured in DWORDS, but accessor returns bytes */
> - header->size = GET_SIZE(readl(disc_table + SIZE_OFFSET));
The macros become unused after this but were not removed?
Overall, this change is nice consolidation. :-)
--
i.
> -
> - return 0;
> -}
> -
> static DEFINE_XARRAY_ALLOC(crashlog_array);
> static struct intel_pmt_namespace pmt_crashlog_ns = {
> .name = "crashlog",
> .xa = &crashlog_array,
> .pmt_pre_decode = pmt_crashlog_pre_decode,
> - .pmt_header_decode = pmt_crashlog_header_decode,
> };
>
> /*
> diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
> index d22f633638be..80773e3c3efa 100644
> --- a/drivers/platform/x86/intel/pmt/telemetry.c
> +++ b/drivers/platform/x86/intel/pmt/telemetry.c
> @@ -27,14 +27,6 @@
>
> #include "class.h"
>
> -#define TELEM_SIZE_OFFSET 0x0
> -#define TELEM_GUID_OFFSET 0x4
> -#define TELEM_BASE_OFFSET 0x8
> -#define TELEM_ACCESS(v) ((v) & GENMASK(3, 0))
> -#define TELEM_TYPE(v) (((v) & GENMASK(7, 4)) >> 4)
> -/* size is in bytes */
> -#define TELEM_SIZE(v) (((v) & GENMASK(27, 12)) >> 10)
> -
> /* Used by client hardware to identify a fixed telemetry entry*/
> #define TELEM_CLIENT_FIXED_BLOCK_GUID 0x10000000
>
> @@ -69,23 +61,6 @@ static bool pmt_telem_region_overlaps(struct device *dev, u32 guid, u32 type)
> return false;
> }
>
> -static int pmt_telem_header_decode(struct intel_pmt_entry *entry,
> - struct device *dev)
> -{
> - void __iomem *disc_table = entry->disc_table;
> - struct intel_pmt_header *header = &entry->header;
> -
> - header->access_type = TELEM_ACCESS(readl(disc_table));
> - header->guid = readl(disc_table + TELEM_GUID_OFFSET);
> - header->base_offset = readl(disc_table + TELEM_BASE_OFFSET);
> -
> - /* Size is measured in DWORDS, but accessor returns bytes */
> - header->size = TELEM_SIZE(readl(disc_table));
> - header->telem_type = TELEM_TYPE(readl(entry->disc_table));
> -
> - return 0;
> -}
> -
> static int pmt_telem_post_decode(struct intel_vsec_device *ivdev,
> struct intel_pmt_entry *entry)
> {
> @@ -135,7 +110,6 @@ static DEFINE_XARRAY_ALLOC(telem_array);
> static struct intel_pmt_namespace pmt_telem_ns = {
> .name = "telem",
> .xa = &telem_array,
> - .pmt_header_decode = pmt_telem_header_decode,
> .pmt_post_decode = pmt_telem_post_decode,
> .pmt_add_endpoint = pmt_telem_add_endpoint,
> };
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 11/22] platform/x86/intel/pmt: Pass discovery index instead of resource
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (9 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 10/22] platform/x86/intel/pmt: Move header decode into common helper David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 12/22] platform/x86/intel/pmt: Unify header fetch and add ACPI source David E. Box
` (11 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Change PMT class code to pass a discovery index rather than a direct struct
resource when creating entries. This allows the class to identify the
discovery source generically without assuming PCI BAR resources. For PCI
devices, the index still resolves to a resource in the intel_vsec_device.
Other discovery sources, such as ACPI, can use the same index without
needing a struct resource.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmt/class.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index a4d6ffed2fed..f94f51178043 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -207,11 +207,12 @@ EXPORT_SYMBOL_GPL(intel_pmt_class);
static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
struct intel_vsec_device *ivdev,
- struct resource *disc_res)
+ int idx)
{
struct pci_dev *pci_dev = to_pci_dev(ivdev->dev);
struct device *dev = &ivdev->auxdev.dev;
struct intel_pmt_header *header = &entry->header;
+ struct resource *disc_res;
u8 bir;
/*
@@ -236,6 +237,7 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
* For access_type LOCAL, the base address is as follows:
* base address = end of discovery region + base offset
*/
+ disc_res = &ivdev->resource[idx];
entry->base_addr = disc_res->end + 1 + header->base_offset;
/*
@@ -413,7 +415,7 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespa
return ret;
}
- ret = intel_pmt_populate_entry(entry, intel_vsec_dev, &intel_vsec_dev->resource[idx]);
+ ret = intel_pmt_populate_entry(entry, intel_vsec_dev, idx);
if (ret)
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 12/22] platform/x86/intel/pmt: Unify header fetch and add ACPI source
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (10 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 11/22] platform/x86/intel/pmt: Pass discovery index instead of resource David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 15:57 ` Ilpo Järvinen
2026-03-13 1:51 ` [PATCH 13/22] platform/x86/intel/pmc: Add PMC SSRAM Kconfig description David E. Box
` (10 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Allow the PMT class to read discovery headers from either PCI MMIO or
ACPI-provided entries, depending on the discovery source. The new
source-aware fetch helper retrieves the first two QWORDs for both paths
while keeping the mapped discovery table available for users such as
crashlog.
Split intel_pmt_populate_entry() into source-specific resolvers:
- pmt_resolve_access_pci(): handles both ACCESS_LOCAL and ACCESS_BARID
for PCI-backed devices and sets entry->pcidev. Same existing
functionality.
- pmt_resolve_access_acpi(): handles only ACCESS_BARID for ACPI-backed
devices, rejecting ACCESS_LOCAL which has no valid semantics without
a physical discovery resource.
This maintains existing PCI behavior and makes no functional changes
for PCI devices.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmt/class.c | 124 +++++++++++++++++++++++--
1 file changed, 115 insertions(+), 9 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index f94f51178043..ddd9c4bf7323 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -205,9 +205,9 @@ struct class intel_pmt_class = {
};
EXPORT_SYMBOL_GPL(intel_pmt_class);
-static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
- struct intel_vsec_device *ivdev,
- int idx)
+static int pmt_resolve_access_pci(struct intel_pmt_entry *entry,
+ struct intel_vsec_device *ivdev,
+ int idx)
{
struct pci_dev *pci_dev = to_pci_dev(ivdev->dev);
struct device *dev = &ivdev->auxdev.dev;
@@ -287,6 +287,82 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
}
entry->pcidev = pci_dev;
+
+ return 0;
+}
+
+static int pmt_resolve_access_acpi(struct intel_pmt_entry *entry,
+ struct intel_vsec_device *ivdev)
+{
+ struct pci_dev *pci_dev = NULL;
+ struct device *dev = &ivdev->auxdev.dev;
+ struct intel_pmt_header *header = &entry->header;
+ u8 bir;
+
+ if (dev_is_pci(ivdev->dev))
+ pci_dev = to_pci_dev(ivdev->dev);
+
+ /*
+ * The base offset should always be 8 byte aligned.
+ *
+ * For non-local access types the lower 3 bits of base offset
+ * contains the index of the base address register where the
+ * telemetry can be found.
+ */
+ bir = GET_BIR(header->base_offset);
+
+ switch (header->access_type) {
+ case ACCESS_BARID:
+ /* ACPI platform drivers use base_addr */
+ if (ivdev->base_addr) {
+ entry->base_addr = ivdev->base_addr +
+ GET_ADDRESS(header->base_offset);
+ break;
+ }
+
+ /* If base_addr is not provided, then this is an ACPI companion device */
+ if (!pci_dev) {
+ dev_err(dev,
+ "ACCESS_BARID requires PCI BAR resources or base_addr\n");
+ return -EINVAL;
+ }
+
+ entry->base_addr = pci_resource_start(pci_dev, bir) +
+ GET_ADDRESS(header->base_offset);
+ break;
+ default:
+ dev_err(dev, "Unsupported access type %d for ACPI based PMT\n",
+ header->access_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
+ struct intel_vsec_device *ivdev,
+ int idx)
+{
+ struct intel_pmt_header *header = &entry->header;
+ struct device *dev = &ivdev->auxdev.dev;
+ int ret;
+
+ switch (ivdev->src) {
+ case INTEL_VSEC_DISC_PCI:
+ ret = pmt_resolve_access_pci(entry, ivdev, idx);
+ break;
+ case INTEL_VSEC_DISC_ACPI:
+ ret = pmt_resolve_access_acpi(entry, ivdev);
+ break;
+ default:
+ dev_err(dev, "Unknown discovery source: %d\n", ivdev->src);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret)
+ return ret;
+
entry->guid = header->guid;
entry->size = header->size;
entry->cb = ivdev->priv_data;
@@ -371,18 +447,48 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
return ret;
}
+static int pmt_get_headers(struct intel_vsec_device *ivdev, int idx,
+ struct intel_pmt_entry *entry, u64 headers[2])
+{
+ struct device *dev = &ivdev->auxdev.dev;
+
+ switch (ivdev->src) {
+ case INTEL_VSEC_DISC_PCI: {
+ void __iomem *disc_table;
+
+ disc_table = devm_ioremap_resource(dev, &ivdev->resource[idx]);
+ if (IS_ERR(disc_table))
+ return PTR_ERR(disc_table);
+
+ memcpy_fromio(headers, disc_table, 2 * sizeof(u64));
+
+ /* Used by crashlog driver */
+ entry->disc_table = disc_table;
+
+ return 0;
+ }
+ case INTEL_VSEC_DISC_ACPI:
+ memcpy(headers, &ivdev->acpi_disc[idx][0], 2 * sizeof(u64));
+
+ return 0;
+ default:
+ dev_err(dev, "Unknown discovery source type: %d\n", ivdev->src);
+ break;
+ }
+
+ return -EINVAL;
+}
+
static int pmt_read_header(struct intel_vsec_device *ivdev, int idx,
struct intel_pmt_entry *entry)
{
struct intel_pmt_header *header = &entry->header;
- struct device *dev = &ivdev->auxdev.dev;
u64 headers[2];
+ int ret;
- entry->disc_table = devm_ioremap_resource(dev, &ivdev->resource[idx]);
- if (IS_ERR(entry->disc_table))
- return PTR_ERR(entry->disc_table);
-
- memcpy_fromio(headers, entry->disc_table, 2 * sizeof(u64));
+ ret = pmt_get_headers(ivdev, idx, entry, headers);
+ if (ret)
+ return ret;
header->access_type = FIELD_GET(PMT_ACCESS_TYPE, headers[0]);
header->telem_type = FIELD_GET(PMT_TELEM_TYPE, headers[0]);
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 12/22] platform/x86/intel/pmt: Unify header fetch and add ACPI source
2026-03-13 1:51 ` [PATCH 12/22] platform/x86/intel/pmt: Unify header fetch and add ACPI source David E. Box
@ 2026-03-17 15:57 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 15:57 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> Allow the PMT class to read discovery headers from either PCI MMIO or
> ACPI-provided entries, depending on the discovery source. The new
> source-aware fetch helper retrieves the first two QWORDs for both paths
> while keeping the mapped discovery table available for users such as
> crashlog.
>
> Split intel_pmt_populate_entry() into source-specific resolvers:
> - pmt_resolve_access_pci(): handles both ACCESS_LOCAL and ACCESS_BARID
> for PCI-backed devices and sets entry->pcidev. Same existing
> functionality.
> - pmt_resolve_access_acpi(): handles only ACCESS_BARID for ACPI-backed
> devices, rejecting ACCESS_LOCAL which has no valid semantics without
> a physical discovery resource.
>
> This maintains existing PCI behavior and makes no functional changes
> for PCI devices.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmt/class.c | 124 +++++++++++++++++++++++--
> 1 file changed, 115 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
> index f94f51178043..ddd9c4bf7323 100644
> --- a/drivers/platform/x86/intel/pmt/class.c
> +++ b/drivers/platform/x86/intel/pmt/class.c
> @@ -205,9 +205,9 @@ struct class intel_pmt_class = {
> };
> EXPORT_SYMBOL_GPL(intel_pmt_class);
>
> -static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
> - struct intel_vsec_device *ivdev,
> - int idx)
> +static int pmt_resolve_access_pci(struct intel_pmt_entry *entry,
> + struct intel_vsec_device *ivdev,
> + int idx)
> {
> struct pci_dev *pci_dev = to_pci_dev(ivdev->dev);
> struct device *dev = &ivdev->auxdev.dev;
> @@ -287,6 +287,82 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
> }
>
> entry->pcidev = pci_dev;
> +
> + return 0;
> +}
> +
> +static int pmt_resolve_access_acpi(struct intel_pmt_entry *entry,
> + struct intel_vsec_device *ivdev)
> +{
> + struct pci_dev *pci_dev = NULL;
> + struct device *dev = &ivdev->auxdev.dev;
> + struct intel_pmt_header *header = &entry->header;
> + u8 bir;
> +
> + if (dev_is_pci(ivdev->dev))
> + pci_dev = to_pci_dev(ivdev->dev);
> +
> + /*
> + * The base offset should always be 8 byte aligned.
> + *
> + * For non-local access types the lower 3 bits of base offset
> + * contains the index of the base address register where the
> + * telemetry can be found.
> + */
> + bir = GET_BIR(header->base_offset);
> +
> + switch (header->access_type) {
> + case ACCESS_BARID:
> + /* ACPI platform drivers use base_addr */
> + if (ivdev->base_addr) {
> + entry->base_addr = ivdev->base_addr +
> + GET_ADDRESS(header->base_offset);
> + break;
> + }
> +
> + /* If base_addr is not provided, then this is an ACPI companion device */
> + if (!pci_dev) {
> + dev_err(dev,
> + "ACCESS_BARID requires PCI BAR resources or base_addr\n");
IMO the extra line is not very useful here.
> + return -EINVAL;
> + }
> +
> + entry->base_addr = pci_resource_start(pci_dev, bir) +
> + GET_ADDRESS(header->base_offset);
> + break;
> + default:
> + dev_err(dev, "Unsupported access type %d for ACPI based PMT\n",
> + header->access_type);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
> + struct intel_vsec_device *ivdev,
> + int idx)
> +{
> + struct intel_pmt_header *header = &entry->header;
> + struct device *dev = &ivdev->auxdev.dev;
> + int ret;
> +
> + switch (ivdev->src) {
> + case INTEL_VSEC_DISC_PCI:
> + ret = pmt_resolve_access_pci(entry, ivdev, idx);
> + break;
> + case INTEL_VSEC_DISC_ACPI:
> + ret = pmt_resolve_access_acpi(entry, ivdev);
> + break;
> + default:
> + dev_err(dev, "Unknown discovery source: %d\n", ivdev->src);
> + ret = -EINVAL;
> + break;
> + }
> +
> + if (ret)
> + return ret;
Instead of deferring to after the switch/case, I'd prefer you handle the
errors within the cases as it, while longer by a few lines, makes
following the logic easier.
> +
> entry->guid = header->guid;
> entry->size = header->size;
> entry->cb = ivdev->priv_data;
> @@ -371,18 +447,48 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
> return ret;
> }
>
> +static int pmt_get_headers(struct intel_vsec_device *ivdev, int idx,
> + struct intel_pmt_entry *entry, u64 headers[2])
> +{
> + struct device *dev = &ivdev->auxdev.dev;
> +
> + switch (ivdev->src) {
> + case INTEL_VSEC_DISC_PCI: {
> + void __iomem *disc_table;
> +
> + disc_table = devm_ioremap_resource(dev, &ivdev->resource[idx]);
> + if (IS_ERR(disc_table))
> + return PTR_ERR(disc_table);
> +
> + memcpy_fromio(headers, disc_table, 2 * sizeof(u64));
> +
> + /* Used by crashlog driver */
> + entry->disc_table = disc_table;
> +
> + return 0;
> + }
> + case INTEL_VSEC_DISC_ACPI:
> + memcpy(headers, &ivdev->acpi_disc[idx][0], 2 * sizeof(u64));
> +
> + return 0;
> + default:
> + dev_err(dev, "Unknown discovery source type: %d\n", ivdev->src);
> + break;
> + }
> +
> + return -EINVAL;
> +}
> +
> static int pmt_read_header(struct intel_vsec_device *ivdev, int idx,
> struct intel_pmt_entry *entry)
> {
> struct intel_pmt_header *header = &entry->header;
> - struct device *dev = &ivdev->auxdev.dev;
> u64 headers[2];
> + int ret;
>
> - entry->disc_table = devm_ioremap_resource(dev, &ivdev->resource[idx]);
> - if (IS_ERR(entry->disc_table))
> - return PTR_ERR(entry->disc_table);
> -
> - memcpy_fromio(headers, entry->disc_table, 2 * sizeof(u64));
> + ret = pmt_get_headers(ivdev, idx, entry, headers);
> + if (ret)
> + return ret;
>
> header->access_type = FIELD_GET(PMT_ACCESS_TYPE, headers[0]);
> header->telem_type = FIELD_GET(PMT_TELEM_TYPE, headers[0]);
>
--
i.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 13/22] platform/x86/intel/pmc: Add PMC SSRAM Kconfig description
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (11 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 12/22] platform/x86/intel/pmt: Unify header fetch and add ACPI source David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 14/22] platform/x86/intel/pmc: Add ACPI PWRM telemetry driver for Nova Lake S David E. Box
` (9 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Add a proper description for the intel_pmc_ssram driver.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmc/Kconfig | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/platform/x86/intel/pmc/Kconfig b/drivers/platform/x86/intel/pmc/Kconfig
index c6ef0bcf76af..0f19dc7edcf9 100644
--- a/drivers/platform/x86/intel/pmc/Kconfig
+++ b/drivers/platform/x86/intel/pmc/Kconfig
@@ -28,3 +28,14 @@ config INTEL_PMC_CORE
config INTEL_PMC_SSRAM_TELEMETRY
tristate
+ help
+ This PCI driver discovers PMC SSRAM telemetry regions through the
+ PMC's MMIO interface and registers them with the Intel VSEC framework
+ as Intel PMT telemetry devices.
+
+ It probes the PMC SSRAM device, extracts DVSEC information from MMIO,
+ reads device IDs and base addresses for multiple PMCs (main, IOE, PCH),
+ and exposes the discovered telemetry through Intel PMT interfaces
+ (including sysfs).
+
+ This option is selected by INTEL_PMC_CORE.
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 14/22] platform/x86/intel/pmc: Add ACPI PWRM telemetry driver for Nova Lake S
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (12 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 13/22] platform/x86/intel/pmc: Add PMC SSRAM Kconfig description David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 16:24 ` Ilpo Järvinen
2026-03-13 1:51 ` [PATCH 15/22] platform/x86/intel/pmc/ssram: Rename probe and PCI ID table for consistency David E. Box
` (8 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Add an ACPI-based PMC PWRM telemetry driver for Nova Lake S. The driver
locates PMT discovery data in _DSD under the Intel VSEC UUID, parses it,
and registers telemetry regions with the PMT/VSEC framework so PMC
telemetry is exposed via existing PMT interfaces.
Export pmc_parse_telem_dsd() and pmc_find_telem_guid() to support ACPI
discovery in other PMC drivers (e.g., ssram_telemetry) without duplicating
ACPI parsing logic. Also export acpi_disc_t typedef from core.h for callers
to properly declare discovery table arrays.
Selected by INTEL_PMC_CORE. Existing PCI functionality is preserved.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmc/Kconfig | 14 ++
drivers/platform/x86/intel/pmc/Makefile | 2 +
drivers/platform/x86/intel/pmc/core.h | 12 +
.../platform/x86/intel/pmc/pwrm_telemetry.c | 227 ++++++++++++++++++
4 files changed, 255 insertions(+)
create mode 100644 drivers/platform/x86/intel/pmc/pwrm_telemetry.c
diff --git a/drivers/platform/x86/intel/pmc/Kconfig b/drivers/platform/x86/intel/pmc/Kconfig
index 0f19dc7edcf9..937186b0b5dd 100644
--- a/drivers/platform/x86/intel/pmc/Kconfig
+++ b/drivers/platform/x86/intel/pmc/Kconfig
@@ -9,6 +9,7 @@ config INTEL_PMC_CORE
depends on ACPI
depends on INTEL_PMT_TELEMETRY
select INTEL_PMC_SSRAM_TELEMETRY
+ select INTEL_PMC_PWRM_TELEMETRY
help
The Intel Platform Controller Hub for Intel Core SoCs provides access
to Power Management Controller registers via various interfaces. This
@@ -39,3 +40,16 @@ config INTEL_PMC_SSRAM_TELEMETRY
(including sysfs).
This option is selected by INTEL_PMC_CORE.
+
+config INTEL_PMC_PWRM_TELEMETRY
+ tristate
+ help
+ This driver discovers PMC PWRM telemetry regions described in ACPI
+ _DSD and registers them with the Intel VSEC framework as Intel PMT
+ telemetry devices.
+
+ It validates the ACPI discovery data and publishes the discovered
+ regions so they can be accessed through the Intel PMT telemetry
+ interfaces (including sysfs).
+
+ This option is selected by INTEL_PMC_CORE.
diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
index bb960c8721d7..fdbb768f7b09 100644
--- a/drivers/platform/x86/intel/pmc/Makefile
+++ b/drivers/platform/x86/intel/pmc/Makefile
@@ -12,3 +12,5 @@ obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core_pltdrv.o
# Intel PMC SSRAM driver
intel_pmc_ssram_telemetry-y += ssram_telemetry.o
obj-$(CONFIG_INTEL_PMC_SSRAM_TELEMETRY) += intel_pmc_ssram_telemetry.o
+intel_pmc_pwrm_telemetry-y += pwrm_telemetry.o
+obj-$(CONFIG_INTEL_PMC_PWRM_TELEMETRY) += intel_pmc_pwrm_telemetry.o
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 118c8740ad3a..284aced99f72 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -562,6 +562,8 @@ int pmc_core_pmt_get_blk_sub_req(struct pmc_dev *pmcdev, struct pmc *pmc,
extern const struct file_operations pmc_core_substate_req_regs_fops;
extern const struct file_operations pmc_core_substate_blk_req_fops;
+extern const guid_t intel_vsec_guid;
+
#define pmc_for_each_mode(mode, pmc) \
for (unsigned int __i = 0, __cond; \
__cond = __i < (pmc)->num_lpm_modes, \
@@ -583,4 +585,14 @@ static const struct file_operations __name ## _fops = { \
.release = single_release, \
}
+struct intel_vsec_header;
+union acpi_object;
+
+/* Avoid checkpatch warning */
+typedef u32 (*acpi_disc_t)[4];
+
+int pmc_parse_telem_dsd(union acpi_object *obj,
+ struct intel_vsec_header *header,
+ acpi_disc_t *acpi_disc);
+union acpi_object *pmc_find_telem_guid(union acpi_object *dsd);
#endif /* PMC_CORE_H */
diff --git a/drivers/platform/x86/intel/pmc/pwrm_telemetry.c b/drivers/platform/x86/intel/pmc/pwrm_telemetry.c
new file mode 100644
index 000000000000..25ca6979c214
--- /dev/null
+++ b/drivers/platform/x86/intel/pmc/pwrm_telemetry.c
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Intel PMC PWRM ACPI driver
+ *
+ * Copyright (C) 2025, Intel Corporation
+ */
+
+#include <linux/acpi.h>
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/intel_vsec.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+
+#include "core.h"
+
+#define ENTRY_LEN 5
+
+/* DWORD2 */
+#define DVSEC_ID_MASK GENMASK(15, 0)
+#define NUM_ENTRIES_MASK GENMASK(23, 16)
+#define ENTRY_SIZE_MASK GENMASK(31, 24)
+
+/* DWORD3 */
+#define TBIR_MASK GENMASK(2, 0)
+#define DISC_TBL_OFF_MASK GENMASK(31, 3)
+
+const guid_t intel_vsec_guid =
+ GUID_INIT(0x294903fb, 0x634d, 0x4fc7, 0xaf, 0x1f, 0x0f, 0xb9,
+ 0x56, 0xb0, 0x4f, 0xc1);
+
+static bool is_valid_entry(union acpi_object *pkg)
+{
+ int i;
+
+ if (!pkg || pkg->type != ACPI_TYPE_PACKAGE || pkg->package.count != ENTRY_LEN)
+ return false;
+
+ if (pkg->package.elements[0].type != ACPI_TYPE_STRING)
+ return false;
+
+ for (i = 1; i < ENTRY_LEN; i++)
+ if (pkg->package.elements[i].type != ACPI_TYPE_INTEGER)
+ return false;
+
+ return true;
+}
+
+int pmc_parse_telem_dsd(union acpi_object *obj,
+ struct intel_vsec_header *header,
+ u32 (**acpi_disc)[4])
+{
+ union acpi_object *vsec_pkg;
+ union acpi_object *disc_pkg;
+ u64 hdr0;
+ u64 hdr1;
+ int num_regions;
+ int i;
+
+ if (!header)
+ return -EINVAL;
+
+ if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 2)
+ return -EINVAL;
+
+ /* First Package is DVSEC info */
+ vsec_pkg = &obj->package.elements[0];
+ if (!is_valid_entry(vsec_pkg))
+ return -EINVAL;
+
+ hdr0 = vsec_pkg->package.elements[3].integer.value;
+ hdr1 = vsec_pkg->package.elements[4].integer.value;
+
+ header->id = FIELD_GET(DVSEC_ID_MASK, hdr0);
+ header->num_entries = FIELD_GET(NUM_ENTRIES_MASK, hdr0);
+ header->entry_size = FIELD_GET(ENTRY_SIZE_MASK, hdr0);
+ header->tbir = FIELD_GET(TBIR_MASK, hdr1);
+ header->offset = FIELD_GET(DISC_TBL_OFF_MASK, hdr1);
+
+ /* Second Package contains the discovery tables */
+ disc_pkg = &obj->package.elements[1];
+ if (disc_pkg->type != ACPI_TYPE_PACKAGE || disc_pkg->package.count < 1)
+ return -EINVAL;
+
+ num_regions = disc_pkg->package.count;
+ if (header->num_entries != num_regions)
+ return -EINVAL;
+
+ *acpi_disc = kmalloc_array(num_regions, sizeof(**acpi_disc), GFP_KERNEL);
+ if (!*acpi_disc)
+ return -ENOMEM;
+
+ for (i = 0; i < num_regions; i++) {
+ union acpi_object *pkg;
+ u64 value;
+ int j;
+
+ pkg = &disc_pkg->package.elements[i];
+ if (!is_valid_entry(pkg)) {
+ kfree(*acpi_disc);
+ return -EINVAL;
+ }
+
+ /* Element 0 is a descriptive string; DWORD values start at index 1. */
+ for (j = 1; j < ENTRY_LEN; j++) {
+ value = pkg->package.elements[j].integer.value;
+ if (value > U32_MAX) {
+ kfree(*acpi_disc);
+ return -ERANGE;
+ }
+
+ (*acpi_disc)[i][j - 1] = value;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(pmc_parse_telem_dsd, "INTEL_PMC_CORE");
+
+union acpi_object *pmc_find_telem_guid(union acpi_object *dsd)
+{
+ int i;
+
+ if (!dsd || dsd->type != ACPI_TYPE_PACKAGE)
+ return NULL;
+
+ for (i = 0; i + 1 < dsd->package.count; i += 2) {
+ union acpi_object *uuid_obj, *data_obj;
+ guid_t uuid;
+
+ uuid_obj = &dsd->package.elements[i];
+ data_obj = &dsd->package.elements[i + 1];
+
+ if (uuid_obj->type != ACPI_TYPE_BUFFER ||
+ uuid_obj->buffer.length != 16)
+ continue;
+
+ memcpy(&uuid, uuid_obj->buffer.pointer, 16);
+ if (guid_equal(&uuid, &intel_vsec_guid))
+ return data_obj;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS_GPL(pmc_find_telem_guid, "INTEL_PMC_CORE");
+
+static int pmc_pwrm_acpi_probe(struct platform_device *pdev)
+{
+ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
+ acpi_handle handle = ACPI_HANDLE(&pdev->dev);
+ struct intel_vsec_header header;
+ struct intel_vsec_header *headers[2] = { &header, NULL };
+ struct intel_vsec_platform_info info = { };
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ u32 (*acpi_disc)[4];
+ union acpi_object *dsd;
+ acpi_status status;
+ int ret;
+
+ if (!handle)
+ return -ENODEV;
+
+ status = acpi_evaluate_object(handle, "_DSD", NULL, &buf);
+ if (ACPI_FAILURE(status))
+ return dev_err_probe(dev, -ENODEV, "Could not evaluate _DSD: %s\n",
+ acpi_format_exception(status));
+
+ dsd = pmc_find_telem_guid(buf.pointer);
+ if (!dsd) {
+ ret = -ENODEV;
+ goto cleanup_acpi_buf;
+ }
+
+ ret = pmc_parse_telem_dsd(dsd, &header, &acpi_disc);
+ if (ret)
+ goto cleanup_acpi_buf;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, header.tbir);
+ if (!res) {
+ ret = -EINVAL;
+ goto cleanup_acpi_disc;
+ }
+
+ info.headers = headers;
+ info.caps = VSEC_CAP_TELEMETRY;
+ info.acpi_disc = acpi_disc;
+ info.src = INTEL_VSEC_DISC_ACPI;
+ info.base_addr = res->start;
+
+ ret = intel_vsec_register(&pdev->dev, &info);
+
+cleanup_acpi_disc:
+ kfree(acpi_disc);
+cleanup_acpi_buf:
+ ACPI_FREE(buf.pointer);
+
+ return ret;
+}
+
+static const struct acpi_device_id pmc_pwrm_acpi_ids[] = {
+ { "INTC1122", 0 }, /* Nova Lake */
+ { "INTC1129", 0 }, /* Nova Lake */
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, pmc_pwrm_acpi_ids);
+
+static struct platform_driver pmc_pwrm_acpi_driver = {
+ .probe = pmc_pwrm_acpi_probe,
+ .driver = {
+ .name = "intel_pmc_pwrm_acpi",
+ .acpi_match_table = ACPI_PTR(pmc_pwrm_acpi_ids),
+ },
+};
+module_platform_driver(pmc_pwrm_acpi_driver);
+
+MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
+MODULE_DESCRIPTION("Intel PMC PWRM ACPI driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("INTEL_VSEC");
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 14/22] platform/x86/intel/pmc: Add ACPI PWRM telemetry driver for Nova Lake S
2026-03-13 1:51 ` [PATCH 14/22] platform/x86/intel/pmc: Add ACPI PWRM telemetry driver for Nova Lake S David E. Box
@ 2026-03-17 16:24 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 16:24 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> Add an ACPI-based PMC PWRM telemetry driver for Nova Lake S. The driver
> locates PMT discovery data in _DSD under the Intel VSEC UUID, parses it,
> and registers telemetry regions with the PMT/VSEC framework so PMC
> telemetry is exposed via existing PMT interfaces.
>
> Export pmc_parse_telem_dsd() and pmc_find_telem_guid() to support ACPI
> discovery in other PMC drivers (e.g., ssram_telemetry) without duplicating
> ACPI parsing logic. Also export acpi_disc_t typedef from core.h for callers
> to properly declare discovery table arrays.
>
> Selected by INTEL_PMC_CORE. Existing PCI functionality is preserved.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/Kconfig | 14 ++
> drivers/platform/x86/intel/pmc/Makefile | 2 +
> drivers/platform/x86/intel/pmc/core.h | 12 +
> .../platform/x86/intel/pmc/pwrm_telemetry.c | 227 ++++++++++++++++++
> 4 files changed, 255 insertions(+)
> create mode 100644 drivers/platform/x86/intel/pmc/pwrm_telemetry.c
>
> diff --git a/drivers/platform/x86/intel/pmc/Kconfig b/drivers/platform/x86/intel/pmc/Kconfig
> index 0f19dc7edcf9..937186b0b5dd 100644
> --- a/drivers/platform/x86/intel/pmc/Kconfig
> +++ b/drivers/platform/x86/intel/pmc/Kconfig
> @@ -9,6 +9,7 @@ config INTEL_PMC_CORE
> depends on ACPI
> depends on INTEL_PMT_TELEMETRY
> select INTEL_PMC_SSRAM_TELEMETRY
> + select INTEL_PMC_PWRM_TELEMETRY
> help
> The Intel Platform Controller Hub for Intel Core SoCs provides access
> to Power Management Controller registers via various interfaces. This
> @@ -39,3 +40,16 @@ config INTEL_PMC_SSRAM_TELEMETRY
> (including sysfs).
>
> This option is selected by INTEL_PMC_CORE.
> +
> +config INTEL_PMC_PWRM_TELEMETRY
> + tristate
> + help
> + This driver discovers PMC PWRM telemetry regions described in ACPI
> + _DSD and registers them with the Intel VSEC framework as Intel PMT
> + telemetry devices.
> +
> + It validates the ACPI discovery data and publishes the discovered
> + regions so they can be accessed through the Intel PMT telemetry
> + interfaces (including sysfs).
> +
> + This option is selected by INTEL_PMC_CORE.
> diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
> index bb960c8721d7..fdbb768f7b09 100644
> --- a/drivers/platform/x86/intel/pmc/Makefile
> +++ b/drivers/platform/x86/intel/pmc/Makefile
> @@ -12,3 +12,5 @@ obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core_pltdrv.o
> # Intel PMC SSRAM driver
> intel_pmc_ssram_telemetry-y += ssram_telemetry.o
> obj-$(CONFIG_INTEL_PMC_SSRAM_TELEMETRY) += intel_pmc_ssram_telemetry.o
> +intel_pmc_pwrm_telemetry-y += pwrm_telemetry.o
> +obj-$(CONFIG_INTEL_PMC_PWRM_TELEMETRY) += intel_pmc_pwrm_telemetry.o
> diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
> index 118c8740ad3a..284aced99f72 100644
> --- a/drivers/platform/x86/intel/pmc/core.h
> +++ b/drivers/platform/x86/intel/pmc/core.h
> @@ -562,6 +562,8 @@ int pmc_core_pmt_get_blk_sub_req(struct pmc_dev *pmcdev, struct pmc *pmc,
> extern const struct file_operations pmc_core_substate_req_regs_fops;
> extern const struct file_operations pmc_core_substate_blk_req_fops;
>
> +extern const guid_t intel_vsec_guid;
Please make sure type is available in this file, not only throught the C
file includes.
> +
> #define pmc_for_each_mode(mode, pmc) \
> for (unsigned int __i = 0, __cond; \
> __cond = __i < (pmc)->num_lpm_modes, \
> @@ -583,4 +585,14 @@ static const struct file_operations __name ## _fops = { \
> .release = single_release, \
> }
>
> +struct intel_vsec_header;
> +union acpi_object;
> +
> +/* Avoid checkpatch warning */
> +typedef u32 (*acpi_disc_t)[4];
> +
> +int pmc_parse_telem_dsd(union acpi_object *obj,
> + struct intel_vsec_header *header,
> + acpi_disc_t *acpi_disc);
> +union acpi_object *pmc_find_telem_guid(union acpi_object *dsd);
> #endif /* PMC_CORE_H */
> diff --git a/drivers/platform/x86/intel/pmc/pwrm_telemetry.c b/drivers/platform/x86/intel/pmc/pwrm_telemetry.c
> new file mode 100644
> index 000000000000..25ca6979c214
> --- /dev/null
> +++ b/drivers/platform/x86/intel/pmc/pwrm_telemetry.c
> @@ -0,0 +1,227 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Intel PMC PWRM ACPI driver
> + *
> + * Copyright (C) 2025, Intel Corporation
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/bitfield.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/intel_vsec.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/resource.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +#include <linux/uuid.h>
> +
> +#include "core.h"
> +
> +#define ENTRY_LEN 5
> +
> +/* DWORD2 */
> +#define DVSEC_ID_MASK GENMASK(15, 0)
GENMASK() needs include too.
> +#define NUM_ENTRIES_MASK GENMASK(23, 16)
> +#define ENTRY_SIZE_MASK GENMASK(31, 24)
> +
> +/* DWORD3 */
> +#define TBIR_MASK GENMASK(2, 0)
> +#define DISC_TBL_OFF_MASK GENMASK(31, 3)
> +
> +const guid_t intel_vsec_guid =
> + GUID_INIT(0x294903fb, 0x634d, 0x4fc7, 0xaf, 0x1f, 0x0f, 0xb9,
> + 0x56, 0xb0, 0x4f, 0xc1);
> +
> +static bool is_valid_entry(union acpi_object *pkg)
> +{
> + int i;
> +
> + if (!pkg || pkg->type != ACPI_TYPE_PACKAGE || pkg->package.count != ENTRY_LEN)
> + return false;
> +
> + if (pkg->package.elements[0].type != ACPI_TYPE_STRING)
> + return false;
> +
> + for (i = 1; i < ENTRY_LEN; i++)
> + if (pkg->package.elements[i].type != ACPI_TYPE_INTEGER)
> + return false;
> +
> + return true;
> +}
> +
> +int pmc_parse_telem_dsd(union acpi_object *obj,
> + struct intel_vsec_header *header,
> + u32 (**acpi_disc)[4])
> +{
> + union acpi_object *vsec_pkg;
> + union acpi_object *disc_pkg;
> + u64 hdr0;
> + u64 hdr1;
u64 hdr0, hdr1;
> + int num_regions;
> + int i;
> +
> + if (!header)
> + return -EINVAL;
> +
> + if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 2)
> + return -EINVAL;
> +
> + /* First Package is DVSEC info */
> + vsec_pkg = &obj->package.elements[0];
> + if (!is_valid_entry(vsec_pkg))
> + return -EINVAL;
> +
> + hdr0 = vsec_pkg->package.elements[3].integer.value;
> + hdr1 = vsec_pkg->package.elements[4].integer.value;
> +
> + header->id = FIELD_GET(DVSEC_ID_MASK, hdr0);
> + header->num_entries = FIELD_GET(NUM_ENTRIES_MASK, hdr0);
> + header->entry_size = FIELD_GET(ENTRY_SIZE_MASK, hdr0);
> + header->tbir = FIELD_GET(TBIR_MASK, hdr1);
> + header->offset = FIELD_GET(DISC_TBL_OFF_MASK, hdr1);
> +
> + /* Second Package contains the discovery tables */
> + disc_pkg = &obj->package.elements[1];
> + if (disc_pkg->type != ACPI_TYPE_PACKAGE || disc_pkg->package.count < 1)
> + return -EINVAL;
> +
> + num_regions = disc_pkg->package.count;
> + if (header->num_entries != num_regions)
> + return -EINVAL;
> +
> + *acpi_disc = kmalloc_array(num_regions, sizeof(**acpi_disc), GFP_KERNEL);
> + if (!*acpi_disc)
> + return -ENOMEM;
> +
> + for (i = 0; i < num_regions; i++) {
> + union acpi_object *pkg;
> + u64 value;
> + int j;
> +
> + pkg = &disc_pkg->package.elements[i];
> + if (!is_valid_entry(pkg)) {
> + kfree(*acpi_disc);
> + return -EINVAL;
> + }
> +
> + /* Element 0 is a descriptive string; DWORD values start at index 1. */
> + for (j = 1; j < ENTRY_LEN; j++) {
> + value = pkg->package.elements[j].integer.value;
> + if (value > U32_MAX) {
> + kfree(*acpi_disc);
> + return -ERANGE;
> + }
> +
> + (*acpi_disc)[i][j - 1] = value;
> + }
> + }
> +
> + return 0;
Should this function return err ptrs instead?
Consider also using __free() + no_free_ptr().
> +}
> +EXPORT_SYMBOL_NS_GPL(pmc_parse_telem_dsd, "INTEL_PMC_CORE");
> +
> +union acpi_object *pmc_find_telem_guid(union acpi_object *dsd)
> +{
> + int i;
> +
> + if (!dsd || dsd->type != ACPI_TYPE_PACKAGE)
> + return NULL;
> +
> + for (i = 0; i + 1 < dsd->package.count; i += 2) {
> + union acpi_object *uuid_obj, *data_obj;
> + guid_t uuid;
> +
> + uuid_obj = &dsd->package.elements[i];
> + data_obj = &dsd->package.elements[i + 1];
> +
> + if (uuid_obj->type != ACPI_TYPE_BUFFER ||
> + uuid_obj->buffer.length != 16)
> + continue;
> +
> + memcpy(&uuid, uuid_obj->buffer.pointer, 16);
> + if (guid_equal(&uuid, &intel_vsec_guid))
> + return data_obj;
> + }
> +
> + return NULL;
> +}
> +EXPORT_SYMBOL_NS_GPL(pmc_find_telem_guid, "INTEL_PMC_CORE");
> +
> +static int pmc_pwrm_acpi_probe(struct platform_device *pdev)
> +{
> + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
> + acpi_handle handle = ACPI_HANDLE(&pdev->dev);
> + struct intel_vsec_header header;
> + struct intel_vsec_header *headers[2] = { &header, NULL };
> + struct intel_vsec_platform_info info = { };
> + struct device *dev = &pdev->dev;
> + struct resource *res;
> + u32 (*acpi_disc)[4];
> + union acpi_object *dsd;
> + acpi_status status;
> + int ret;
> +
> + if (!handle)
> + return -ENODEV;
> +
> + status = acpi_evaluate_object(handle, "_DSD", NULL, &buf);
> + if (ACPI_FAILURE(status))
> + return dev_err_probe(dev, -ENODEV, "Could not evaluate _DSD: %s\n",
> + acpi_format_exception(status));
Braces.
> +
> + dsd = pmc_find_telem_guid(buf.pointer);
> + if (!dsd) {
> + ret = -ENODEV;
> + goto cleanup_acpi_buf;
> + }
> +
> + ret = pmc_parse_telem_dsd(dsd, &header, &acpi_disc);
> + if (ret)
> + goto cleanup_acpi_buf;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, header.tbir);
> + if (!res) {
> + ret = -EINVAL;
> + goto cleanup_acpi_disc;
> + }
> +
> + info.headers = headers;
> + info.caps = VSEC_CAP_TELEMETRY;
> + info.acpi_disc = acpi_disc;
> + info.src = INTEL_VSEC_DISC_ACPI;
> + info.base_addr = res->start;
> +
> + ret = intel_vsec_register(&pdev->dev, &info);
> +
> +cleanup_acpi_disc:
> + kfree(acpi_disc);
> +cleanup_acpi_buf:
> + ACPI_FREE(buf.pointer);
My impression is that these days kfree() is used directly.
Both look like they could use __free().
> +
> + return ret;
> +}
> +
> +static const struct acpi_device_id pmc_pwrm_acpi_ids[] = {
> + { "INTC1122", 0 }, /* Nova Lake */
> + { "INTC1129", 0 }, /* Nova Lake */
> + { }
> +};
> +MODULE_DEVICE_TABLE(acpi, pmc_pwrm_acpi_ids);
> +
> +static struct platform_driver pmc_pwrm_acpi_driver = {
> + .probe = pmc_pwrm_acpi_probe,
> + .driver = {
> + .name = "intel_pmc_pwrm_acpi",
> + .acpi_match_table = ACPI_PTR(pmc_pwrm_acpi_ids),
> + },
> +};
> +module_platform_driver(pmc_pwrm_acpi_driver);
> +
> +MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
> +MODULE_DESCRIPTION("Intel PMC PWRM ACPI driver");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS("INTEL_VSEC");
>
--
i.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 15/22] platform/x86/intel/pmc/ssram: Rename probe and PCI ID table for consistency
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (13 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 14/22] platform/x86/intel/pmc: Add ACPI PWRM telemetry driver for Nova Lake S David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 16:26 ` Ilpo Järvinen
2026-03-13 1:51 ` [PATCH 16/22] platform/x86/intel/pmc/ssram: Use fixed-size static pmc array David E. Box
` (7 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Rename intel_pmc_ssram_telemetry_probe() to pmc_ssram_telemetry_probe() and
intel_pmc_ssram_telemetry_pci_ids[] to pmc_ssram_telemetry_pci_ids[],
updating the MODULE_DEVICE_TABLE() and pci_driver wiring accordingly.
This aligns the symbol names with the driver filename and module name,
reduces redundant intel_ prefixes, and improves readability. No functional
behavior changes are intended.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmc/ssram_telemetry.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 6f6e83e70fc5..1deb4d71da3f 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -149,7 +149,7 @@ int pmc_ssram_telemetry_get_pmc_info(unsigned int pmc_idx,
}
EXPORT_SYMBOL_GPL(pmc_ssram_telemetry_get_pmc_info);
-static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
+static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
{
int ret;
@@ -183,7 +183,7 @@ static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct
return ret;
}
-static const struct pci_device_id intel_pmc_ssram_telemetry_pci_ids[] = {
+static const struct pci_device_id pmc_ssram_telemetry_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_MTL_SOCM) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCS) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCM) },
@@ -193,14 +193,14 @@ static const struct pci_device_id intel_pmc_ssram_telemetry_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_WCL_PCDN) },
{ }
};
-MODULE_DEVICE_TABLE(pci, intel_pmc_ssram_telemetry_pci_ids);
+MODULE_DEVICE_TABLE(pci, pmc_ssram_telemetry_pci_ids);
-static struct pci_driver intel_pmc_ssram_telemetry_driver = {
+static struct pci_driver pmc_ssram_telemetry_driver = {
.name = "intel_pmc_ssram_telemetry",
- .id_table = intel_pmc_ssram_telemetry_pci_ids,
- .probe = intel_pmc_ssram_telemetry_probe,
+ .id_table = pmc_ssram_telemetry_pci_ids,
+ .probe = pmc_ssram_telemetry_probe,
};
-module_pci_driver(intel_pmc_ssram_telemetry_driver);
+module_pci_driver(pmc_ssram_telemetry_driver);
MODULE_IMPORT_NS("INTEL_VSEC");
MODULE_AUTHOR("Xi Pardee <xi.pardee@intel.com>");
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 15/22] platform/x86/intel/pmc/ssram: Rename probe and PCI ID table for consistency
2026-03-13 1:51 ` [PATCH 15/22] platform/x86/intel/pmc/ssram: Rename probe and PCI ID table for consistency David E. Box
@ 2026-03-17 16:26 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 16:26 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
[-- Attachment #1: Type: text/plain, Size: 2725 bytes --]
On Thu, 12 Mar 2026, David E. Box wrote:
> Rename intel_pmc_ssram_telemetry_probe() to pmc_ssram_telemetry_probe() and
> intel_pmc_ssram_telemetry_pci_ids[] to pmc_ssram_telemetry_pci_ids[],
> updating the MODULE_DEVICE_TABLE() and pci_driver wiring accordingly.
>
> This aligns the symbol names with the driver filename and module name,
> reduces redundant intel_ prefixes, and improves readability. No functional
> behavior changes are intended.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/ssram_telemetry.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index 6f6e83e70fc5..1deb4d71da3f 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -149,7 +149,7 @@ int pmc_ssram_telemetry_get_pmc_info(unsigned int pmc_idx,
> }
> EXPORT_SYMBOL_GPL(pmc_ssram_telemetry_get_pmc_info);
>
> -static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
> +static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
> {
> int ret;
>
> @@ -183,7 +183,7 @@ static int intel_pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct
> return ret;
> }
>
> -static const struct pci_device_id intel_pmc_ssram_telemetry_pci_ids[] = {
> +static const struct pci_device_id pmc_ssram_telemetry_pci_ids[] = {
> { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_MTL_SOCM) },
> { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCS) },
> { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCM) },
> @@ -193,14 +193,14 @@ static const struct pci_device_id intel_pmc_ssram_telemetry_pci_ids[] = {
> { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_WCL_PCDN) },
> { }
> };
> -MODULE_DEVICE_TABLE(pci, intel_pmc_ssram_telemetry_pci_ids);
> +MODULE_DEVICE_TABLE(pci, pmc_ssram_telemetry_pci_ids);
>
> -static struct pci_driver intel_pmc_ssram_telemetry_driver = {
> +static struct pci_driver pmc_ssram_telemetry_driver = {
> .name = "intel_pmc_ssram_telemetry",
> - .id_table = intel_pmc_ssram_telemetry_pci_ids,
> - .probe = intel_pmc_ssram_telemetry_probe,
> + .id_table = pmc_ssram_telemetry_pci_ids,
> + .probe = pmc_ssram_telemetry_probe,
> };
> -module_pci_driver(intel_pmc_ssram_telemetry_driver);
> +module_pci_driver(pmc_ssram_telemetry_driver);
>
> MODULE_IMPORT_NS("INTEL_VSEC");
> MODULE_AUTHOR("Xi Pardee <xi.pardee@intel.com>");
>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 16/22] platform/x86/intel/pmc/ssram: Use fixed-size static pmc array
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (14 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 15/22] platform/x86/intel/pmc/ssram: Rename probe and PCI ID table for consistency David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-13 1:51 ` [PATCH 17/22] platform/x86/intel/pmc/ssram: Refactor DEVID/PWRMBASE extraction into helper David E. Box
` (6 subsequent siblings)
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
From: Xi Pardee <xi.pardee@linux.intel.com>
Switch pmc_ssram_telems from a devm-allocated pointer to a fixed-size
static array, eliminating per-probe allocation overhead and simplifying
lifetime management.
Correspondingly simplify pmc_ssram_telemetry_get_pmc_info() validation to
check devid availability and tighten input bounds checking. Drop
null-pointer checks now that the storage is static.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmc/ssram_telemetry.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 1deb4d71da3f..9c3d7ba2fd52 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -24,7 +24,7 @@
DEFINE_FREE(pmc_ssram_telemetry_iounmap, void __iomem *, if (_T) iounmap(_T))
-static struct pmc_ssram_telemetry *pmc_ssram_telems;
+static struct pmc_ssram_telemetry pmc_ssram_telems[3];
static bool device_probed;
static int
@@ -140,7 +140,7 @@ int pmc_ssram_telemetry_get_pmc_info(unsigned int pmc_idx,
if (pmc_idx >= MAX_NUM_PMC)
return -EINVAL;
- if (!pmc_ssram_telems || !pmc_ssram_telems[pmc_idx].devid)
+ if (!pmc_ssram_telems[pmc_idx].devid)
return -ENODEV;
pmc_ssram_telemetry->devid = pmc_ssram_telems[pmc_idx].devid;
@@ -153,12 +153,6 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
{
int ret;
- pmc_ssram_telems = devm_kzalloc(&pcidev->dev, sizeof(*pmc_ssram_telems) * MAX_NUM_PMC,
- GFP_KERNEL);
- if (!pmc_ssram_telems) {
- ret = -ENOMEM;
- goto probe_finish;
- }
ret = pcim_enable_device(pcidev);
if (ret) {
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* [PATCH 17/22] platform/x86/intel/pmc/ssram: Refactor DEVID/PWRMBASE extraction into helper
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (15 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 16/22] platform/x86/intel/pmc/ssram: Use fixed-size static pmc array David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 16:33 ` Ilpo Järvinen
2026-03-13 1:51 ` [PATCH 18/22] platform/x86/intel/pmc/ssram: Add PCI platform data David E. Box
` (5 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Move DEVID/PWRMBASE extraction into pmc_ssram_get_devid_pwrmbase().
This is a preparatory refactor to place functionality in a common helper
for reuse by a subsequent patch, while keeping behavior unchanged in this
step.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
.../platform/x86/intel/pmc/ssram_telemetry.c | 31 ++++++++++++-------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 9c3d7ba2fd52..75a80a74a069 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -27,6 +27,23 @@ DEFINE_FREE(pmc_ssram_telemetry_iounmap, void __iomem *, if (_T) iounmap(_T))
static struct pmc_ssram_telemetry pmc_ssram_telems[3];
static bool device_probed;
+static inline u64 get_base(void __iomem *addr, u32 offset)
+{
+ return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3);
+}
+
+static void pmc_ssram_get_devid_pwrmbase(void __iomem *ssram, unsigned int pmc_idx)
+{
+ u64 pwrm_base;
+ u16 devid;
+
+ pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
+ devid = readw(ssram + SSRAM_DEVID_OFFSET);
+
+ pmc_ssram_telems[pmc_idx].devid = devid;
+ pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
+}
+
static int
pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, u64 ssram_base, void __iomem *ssram)
{
@@ -63,18 +80,12 @@ pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, u64 ssram_base, void __iomem
return intel_vsec_register(&pcidev->dev, &info);
}
-static inline u64 get_base(void __iomem *addr, u32 offset)
-{
- return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3);
-}
-
static int
pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned int pmc_idx, u32 offset)
{
void __iomem __free(pmc_ssram_telemetry_iounmap) *tmp_ssram = NULL;
void __iomem __free(pmc_ssram_telemetry_iounmap) *ssram = NULL;
- u64 ssram_base, pwrm_base;
- u16 devid;
+ u64 ssram_base;
ssram_base = pci_resource_start(pcidev, 0);
tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
@@ -99,11 +110,7 @@ pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned int pmc_idx, u32 of
ssram = no_free_ptr(tmp_ssram);
}
- pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
- devid = readw(ssram + SSRAM_DEVID_OFFSET);
-
- pmc_ssram_telems[pmc_idx].devid = devid;
- pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
+ pmc_ssram_get_devid_pwrmbase(ssram, pmc_idx);
/* Find and register and PMC telemetry entries */
return pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 17/22] platform/x86/intel/pmc/ssram: Refactor DEVID/PWRMBASE extraction into helper
2026-03-13 1:51 ` [PATCH 17/22] platform/x86/intel/pmc/ssram: Refactor DEVID/PWRMBASE extraction into helper David E. Box
@ 2026-03-17 16:33 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 16:33 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> Move DEVID/PWRMBASE extraction into pmc_ssram_get_devid_pwrmbase().
>
> This is a preparatory refactor to place functionality in a common helper
> for reuse by a subsequent patch, while keeping behavior unchanged in this
> step.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> .../platform/x86/intel/pmc/ssram_telemetry.c | 31 ++++++++++++-------
> 1 file changed, 19 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index 9c3d7ba2fd52..75a80a74a069 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -27,6 +27,23 @@ DEFINE_FREE(pmc_ssram_telemetry_iounmap, void __iomem *, if (_T) iounmap(_T))
> static struct pmc_ssram_telemetry pmc_ssram_telems[3];
> static bool device_probed;
>
> +static inline u64 get_base(void __iomem *addr, u32 offset)
> +{
> + return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3);
A pre-existing problem: Header for GENMASK_ULL() is missing from this
file.
I also would prefer having that field named with define but that too is a
pre-existing thing.
--
i.
> +}
> +
> +static void pmc_ssram_get_devid_pwrmbase(void __iomem *ssram, unsigned int pmc_idx)
> +{
> + u64 pwrm_base;
> + u16 devid;
> +
> + pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
> + devid = readw(ssram + SSRAM_DEVID_OFFSET);
> +
> + pmc_ssram_telems[pmc_idx].devid = devid;
> + pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
> +}
> +
> static int
> pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, u64 ssram_base, void __iomem *ssram)
> {
> @@ -63,18 +80,12 @@ pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, u64 ssram_base, void __iomem
> return intel_vsec_register(&pcidev->dev, &info);
> }
>
> -static inline u64 get_base(void __iomem *addr, u32 offset)
> -{
> - return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3);
> -}
> -
> static int
> pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned int pmc_idx, u32 offset)
> {
> void __iomem __free(pmc_ssram_telemetry_iounmap) *tmp_ssram = NULL;
> void __iomem __free(pmc_ssram_telemetry_iounmap) *ssram = NULL;
> - u64 ssram_base, pwrm_base;
> - u16 devid;
> + u64 ssram_base;
>
> ssram_base = pci_resource_start(pcidev, 0);
> tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
> @@ -99,11 +110,7 @@ pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned int pmc_idx, u32 of
> ssram = no_free_ptr(tmp_ssram);
> }
>
> - pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
> - devid = readw(ssram + SSRAM_DEVID_OFFSET);
> -
> - pmc_ssram_telems[pmc_idx].devid = devid;
> - pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
> + pmc_ssram_get_devid_pwrmbase(ssram, pmc_idx);
>
> /* Find and register and PMC telemetry entries */
> return pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 18/22] platform/x86/intel/pmc/ssram: Add PCI platform data
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (16 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 17/22] platform/x86/intel/pmc/ssram: Refactor DEVID/PWRMBASE extraction into helper David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 16:35 ` Ilpo Järvinen
2026-03-13 1:51 ` [PATCH 19/22] platform/x86/intel/pmc/ssram: Refactor memory barrier for reentrant probe David E. Box
` (4 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Add per-device platform data for SSRAM telemetry PCI IDs and route probe
through a method selector driven by id->driver_data.
This is a preparatory refactor for follow-on discovery methods while
preserving current behavior: all supported IDs continue to use the PCI
initialization path.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
.../platform/x86/intel/pmc/ssram_telemetry.c | 69 +++++++++++++++----
1 file changed, 55 insertions(+), 14 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 75a80a74a069..7db98037c521 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -24,6 +24,18 @@
DEFINE_FREE(pmc_ssram_telemetry_iounmap, void __iomem *, if (_T) iounmap(_T))
+enum resource_method {
+ RES_METHOD_PCI,
+};
+
+struct ssram_type {
+ enum resource_method method;
+};
+
+static const struct ssram_type pci_main = {
+ .method = RES_METHOD_PCI,
+};
+
static struct pmc_ssram_telemetry pmc_ssram_telems[3];
static bool device_probed;
@@ -81,7 +93,7 @@ pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, u64 ssram_base, void __iomem
}
static int
-pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned int pmc_idx, u32 offset)
+pmc_ssram_telemetry_get_pmc_pci(struct pci_dev *pcidev, unsigned int pmc_idx, u32 offset)
{
void __iomem __free(pmc_ssram_telemetry_iounmap) *tmp_ssram = NULL;
void __iomem __free(pmc_ssram_telemetry_iounmap) *ssram = NULL;
@@ -116,6 +128,20 @@ pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned int pmc_idx, u32 of
return pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
}
+static int pmc_ssram_telemetry_pci_init(struct pci_dev *pcidev)
+{
+ int ret;
+
+ ret = pmc_ssram_telemetry_get_pmc_pci(pcidev, PMC_IDX_MAIN, 0);
+ if (ret)
+ return ret;
+
+ pmc_ssram_telemetry_get_pmc_pci(pcidev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
+ pmc_ssram_telemetry_get_pmc_pci(pcidev, PMC_IDX_PCH, SSRAM_PCH_OFFSET);
+
+ return ret;
+}
+
/**
* pmc_ssram_telemetry_get_pmc_info() - Get a PMC devid and base_addr information
* @pmc_idx: Index of the PMC
@@ -158,8 +184,18 @@ EXPORT_SYMBOL_GPL(pmc_ssram_telemetry_get_pmc_info);
static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
{
+ const struct ssram_type *ssram_type;
+ enum resource_method method;
int ret;
+ ssram_type = (const struct ssram_type *)id->driver_data;
+ if (!ssram_type) {
+ dev_dbg(&pcidev->dev, "missing driver data\n");
+ ret = -EINVAL;
+ goto probe_finish;
+ }
+
+ method = ssram_type->method;
ret = pcim_enable_device(pcidev);
if (ret) {
@@ -167,12 +203,10 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
goto probe_finish;
}
- ret = pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_MAIN, 0);
- if (ret)
- goto probe_finish;
-
- pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
- pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_PCH, SSRAM_PCH_OFFSET);
+ if (method == RES_METHOD_PCI)
+ ret = pmc_ssram_telemetry_pci_init(pcidev);
+ else
+ ret = -EINVAL;
probe_finish:
/*
@@ -185,13 +219,20 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
}
static const struct pci_device_id pmc_ssram_telemetry_pci_ids[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_MTL_SOCM) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCS) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCM) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_LNL_SOCM) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDH) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDP) },
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_WCL_PCDN) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_MTL_SOCM),
+ .driver_data = (kernel_ulong_t)&pci_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCS),
+ .driver_data = (kernel_ulong_t)&pci_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCM),
+ .driver_data = (kernel_ulong_t)&pci_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_LNL_SOCM),
+ .driver_data = (kernel_ulong_t)&pci_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDH),
+ .driver_data = (kernel_ulong_t)&pci_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDP),
+ .driver_data = (kernel_ulong_t)&pci_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_WCL_PCDN),
+ .driver_data = (kernel_ulong_t)&pci_main },
{ }
};
MODULE_DEVICE_TABLE(pci, pmc_ssram_telemetry_pci_ids);
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 18/22] platform/x86/intel/pmc/ssram: Add PCI platform data
2026-03-13 1:51 ` [PATCH 18/22] platform/x86/intel/pmc/ssram: Add PCI platform data David E. Box
@ 2026-03-17 16:35 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 16:35 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> Add per-device platform data for SSRAM telemetry PCI IDs and route probe
> through a method selector driven by id->driver_data.
>
> This is a preparatory refactor for follow-on discovery methods while
> preserving current behavior: all supported IDs continue to use the PCI
> initialization path.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> .../platform/x86/intel/pmc/ssram_telemetry.c | 69 +++++++++++++++----
> 1 file changed, 55 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index 75a80a74a069..7db98037c521 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -24,6 +24,18 @@
>
> DEFINE_FREE(pmc_ssram_telemetry_iounmap, void __iomem *, if (_T) iounmap(_T))
>
> +enum resource_method {
> + RES_METHOD_PCI,
> +};
> +
> +struct ssram_type {
> + enum resource_method method;
> +};
> +
> +static const struct ssram_type pci_main = {
> + .method = RES_METHOD_PCI,
> +};
> +
> static struct pmc_ssram_telemetry pmc_ssram_telems[3];
> static bool device_probed;
>
> @@ -81,7 +93,7 @@ pmc_ssram_telemetry_add_pmt(struct pci_dev *pcidev, u64 ssram_base, void __iomem
> }
>
> static int
> -pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned int pmc_idx, u32 offset)
> +pmc_ssram_telemetry_get_pmc_pci(struct pci_dev *pcidev, unsigned int pmc_idx, u32 offset)
> {
> void __iomem __free(pmc_ssram_telemetry_iounmap) *tmp_ssram = NULL;
> void __iomem __free(pmc_ssram_telemetry_iounmap) *ssram = NULL;
> @@ -116,6 +128,20 @@ pmc_ssram_telemetry_get_pmc(struct pci_dev *pcidev, unsigned int pmc_idx, u32 of
> return pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
> }
>
> +static int pmc_ssram_telemetry_pci_init(struct pci_dev *pcidev)
> +{
> + int ret;
> +
> + ret = pmc_ssram_telemetry_get_pmc_pci(pcidev, PMC_IDX_MAIN, 0);
> + if (ret)
> + return ret;
> +
> + pmc_ssram_telemetry_get_pmc_pci(pcidev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
> + pmc_ssram_telemetry_get_pmc_pci(pcidev, PMC_IDX_PCH, SSRAM_PCH_OFFSET);
> +
> + return ret;
> +}
> +
> /**
> * pmc_ssram_telemetry_get_pmc_info() - Get a PMC devid and base_addr information
> * @pmc_idx: Index of the PMC
> @@ -158,8 +184,18 @@ EXPORT_SYMBOL_GPL(pmc_ssram_telemetry_get_pmc_info);
>
> static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
> {
> + const struct ssram_type *ssram_type;
> + enum resource_method method;
> int ret;
>
> + ssram_type = (const struct ssram_type *)id->driver_data;
> + if (!ssram_type) {
> + dev_dbg(&pcidev->dev, "missing driver data\n");
Add #include.
> + ret = -EINVAL;
> + goto probe_finish;
> + }
> +
> + method = ssram_type->method;
>
> ret = pcim_enable_device(pcidev);
> if (ret) {
> @@ -167,12 +203,10 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
> goto probe_finish;
> }
>
> - ret = pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_MAIN, 0);
> - if (ret)
> - goto probe_finish;
> -
> - pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_IOE, SSRAM_IOE_OFFSET);
> - pmc_ssram_telemetry_get_pmc(pcidev, PMC_IDX_PCH, SSRAM_PCH_OFFSET);
> + if (method == RES_METHOD_PCI)
> + ret = pmc_ssram_telemetry_pci_init(pcidev);
> + else
> + ret = -EINVAL;
>
> probe_finish:
> /*
> @@ -185,13 +219,20 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
> }
>
> static const struct pci_device_id pmc_ssram_telemetry_pci_ids[] = {
> - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_MTL_SOCM) },
> - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCS) },
> - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCM) },
> - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_LNL_SOCM) },
> - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDH) },
> - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDP) },
> - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_WCL_PCDN) },
> + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_MTL_SOCM),
> + .driver_data = (kernel_ulong_t)&pci_main },
> + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCS),
> + .driver_data = (kernel_ulong_t)&pci_main },
> + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCM),
> + .driver_data = (kernel_ulong_t)&pci_main },
> + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_LNL_SOCM),
> + .driver_data = (kernel_ulong_t)&pci_main },
> + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDH),
> + .driver_data = (kernel_ulong_t)&pci_main },
> + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDP),
> + .driver_data = (kernel_ulong_t)&pci_main },
> + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_WCL_PCDN),
> + .driver_data = (kernel_ulong_t)&pci_main },
> { }
> };
> MODULE_DEVICE_TABLE(pci, pmc_ssram_telemetry_pci_ids);
>
--
i.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 19/22] platform/x86/intel/pmc/ssram: Refactor memory barrier for reentrant probe
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (17 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 18/22] platform/x86/intel/pmc/ssram: Add PCI platform data David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 16:40 ` Ilpo Järvinen
2026-03-13 1:51 ` [PATCH 20/22] platform/x86/intel/pmc/ssram: Add ACPI discovery scaffolding David E. Box
` (3 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
From: Xi Pardee <xi.pardee@linux.intel.com>
Switch the readiness synchronization from a global device_probed flag to
per-index devid publication. This is required because a subsequent patch
makes probe reentrant, so a single global flag can no longer reliably
signal completion.
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
.../platform/x86/intel/pmc/ssram_telemetry.c | 34 ++++++++-----------
1 file changed, 14 insertions(+), 20 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 7db98037c521..246efdcf6950 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -37,7 +37,6 @@ static const struct ssram_type pci_main = {
};
static struct pmc_ssram_telemetry pmc_ssram_telems[3];
-static bool device_probed;
static inline u64 get_base(void __iomem *addr, u32 offset)
{
@@ -52,8 +51,13 @@ static void pmc_ssram_get_devid_pwrmbase(void __iomem *ssram, unsigned int pmc_i
pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
devid = readw(ssram + SSRAM_DEVID_OFFSET);
- pmc_ssram_telems[pmc_idx].devid = devid;
pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
+ /*
+ * Memory barrier is used to ensure the correct write order between base_addr
+ * and devid.
+ */
+ smp_wmb();
+ pmc_ssram_telems[pmc_idx].devid = devid;
}
static int
@@ -151,32 +155,28 @@ static int pmc_ssram_telemetry_pci_init(struct pci_dev *pcidev)
* * 0 - Success
* * -EAGAIN - Probe function has not finished yet. Try again.
* * -EINVAL - Invalid pmc_idx
- * * -ENODEV - PMC device is not available
*/
int pmc_ssram_telemetry_get_pmc_info(unsigned int pmc_idx,
struct pmc_ssram_telemetry *pmc_ssram_telemetry)
{
+ if (pmc_idx >= MAX_NUM_PMC)
+ return -EINVAL;
+
/*
* PMCs are discovered in probe function. If this function is called before
- * probe function complete, the result would be invalid. Use device_probed
- * variable to avoid this case. Return -EAGAIN to inform the consumer to call
+ * probe function complete, the result would be invalid. Use devid to avoid
+ * this case. Return -EAGAIN to inform the consumer to call
* again later.
*/
- if (!device_probed)
+ if (!pmc_ssram_telems[pmc_idx].devid)
return -EAGAIN;
+ pmc_ssram_telemetry->devid = pmc_ssram_telems[pmc_idx].devid;
/*
* Memory barrier is used to ensure the correct read order between
- * device_probed variable and PMC info.
+ * devid variable and base_addr.
*/
smp_rmb();
- if (pmc_idx >= MAX_NUM_PMC)
- return -EINVAL;
-
- if (!pmc_ssram_telems[pmc_idx].devid)
- return -ENODEV;
-
- pmc_ssram_telemetry->devid = pmc_ssram_telems[pmc_idx].devid;
pmc_ssram_telemetry->base_addr = pmc_ssram_telems[pmc_idx].base_addr;
return 0;
}
@@ -209,12 +209,6 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
ret = -EINVAL;
probe_finish:
- /*
- * Memory barrier is used to ensure the correct write order between PMC info
- * and device_probed variable.
- */
- smp_wmb();
- device_probed = true;
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 19/22] platform/x86/intel/pmc/ssram: Refactor memory barrier for reentrant probe
2026-03-13 1:51 ` [PATCH 19/22] platform/x86/intel/pmc/ssram: Refactor memory barrier for reentrant probe David E. Box
@ 2026-03-17 16:40 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 16:40 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> From: Xi Pardee <xi.pardee@linux.intel.com>
>
> Switch the readiness synchronization from a global device_probed flag to
> per-index devid publication.
It would be nice if you could expand the synchronization explanation a
bit. It's mostly in the comments below but it wouldn't hurt to add it here
as well.
> This is required because a subsequent patch
> makes probe reentrant, so a single global flag can no longer reliably
> signal completion.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> .../platform/x86/intel/pmc/ssram_telemetry.c | 34 ++++++++-----------
> 1 file changed, 14 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index 7db98037c521..246efdcf6950 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -37,7 +37,6 @@ static const struct ssram_type pci_main = {
> };
>
> static struct pmc_ssram_telemetry pmc_ssram_telems[3];
> -static bool device_probed;
>
> static inline u64 get_base(void __iomem *addr, u32 offset)
> {
> @@ -52,8 +51,13 @@ static void pmc_ssram_get_devid_pwrmbase(void __iomem *ssram, unsigned int pmc_i
> pwrm_base = get_base(ssram, SSRAM_PWRM_OFFSET);
> devid = readw(ssram + SSRAM_DEVID_OFFSET);
>
> - pmc_ssram_telems[pmc_idx].devid = devid;
> pmc_ssram_telems[pmc_idx].base_addr = pwrm_base;
> + /*
> + * Memory barrier is used to ensure the correct write order between base_addr
> + * and devid.
> + */
> + smp_wmb();
> + pmc_ssram_telems[pmc_idx].devid = devid;
> }
>
> static int
> @@ -151,32 +155,28 @@ static int pmc_ssram_telemetry_pci_init(struct pci_dev *pcidev)
> * * 0 - Success
> * * -EAGAIN - Probe function has not finished yet. Try again.
> * * -EINVAL - Invalid pmc_idx
> - * * -ENODEV - PMC device is not available
> */
> int pmc_ssram_telemetry_get_pmc_info(unsigned int pmc_idx,
> struct pmc_ssram_telemetry *pmc_ssram_telemetry)
> {
> + if (pmc_idx >= MAX_NUM_PMC)
> + return -EINVAL;
> +
> /*
> * PMCs are discovered in probe function. If this function is called before
> - * probe function complete, the result would be invalid. Use device_probed
> - * variable to avoid this case. Return -EAGAIN to inform the consumer to call
> + * probe function complete, the result would be invalid. Use devid to avoid
> + * this case. Return -EAGAIN to inform the consumer to call
> * again later.
> */
> - if (!device_probed)
> + if (!pmc_ssram_telems[pmc_idx].devid)
> return -EAGAIN;
>
> + pmc_ssram_telemetry->devid = pmc_ssram_telems[pmc_idx].devid;
> /*
> * Memory barrier is used to ensure the correct read order between
> - * device_probed variable and PMC info.
> + * devid variable and base_addr.
> */
> smp_rmb();
> - if (pmc_idx >= MAX_NUM_PMC)
> - return -EINVAL;
> -
> - if (!pmc_ssram_telems[pmc_idx].devid)
> - return -ENODEV;
> -
> - pmc_ssram_telemetry->devid = pmc_ssram_telems[pmc_idx].devid;
> pmc_ssram_telemetry->base_addr = pmc_ssram_telems[pmc_idx].base_addr;
> return 0;
> }
> @@ -209,12 +209,6 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
> ret = -EINVAL;
>
> probe_finish:
This label becomes pointless after the removal and the gotoers should just
return directly.
> - /*
> - * Memory barrier is used to ensure the correct write order between PMC info
> - * and device_probed variable.
> - */
> - smp_wmb();
> - device_probed = true;
> return ret;
--
i.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 20/22] platform/x86/intel/pmc/ssram: Add ACPI discovery scaffolding
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (18 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 19/22] platform/x86/intel/pmc/ssram: Refactor memory barrier for reentrant probe David E. Box
@ 2026-03-13 1:51 ` David E. Box
2026-03-17 16:45 ` Ilpo Järvinen
2026-03-13 1:52 ` [PATCH 21/22] platform/x86/intel/pmc/ssram: Make PMT registration optional David E. Box
` (2 subsequent siblings)
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:51 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Prepare the SSRAM telemetry driver for ACPI-based discovery by adding the
common initialization path and selection framework needed for resource
discovery from the ACPI companion device.
At this stage, existing supported devices continue to use the PCI path.
This change lays the groundwork for follow-on patches that wire platform
IDs to the ACPI policy path.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
---
.../platform/x86/intel/pmc/ssram_telemetry.c | 79 +++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 246efdcf6950..b937ebb2322f 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -5,6 +5,7 @@
* Copyright (c) 2023, Intel Corporation.
*/
+#include <linux/acpi.h>
#include <linux/cleanup.h>
#include <linux/intel_vsec.h>
#include <linux/pci.h>
@@ -26,14 +27,17 @@ DEFINE_FREE(pmc_ssram_telemetry_iounmap, void __iomem *, if (_T) iounmap(_T))
enum resource_method {
RES_METHOD_PCI,
+ RES_METHOD_ACPI,
};
struct ssram_type {
enum resource_method method;
+ enum pmc_index p_index;
};
static const struct ssram_type pci_main = {
.method = RES_METHOD_PCI,
+ .p_index = PMC_IDX_MAIN,
};
static struct pmc_ssram_telemetry pmc_ssram_telems[3];
@@ -146,6 +150,76 @@ static int pmc_ssram_telemetry_pci_init(struct pci_dev *pcidev)
return ret;
}
+static int pmc_ssram_telemetry_get_pmc_acpi(struct pci_dev *pcidev, unsigned int pmc_idx)
+{
+ void __iomem __free(pmc_ssram_telemetry_iounmap) * ssram = NULL;
+ u64 ssram_base;
+
+ ssram_base = pci_resource_start(pcidev, 0);
+ if (!ssram_base)
+ return -ENODEV;
+
+ ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
+ if (!ssram)
+ return -ENOMEM;
+
+ pmc_ssram_get_devid_pwrmbase(ssram, pmc_idx);
+
+ return 0;
+}
+
+static int pmc_ssram_telemetry_acpi_init(struct pci_dev *pcidev,
+ enum pmc_index index)
+{
+ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
+ acpi_handle handle = ACPI_HANDLE(&pcidev->dev);
+ struct intel_vsec_header header;
+ struct intel_vsec_header *headers[2] = { &header, NULL };
+ struct intel_vsec_platform_info info = { };
+ union acpi_object *dsd;
+ u32 (*acpi_disc)[4];
+ acpi_status status;
+ int ret;
+
+ if (!handle)
+ return -ENODEV;
+
+ status = acpi_evaluate_object(handle, "_DSD", NULL, &buf);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ dsd = pmc_find_telem_guid(buf.pointer);
+ if (!dsd) {
+ ret = -ENODEV;
+ goto cleanup_acpi_buf;
+ }
+
+ ret = pmc_parse_telem_dsd(dsd, &header, &acpi_disc);
+ if (ret)
+ goto cleanup_acpi_buf;
+
+ info.headers = headers;
+ info.caps = VSEC_CAP_TELEMETRY;
+ info.acpi_disc = acpi_disc;
+ info.src = INTEL_VSEC_DISC_ACPI;
+
+ /* This is an ACPI companion device. PCI BAR will be used for base addr. */
+ info.base_addr = 0;
+
+ ret = intel_vsec_register(&pcidev->dev, &info);
+ if (ret)
+ goto cleanup_acpi_disc;
+
+ ret = pmc_ssram_telemetry_get_pmc_acpi(pcidev, index);
+
+cleanup_acpi_disc:
+ kfree(acpi_disc);
+cleanup_acpi_buf:
+ ACPI_FREE(buf.pointer);
+
+ return ret;
+}
+
/**
* pmc_ssram_telemetry_get_pmc_info() - Get a PMC devid and base_addr information
* @pmc_idx: Index of the PMC
@@ -186,6 +260,7 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
{
const struct ssram_type *ssram_type;
enum resource_method method;
+ enum pmc_index index;
int ret;
ssram_type = (const struct ssram_type *)id->driver_data;
@@ -196,6 +271,7 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
}
method = ssram_type->method;
+ index = ssram_type->p_index;
ret = pcim_enable_device(pcidev);
if (ret) {
@@ -205,6 +281,8 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
if (method == RES_METHOD_PCI)
ret = pmc_ssram_telemetry_pci_init(pcidev);
+ else if (method == RES_METHOD_ACPI)
+ ret = pmc_ssram_telemetry_acpi_init(pcidev, index);
else
ret = -EINVAL;
@@ -238,6 +316,7 @@ static struct pci_driver pmc_ssram_telemetry_driver = {
};
module_pci_driver(pmc_ssram_telemetry_driver);
+MODULE_IMPORT_NS("INTEL_PMC_CORE");
MODULE_IMPORT_NS("INTEL_VSEC");
MODULE_AUTHOR("Xi Pardee <xi.pardee@intel.com>");
MODULE_DESCRIPTION("Intel PMC SSRAM Telemetry driver");
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 20/22] platform/x86/intel/pmc/ssram: Add ACPI discovery scaffolding
2026-03-13 1:51 ` [PATCH 20/22] platform/x86/intel/pmc/ssram: Add ACPI discovery scaffolding David E. Box
@ 2026-03-17 16:45 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 16:45 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> Prepare the SSRAM telemetry driver for ACPI-based discovery by adding the
> common initialization path and selection framework needed for resource
> discovery from the ACPI companion device.
>
> At this stage, existing supported devices continue to use the PCI path.
> This change lays the groundwork for follow-on patches that wire platform
> IDs to the ACPI policy path.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
> ---
> .../platform/x86/intel/pmc/ssram_telemetry.c | 79 +++++++++++++++++++
> 1 file changed, 79 insertions(+)
>
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index 246efdcf6950..b937ebb2322f 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -5,6 +5,7 @@
> * Copyright (c) 2023, Intel Corporation.
> */
>
> +#include <linux/acpi.h>
> #include <linux/cleanup.h>
> #include <linux/intel_vsec.h>
> #include <linux/pci.h>
> @@ -26,14 +27,17 @@ DEFINE_FREE(pmc_ssram_telemetry_iounmap, void __iomem *, if (_T) iounmap(_T))
>
> enum resource_method {
> RES_METHOD_PCI,
> + RES_METHOD_ACPI,
> };
>
> struct ssram_type {
> enum resource_method method;
> + enum pmc_index p_index;
> };
>
> static const struct ssram_type pci_main = {
> .method = RES_METHOD_PCI,
> + .p_index = PMC_IDX_MAIN,
> };
>
> static struct pmc_ssram_telemetry pmc_ssram_telems[3];
> @@ -146,6 +150,76 @@ static int pmc_ssram_telemetry_pci_init(struct pci_dev *pcidev)
> return ret;
> }
>
> +static int pmc_ssram_telemetry_get_pmc_acpi(struct pci_dev *pcidev, unsigned int pmc_idx)
> +{
> + void __iomem __free(pmc_ssram_telemetry_iounmap) * ssram = NULL;
__free() ... = NULL is a bad pattern as explained in the long comment in
cleanup.h. The variable should be declared right at site of assignment.
It's not problem in this case but it is stick to the safer pattern.
> + u64 ssram_base;
> +
> + ssram_base = pci_resource_start(pcidev, 0);
> + if (!ssram_base)
> + return -ENODEV;
> +
> + ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
> + if (!ssram)
> + return -ENOMEM;
> +
> + pmc_ssram_get_devid_pwrmbase(ssram, pmc_idx);
> +
> + return 0;
> +}
> +
> +static int pmc_ssram_telemetry_acpi_init(struct pci_dev *pcidev,
> + enum pmc_index index)
> +{
> + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
> + acpi_handle handle = ACPI_HANDLE(&pcidev->dev);
> + struct intel_vsec_header header;
> + struct intel_vsec_header *headers[2] = { &header, NULL };
> + struct intel_vsec_platform_info info = { };
> + union acpi_object *dsd;
> + u32 (*acpi_disc)[4];
> + acpi_status status;
> + int ret;
> +
> + if (!handle)
> + return -ENODEV;
> +
> + status = acpi_evaluate_object(handle, "_DSD", NULL, &buf);
> + if (ACPI_FAILURE(status))
> + return -ENODEV;
> +
> + dsd = pmc_find_telem_guid(buf.pointer);
> + if (!dsd) {
> + ret = -ENODEV;
> + goto cleanup_acpi_buf;
> + }
> +
> + ret = pmc_parse_telem_dsd(dsd, &header, &acpi_disc);
> + if (ret)
> + goto cleanup_acpi_buf;
> +
> + info.headers = headers;
> + info.caps = VSEC_CAP_TELEMETRY;
> + info.acpi_disc = acpi_disc;
> + info.src = INTEL_VSEC_DISC_ACPI;
> +
> + /* This is an ACPI companion device. PCI BAR will be used for base addr. */
> + info.base_addr = 0;
> +
> + ret = intel_vsec_register(&pcidev->dev, &info);
> + if (ret)
> + goto cleanup_acpi_disc;
> +
> + ret = pmc_ssram_telemetry_get_pmc_acpi(pcidev, index);
> +
> +cleanup_acpi_disc:
> + kfree(acpi_disc);
> +cleanup_acpi_buf:
> + ACPI_FREE(buf.pointer);
kfree() + __free() as mentioned to some other patch.
> +
> + return ret;
> +}
> +
> /**
> * pmc_ssram_telemetry_get_pmc_info() - Get a PMC devid and base_addr information
> * @pmc_idx: Index of the PMC
> @@ -186,6 +260,7 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
> {
> const struct ssram_type *ssram_type;
> enum resource_method method;
> + enum pmc_index index;
> int ret;
>
> ssram_type = (const struct ssram_type *)id->driver_data;
> @@ -196,6 +271,7 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
> }
>
> method = ssram_type->method;
> + index = ssram_type->p_index;
>
> ret = pcim_enable_device(pcidev);
> if (ret) {
> @@ -205,6 +281,8 @@ static int pmc_ssram_telemetry_probe(struct pci_dev *pcidev, const struct pci_de
>
> if (method == RES_METHOD_PCI)
> ret = pmc_ssram_telemetry_pci_init(pcidev);
> + else if (method == RES_METHOD_ACPI)
> + ret = pmc_ssram_telemetry_acpi_init(pcidev, index);
> else
> ret = -EINVAL;
>
> @@ -238,6 +316,7 @@ static struct pci_driver pmc_ssram_telemetry_driver = {
> };
> module_pci_driver(pmc_ssram_telemetry_driver);
>
> +MODULE_IMPORT_NS("INTEL_PMC_CORE");
> MODULE_IMPORT_NS("INTEL_VSEC");
> MODULE_AUTHOR("Xi Pardee <xi.pardee@intel.com>");
> MODULE_DESCRIPTION("Intel PMC SSRAM Telemetry driver");
>
--
i.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 21/22] platform/x86/intel/pmc/ssram: Make PMT registration optional
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (19 preceding siblings ...)
2026-03-13 1:51 ` [PATCH 20/22] platform/x86/intel/pmc/ssram: Add ACPI discovery scaffolding David E. Box
@ 2026-03-13 1:52 ` David E. Box
2026-03-17 16:48 ` Ilpo Järvinen
2026-03-13 1:52 ` [PATCH 22/22] platform/x86/intel/pmc: Add NVL PCI IDs for SSRAM telemetry discovery David E. Box
2026-03-13 15:03 ` [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry srinivas pandruvada
22 siblings, 1 reply; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:52 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
The SSRAM telemetry driver extracts essential PMC device ID and power
management base address information that intel_pmc_core depends on for core
functionality. PMT registration failure should not prevent this critical
data from being available, as it would break intel_pmc_core operation
entirely.
Change the behavior to log a warning when PMT registration fails but
continue with successful driver initialization, ensuring the primary
telemetry data remains accessible to dependent drivers.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmc/ssram_telemetry.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index b937ebb2322f..12b7c1299c2f 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -106,6 +106,7 @@ pmc_ssram_telemetry_get_pmc_pci(struct pci_dev *pcidev, unsigned int pmc_idx, u3
void __iomem __free(pmc_ssram_telemetry_iounmap) *tmp_ssram = NULL;
void __iomem __free(pmc_ssram_telemetry_iounmap) *ssram = NULL;
u64 ssram_base;
+ int ret;
ssram_base = pci_resource_start(pcidev, 0);
tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
@@ -133,7 +134,11 @@ pmc_ssram_telemetry_get_pmc_pci(struct pci_dev *pcidev, unsigned int pmc_idx, u3
pmc_ssram_get_devid_pwrmbase(ssram, pmc_idx);
/* Find and register and PMC telemetry entries */
- return pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
+ ret = pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
+ if (ret)
+ dev_warn(&pcidev->dev, "could not register PMT\n");
+
+ return 0;
}
static int pmc_ssram_telemetry_pci_init(struct pci_dev *pcidev)
@@ -208,12 +213,12 @@ static int pmc_ssram_telemetry_acpi_init(struct pci_dev *pcidev,
ret = intel_vsec_register(&pcidev->dev, &info);
if (ret)
- goto cleanup_acpi_disc;
+ dev_warn(&pcidev->dev, "could not register PMT\n");
ret = pmc_ssram_telemetry_get_pmc_acpi(pcidev, index);
-cleanup_acpi_disc:
kfree(acpi_disc);
+
cleanup_acpi_buf:
ACPI_FREE(buf.pointer);
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 21/22] platform/x86/intel/pmc/ssram: Make PMT registration optional
2026-03-13 1:52 ` [PATCH 21/22] platform/x86/intel/pmc/ssram: Make PMT registration optional David E. Box
@ 2026-03-17 16:48 ` Ilpo Järvinen
0 siblings, 0 replies; 34+ messages in thread
From: Ilpo Järvinen @ 2026-03-17 16:48 UTC (permalink / raw)
To: David E. Box
Cc: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee,
Hans de Goede, LKML, platform-driver-x86
On Thu, 12 Mar 2026, David E. Box wrote:
> The SSRAM telemetry driver extracts essential PMC device ID and power
> management base address information that intel_pmc_core depends on for core
> functionality. PMT registration failure should not prevent this critical
> data from being available, as it would break intel_pmc_core operation
Are you missing a "not" here? I find the entire sentence hard to
understand.
> entirely.
>
> Change the behavior to log a warning when PMT registration fails but
> continue with successful driver initialization, ensuring the primary
> telemetry data remains accessible to dependent drivers.
>
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/ssram_telemetry.c | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> index b937ebb2322f..12b7c1299c2f 100644
> --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
> @@ -106,6 +106,7 @@ pmc_ssram_telemetry_get_pmc_pci(struct pci_dev *pcidev, unsigned int pmc_idx, u3
> void __iomem __free(pmc_ssram_telemetry_iounmap) *tmp_ssram = NULL;
> void __iomem __free(pmc_ssram_telemetry_iounmap) *ssram = NULL;
> u64 ssram_base;
> + int ret;
>
> ssram_base = pci_resource_start(pcidev, 0);
> tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
> @@ -133,7 +134,11 @@ pmc_ssram_telemetry_get_pmc_pci(struct pci_dev *pcidev, unsigned int pmc_idx, u3
> pmc_ssram_get_devid_pwrmbase(ssram, pmc_idx);
>
> /* Find and register and PMC telemetry entries */
> - return pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
> + ret = pmc_ssram_telemetry_add_pmt(pcidev, ssram_base, ssram);
> + if (ret)
> + dev_warn(&pcidev->dev, "could not register PMT\n");
> +
> + return 0;
> }
>
> static int pmc_ssram_telemetry_pci_init(struct pci_dev *pcidev)
> @@ -208,12 +213,12 @@ static int pmc_ssram_telemetry_acpi_init(struct pci_dev *pcidev,
>
> ret = intel_vsec_register(&pcidev->dev, &info);
> if (ret)
> - goto cleanup_acpi_disc;
> + dev_warn(&pcidev->dev, "could not register PMT\n");
>
> ret = pmc_ssram_telemetry_get_pmc_acpi(pcidev, index);
>
> -cleanup_acpi_disc:
> kfree(acpi_disc);
> +
> cleanup_acpi_buf:
> ACPI_FREE(buf.pointer);
>
>
--
i.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 22/22] platform/x86/intel/pmc: Add NVL PCI IDs for SSRAM telemetry discovery
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (20 preceding siblings ...)
2026-03-13 1:52 ` [PATCH 21/22] platform/x86/intel/pmc/ssram: Make PMT registration optional David E. Box
@ 2026-03-13 1:52 ` David E. Box
2026-03-13 15:03 ` [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry srinivas pandruvada
22 siblings, 0 replies; 34+ messages in thread
From: David E. Box @ 2026-03-13 1:52 UTC (permalink / raw)
To: thomas.hellstrom, rodrigo.vivi, irenic.rajneesh, ilpo.jarvinen,
srinivas.pandruvada, intel-xe, dri-devel, xi.pardee
Cc: david.e.box, hansg, linux-kernel, platform-driver-x86
Add Nova Lake S PMC device IDs to enable binding of the SSRAM telemetry
driver on NVL platforms, and map them to the ACPI-based discovery policy.
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
drivers/platform/x86/intel/pmc/core.h | 5 +++++
drivers/platform/x86/intel/pmc/ssram_telemetry.c | 16 ++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 284aced99f72..57557ad7d43b 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -329,6 +329,11 @@ enum ppfear_regs {
#define PMC_DEVID_MTL_IOEP 0x7ecf
#define PMC_DEVID_MTL_IOEM 0x7ebf
+/* NVL */
+#define PMC_DEVID_NVL_PCDH 0xd37e
+#define PMC_DEVID_NVL_PCDS 0xd47e
+#define PMC_DEVID_NVL_PCHS 0x6e27
+
extern const char *pmc_lpm_modes[];
struct pmc_bit_map {
diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
index 12b7c1299c2f..930b4a510c71 100644
--- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c
+++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c
@@ -40,6 +40,16 @@ static const struct ssram_type pci_main = {
.p_index = PMC_IDX_MAIN,
};
+static const struct ssram_type acpi_main = {
+ .method = RES_METHOD_ACPI,
+ .p_index = PMC_IDX_MAIN,
+};
+
+static const struct ssram_type acpi_pch = {
+ .method = RES_METHOD_ACPI,
+ .p_index = PMC_IDX_PCH,
+};
+
static struct pmc_ssram_telemetry pmc_ssram_telems[3];
static inline u64 get_base(void __iomem *addr, u32 offset)
@@ -310,6 +320,12 @@ static const struct pci_device_id pmc_ssram_telemetry_pci_ids[] = {
.driver_data = (kernel_ulong_t)&pci_main },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_WCL_PCDN),
.driver_data = (kernel_ulong_t)&pci_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_NVL_PCDH),
+ .driver_data = (kernel_ulong_t)&acpi_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_NVL_PCDS),
+ .driver_data = (kernel_ulong_t)&acpi_main },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_NVL_PCHS),
+ .driver_data = (kernel_ulong_t)&acpi_pch },
{ }
};
MODULE_DEVICE_TABLE(pci, pmc_ssram_telemetry_pci_ids);
--
2.43.0
^ permalink raw reply related [flat|nested] 34+ messages in thread* Re: [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry
2026-03-13 1:51 [PATCH 00/22] platform/x86/intel: Add ACPI PMT discovery support and enable NVL PMC telemetry David E. Box
` (21 preceding siblings ...)
2026-03-13 1:52 ` [PATCH 22/22] platform/x86/intel/pmc: Add NVL PCI IDs for SSRAM telemetry discovery David E. Box
@ 2026-03-13 15:03 ` srinivas pandruvada
22 siblings, 0 replies; 34+ messages in thread
From: srinivas pandruvada @ 2026-03-13 15:03 UTC (permalink / raw)
To: David E. Box, thomas.hellstrom, rodrigo.vivi, irenic.rajneesh,
ilpo.jarvinen, intel-xe, dri-devel, xi.pardee
Cc: hansg, linux-kernel, platform-driver-x86
On Thu, 2026-03-12 at 18:51 -0700, David E. Box wrote:
> This series adds ACPI-based PMT discovery support and wires it into
> the
> Intel PMC telemetry stack for Nova Lake S.
I think this series is v7, missing patch prefix for versions.
Thanks,
Srinivas
>
> Today, PMT discovery flow is primarily PCI-oriented. Some platforms
> expose
> PMT discovery via ACPI _DSD, and PMC telemetry needs to consume that
> path
> for both standalone and companion-device cases. This series addresses
> that
> in three logical steps:
>
> 1. Prepare intel_vsec for ACPI-backed discovery
> 2. Refactor PMT class handling so discovery source is
> abstracted (PCI or ACPI)
> 3. Add/enable PMC consumers using ACPI discovery, including NVL
> SSRAM support
>
> Patches 1–6 were previously posted here:
> https://lore.kernel.org/all/20260303051953.1453372-1-david.e.box@linux.intel.com/
>
> Series layout
>
> 01-06: intel_vsec cleanup/generalization for ACPI-capable
> discovery
> plumbing. Previous changelog up to V7 included.
> Major patches:
> Patch 6 - adds ACPI support in VSEC driver
>
> 07-12: PMT class refactor and ACPI discovery-source support
> Major patches:
> Patch 12 - adds ACPI support in PMT driver
>
> 13-22: PMC driver integration
> Major patches:
> Patch 14 - adds new ACPI platform driver
> Patch 20 - adds ACPI discovery support in ssram driver
> Patch 22 - adds NVL IDs for SSRAM discovery
>
> David E. Box (20):
> platform/x86/intel/vsec: Refactor base_addr handling
> platform/x86/intel/vsec: Make driver_data info const
> platform/x86/intel/vsec: Decouple add/link helpers from PCI
> platform/x86/intel/vsec: Switch exported helpers from pci_dev to
> device
> platform/x86/intel/vsec: Return real error codes from registration
> path
> platform/x86/intel/vsec: Plumb ACPI PMT discovery tables through
> vsec
> platform/x86/intel/pmt: Add pre/post decode hooks around header
> parsing
> platform/x86/intel/pmt/crashlog: Split init into pre-decode
> platform/x86/intel/pmt/telemetry: Move overlap check to post-decode
> hook
> platform/x86/intel/pmt: Move header decode into common helper
> platform/x86/intel/pmt: Pass discovery index instead of resource
> platform/x86/intel/pmt: Unify header fetch and add ACPI source
> platform/x86/intel/pmc: Add PMC SSRAM Kconfig description
> platform/x86/intel/pmc: Add ACPI PWRM telemetry driver for Nova
> Lake S
> platform/x86/intel/pmc/ssram: Rename probe and PCI ID table for
> consistency
> platform/x86/intel/pmc/ssram: Refactor DEVID/PWRMBASE extraction
> into
> helper
> platform/x86/intel/pmc/ssram: Add PCI platform data
> platform/x86/intel/pmc/ssram: Add ACPI discovery scaffolding
> platform/x86/intel/pmc/ssram: Make PMT registration optional
> platform/x86/intel/pmc: Add NVL PCI IDs for SSRAM telemetry
> discovery
>
> Xi Pardee (2):
> platform/x86/intel/pmc/ssram: Use fixed-size static pmc array
> platform/x86/intel/pmc/ssram: Refactor memory barrier for reentrant
> probe
>
> drivers/gpu/drm/xe/xe_debugfs.c | 2 +-
> drivers/gpu/drm/xe/xe_hwmon.c | 2 +-
> drivers/gpu/drm/xe/xe_vsec.c | 7 +-
> drivers/gpu/drm/xe/xe_vsec.h | 4 +-
> drivers/platform/x86/intel/pmc/Kconfig | 25 ++
> drivers/platform/x86/intel/pmc/Makefile | 2 +
> drivers/platform/x86/intel/pmc/core.c | 4 +-
> drivers/platform/x86/intel/pmc/core.h | 17 ++
> .../platform/x86/intel/pmc/pwrm_telemetry.c | 227 ++++++++++++++++
> .../platform/x86/intel/pmc/ssram_telemetry.c | 254 ++++++++++++++--
> --
> drivers/platform/x86/intel/pmt/class.c | 170 ++++++++++--
> drivers/platform/x86/intel/pmt/class.h | 25 +-
> drivers/platform/x86/intel/pmt/crashlog.c | 16 +-
> drivers/platform/x86/intel/pmt/discovery.c | 4 +-
> drivers/platform/x86/intel/pmt/telemetry.c | 45 +---
> drivers/platform/x86/intel/pmt/telemetry.h | 12 +-
> drivers/platform/x86/intel/sdsi.c | 5 +-
> drivers/platform/x86/intel/vsec.c | 121 +++++----
> drivers/platform/x86/intel/vsec_tpmi.c | 8 +-
> include/linux/intel_vsec.h | 39 ++-
> 20 files changed, 784 insertions(+), 205 deletions(-)
> create mode 100644 drivers/platform/x86/intel/pmc/pwrm_telemetry.c
>
>
> base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
^ permalink raw reply [flat|nested] 34+ messages in thread