* [PATCH v4 00/18] Crescent Island PMT support
@ 2026-09-01 19:27 Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 01/18] platform/x86/intel/pmt: complete pcidev to device update Michael J. Ruhl
` (17 more replies)
0 siblings, 18 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
The Crescent Island (CRI) GPU supports PMT via Xe driver
registration.
The CRI PMT MMIO mapping is shared for each PMT feature and it is
necessary to set an index register value to access the correct memory
space.
The PMT driver has a callback infrastructure to access data areas with
driver specific access. It is does not support the PMT control access.
CRI discovery/control spaces are part of the access window so a driver
callback is necessary to allow for the correct window to be exposed.
Add control path callback support to the PMT driver.
Add CRI PMT discovery information.
Update the Xe driver to support the CRI PMT access.
The crashlog access needs to be done with power enabled (telem is only
available when the device is powered).
Determine which access is requested, and do the appropriate power
request.
CRI FW is loaded at device power. Support the late-binding API to
wait for FW readiness. (pending sysctl patch set implements the API).
v2:
Address AI feedback:
- add missing entry->cb check
- address SRIOV VF concerns
- use xe_pm_runtime_put instead of _get in error path
Address review comments:
- redo power/lock sequencing
- support device hotplug events
v3:
- cleanup power manangement flow
- fixed an out of order power management locking issue
- add a GUID caching mechanism, for GUID read
- removed unused parameter (mmio)
v4:
- address various review comments
- refactor crashlog to allow for return values
- for callback usage, decouple PMT remap of data areas
- use IS_SRIOV_VF() rather than expose soc-remapper internals
- separate locking fixes intos distinct steps
- refactor define update patches to seperate BMG and CRI updates
- separate internal GUID into separate steps
Michael J. Ruhl (18):
platform/x86/intel/pmt: complete pcidev to device update
platform/x86/intel/pmt: refactor rmw with a return value
platform/x86/intel/pmt: refactor rc with a return value
platform/x86/intel/pmt: Add register access callbacks
platform/x86/intel/pmt: Add helpers for callback info
platform/x86/intel/pmt: Do not remap when using callbacks
drm/xe/vsec: Do not register BMG PMT for VF
drm/xe/vsec: Correct locking order
drm/xe/vsec: Use correct pm state get
drm/xe/vsec: Support possible hotplug exit
drm/xe/vsec: Support Crescent Island PMT
drm/xe/vsec: Refactor BattleMage PMT defines
drm/xe/vsec: Crescent Island PMT decode
drm/xe/vsec: Crescent Island PMT callbacks
drm/xe/vsec: Support late bind fw information
drm/xe/vsec: Add PMT GUID internal access
drm/xe/vsec: Update PMT internal access
drm/xe/vsec: Refactor platform check
drivers/gpu/drm/xe/regs/xe_pmt.h | 12 +-
drivers/gpu/drm/xe/xe_debugfs.c | 45 +-
drivers/gpu/drm/xe/xe_device.c | 4 +-
drivers/gpu/drm/xe/xe_device_types.h | 9 +
drivers/gpu/drm/xe/xe_hwmon.c | 10 +-
drivers/gpu/drm/xe/xe_pcode.c | 10 +-
drivers/gpu/drm/xe/xe_vsec.c | 515 +++++++++++++++++++--
drivers/gpu/drm/xe/xe_vsec.h | 3 +-
drivers/platform/x86/intel/pmt/class.c | 26 +-
drivers/platform/x86/intel/pmt/class.h | 18 +-
drivers/platform/x86/intel/pmt/crashlog.c | 243 ++++++----
drivers/platform/x86/intel/pmt/discovery.c | 2 +-
include/linux/intel_vsec.h | 14 +-
13 files changed, 743 insertions(+), 168 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 01/18] platform/x86/intel/pmt: complete pcidev to device update
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 02/18] platform/x86/intel/pmt: refactor rmw with a return value Michael J. Ruhl
` (16 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
The update that moved struct pci_dev usage to struct device
is incomplete. Only telemetry endpoints are covered.
Other PMT features (crashlog) are now blocked from using
the callback mechanism.
Change struct intel_pmt_entry pci_dev member to device.
Update callback usage to use the intel_pmt_entry rather than
the telemetry endpoint.
Fixes: 353042d54d82 ("platform/x86/intel/vsec: Switch exported helpers from pci_dev to device")
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/platform/x86/intel/pmt/class.c | 5 ++---
drivers/platform/x86/intel/pmt/class.h | 3 +--
drivers/platform/x86/intel/pmt/discovery.c | 2 +-
3 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index d0ab8e33c62a..402d51df834a 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -100,7 +100,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->ep->dev, entry->cb, entry->header.guid, buf,
+ count = pmt_telem_read_mmio(entry->dev, entry->cb, entry->header.guid, buf,
entry->base, off, count);
return count;
@@ -286,8 +286,6 @@ static int pmt_resolve_access_pci(struct intel_pmt_entry *entry,
return -EINVAL;
}
- entry->pcidev = pci_dev;
-
return 0;
}
@@ -365,6 +363,7 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
entry->guid = header->guid;
entry->size = header->size;
entry->cb = ivdev->priv_data;
+ entry->dev = ivdev->dev;
return 0;
}
diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
index a0ece4fc3837..258cb460e61c 100644
--- a/drivers/platform/x86/intel/pmt/class.h
+++ b/drivers/platform/x86/intel/pmt/class.h
@@ -20,7 +20,6 @@
#define GET_ADDRESS(v) ((v) & GENMASK(31, 3))
struct device;
-struct pci_dev;
extern struct class intel_pmt_class;
struct telem_endpoint {
@@ -42,7 +41,7 @@ struct intel_pmt_header {
struct intel_pmt_entry {
struct telem_endpoint *ep;
- struct pci_dev *pcidev;
+ struct device *dev;
struct intel_pmt_header header;
u32 disc_header[PMT_DISC_DWORDS];
struct bin_attribute pmt_bin_attr;
diff --git a/drivers/platform/x86/intel/pmt/discovery.c b/drivers/platform/x86/intel/pmt/discovery.c
index c482368bfaae..f4203d240f54 100644
--- a/drivers/platform/x86/intel/pmt/discovery.c
+++ b/drivers/platform/x86/intel/pmt/discovery.c
@@ -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->dev)
+ if (feature->priv->parent != entry->dev)
continue;
pmt_get_features(entry, feature);
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 02/18] platform/x86/intel/pmt: refactor rmw with a return value
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 01/18] platform/x86/intel/pmt: complete pcidev to device update Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-02 9:05 ` Ilpo Järvinen
2026-09-02 9:07 ` Ilpo Järvinen
2026-09-01 19:27 ` [PATCH v4 03/18] platform/x86/intel/pmt: refactor rc " Michael J. Ruhl
` (15 subsequent siblings)
17 siblings, 2 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Upcoming changes will include possible failures from HW
accesses.
Refactor pmt_crashlog_rwm with a return value.
Update all necessary usage to use the return code.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/platform/x86/intel/pmt/crashlog.c | 88 ++++++++++++-----------
1 file changed, 45 insertions(+), 43 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
index f936daf99e4d..ebc7880d95bd 100644
--- a/drivers/platform/x86/intel/pmt/crashlog.c
+++ b/drivers/platform/x86/intel/pmt/crashlog.c
@@ -125,7 +125,7 @@ struct pmt_crashlog_priv {
*/
/* Read, modify, write the control register, setting or clearing @bit based on @set */
-static void pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
+static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
{
const struct crashlog_control *control = &crashlog->info->control;
struct intel_pmt_entry *entry = &crashlog->entry;
@@ -139,6 +139,8 @@ static void pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
reg &= ~bit;
writel(reg, entry->disc_table + control->offset);
+
+ return 0;
}
/* Read the status register and see if the specified @bit is set */
@@ -181,20 +183,20 @@ static bool pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_typ
return false;
}
-static void pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
+static int pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
bool disable)
{
- pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
+ return pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
}
-static void pmt_crashlog_set_clear(struct crashlog_entry *crashlog)
+static int pmt_crashlog_set_clear(struct crashlog_entry *crashlog)
{
- pmt_crashlog_rmw(crashlog, crashlog->info->control.clear, true);
+ return pmt_crashlog_rmw(crashlog, crashlog->info->control.clear, true);
}
-static void pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
+static int pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
{
- pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
+ return pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
}
static bool pmt_crashlog_cleared(struct crashlog_entry *crashlog)
@@ -207,9 +209,9 @@ static bool pmt_crashlog_consumed(struct crashlog_entry *crashlog)
return pmt_crashlog_rc(crashlog, crashlog->info->status.consumed);
}
-static void pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
+static int pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
{
- pmt_crashlog_rmw(crashlog, crashlog->info->control.consume, true);
+ return pmt_crashlog_rmw(crashlog, crashlog->info->control.consume, true);
}
static bool pmt_crashlog_error(struct crashlog_entry *crashlog)
@@ -222,9 +224,9 @@ static bool pmt_crashlog_rearm(struct crashlog_entry *crashlog)
return pmt_crashlog_rc(crashlog, crashlog->info->status.rearmed);
}
-static void pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
+static int pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
{
- pmt_crashlog_rmw(crashlog, crashlog->info->control.rearm, true);
+ return pmt_crashlog_rmw(crashlog, crashlog->info->control.rearm, true);
}
/*
@@ -245,13 +247,13 @@ clear_store(struct device *dev, struct device_attribute *attr,
{
struct crashlog_entry *crashlog;
bool clear;
- int result;
+ int ret;
crashlog = dev_get_drvdata(dev);
- result = kstrtobool(buf, &clear);
- if (result)
- return result;
+ ret = kstrtobool(buf, &clear);
+ if (ret)
+ return ret;
/* set bit only */
if (!clear)
@@ -259,9 +261,9 @@ clear_store(struct device *dev, struct device_attribute *attr,
guard(mutex)(&crashlog->control_mutex);
- pmt_crashlog_set_clear(crashlog);
+ ret = pmt_crashlog_set_clear(crashlog);
- return count;
+ return ret ? ret : count;
}
static DEVICE_ATTR_RW(clear);
@@ -280,13 +282,13 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
{
struct crashlog_entry *crashlog;
bool consumed;
- int result;
+ int ret;
crashlog = dev_get_drvdata(dev);
- result = kstrtobool(buf, &consumed);
- if (result)
- return result;
+ ret = kstrtobool(buf, &consumed);
+ if (ret)
+ return ret;
/* set bit only */
if (!consumed)
@@ -300,9 +302,9 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
if (!pmt_crashlog_complete(crashlog))
return -EEXIST;
- pmt_crashlog_set_consumed(crashlog);
+ ret = pmt_crashlog_set_consumed(crashlog);
- return count;
+ return ret ? ret : count;
}
static DEVICE_ATTR_RW(consumed);
@@ -321,19 +323,19 @@ enable_store(struct device *dev, struct device_attribute *attr,
{
struct crashlog_entry *crashlog;
bool enabled;
- int result;
+ int ret;
crashlog = dev_get_drvdata(dev);
- result = kstrtobool(buf, &enabled);
- if (result)
- return result;
+ ret = kstrtobool(buf, &enabled);
+ if (ret)
+ return ret;
guard(mutex)(&crashlog->control_mutex);
- pmt_crashlog_set_disable(crashlog, !enabled);
+ ret = pmt_crashlog_set_disable(crashlog, !enabled);
- return count;
+ return ret ? ret : count;
}
static DEVICE_ATTR_RW(enable);
@@ -362,13 +364,13 @@ rearm_store(struct device *dev, struct device_attribute *attr, const char *buf,
{
struct crashlog_entry *crashlog;
bool rearm;
- int result;
+ int ret;
crashlog = dev_get_drvdata(dev);
- result = kstrtobool(buf, &rearm);
- if (result)
- return result;
+ ret = kstrtobool(buf, &rearm);
+ if (ret)
+ return ret;
/* set only */
if (!rearm)
@@ -376,9 +378,9 @@ rearm_store(struct device *dev, struct device_attribute *attr, const char *buf,
guard(mutex)(&crashlog->control_mutex);
- pmt_crashlog_set_rearm(crashlog);
+ ret = pmt_crashlog_set_rearm(crashlog);
- return count;
+ return ret ? ret : count;
}
static DEVICE_ATTR_RW(rearm);
@@ -400,13 +402,13 @@ trigger_store(struct device *dev, struct device_attribute *attr,
{
struct crashlog_entry *crashlog;
bool trigger;
- int result;
+ int ret;
crashlog = dev_get_drvdata(dev);
- result = kstrtobool(buf, &trigger);
- if (result)
- return result;
+ ret = kstrtobool(buf, &trigger);
+ if (ret)
+ return ret;
guard(mutex)(&crashlog->control_mutex);
@@ -415,17 +417,17 @@ trigger_store(struct device *dev, struct device_attribute *attr,
return -EBUSY;
if (!trigger) {
- pmt_crashlog_set_clear(crashlog);
- return count;
+ ret = pmt_crashlog_set_clear(crashlog);
+ return ret ? ret : count;
}
/* we cannot trigger a new crash if one is still pending */
if (pmt_crashlog_complete(crashlog))
return -EEXIST;
- pmt_crashlog_set_execute(crashlog);
+ ret = pmt_crashlog_set_execute(crashlog);
- return count;
+ return ret ? ret : count;
}
static DEVICE_ATTR_RW(trigger);
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 03/18] platform/x86/intel/pmt: refactor rc with a return value
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 01/18] platform/x86/intel/pmt: complete pcidev to device update Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 02/18] platform/x86/intel/pmt: refactor rmw with a return value Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-02 9:08 ` Ilpo Järvinen
2026-09-01 19:27 ` [PATCH v4 04/18] platform/x86/intel/pmt: Add register access callbacks Michael J. Ruhl
` (14 subsequent siblings)
17 siblings, 1 reply; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Upcoming changes will include possible failures from HW
accesses.
Refactor pmt_crashlog_rw with a return value.
Update all necessary usage to use the return code.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/platform/x86/intel/pmt/crashlog.c | 109 +++++++++++++++-------
1 file changed, 77 insertions(+), 32 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
index ebc7880d95bd..83323b1ce4a9 100644
--- a/drivers/platform/x86/intel/pmt/crashlog.c
+++ b/drivers/platform/x86/intel/pmt/crashlog.c
@@ -144,27 +144,29 @@ static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
}
/* Read the status register and see if the specified @bit is set */
-static bool pmt_crashlog_rc(struct crashlog_entry *crashlog, u32 bit)
+static int pmt_crashlog_rc(struct crashlog_entry *crashlog, u32 bit, bool *state)
{
const struct crashlog_status *status = &crashlog->info->status;
u32 reg = readl(crashlog->entry.disc_table + status->offset);
- return !!(reg & bit);
+ *state = !!(reg & bit);
+
+ return 0;
}
-static bool pmt_crashlog_complete(struct crashlog_entry *crashlog)
+static int pmt_crashlog_complete(struct crashlog_entry *crashlog, bool *state)
{
/* return current value of the crashlog complete flag */
- return pmt_crashlog_rc(crashlog, crashlog->info->status.complete);
+ return pmt_crashlog_rc(crashlog, crashlog->info->status.complete, state);
}
-static bool pmt_crashlog_disabled(struct crashlog_entry *crashlog)
+static int pmt_crashlog_disabled(struct crashlog_entry *crashlog, bool *state)
{
/* return current value of the crashlog disabled flag */
- return pmt_crashlog_rc(crashlog, crashlog->info->status.disabled);
+ return pmt_crashlog_rc(crashlog, crashlog->info->status.disabled, state);
}
-static bool pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_type, u32 *version)
+static int pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_type, u32 *version)
{
u32 discovery_header = readl(entry->disc_table + CONTROL_OFFSET);
@@ -184,7 +186,7 @@ static bool pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_typ
}
static int pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
- bool disable)
+ bool disable)
{
return pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
}
@@ -199,14 +201,14 @@ static int pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
return pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
}
-static bool pmt_crashlog_cleared(struct crashlog_entry *crashlog)
+static int pmt_crashlog_cleared(struct crashlog_entry *crashlog, bool *state)
{
- return pmt_crashlog_rc(crashlog, crashlog->info->status.cleared);
+ return pmt_crashlog_rc(crashlog, crashlog->info->status.cleared, state);
}
-static bool pmt_crashlog_consumed(struct crashlog_entry *crashlog)
+static int pmt_crashlog_consumed(struct crashlog_entry *crashlog, bool *state)
{
- return pmt_crashlog_rc(crashlog, crashlog->info->status.consumed);
+ return pmt_crashlog_rc(crashlog, crashlog->info->status.consumed, state);
}
static int pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
@@ -214,14 +216,14 @@ static int pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
return pmt_crashlog_rmw(crashlog, crashlog->info->control.consume, true);
}
-static bool pmt_crashlog_error(struct crashlog_entry *crashlog)
+static int pmt_crashlog_error(struct crashlog_entry *crashlog, bool *state)
{
- return pmt_crashlog_rc(crashlog, crashlog->info->status.error);
+ return pmt_crashlog_rc(crashlog, crashlog->info->status.error, state);
}
-static bool pmt_crashlog_rearm(struct crashlog_entry *crashlog)
+static int pmt_crashlog_rearm(struct crashlog_entry *crashlog, bool *state)
{
- return pmt_crashlog_rc(crashlog, crashlog->info->status.rearmed);
+ return pmt_crashlog_rc(crashlog, crashlog->info->status.rearmed, state);
}
static int pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
@@ -236,9 +238,14 @@ static ssize_t
clear_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct crashlog_entry *crashlog = dev_get_drvdata(dev);
- bool cleared = pmt_crashlog_cleared(crashlog);
+ bool cleared;
+ int ret;
- return sysfs_emit(buf, "%d\n", cleared);
+ ret = pmt_crashlog_cleared(crashlog, &cleared);
+ if (ret)
+ return sysfs_emit(buf, "read error: %d\n", ret);
+ else
+ return sysfs_emit(buf, "%d\n", cleared);
}
static ssize_t
@@ -271,9 +278,14 @@ static ssize_t
consumed_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct crashlog_entry *crashlog = dev_get_drvdata(dev);
- bool consumed = pmt_crashlog_consumed(crashlog);
+ bool consumed;
+ int ret;
- return sysfs_emit(buf, "%d\n", consumed);
+ ret = pmt_crashlog_consumed(crashlog, &consumed);
+ if (ret)
+ return sysfs_emit(buf, "read error: %d\n", ret);
+ else
+ return sysfs_emit(buf, "%d\n", consumed);
}
static ssize_t
@@ -281,7 +293,9 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
size_t count)
{
struct crashlog_entry *crashlog;
+ bool complete;
bool consumed;
+ bool disabled;
int ret;
crashlog = dev_get_drvdata(dev);
@@ -296,10 +310,16 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
guard(mutex)(&crashlog->control_mutex);
- if (pmt_crashlog_disabled(crashlog))
+ ret = pmt_crashlog_disabled(crashlog, &disabled);
+ if (ret)
+ return ret;
+ if (disabled)
return -EBUSY;
- if (!pmt_crashlog_complete(crashlog))
+ ret = pmt_crashlog_complete(crashlog, &complete);
+ if (ret)
+ return ret;
+ if (!complete)
return -EEXIST;
ret = pmt_crashlog_set_consumed(crashlog);
@@ -312,9 +332,14 @@ static ssize_t
enable_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct crashlog_entry *crashlog = dev_get_drvdata(dev);
- bool enabled = !pmt_crashlog_disabled(crashlog);
+ bool enabled;
+ int ret;
- return sprintf(buf, "%d\n", enabled);
+ ret = pmt_crashlog_disabled(crashlog, &enabled);
+ if (ret)
+ return sysfs_emit(buf, "error: %d\n", ret);
+ else
+ return sysfs_emit(buf, "%d\n", enabled);
}
static ssize_t
@@ -343,9 +368,14 @@ static ssize_t
error_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct crashlog_entry *crashlog = dev_get_drvdata(dev);
- bool error = pmt_crashlog_error(crashlog);
+ bool error;
+ int ret;
- return sysfs_emit(buf, "%d\n", error);
+ ret = pmt_crashlog_error(crashlog, &error);
+ if (ret)
+ return sysfs_emit(buf, "read error: %d\n", ret);
+ else
+ return sysfs_emit(buf, "%d\n", error);
}
static DEVICE_ATTR_RO(error);
@@ -353,9 +383,14 @@ static ssize_t
rearm_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct crashlog_entry *crashlog = dev_get_drvdata(dev);
- int rearmed = pmt_crashlog_rearm(crashlog);
+ bool rearmed;
+ int ret;
- return sysfs_emit(buf, "%d\n", rearmed);
+ ret = pmt_crashlog_rearm(crashlog, &rearmed);
+ if (ret)
+ return sysfs_emit(buf, "read error: %d\n", ret);
+ else
+ return sysfs_emit(buf, "%d\n", rearmed);
}
static ssize_t
@@ -389,11 +424,15 @@ trigger_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct crashlog_entry *crashlog;
bool trigger;
+ int ret;
crashlog = dev_get_drvdata(dev);
- trigger = pmt_crashlog_complete(crashlog);
- return sprintf(buf, "%d\n", trigger);
+ ret = pmt_crashlog_complete(crashlog, &trigger);
+ if (ret)
+ return sysfs_emit(buf, "read error: %d\n", ret);
+ else
+ return sysfs_emit(buf, "%d\n", trigger);
}
static ssize_t
@@ -401,6 +440,8 @@ trigger_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct crashlog_entry *crashlog;
+ bool complete;
+ bool disabled;
bool trigger;
int ret;
@@ -413,7 +454,10 @@ trigger_store(struct device *dev, struct device_attribute *attr,
guard(mutex)(&crashlog->control_mutex);
/* if device is currently disabled, return busy */
- if (pmt_crashlog_disabled(crashlog))
+ ret = pmt_crashlog_disabled(crashlog, &disabled);
+ if (ret)
+ return ret;
+ if (disabled)
return -EBUSY;
if (!trigger) {
@@ -422,7 +466,8 @@ trigger_store(struct device *dev, struct device_attribute *attr,
}
/* we cannot trigger a new crash if one is still pending */
- if (pmt_crashlog_complete(crashlog))
+ ret = pmt_crashlog_complete(crashlog, &complete);
+ if (complete)
return -EEXIST;
ret = pmt_crashlog_set_execute(crashlog);
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 04/18] platform/x86/intel/pmt: Add register access callbacks
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (2 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 03/18] platform/x86/intel/pmt: refactor rc " Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 05/18] platform/x86/intel/pmt: Add helpers for callback info Michael J. Ruhl
` (13 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Some HW does not have direct MMIO access to PMT control and data
features.
Augment the current callback infrastructure (data access) to allow
a registered driver to customize read/write access to the control
paths for PMT usage.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/platform/x86/intel/pmt/crashlog.c | 46 +++++++++++++++++++++--
include/linux/intel_vsec.h | 14 ++++++-
2 files changed, 56 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
index 83323b1ce4a9..142c368a60f8 100644
--- a/drivers/platform/x86/intel/pmt/crashlog.c
+++ b/drivers/platform/x86/intel/pmt/crashlog.c
@@ -11,10 +11,12 @@
#include <linux/auxiliary_bus.h>
#include <linux/cleanup.h>
#include <linux/intel_vsec.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pci.h>
+#include <linux/printk.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/overflow.h>
@@ -124,12 +126,36 @@ struct pmt_crashlog_priv {
* I/O
*/
+static int pmt_crashlog_read_reg(struct intel_pmt_entry *entry, u32 *reg, u32 offset)
+{
+ int ret;
+
+ *reg = 0;
+
+ if (entry->cb && entry->cb->read_reg) {
+ ret = entry->cb->read_reg(entry->dev, entry->header.guid, reg, offset);
+ if (ret) {
+ pr_err_ratelimited("failed to read reg: %d\n", ret);
+ return ret;
+ }
+ } else {
+ *reg = readl(entry->disc_table + offset);
+ }
+
+ return 0;
+}
+
/* Read, modify, write the control register, setting or clearing @bit based on @set */
static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
{
const struct crashlog_control *control = &crashlog->info->control;
struct intel_pmt_entry *entry = &crashlog->entry;
- u32 reg = readl(entry->disc_table + control->offset);
+ u32 reg;
+ int ret;
+
+ ret = pmt_crashlog_read_reg(entry, ®, control->offset);
+ if (ret)
+ return ret;
reg &= ~control->trigger_mask;
@@ -138,7 +164,15 @@ static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
else
reg &= ~bit;
- writel(reg, entry->disc_table + control->offset);
+ if (entry->cb && entry->cb->write_reg) {
+ ret = entry->cb->write_reg(entry->dev, entry->header.guid, reg, control->offset);
+ if (ret) {
+ pr_err_ratelimited("failed to write reg: %d\n", ret);
+ return ret;
+ }
+ } else {
+ writel(reg, entry->disc_table + control->offset);
+ }
return 0;
}
@@ -147,7 +181,13 @@ static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
static int pmt_crashlog_rc(struct crashlog_entry *crashlog, u32 bit, bool *state)
{
const struct crashlog_status *status = &crashlog->info->status;
- u32 reg = readl(crashlog->entry.disc_table + status->offset);
+ struct intel_pmt_entry *entry = &crashlog->entry;
+ u32 reg;
+ int ret;
+
+ ret = pmt_crashlog_read_reg(entry, ®, status->offset);
+ if (ret)
+ return false;
*state = !!(reg & bit);
diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index 843cda8f8644..917d9397a993 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -90,13 +90,25 @@ enum intel_vsec_quirks {
* @read_telem: when specified, called by client driver to access PMT
* data (instead of direct copy).
* * dev: device reference for the callback's use
- * * guid: ID of data to acccss
+ * * guid: ID of data to access
* * data: buffer for the data to be copied
* * off: offset into the requested buffer
* * count: size of buffer
+ * @read_reg: when specified called by client driver to read PMT state
+ * * dev: device reference for the callback's use
+ * * guid: ID of data to access
+ * * reg_data: register data
+ * * offset: offset of register to read
+ * @write_reg: when specified called by client driver to write PMT state
+ * * dev: device reference for the callback's use
+ * * guid: ID of data to access
+ * * reg_data: register data
+ * * offset: offset of register to write
*/
struct pmt_callbacks {
int (*read_telem)(struct device *dev, u32 guid, u64 *data, loff_t off, u32 count);
+ int (*read_reg)(struct device *dev, u32 guid, u32 *reg_data, u32 offset);
+ int (*write_reg)(struct device *dev, u32 guid, u32 reg_data, u32 offset);
};
struct vsec_feature_dependency {
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 05/18] platform/x86/intel/pmt: Add helpers for callback info
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (3 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 04/18] platform/x86/intel/pmt: Add register access callbacks Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-02 9:10 ` Ilpo Järvinen
2026-09-01 19:27 ` [PATCH v4 06/18] platform/x86/intel/pmt: Do not remap when using callbacks Michael J. Ruhl
` (12 subsequent siblings)
17 siblings, 1 reply; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Refactor some open coded checks into helpers.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/platform/x86/intel/pmt/class.c | 2 +-
drivers/platform/x86/intel/pmt/class.h | 15 +++++++++++++++
drivers/platform/x86/intel/pmt/crashlog.c | 4 ++--
3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index 402d51df834a..af7c951b569a 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -64,7 +64,7 @@ pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count)
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)
+ if (is_cb_read_telem(cb))
return cb->read_telem(dev, guid, buf, off, count);
addr += off;
diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
index 258cb460e61c..d8291a5f08a7 100644
--- a/drivers/platform/x86/intel/pmt/class.h
+++ b/drivers/platform/x86/intel/pmt/class.h
@@ -71,6 +71,21 @@ struct intel_pmt_namespace {
struct intel_pmt_entry *entry);
};
+static inline bool is_cb_read_telem(struct pmt_callbacks *cb)
+{
+ return cb && cb->read_telem ? true : false;
+}
+
+static inline bool is_cb_read_reg(struct pmt_callbacks *cb)
+{
+ return cb && cb->read_reg ? true : false;
+}
+
+static inline bool is_cb_write_reg(struct pmt_callbacks *cb)
+{
+ return cb && cb->write_reg ? true : false;
+}
+
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);
diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
index 142c368a60f8..32f6a7d42b8d 100644
--- a/drivers/platform/x86/intel/pmt/crashlog.c
+++ b/drivers/platform/x86/intel/pmt/crashlog.c
@@ -132,7 +132,7 @@ static int pmt_crashlog_read_reg(struct intel_pmt_entry *entry, u32 *reg, u32 of
*reg = 0;
- if (entry->cb && entry->cb->read_reg) {
+ if (is_cb_read_reg(entry->cb)) {
ret = entry->cb->read_reg(entry->dev, entry->header.guid, reg, offset);
if (ret) {
pr_err_ratelimited("failed to read reg: %d\n", ret);
@@ -164,7 +164,7 @@ static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
else
reg &= ~bit;
- if (entry->cb && entry->cb->write_reg) {
+ if (is_cb_write_reg(entry->cb)) {
ret = entry->cb->write_reg(entry->dev, entry->header.guid, reg, control->offset);
if (ret) {
pr_err_ratelimited("failed to write reg: %d\n", ret);
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 06/18] platform/x86/intel/pmt: Do not remap when using callbacks
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (4 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 05/18] platform/x86/intel/pmt: Add helpers for callback info Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-02 9:18 ` Ilpo Järvinen
2026-09-01 19:27 ` [PATCH v4 07/18] drm/xe/vsec: Do not register BMG PMT for VF Michael J. Ruhl
` (11 subsequent siblings)
17 siblings, 1 reply; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
A callback indicates that the parent driver is responsible
for accessing the data area. Creating a PMT memory remap
is redundant.
If a read_telem callback has been provided, do not create a
remap.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/platform/x86/intel/pmt/class.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index af7c951b569a..350129121ff1 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -373,7 +373,6 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
struct device *parent)
{
struct intel_vsec_device *ivdev = dev_to_ivdev(parent);
- struct resource res = {0};
struct device *dev;
int ret;
@@ -403,14 +402,18 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
if (!entry->size)
return 0;
- res.start = entry->base_addr;
- res.end = res.start + entry->size - 1;
- res.flags = IORESOURCE_MEM;
+ if (!is_cb_read_telem(entry->cb)) {
+ struct resource res = {0};
- entry->base = devm_ioremap_resource(dev, &res);
- if (IS_ERR(entry->base)) {
- ret = PTR_ERR(entry->base);
- goto fail_ioremap;
+ res.start = entry->base_addr;
+ res.end = res.start + entry->size - 1;
+ res.flags = IORESOURCE_MEM;
+
+ entry->base = devm_ioremap_resource(dev, &res);
+ if (IS_ERR(entry->base)) {
+ ret = PTR_ERR(entry->base);
+ goto fail_ioremap;
+ }
}
sysfs_bin_attr_init(&entry->pmt_bin_attr);
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 07/18] drm/xe/vsec: Do not register BMG PMT for VF
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (5 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 06/18] platform/x86/intel/pmt: Do not remap when using callbacks Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 08/18] drm/xe/vsec: Correct locking order Michael J. Ruhl
` (10 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
BMG PMT is not supported for VF nodes.
If IS_SRIOV_VF() is true, do NOT register with PMT.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_vsec.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index a9baf0bfe572..71bc359b2ad1 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -149,6 +149,9 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
u32 offset;
int ret;
+ if (IS_SRIOV_VF(xe))
+ return -EINVAL;
+
ret = xe_guid_decode(guid, &mem_region, &offset);
if (ret)
return ret;
@@ -157,9 +160,6 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
guard(mutex)(&xe->pmt.lock);
- if (!xe->soc_remapper.set_telem_region)
- return -ENODEV;
-
/* indicate that we are not at an appropriate power level */
if (!xe_pm_runtime_get_if_active(xe))
return -ENODATA;
@@ -210,6 +210,8 @@ void xe_vsec_init(struct xe_device *xe)
switch (platform) {
case XE_VSEC_BMG:
+ if (IS_SRIOV_VF(xe))
+ return;
info->priv_data = &xe_pmt_cb;
break;
default:
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 08/18] drm/xe/vsec: Correct locking order
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (6 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 07/18] drm/xe/vsec: Do not register BMG PMT for VF Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 09/18] drm/xe/vsec: Use correct pm state get Michael J. Ruhl
` (9 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Xe locking order is power state first, and then local locks.
Reorder locking to correct usage.
Use excplicit functions because of multiple locks.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_vsec.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index 71bc359b2ad1..dd7723ba6c1c 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -158,16 +158,19 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
telem_addr += offset + user_offset;
- guard(mutex)(&xe->pmt.lock);
-
/* indicate that we are not at an appropriate power level */
if (!xe_pm_runtime_get_if_active(xe))
return -ENODATA;
+ mutex_lock(&xe->pmt.lock);
+
/* set SoC re-mapper index register based on GUID memory region */
xe->soc_remapper.set_telem_region(xe, mem_region);
memcpy_fromio(data, telem_addr, count);
+
+ mutex_unlock(&xe->pmt.lock);
+
xe_pm_runtime_put(xe);
return count;
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 09/18] drm/xe/vsec: Use correct pm state get
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (7 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 08/18] drm/xe/vsec: Correct locking order Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 10/18] drm/xe/vsec: Support possible hotplug exit Michael J. Ruhl
` (8 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Crashlog needs to be collected at all times. The current pm
check assumes telemetry only.
Update read path to enable device for crashlog instances.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
Fixes: 2c402a801c19 ("platform/x86/intel/pmt: support BMG crashlog")
---
drivers/gpu/drm/xe/xe_vsec.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index dd7723ba6c1c..468a221378fa 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -145,6 +145,7 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
{
struct xe_device *xe = kdev_to_xe_device(dev);
void __iomem *telem_addr = xe->mmio.regs + BMG_TELEMETRY_OFFSET;
+ u32 cap_type = FIELD_GET(GUID_CAP_TYPE, guid);
u32 mem_region;
u32 offset;
int ret;
@@ -158,9 +159,18 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
telem_addr += offset + user_offset;
- /* indicate that we are not at an appropriate power level */
- if (!xe_pm_runtime_get_if_active(xe))
- return -ENODATA;
+ /* Always allow crashlog. Telemetry, only when powered */
+ switch (cap_type) {
+ case CRASHLOG:
+ xe_pm_runtime_get(xe);
+ break;
+ case TELEMETRY:
+ if (!xe_pm_runtime_get_if_active(xe))
+ return -ENODATA;
+ break;
+ case WATCHER:
+ return -EINVAL;
+ }
mutex_lock(&xe->pmt.lock);
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 10/18] drm/xe/vsec: Support possible hotplug exit
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (8 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 09/18] drm/xe/vsec: Use correct pm state get Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 11/18] drm/xe/vsec: Support Crescent Island PMT Michael J. Ruhl
` (7 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
DRM has an API that will verify that a device is valid in
the hotplug context.
Verify device is valid before access in the VSEC callback
API.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_vsec.c | 35 +++++++++++++++++++++++++++--------
1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index 468a221378fa..c6299629dc27 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -10,6 +10,8 @@
#include <linux/pci.h>
#include <linux/types.h>
+#include <drm/drm_drv.h>
+
#include "xe_device.h"
#include "xe_device_types.h"
#include "xe_mmio.h"
@@ -140,6 +142,11 @@ static int xe_guid_decode(u32 guid, int *index, u32 *offset)
return 0;
}
+/*
+ * xe_pmt_telem_read is a callback API. I.e this can be accessed external to
+ * XE driver (PMT driver scope). Because of this, DRM hotplug needs to be
+ * verified (drm_dev_enter()).
+ */
int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offset,
u32 count)
{
@@ -148,14 +155,20 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
u32 cap_type = FIELD_GET(GUID_CAP_TYPE, guid);
u32 mem_region;
u32 offset;
- int ret;
+ int ret = 0;
+ int idx;
- if (IS_SRIOV_VF(xe))
- return -EINVAL;
+ if (!drm_dev_enter(&xe->drm, &idx))
+ return -ENODEV;
+
+ if (IS_SRIOV_VF(xe)) {
+ ret = -EINVAL;
+ goto dev_exit;
+ }
ret = xe_guid_decode(guid, &mem_region, &offset);
if (ret)
- return ret;
+ goto dev_exit;
telem_addr += offset + user_offset;
@@ -165,11 +178,14 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
xe_pm_runtime_get(xe);
break;
case TELEMETRY:
- if (!xe_pm_runtime_get_if_active(xe))
- return -ENODATA;
+ if (!xe_pm_runtime_get_if_active(xe)) {
+ ret = -ENODATA;
+ goto dev_exit;
+ }
break;
case WATCHER:
- return -EINVAL;
+ ret = -EINVAL;
+ goto dev_exit;
}
mutex_lock(&xe->pmt.lock);
@@ -183,7 +199,10 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
xe_pm_runtime_put(xe);
- return count;
+dev_exit:
+ drm_dev_exit(idx);
+
+ return ret == 0 ? count : ret;
}
static struct pmt_callbacks xe_pmt_cb = {
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 11/18] drm/xe/vsec: Support Crescent Island PMT
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (9 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 10/18] drm/xe/vsec: Support possible hotplug exit Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 12/18] drm/xe/vsec: Refactor BattleMage PMT defines Michael J. Ruhl
` (6 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Crescent Island (CRI) supports PMT telemetry and crashlog.
Add Crescent Island (CRI) discovery structure (DVSEC)
information to allow for Xe registration.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/regs/xe_pmt.h | 8 +++--
drivers/gpu/drm/xe/xe_vsec.c | 51 +++++++++++++++++++++++++++++---
2 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/xe/regs/xe_pmt.h b/drivers/gpu/drm/xe/regs/xe_pmt.h
index a62ab05c6b4c..2f6658395587 100644
--- a/drivers/gpu/drm/xe/regs/xe_pmt.h
+++ b/drivers/gpu/drm/xe/regs/xe_pmt.h
@@ -17,8 +17,12 @@
#define PUNIT_VERSION_OFFSET 0xA0
-#define BMG_TELEMETRY_BASE_OFFSET 0xE0000
-#define BMG_TELEMETRY_OFFSET (SOC_BASE + BMG_TELEMETRY_BASE_OFFSET)
+#define XE_PMT_BASE_OFFSET 0xE0000
+
+#define BMG_TELEMETRY_OFFSET (SOC_BASE + XE_PMT_BASE_OFFSET)
+
+/* for CRI discovery and telemetry are in an indexed window */
+#define CRI_PMT_OFFSET (SOC_BASE + XE_PMT_BASE_OFFSET)
#define BMG_MODS_RESIDENCY_OFFSET (0x4D0)
#define BMG_G2_RESIDENCY_OFFSET (0x530)
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index c6299629dc27..0604e65d10a0 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pci.h>
+#include <linux/sizes.h>
#include <linux/types.h>
#include <drm/drm_drv.h>
@@ -21,12 +22,23 @@
#include "regs/xe_pmt.h"
-/* PMT GUID value for BMG devices. NOTE: this is NOT a PCI id */
+/* PMT GUID value for BMG and CRI devices. NOTE: this is NOT a PCI id */
#define BMG_DEVICE_ID 0xE2F8
+#define CRI_DEVICE_ID 0xE2FA
+
+/*
+ * sizeof(Crashlog Type1 Version2) = 0x18 (24) bytes
+ * For BMG and CRI PUNIT and OOBMSMS crashlogs are consecutive.
+ */
+#define BMG_CRASHLOG_PUNIT_DISC_OFFSET (0x60)
+#define BMG_CRASHLOG_OOBMSM_DISC_OFFSET (BMG_CRASHLOG_PUNIT_DISC_OFFSET + 0x18)
+
+#define CRI_CRASHLOG_PUNIT_DISC_OFFSET (0x80)
+#define CRI_CRASHLOG_OOBMSM_DISC_OFFSET (CRI_CRASHLOG_PUNIT_DISC_OFFSET + 0x18)
static struct intel_vsec_header bmg_telemetry = {
.rev = 1,
- .length = 0x10,
+ .length = SZ_16,
.id = VSEC_ID_TELEMETRY,
.num_entries = 2,
.entry_size = 4,
@@ -36,12 +48,12 @@ static struct intel_vsec_header bmg_telemetry = {
static struct intel_vsec_header bmg_crashlog = {
.rev = 1,
- .length = 0x10,
+ .length = SZ_16,
.id = VSEC_ID_CRASHLOG,
.num_entries = 2,
.entry_size = 6,
.tbir = 0,
- .offset = BMG_DISCOVERY_OFFSET + 0x60,
+ .offset = BMG_DISCOVERY_OFFSET + BMG_CRASHLOG_PUNIT_DISC_OFFSET,
};
static struct intel_vsec_header *bmg_capabilities[] = {
@@ -50,9 +62,36 @@ static struct intel_vsec_header *bmg_capabilities[] = {
NULL
};
+static struct intel_vsec_header cri_telemetry = {
+ .rev = 1,
+ .length = SZ_16,
+ .id = VSEC_ID_TELEMETRY,
+ .num_entries = 3,
+ .entry_size = 4,
+ .tbir = 0,
+ .offset = CRI_PMT_OFFSET,
+};
+
+static struct intel_vsec_header cri_crashlog = {
+ .rev = 1,
+ .length = SZ_16,
+ .id = VSEC_ID_CRASHLOG,
+ .num_entries = 2,
+ .entry_size = 6,
+ .tbir = 0,
+ .offset = CRI_PMT_OFFSET + CRI_CRASHLOG_PUNIT_DISC_OFFSET,
+};
+
+static struct intel_vsec_header *cri_capabilities[] = {
+ &cri_telemetry,
+ &cri_crashlog,
+ NULL
+};
+
enum xe_vsec {
XE_VSEC_UNKNOWN = 0,
XE_VSEC_BMG,
+ XE_VSEC_CRI,
};
static struct intel_vsec_platform_info xe_vsec_info[] = {
@@ -60,6 +99,10 @@ static struct intel_vsec_platform_info xe_vsec_info[] = {
.caps = VSEC_CAP_TELEMETRY | VSEC_CAP_CRASHLOG,
.headers = bmg_capabilities,
},
+ [XE_VSEC_CRI] = {
+ .caps = VSEC_CAP_TELEMETRY | VSEC_CAP_CRASHLOG,
+ .headers = cri_capabilities,
+ },
{ }
};
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 12/18] drm/xe/vsec: Refactor BattleMage PMT defines
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (10 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 11/18] drm/xe/vsec: Support Crescent Island PMT Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 13/18] drm/xe/vsec: Crescent Island PMT decode Michael J. Ruhl
` (5 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Rename generic defines to be BMG specific.
Define several magic numbers.
Add a base offset for more flexibility.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_device_types.h | 2 ++
drivers/gpu/drm/xe/xe_vsec.c | 32 +++++++++++++++++-----------
2 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 180d450a6deb..3f1a70813a99 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -466,6 +466,8 @@ struct xe_device {
struct {
/** @pmt.lock: protect access for telemetry data */
struct mutex lock;
+ /** @pmt.base_offset: device specific base offset */
+ u64 base_offset;
} pmt;
/** @soc_remapper: SoC remapper object */
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index 0604e65d10a0..c109fc2d13b9 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -122,10 +122,15 @@ static struct intel_vsec_platform_info xe_vsec_info[] = {
#define GUID_CAP_TYPE GENMASK(29, 28)
#define GUID_RECORD_ID GENMASK(31, 30)
-#define PUNIT_TELEMETRY_OFFSET 0x0200
-#define PUNIT_WATCHER_OFFSET 0x14A0
-#define OOBMSM_0_WATCHER_OFFSET 0x18D8
-#define OOBMSM_1_TELEMETRY_OFFSET 0x1000
+#define BMG_IDX_TELEM_PUNIT 0x00
+#define BMG_IDX_TELEM_OOBMSM 0x01
+#define BMG_IDX_CRASHLOG_PUNIT 0x02
+#define BMG_IDX_CRASHLOG_OOBMSM 0x04
+
+#define BMG_PUNIT_TELEMETRY_OFFSET 0x0200
+#define BMG_PUNIT_WATCHER_OFFSET 0x14A0
+#define BMG_OOBMSM_0_WATCHER_OFFSET 0x18D8
+#define BMG_OOBMSM_1_TELEMETRY_OFFSET 0x1000
enum record_id {
PUNIT,
@@ -154,29 +159,29 @@ static int xe_guid_decode(u32 guid, int *index, u32 *offset)
*offset = 0;
if (cap_type == CRASHLOG) {
- *index = record_id == PUNIT ? 2 : 4;
+ *index = record_id == PUNIT ? BMG_IDX_CRASHLOG_PUNIT : BMG_IDX_CRASHLOG_OOBMSM;
return 0;
}
switch (record_id) {
case PUNIT:
- *index = 0;
+ *index = BMG_IDX_TELEM_PUNIT;
if (cap_type == TELEMETRY)
- *offset = PUNIT_TELEMETRY_OFFSET;
+ *offset = BMG_PUNIT_TELEMETRY_OFFSET;
else
- *offset = PUNIT_WATCHER_OFFSET;
+ *offset = BMG_PUNIT_WATCHER_OFFSET;
break;
case OOBMSM_0:
- *index = 1;
+ *index = BMG_IDX_TELEM_OOBMSM;
if (cap_type == WATCHER)
- *offset = OOBMSM_0_WATCHER_OFFSET;
+ *offset = BMG_OOBMSM_0_WATCHER_OFFSET;
break;
case OOBMSM_1:
- *index = 1;
+ *index = BMG_IDX_TELEM_OOBMSM;
if (cap_type == TELEMETRY)
- *offset = OOBMSM_1_TELEMETRY_OFFSET;
+ *offset = BMG_OOBMSM_1_TELEMETRY_OFFSET;
break;
default:
return -EINVAL;
@@ -194,8 +199,8 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
u32 count)
{
struct xe_device *xe = kdev_to_xe_device(dev);
- void __iomem *telem_addr = xe->mmio.regs + BMG_TELEMETRY_OFFSET;
u32 cap_type = FIELD_GET(GUID_CAP_TYPE, guid);
+ void __iomem *telem_addr = xe->mmio.regs + xe->pmt.base_offset;
u32 mem_region;
u32 offset;
int ret = 0;
@@ -287,6 +292,7 @@ void xe_vsec_init(struct xe_device *xe)
case XE_VSEC_BMG:
if (IS_SRIOV_VF(xe))
return;
+ xe->pmt.base_offset = BMG_TELEMETRY_OFFSET;
info->priv_data = &xe_pmt_cb;
break;
default:
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 13/18] drm/xe/vsec: Crescent Island PMT decode
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (11 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 12/18] drm/xe/vsec: Refactor BattleMage PMT defines Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 14/18] drm/xe/vsec: Crescent Island PMT callbacks Michael J. Ruhl
` (4 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Crescent Island (CRI) has different index and offset values for
accessing the PMT data area.
Update the decode path to support the CRI device.
Update the data read callback so to support the CRI usage.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_vsec.c | 98 ++++++++++++++++++++++++++++++++----
1 file changed, 89 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index c109fc2d13b9..d95f4343c78d 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -109,19 +109,25 @@ static struct intel_vsec_platform_info xe_vsec_info[] = {
/*
* The GUID will have the following bits to decode:
* [0:3] - {Telemetry space iteration number (0,1,..)}
- * [4:7] - Segment (SEGMENT_INDEPENDENT-0, Client-1, Server-2)
+ * [4:7] - BMG Segment (SEGMENT_INDEPENDENT-0, Client-1, Server-2)
+ * [4:5] - CRI Segment (SEGMENT_INDEPENDENT-0, Client-1, Server-2)
+ * [6:7] - CRI Instance
* [8:11] - SOC_SKU
* [12:27] – Device ID – changes for each down bin SKU’s
* [28:29] - Capability Type (Crashlog-0, Telemetry Aggregator-1, Watcher-2)
* [30:31] - Record-ID (0-PUNIT, 1-OOBMSM_0, 2-OOBMSM_1)
*/
#define GUID_TELEM_ITERATION GENMASK(3, 0)
-#define GUID_SEGMENT GENMASK(7, 4)
#define GUID_SOC_SKU GENMASK(11, 8)
#define GUID_DEVICE_ID GENMASK(27, 12)
#define GUID_CAP_TYPE GENMASK(29, 28)
#define GUID_RECORD_ID GENMASK(31, 30)
+#define BMG_GUID_SEGMENT GENMASK(7, 4)
+
+#define CRI_GUID_SEGMENT GENMASK(5, 4)
+#define CRI_GUID_INSTANCE GENMASK(7, 6)
+
#define BMG_IDX_TELEM_PUNIT 0x00
#define BMG_IDX_TELEM_OOBMSM 0x01
#define BMG_IDX_CRASHLOG_PUNIT 0x02
@@ -132,6 +138,18 @@ static struct intel_vsec_platform_info xe_vsec_info[] = {
#define BMG_OOBMSM_0_WATCHER_OFFSET 0x18D8
#define BMG_OOBMSM_1_TELEMETRY_OFFSET 0x1000
+#define CRI_IDX_TELEM_DISCOVERY 0x00
+#define CRI_IDX_TELEM_PUNIT 0x01
+#define CRI_IDX_TELEM_OOBMSM 0x02
+#define CRI_IDX_CRASHLOG_PUNIT 0x03
+#define CRI_IDX_WATCHER_OOBMSM 0x03 /* PUNIT and OOBMSM share this index */
+#define CRI_IDX_CRASHLOG_OOBMSM 0x04
+
+#define CRI_PUNIT_WATCHER_OFFSET 0x08A0
+#define CRI_OOBMSM_WATCHER_OFFSET 0x0CF8
+#define CRI_OOBMSM_GFSP_TELEMETRY_OFFSET 0x1600
+#define CRI_PUNIT_CRASHLOG_OFFSET 0x0E78
+
enum record_id {
PUNIT,
OOBMSM_0,
@@ -148,13 +166,6 @@ static int xe_guid_decode(u32 guid, int *index, u32 *offset)
{
u32 record_id = FIELD_GET(GUID_RECORD_ID, guid);
u32 cap_type = FIELD_GET(GUID_CAP_TYPE, guid);
- u32 device_id = FIELD_GET(GUID_DEVICE_ID, guid);
-
- if (device_id != BMG_DEVICE_ID)
- return -ENODEV;
-
- if (cap_type > WATCHER)
- return -EINVAL;
*offset = 0;
@@ -190,6 +201,75 @@ static int xe_guid_decode(u32 guid, int *index, u32 *offset)
return 0;
}
+static int cri_guid_decode(u32 guid, int *index, u32 *offset)
+{
+ u32 record_id = FIELD_GET(GUID_RECORD_ID, guid);
+ u32 cap_type = FIELD_GET(GUID_CAP_TYPE, guid);
+ u32 instance = FIELD_GET(CRI_GUID_INSTANCE, guid);
+
+ *offset = 0;
+
+ if (cap_type == CRASHLOG) {
+ if (record_id == PUNIT) {
+ *index = CRI_IDX_CRASHLOG_PUNIT;
+ *offset = CRI_PUNIT_CRASHLOG_OFFSET;
+ } else {
+ *index = CRI_IDX_CRASHLOG_OOBMSM;
+ }
+ return 0;
+ }
+
+ switch (record_id) {
+ case PUNIT:
+ *index = CRI_IDX_TELEM_PUNIT;
+ if (cap_type == WATCHER)
+ *offset = CRI_PUNIT_WATCHER_OFFSET;
+ break;
+
+ case OOBMSM_0:
+ *index = CRI_IDX_TELEM_OOBMSM;
+ switch (instance) {
+ case 0:
+ if (cap_type == WATCHER) {
+ *index = CRI_IDX_WATCHER_OOBMSM;
+ *offset = CRI_OOBMSM_WATCHER_OFFSET;
+ }
+ break;
+
+ case 1:
+ if (cap_type == TELEMETRY)
+ *offset = CRI_OOBMSM_GFSP_TELEMETRY_OFFSET;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int xe_guid_decode(u32 guid, int *index, u32 *offset)
+{
+ u32 cap_type = FIELD_GET(GUID_CAP_TYPE, guid);
+ u32 device_id = FIELD_GET(GUID_DEVICE_ID, guid);
+
+ if (cap_type > WATCHER)
+ return -EINVAL;
+
+ if (device_id == BMG_DEVICE_ID)
+ return bmg_guid_decode(guid, index, offset);
+
+ if (device_id == CRI_DEVICE_ID)
+ return cri_guid_decode(guid, index, offset);
+
+ return -ENODEV;
+}
+
/*
* xe_pmt_telem_read is a callback API. I.e this can be accessed external to
* XE driver (PMT driver scope). Because of this, DRM hotplug needs to be
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 14/18] drm/xe/vsec: Crescent Island PMT callbacks
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (12 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 13/18] drm/xe/vsec: Crescent Island PMT decode Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 15/18] drm/xe/vsec: Support late bind fw information Michael J. Ruhl
` (3 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
CRI PMT support requires callbacks to access the discovery status
and control areas. Access is a common MMIO area that requires an
index to be set before access is allowed.
Introduce the necessary callbacks to get the status and control
information for CRI PMT usage.
Add the glue logic to register the CRI PMT functionality.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_vsec.c | 108 ++++++++++++++++++++++++++++++++++-
1 file changed, 105 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index d95f4343c78d..e58fea788ace 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -333,17 +333,110 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
return ret == 0 ? count : ret;
}
-static struct pmt_callbacks xe_pmt_cb = {
+/**
+ * xe_pmt_read_reg() - read a crashlog register
+ * @dev: the xe device that registered the callback
+ * @guid: PMT guid of the crashlog instance
+ * @reg: data read from the PMT data structure
+ * @offset: which data to read from the PMT data structure
+ *
+ * Read the requested PMT register based on the pcie device and guid. The
+ * supported struct is the Crashlog Type1 Version2.
+ *
+ * Currently this is for CRI only.
+ */
+static int xe_pmt_read_reg(struct device *dev, u32 guid, u32 *reg, u32 offset)
+{
+ struct xe_device *xe = kdev_to_xe_device(dev);
+ void __iomem *disc_addr = xe->mmio.regs + xe->pmt.base_offset;
+ int ret = 0;
+ u32 inst;
+ int idx;
+
+ if (!drm_dev_enter(&xe->drm, &idx))
+ return -ENODEV;
+
+ if (FIELD_GET(GUID_DEVICE_ID, guid) != CRI_DEVICE_ID ||
+ FIELD_GET(GUID_CAP_TYPE, guid) != CRASHLOG) {
+ ret = -EINVAL;
+ goto dev_exit;
+ }
+
+ inst = FIELD_GET(GUID_RECORD_ID, guid) == PUNIT ?
+ CRI_CRASHLOG_PUNIT_DISC_OFFSET : CRI_CRASHLOG_OOBMSM_DISC_OFFSET;
+ disc_addr += inst + offset;
+
+ xe_pm_runtime_get(xe);
+ mutex_lock(&xe->pmt.lock);
+
+ xe->soc_remapper.set_telem_region(xe, CRI_IDX_TELEM_DISCOVERY);
+
+ memcpy_fromio(reg, disc_addr, sizeof(*reg));
+
+ mutex_unlock(&xe->pmt.lock);
+ xe_pm_runtime_put(xe);
+
+dev_exit:
+ drm_dev_exit(idx);
+
+ return ret;
+}
+
+static int xe_pmt_write_reg(struct device *dev, u32 guid, u32 reg, u32 offset)
+{
+ struct xe_device *xe = kdev_to_xe_device(dev);
+ void __iomem *disc_addr = xe->mmio.regs + xe->pmt.base_offset;
+ int ret = 0;
+ u32 inst;
+ int idx;
+
+ if (!drm_dev_enter(&xe->drm, &idx))
+ return -ENODEV;
+
+ if (FIELD_GET(GUID_DEVICE_ID, guid) != CRI_DEVICE_ID ||
+ FIELD_GET(GUID_CAP_TYPE, guid) != CRASHLOG) {
+ ret = -EINVAL;
+ goto dev_exit;
+ }
+
+ inst = FIELD_GET(GUID_RECORD_ID, guid) == PUNIT ?
+ CRI_CRASHLOG_PUNIT_DISC_OFFSET : CRI_CRASHLOG_OOBMSM_DISC_OFFSET;
+ disc_addr += inst + offset;
+
+ xe_pm_runtime_get(xe);
+ mutex_lock(&xe->pmt.lock);
+
+ xe->soc_remapper.set_telem_region(xe, CRI_IDX_TELEM_DISCOVERY);
+
+ memcpy_toio(disc_addr, ®, sizeof(reg));
+
+ mutex_unlock(&xe->pmt.lock);
+ xe_pm_runtime_put(xe);
+
+dev_exit:
+ drm_dev_exit(idx);
+
+ return ret;
+}
+
+static struct pmt_callbacks xe_bmg_pmt_cb = {
.read_telem = xe_pmt_telem_read,
};
+static struct pmt_callbacks xe_cri_pmt_cb = {
+ .read_telem = xe_pmt_telem_read,
+ .read_reg = xe_pmt_read_reg,
+ .write_reg = xe_pmt_write_reg,
+};
+
static const int vsec_platforms[] = {
[XE_BATTLEMAGE] = XE_VSEC_BMG,
+ [XE_CRESCENTISLAND] = XE_VSEC_CRI,
};
static enum xe_vsec get_platform_info(struct xe_device *xe)
{
- if (xe->info.platform > XE_BATTLEMAGE)
+ if (xe->info.platform > XE_CRESCENTISLAND)
return XE_VSEC_UNKNOWN;
return vsec_platforms[xe->info.platform];
@@ -373,8 +466,17 @@ void xe_vsec_init(struct xe_device *xe)
if (IS_SRIOV_VF(xe))
return;
xe->pmt.base_offset = BMG_TELEMETRY_OFFSET;
- info->priv_data = &xe_pmt_cb;
+ info->priv_data = &xe_bmg_pmt_cb;
break;
+
+ case XE_VSEC_CRI:
+ if (IS_SRIOV_VF(xe))
+ return;
+ xe->pmt.base_offset = CRI_PMT_OFFSET;
+ info->priv_data = &xe_cri_pmt_cb;
+ xe->soc_remapper.set_telem_region(xe, CRI_IDX_TELEM_DISCOVERY);
+ break;
+
default:
break;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 15/18] drm/xe/vsec: Support late bind fw information
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (13 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 14/18] drm/xe/vsec: Crescent Island PMT callbacks Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 16/18] drm/xe/vsec: Add PMT GUID internal access Michael J. Ruhl
` (2 subsequent siblings)
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
CRI FW is loaded on power on. Because of this, access to
the FW cannot be done until it is running.
Update the XE PMT probe and access to check for late bind
devices, verify, and wait for the appropriate FW state
before probe or access.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_device.c | 4 +-
drivers/gpu/drm/xe/xe_device_types.h | 5 +
drivers/gpu/drm/xe/xe_vsec.c | 136 +++++++++++++++++++++++++--
drivers/gpu/drm/xe/xe_vsec.h | 2 +-
4 files changed, 138 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 396d02eb2af8..0dffabed2e99 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -1140,7 +1140,9 @@ int xe_device_probe(struct xe_device *xe)
for_each_gt(gt, xe, id)
xe_gt_sanitize_freq(gt);
- xe_vsec_init(xe);
+ err = xe_vsec_init(xe);
+ if (err)
+ goto err_unregister_display;
err = xe_sriov_init_late(xe);
if (err)
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 3f1a70813a99..69e052ac5a82 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -7,6 +7,7 @@
#define _XE_DEVICE_TYPES_H_
#include <linux/pci.h>
+#include <linux/workqueue.h>
#include <drm/drm_device.h>
#include <drm/drm_file.h>
@@ -468,6 +469,10 @@ struct xe_device {
struct mutex lock;
/** @pmt.base_offset: device specific base offset */
u64 base_offset;
+ /** @pmt.work: support late-bind probe */
+ struct delayed_work work;
+ /** @pmt.retry_count: late-bind probe retry */
+ u32 retry_count;
} pmt;
/** @soc_remapper: SoC remapper object */
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index e58fea788ace..8284977377bd 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -3,6 +3,7 @@
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/cleanup.h>
+#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/intel_vsec.h>
#include <linux/module.h>
@@ -18,6 +19,7 @@
#include "xe_mmio.h"
#include "xe_platform_types.h"
#include "xe_pm.h"
+#include "xe_sysctrl.h"
#include "xe_vsec.h"
#include "regs/xe_pmt.h"
@@ -162,7 +164,15 @@ enum capability {
WATCHER,
};
-static int xe_guid_decode(u32 guid, int *index, u32 *offset)
+/*
+ * Late bind will delay 100msec for up to 20 seconds
+ */
+#define VSEC_LATE_BIND_DELAY_MSEC 100
+#define VSEC_LATE_BIND_RETRY 200
+
+static void cri_late_bind_probe(struct xe_device *xe);
+
+static int bmg_guid_decode(u32 guid, int *index, u32 *offset)
{
u32 record_id = FIELD_GET(GUID_RECORD_ID, guid);
u32 cap_type = FIELD_GET(GUID_CAP_TYPE, guid);
@@ -270,6 +280,48 @@ static int xe_guid_decode(u32 guid, int *index, u32 *offset)
return -ENODEV;
}
+static void cri_late_bind_probe_work(struct work_struct *work)
+{
+ struct xe_device *xe = container_of(work, struct xe_device, pmt.work.work);
+
+ if (xe_is_oobmsm_fw_ready(xe)) {
+ cri_late_bind_probe(xe);
+ xe_pm_runtime_put(xe);
+ return;
+ }
+
+ xe->pmt.retry_count++;
+
+ /* wait up to 20 seconds */
+ if (xe->pmt.retry_count == VSEC_LATE_BIND_RETRY) {
+ drm_warn(&xe->drm, "PMT probe: Late Binding failed to complete\n");
+ xe_pm_runtime_put(xe);
+ return;
+ }
+
+ if (!schedule_delayed_work(&xe->pmt.work, msecs_to_jiffies(VSEC_LATE_BIND_DELAY_MSEC)))
+ xe_pm_runtime_put(xe);
+}
+
+static bool wait_for_fw(struct xe_device *xe)
+{
+ int retries = VSEC_LATE_BIND_RETRY; /* wait up to 20 secs */
+
+ if (xe->info.platform != XE_CRESCENTISLAND)
+ return true;
+
+ while (retries--) {
+ if (xe_is_oobmsm_fw_ready(xe))
+ return true;
+
+ msleep(VSEC_LATE_BIND_DELAY_MSEC);
+ }
+
+ drm_warn(&xe->drm, "Late Binding failed to complete\n");
+
+ return false;
+}
+
/*
* xe_pmt_telem_read is a callback API. I.e this can be accessed external to
* XE driver (PMT driver scope). Because of this, DRM hotplug needs to be
@@ -316,6 +368,11 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
goto dev_exit;
}
+ if (!wait_for_fw(xe)) {
+ ret = -ENODATA;
+ goto runtime_exit;
+ }
+
mutex_lock(&xe->pmt.lock);
/* set SoC re-mapper index register based on GUID memory region */
@@ -325,6 +382,7 @@ int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offse
mutex_unlock(&xe->pmt.lock);
+runtime_exit:
xe_pm_runtime_put(xe);
dev_exit:
@@ -367,6 +425,10 @@ static int xe_pmt_read_reg(struct device *dev, u32 guid, u32 *reg, u32 offset)
disc_addr += inst + offset;
xe_pm_runtime_get(xe);
+ if (!wait_for_fw(xe)) {
+ ret = -ENODATA;
+ goto runtime_exit;
+ }
mutex_lock(&xe->pmt.lock);
xe->soc_remapper.set_telem_region(xe, CRI_IDX_TELEM_DISCOVERY);
@@ -374,6 +436,8 @@ static int xe_pmt_read_reg(struct device *dev, u32 guid, u32 *reg, u32 offset)
memcpy_fromio(reg, disc_addr, sizeof(*reg));
mutex_unlock(&xe->pmt.lock);
+
+runtime_exit:
xe_pm_runtime_put(xe);
dev_exit:
@@ -404,6 +468,10 @@ static int xe_pmt_write_reg(struct device *dev, u32 guid, u32 reg, u32 offset)
disc_addr += inst + offset;
xe_pm_runtime_get(xe);
+ if (!wait_for_fw(xe)) {
+ ret = -ENODATA;
+ goto runtime_exit;
+ }
mutex_lock(&xe->pmt.lock);
xe->soc_remapper.set_telem_region(xe, CRI_IDX_TELEM_DISCOVERY);
@@ -411,6 +479,8 @@ static int xe_pmt_write_reg(struct device *dev, u32 guid, u32 reg, u32 offset)
memcpy_toio(disc_addr, ®, sizeof(reg));
mutex_unlock(&xe->pmt.lock);
+
+runtime_exit:
xe_pm_runtime_put(xe);
dev_exit:
@@ -442,12 +512,44 @@ static enum xe_vsec get_platform_info(struct xe_device *xe)
return vsec_platforms[xe->info.platform];
}
+static void cri_late_bind_probe(struct xe_device *xe)
+{
+ struct intel_vsec_platform_info *info;
+ struct device *dev = xe->drm.dev;
+ enum xe_vsec platform;
+
+ platform = get_platform_info(xe);
+ if (platform != XE_VSEC_CRI)
+ return;
+
+ info = &xe_vsec_info[platform];
+ if (!info->headers)
+ return;
+
+ info->priv_data = &xe_cri_pmt_cb;
+ xe->soc_remapper.set_telem_region(xe, CRI_IDX_TELEM_DISCOVERY);
+
+ intel_vsec_register(dev, info);
+}
+
+static void vsec_disable_late_bind_work(void *arg)
+{
+ struct xe_device *xe = arg;
+
+ /*
+ * If the queued work is canceled, the runtime reference needs to be
+ * released here.
+ */
+ if (disable_delayed_work_sync(&xe->pmt.work))
+ xe_pm_runtime_put(xe);
+}
+
/**
* xe_vsec_init - Initialize resources and add intel_vsec auxiliary
* interface
* @xe: valid xe instance
*/
-void xe_vsec_init(struct xe_device *xe)
+int xe_vsec_init(struct xe_device *xe)
{
struct intel_vsec_platform_info *info;
struct device *dev = xe->drm.dev;
@@ -455,30 +557,45 @@ void xe_vsec_init(struct xe_device *xe)
platform = get_platform_info(xe);
if (platform == XE_VSEC_UNKNOWN)
- return;
+ return 0;
info = &xe_vsec_info[platform];
if (!info->headers)
- return;
+ return 0;
switch (platform) {
case XE_VSEC_BMG:
if (IS_SRIOV_VF(xe))
- return;
+ return 0;
xe->pmt.base_offset = BMG_TELEMETRY_OFFSET;
info->priv_data = &xe_bmg_pmt_cb;
break;
case XE_VSEC_CRI:
if (IS_SRIOV_VF(xe))
- return;
+ return 0;
+
xe->pmt.base_offset = CRI_PMT_OFFSET;
+
+ xe->pmt.retry_count = 0;
+ INIT_DELAYED_WORK(&xe->pmt.work, cri_late_bind_probe_work);
+
+ xe_pm_runtime_get_noresume(xe);
+ if (!xe_is_oobmsm_fw_ready(xe)) {
+ schedule_delayed_work(&xe->pmt.work,
+ msecs_to_jiffies(VSEC_LATE_BIND_DELAY_MSEC));
+ return devm_add_action_or_reset(xe->drm.dev,
+ vsec_disable_late_bind_work,
+ xe);
+ }
+
info->priv_data = &xe_cri_pmt_cb;
xe->soc_remapper.set_telem_region(xe, CRI_IDX_TELEM_DISCOVERY);
break;
default:
- break;
+ drm_err(&xe->drm, "Unsupported platform: %u\n", platform);
+ return 0;
}
/*
@@ -486,5 +603,10 @@ void xe_vsec_init(struct xe_device *xe)
* resources.
*/
intel_vsec_register(dev, info);
+
+ if (platform == XE_VSEC_CRI)
+ xe_pm_runtime_put(xe);
+
+ return 0;
}
MODULE_IMPORT_NS("INTEL_VSEC");
diff --git a/drivers/gpu/drm/xe/xe_vsec.h b/drivers/gpu/drm/xe/xe_vsec.h
index a25b4e6e681b..c4a1e2fc67d8 100644
--- a/drivers/gpu/drm/xe/xe_vsec.h
+++ b/drivers/gpu/drm/xe/xe_vsec.h
@@ -9,7 +9,7 @@
struct device;
struct xe_device;
-void xe_vsec_init(struct xe_device *xe);
+int xe_vsec_init(struct xe_device *xe);
int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offset, u32 count);
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 16/18] drm/xe/vsec: Add PMT GUID internal access
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (14 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 15/18] drm/xe/vsec: Support late bind fw information Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 17/18] drm/xe/vsec: Update PMT " Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 18/18] drm/xe/vsec: Refactor platform check Michael J. Ruhl
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Xe accesses the PMT infrastructure directly. The current
usage is supported ONLY by BMG devices.
CRI has further requirements for access.
Add the plaform id to the GUID register define and use that
for the register access.
Add an API to allow access the GUID based on the platform.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/regs/xe_pmt.h | 4 ++-
drivers/gpu/drm/xe/xe_debugfs.c | 3 +-
drivers/gpu/drm/xe/xe_device_types.h | 2 ++
drivers/gpu/drm/xe/xe_hwmon.c | 2 +-
drivers/gpu/drm/xe/xe_pcode.c | 2 +-
drivers/gpu/drm/xe/xe_vsec.c | 42 ++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_vsec.h | 1 +
7 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/xe/regs/xe_pmt.h b/drivers/gpu/drm/xe/regs/xe_pmt.h
index 2f6658395587..fb5b5a8648ba 100644
--- a/drivers/gpu/drm/xe/regs/xe_pmt.h
+++ b/drivers/gpu/drm/xe/regs/xe_pmt.h
@@ -10,7 +10,7 @@
#define BMG_PMT_BASE_OFFSET 0xDB000
#define BMG_DISCOVERY_OFFSET (SOC_BASE + BMG_PMT_BASE_OFFSET)
-#define PUNIT_TELEMETRY_GUID XE_REG(BMG_DISCOVERY_OFFSET + 0x4)
+#define BMG_PUNIT_TELEMETRY_GUID XE_REG(BMG_DISCOVERY_OFFSET + 0x4)
#define BMG_ENERGY_STATUS_PMT_OFFSET (0x30)
#define ENERGY_PKG REG_GENMASK64(31, 0)
#define ENERGY_CARD REG_GENMASK64(63, 32)
@@ -24,6 +24,8 @@
/* for CRI discovery and telemetry are in an indexed window */
#define CRI_PMT_OFFSET (SOC_BASE + XE_PMT_BASE_OFFSET)
+#define CRI_PUNIT_TELEMETRY_GUID XE_REG(CRI_PMT_OFFSET + 0x4)
+
#define BMG_MODS_RESIDENCY_OFFSET (0x4D0)
#define BMG_G2_RESIDENCY_OFFSET (0x530)
#define BMG_G6_RESIDENCY_OFFSET (0x538)
diff --git a/drivers/gpu/drm/xe/xe_debugfs.c b/drivers/gpu/drm/xe/xe_debugfs.c
index 28135f84e286..b01f1e649b51 100644
--- a/drivers/gpu/drm/xe/xe_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_debugfs.c
@@ -101,10 +101,11 @@ static void read_residency_counter(struct xe_device *xe, struct xe_mmio *mmio,
u32 offset, const char *name, struct drm_printer *p)
{
u64 residency = 0;
+
int ret;
ret = xe_pmt_telem_read(xe->drm.dev,
- xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID),
+ xe_mmio_read32(mmio, BMG_PUNIT_TELEMETRY_GUID),
&residency, offset, sizeof(residency));
if (ret != sizeof(residency)) {
drm_warn(&xe->drm, "%s counter failed to read, ret %d\n", name, ret);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 69e052ac5a82..2a8c519e1639 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -473,6 +473,8 @@ struct xe_device {
struct delayed_work work;
/** @pmt.retry_count: late-bind probe retry */
u32 retry_count;
+ /** @pmt.punit_guid_cache: cache of the PUINT GUID */
+ u32 punit_guid_cache;
} pmt;
/** @soc_remapper: SoC remapper object */
diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
index 5284cab6703d..b9740224e07f 100644
--- a/drivers/gpu/drm/xe/xe_hwmon.c
+++ b/drivers/gpu/drm/xe/xe_hwmon.c
@@ -519,7 +519,7 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy)
u64 pmt_val;
ret = xe_pmt_telem_read(hwmon->xe->drm.dev,
- xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID),
+ xe_mmio_read32(mmio, BMG_PUNIT_TELEMETRY_GUID),
&pmt_val, BMG_ENERGY_STATUS_PMT_OFFSET, sizeof(pmt_val));
if (ret != sizeof(pmt_val)) {
drm_warn(&hwmon->xe->drm, "energy read from pmt failed, ret %d\n", ret);
diff --git a/drivers/gpu/drm/xe/xe_pcode.c b/drivers/gpu/drm/xe/xe_pcode.c
index d502205bb72a..844d8c6face6 100644
--- a/drivers/gpu/drm/xe/xe_pcode.c
+++ b/drivers/gpu/drm/xe/xe_pcode.c
@@ -369,7 +369,7 @@ int xe_get_pcode_version(struct xe_device *xe, struct xe_pcode_version *version)
guard(xe_pm_runtime)(xe);
ret = xe_pmt_telem_read(xe->drm.dev,
- xe_mmio_read32(xe_root_tile_mmio(xe), PUNIT_TELEMETRY_GUID),
+ xe_mmio_read32(xe_root_tile_mmio(xe), BMG_PUNIT_TELEMETRY_GUID),
(u64 *)version, PUNIT_VERSION_OFFSET, sizeof(*version));
if (ret != sizeof(*version)) {
xe_warn(xe, "pcode version read from PMT failed, ret %pe\n", ERR_PTR(ret));
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index 8284977377bd..2c05b0b297c2 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -544,6 +544,48 @@ static void vsec_disable_late_bind_work(void *arg)
xe_pm_runtime_put(xe);
}
+int xe_vsec_get_guid(struct xe_device *xe, u32 *guid)
+{
+ struct xe_mmio *mmio = xe_root_tile_mmio(xe);
+
+ if (IS_SRIOV_VF(xe))
+ return -EINVAL;
+
+ if (!xe_pm_runtime_get_if_active(xe))
+ return -ENODATA;
+
+ mutex_lock(&xe->pmt.lock);
+
+ if (xe->pmt.punit_guid_cache) {
+ *guid = xe->pmt.punit_guid_cache;
+ goto unlock;
+ }
+
+ switch (xe->info.platform) {
+ case XE_BATTLEMAGE:
+ *guid = xe_mmio_read32(mmio, BMG_PUNIT_TELEMETRY_GUID);
+ break;
+
+ case XE_CRESCENTISLAND:
+ xe->soc_remapper.set_telem_region(xe, CRI_IDX_TELEM_DISCOVERY);
+ *guid = xe_mmio_read32(mmio, CRI_PUNIT_TELEMETRY_GUID);
+ break;
+
+ default:
+ *guid = 0;
+ drm_err(&xe->drm, "Unsupported platform: %u\n", xe->info.platform);
+ break;
+ }
+
+ xe->pmt.punit_guid_cache = *guid;
+
+unlock:
+ mutex_unlock(&xe->pmt.lock);
+ xe_pm_runtime_put(xe);
+
+ return 0;
+}
+
/**
* xe_vsec_init - Initialize resources and add intel_vsec auxiliary
* interface
diff --git a/drivers/gpu/drm/xe/xe_vsec.h b/drivers/gpu/drm/xe/xe_vsec.h
index c4a1e2fc67d8..50187fdc1207 100644
--- a/drivers/gpu/drm/xe/xe_vsec.h
+++ b/drivers/gpu/drm/xe/xe_vsec.h
@@ -10,6 +10,7 @@ struct device;
struct xe_device;
int xe_vsec_init(struct xe_device *xe);
+int xe_vsec_get_guid(struct xe_device *xe, u32 *guid);
int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offset, u32 count);
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 17/18] drm/xe/vsec: Update PMT internal access
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (15 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 16/18] drm/xe/vsec: Add PMT GUID internal access Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 18/18] drm/xe/vsec: Refactor platform check Michael J. Ruhl
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
Current PMT internal access assumes BMG devices.
Use the new PMT GUID API to read the device specific guid.
Minor cleanup for a newly unused parameter (mmio).
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_debugfs.c | 27 ++++++++++++++-------------
drivers/gpu/drm/xe/xe_hwmon.c | 10 ++++++++--
drivers/gpu/drm/xe/xe_pcode.c | 10 ++++++++--
3 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_debugfs.c b/drivers/gpu/drm/xe/xe_debugfs.c
index b01f1e649b51..f17b993755f3 100644
--- a/drivers/gpu/drm/xe/xe_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_debugfs.c
@@ -5,6 +5,7 @@
#include "xe_debugfs.h"
+#include <linux/array_size.h>
#include <linux/bits.h>
#include <linux/debugfs.h>
#include <linux/fault-inject.h>
@@ -21,7 +22,6 @@
#include "xe_gt_printk.h"
#include "xe_guc_ads.h"
#include "xe_hw_engine.h"
-#include "xe_mmio.h"
#include "xe_pagefault.h"
#include "xe_pcode.h"
#include "xe_pm.h"
@@ -97,16 +97,20 @@ static void xe_fault_inject_debugfs_register(struct xe_device *xe,
}
}
-static void read_residency_counter(struct xe_device *xe, struct xe_mmio *mmio,
- u32 offset, const char *name, struct drm_printer *p)
+static void read_residency_counter(struct xe_device *xe, u32 offset, const char *name,
+ struct drm_printer *p)
{
u64 residency = 0;
-
+ u32 guid;
int ret;
- ret = xe_pmt_telem_read(xe->drm.dev,
- xe_mmio_read32(mmio, BMG_PUNIT_TELEMETRY_GUID),
- &residency, offset, sizeof(residency));
+ ret = xe_vsec_get_guid(xe, &guid);
+ if (ret) {
+ drm_warn(&xe->drm, "PMT device is not available: %d\n", ret);
+ return;
+ }
+
+ ret = xe_pmt_telem_read(xe->drm.dev, guid, &residency, offset, sizeof(residency));
if (ret != sizeof(residency)) {
drm_warn(&xe->drm, "%s counter failed to read, ret %d\n", name, ret);
return;
@@ -245,13 +249,12 @@ static int pcode_info(struct seq_file *m, void *data)
static int dgfx_pkg_residencies_show(struct seq_file *m, void *data)
{
struct xe_device *xe;
- struct xe_mmio *mmio;
struct drm_printer p;
xe = node_to_xe(m->private);
p = drm_seq_file_printer(m);
guard(xe_pm_runtime)(xe);
- mmio = xe_root_tile_mmio(xe);
+
static const struct {
u32 offset;
const char *name;
@@ -265,7 +268,7 @@ static int dgfx_pkg_residencies_show(struct seq_file *m, void *data)
};
for (int i = 0; i < ARRAY_SIZE(residencies); i++)
- read_residency_counter(xe, mmio, residencies[i].offset, residencies[i].name, &p);
+ read_residency_counter(xe, residencies[i].offset, residencies[i].name, &p);
return 0;
}
@@ -273,13 +276,11 @@ static int dgfx_pkg_residencies_show(struct seq_file *m, void *data)
static int dgfx_pcie_link_residencies_show(struct seq_file *m, void *data)
{
struct xe_device *xe;
- struct xe_mmio *mmio;
struct drm_printer p;
xe = node_to_xe(m->private);
p = drm_seq_file_printer(m);
guard(xe_pm_runtime)(xe);
- mmio = xe_root_tile_mmio(xe);
static const struct {
u32 offset;
@@ -291,7 +292,7 @@ static int dgfx_pcie_link_residencies_show(struct seq_file *m, void *data)
};
for (int i = 0; i < ARRAY_SIZE(residencies); i++)
- read_residency_counter(xe, mmio, residencies[i].offset, residencies[i].name, &p);
+ read_residency_counter(xe, residencies[i].offset, residencies[i].name, &p);
return 0;
}
diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
index b9740224e07f..c44a7d24816d 100644
--- a/drivers/gpu/drm/xe/xe_hwmon.c
+++ b/drivers/gpu/drm/xe/xe_hwmon.c
@@ -517,9 +517,15 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy)
if (hwmon->xe->info.platform == XE_BATTLEMAGE) {
u64 pmt_val;
+ u32 guid;
- ret = xe_pmt_telem_read(hwmon->xe->drm.dev,
- xe_mmio_read32(mmio, BMG_PUNIT_TELEMETRY_GUID),
+ ret = xe_vsec_get_guid(hwmon->xe, &guid);
+ if (ret) {
+ drm_warn(&hwmon->xe->drm, "PMT device is not available: %d\n", ret);
+ *energy = 0;
+ return;
+ }
+ ret = xe_pmt_telem_read(hwmon->xe->drm.dev, guid,
&pmt_val, BMG_ENERGY_STATUS_PMT_OFFSET, sizeof(pmt_val));
if (ret != sizeof(pmt_val)) {
drm_warn(&hwmon->xe->drm, "energy read from pmt failed, ret %d\n", ret);
diff --git a/drivers/gpu/drm/xe/xe_pcode.c b/drivers/gpu/drm/xe/xe_pcode.c
index 844d8c6face6..039c23086990 100644
--- a/drivers/gpu/drm/xe/xe_pcode.c
+++ b/drivers/gpu/drm/xe/xe_pcode.c
@@ -365,11 +365,17 @@ ALLOW_ERROR_INJECTION(xe_pcode_probe_early, ERRNO); /* See xe_pci_probe */
int xe_get_pcode_version(struct xe_device *xe, struct xe_pcode_version *version)
{
int ret = 0;
+ u32 guid;
guard(xe_pm_runtime)(xe);
- ret = xe_pmt_telem_read(xe->drm.dev,
- xe_mmio_read32(xe_root_tile_mmio(xe), BMG_PUNIT_TELEMETRY_GUID),
+ ret = xe_vsec_get_guid(xe, &guid);
+ if (ret) {
+ xe_warn(xe, "PMT device is not availalbe: %d\n", ret);
+ return ret;
+ }
+
+ ret = xe_pmt_telem_read(xe->drm.dev, guid,
(u64 *)version, PUNIT_VERSION_OFFSET, sizeof(*version));
if (ret != sizeof(*version)) {
xe_warn(xe, "pcode version read from PMT failed, ret %pe\n", ERR_PTR(ret));
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 18/18] drm/xe/vsec: Refactor platform check
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
` (16 preceding siblings ...)
2026-09-01 19:27 ` [PATCH v4 17/18] drm/xe/vsec: Update PMT " Michael J. Ruhl
@ 2026-09-01 19:27 ` Michael J. Ruhl
17 siblings, 0 replies; 24+ messages in thread
From: Michael J. Ruhl @ 2026-09-01 19:27 UTC (permalink / raw)
To: platform-driver-x86, intel-xe, hansg, ilpo.jarvinen,
matthew.brost, rodrigo.vivi, thomas.hellstrom, airlied, simona,
david.e.box, anoop.c.vijay, badal.nilawar, matthew.d.roper,
james.ausmus, karthik.poosa
For debugfs, residencies and pcode_info are available on
the BMG and CRI (!SRIOV_VF) platforms.
Refactor to have one code path for adding the debugfs
entries.
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
---
drivers/gpu/drm/xe/xe_debugfs.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_debugfs.c b/drivers/gpu/drm/xe/xe_debugfs.c
index f17b993755f3..9e32a5e230b9 100644
--- a/drivers/gpu/drm/xe/xe_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_debugfs.c
@@ -712,23 +712,22 @@ void xe_debugfs_register(struct xe_device *xe)
ARRAY_SIZE(debugfs_list),
root, minor);
- if (xe->info.platform == XE_BATTLEMAGE && !IS_SRIOV_VF(xe)) {
- drm_debugfs_create_files(debugfs_residencies,
- ARRAY_SIZE(debugfs_residencies),
- root, minor);
- }
-
/*
- * Pcode version read from PMT is currently only supported on CRI and BMG platforms in PF
- * mode, as both platforms support the necessary telemetry read mechanism and have a fixed
- * PUNIT_VERSION_OFFSET.
+ * Residencies and Pcode version read from PMT is currently only supported on CRI and BMG
+ * platforms in PF mode. Both platforms support the necessary telemetry read mechanism
+ * and have a fixed offsets for the required data.
* Attempting this access on other platforms must be verified before enabling support.
*/
if (!IS_SRIOV_VF(xe) &&
- (xe->info.platform == XE_CRESCENTISLAND || xe->info.platform == XE_BATTLEMAGE))
+ (xe->info.platform == XE_CRESCENTISLAND || xe->info.platform == XE_BATTLEMAGE)) {
+ drm_debugfs_create_files(debugfs_residencies,
+ ARRAY_SIZE(debugfs_residencies),
+ root, minor);
+
drm_debugfs_create_files(pcode_info_debugfs,
ARRAY_SIZE(pcode_info_debugfs),
root, minor);
+ }
debugfs_create_file("forcewake_all", 0400, root, xe,
&forcewake_all_fops);
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v4 02/18] platform/x86/intel/pmt: refactor rmw with a return value
2026-09-01 19:27 ` [PATCH v4 02/18] platform/x86/intel/pmt: refactor rmw with a return value Michael J. Ruhl
@ 2026-09-02 9:05 ` Ilpo Järvinen
2026-09-02 9:07 ` Ilpo Järvinen
1 sibling, 0 replies; 24+ messages in thread
From: Ilpo Järvinen @ 2026-09-02 9:05 UTC (permalink / raw)
To: Michael J. Ruhl
Cc: platform-driver-x86, intel-xe, Hans de Goede, matthew.brost,
rodrigo.vivi, thomas.hellstrom, airlied, simona, david.e.box,
anoop.c.vijay, badal.nilawar, matthew.d.roper, james.ausmus,
karthik.poosa
On Tue, 1 Sep 2026, Michael J. Ruhl wrote:
> Upcoming changes will include possible failures from HW
> accesses.
>
> Refactor pmt_crashlog_rwm with a return value.
>
> Update all necessary usage to use the return code.
>
> Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
> ---
> drivers/platform/x86/intel/pmt/crashlog.c | 88 ++++++++++++-----------
> 1 file changed, 45 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
> index f936daf99e4d..ebc7880d95bd 100644
> --- a/drivers/platform/x86/intel/pmt/crashlog.c
> +++ b/drivers/platform/x86/intel/pmt/crashlog.c
> @@ -125,7 +125,7 @@ struct pmt_crashlog_priv {
> */
>
> /* Read, modify, write the control register, setting or clearing @bit based on @set */
> -static void pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
> +static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
> {
> const struct crashlog_control *control = &crashlog->info->control;
> struct intel_pmt_entry *entry = &crashlog->entry;
> @@ -139,6 +139,8 @@ static void pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
> reg &= ~bit;
>
> writel(reg, entry->disc_table + control->offset);
> +
> + return 0;
> }
>
> /* Read the status register and see if the specified @bit is set */
> @@ -181,20 +183,20 @@ static bool pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_typ
> return false;
> }
>
> -static void pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
> +static int pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
> bool disable)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
> }
>
> -static void pmt_crashlog_set_clear(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_set_clear(struct crashlog_entry *crashlog)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.clear, true);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.clear, true);
> }
>
> -static void pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
> }
>
> static bool pmt_crashlog_cleared(struct crashlog_entry *crashlog)
> @@ -207,9 +209,9 @@ static bool pmt_crashlog_consumed(struct crashlog_entry *crashlog)
> return pmt_crashlog_rc(crashlog, crashlog->info->status.consumed);
> }
>
> -static void pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.consume, true);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.consume, true);
> }
>
> static bool pmt_crashlog_error(struct crashlog_entry *crashlog)
> @@ -222,9 +224,9 @@ static bool pmt_crashlog_rearm(struct crashlog_entry *crashlog)
> return pmt_crashlog_rc(crashlog, crashlog->info->status.rearmed);
> }
>
> -static void pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.rearm, true);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.rearm, true);
> }
>
> /*
> @@ -245,13 +247,13 @@ clear_store(struct device *dev, struct device_attribute *attr,
> {
> struct crashlog_entry *crashlog;
> bool clear;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &clear);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &clear);
> + if (ret)
> + return ret;
>
> /* set bit only */
> if (!clear)
> @@ -259,9 +261,9 @@ clear_store(struct device *dev, struct device_attribute *attr,
>
> guard(mutex)(&crashlog->control_mutex);
>
> - pmt_crashlog_set_clear(crashlog);
> + ret = pmt_crashlog_set_clear(crashlog);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(clear);
>
> @@ -280,13 +282,13 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
> {
> struct crashlog_entry *crashlog;
> bool consumed;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &consumed);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &consumed);
> + if (ret)
> + return ret;
>
> /* set bit only */
> if (!consumed)
> @@ -300,9 +302,9 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
> if (!pmt_crashlog_complete(crashlog))
> return -EEXIST;
>
> - pmt_crashlog_set_consumed(crashlog);
> + ret = pmt_crashlog_set_consumed(crashlog);
>
> - return count;
> + return ret ? ret : count;
You can use the more concise form for these:
return ret ?: count;
--
i.
> }
> static DEVICE_ATTR_RW(consumed);
>
> @@ -321,19 +323,19 @@ enable_store(struct device *dev, struct device_attribute *attr,
> {
> struct crashlog_entry *crashlog;
> bool enabled;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &enabled);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &enabled);
> + if (ret)
> + return ret;
>
> guard(mutex)(&crashlog->control_mutex);
>
> - pmt_crashlog_set_disable(crashlog, !enabled);
> + ret = pmt_crashlog_set_disable(crashlog, !enabled);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(enable);
>
> @@ -362,13 +364,13 @@ rearm_store(struct device *dev, struct device_attribute *attr, const char *buf,
> {
> struct crashlog_entry *crashlog;
> bool rearm;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &rearm);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &rearm);
> + if (ret)
> + return ret;
>
> /* set only */
> if (!rearm)
> @@ -376,9 +378,9 @@ rearm_store(struct device *dev, struct device_attribute *attr, const char *buf,
>
> guard(mutex)(&crashlog->control_mutex);
>
> - pmt_crashlog_set_rearm(crashlog);
> + ret = pmt_crashlog_set_rearm(crashlog);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(rearm);
>
> @@ -400,13 +402,13 @@ trigger_store(struct device *dev, struct device_attribute *attr,
> {
> struct crashlog_entry *crashlog;
> bool trigger;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &trigger);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &trigger);
> + if (ret)
> + return ret;
>
> guard(mutex)(&crashlog->control_mutex);
>
> @@ -415,17 +417,17 @@ trigger_store(struct device *dev, struct device_attribute *attr,
> return -EBUSY;
>
> if (!trigger) {
> - pmt_crashlog_set_clear(crashlog);
> - return count;
> + ret = pmt_crashlog_set_clear(crashlog);
> + return ret ? ret : count;
> }
>
> /* we cannot trigger a new crash if one is still pending */
> if (pmt_crashlog_complete(crashlog))
> return -EEXIST;
>
> - pmt_crashlog_set_execute(crashlog);
> + ret = pmt_crashlog_set_execute(crashlog);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(trigger);
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 02/18] platform/x86/intel/pmt: refactor rmw with a return value
2026-09-01 19:27 ` [PATCH v4 02/18] platform/x86/intel/pmt: refactor rmw with a return value Michael J. Ruhl
2026-09-02 9:05 ` Ilpo Järvinen
@ 2026-09-02 9:07 ` Ilpo Järvinen
1 sibling, 0 replies; 24+ messages in thread
From: Ilpo Järvinen @ 2026-09-02 9:07 UTC (permalink / raw)
To: Michael J. Ruhl
Cc: platform-driver-x86, intel-xe, Hans de Goede, matthew.brost,
rodrigo.vivi, thomas.hellstrom, airlied, simona, david.e.box,
anoop.c.vijay, badal.nilawar, matthew.d.roper, james.ausmus,
karthik.poosa
On Tue, 1 Sep 2026, Michael J. Ruhl wrote:
> Upcoming changes will include possible failures from HW
> accesses.
Too short line.
> Refactor pmt_crashlog_rwm with a return value.
Also, please include () in the changelog to any function name.
--
i.
>
> Update all necessary usage to use the return code.
>
> Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
> ---
> drivers/platform/x86/intel/pmt/crashlog.c | 88 ++++++++++++-----------
> 1 file changed, 45 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
> index f936daf99e4d..ebc7880d95bd 100644
> --- a/drivers/platform/x86/intel/pmt/crashlog.c
> +++ b/drivers/platform/x86/intel/pmt/crashlog.c
> @@ -125,7 +125,7 @@ struct pmt_crashlog_priv {
> */
>
> /* Read, modify, write the control register, setting or clearing @bit based on @set */
> -static void pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
> +static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
> {
> const struct crashlog_control *control = &crashlog->info->control;
> struct intel_pmt_entry *entry = &crashlog->entry;
> @@ -139,6 +139,8 @@ static void pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
> reg &= ~bit;
>
> writel(reg, entry->disc_table + control->offset);
> +
> + return 0;
> }
>
> /* Read the status register and see if the specified @bit is set */
> @@ -181,20 +183,20 @@ static bool pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_typ
> return false;
> }
>
> -static void pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
> +static int pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
> bool disable)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
> }
>
> -static void pmt_crashlog_set_clear(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_set_clear(struct crashlog_entry *crashlog)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.clear, true);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.clear, true);
> }
>
> -static void pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
> }
>
> static bool pmt_crashlog_cleared(struct crashlog_entry *crashlog)
> @@ -207,9 +209,9 @@ static bool pmt_crashlog_consumed(struct crashlog_entry *crashlog)
> return pmt_crashlog_rc(crashlog, crashlog->info->status.consumed);
> }
>
> -static void pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.consume, true);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.consume, true);
> }
>
> static bool pmt_crashlog_error(struct crashlog_entry *crashlog)
> @@ -222,9 +224,9 @@ static bool pmt_crashlog_rearm(struct crashlog_entry *crashlog)
> return pmt_crashlog_rc(crashlog, crashlog->info->status.rearmed);
> }
>
> -static void pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
> {
> - pmt_crashlog_rmw(crashlog, crashlog->info->control.rearm, true);
> + return pmt_crashlog_rmw(crashlog, crashlog->info->control.rearm, true);
> }
>
> /*
> @@ -245,13 +247,13 @@ clear_store(struct device *dev, struct device_attribute *attr,
> {
> struct crashlog_entry *crashlog;
> bool clear;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &clear);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &clear);
> + if (ret)
> + return ret;
>
> /* set bit only */
> if (!clear)
> @@ -259,9 +261,9 @@ clear_store(struct device *dev, struct device_attribute *attr,
>
> guard(mutex)(&crashlog->control_mutex);
>
> - pmt_crashlog_set_clear(crashlog);
> + ret = pmt_crashlog_set_clear(crashlog);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(clear);
>
> @@ -280,13 +282,13 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
> {
> struct crashlog_entry *crashlog;
> bool consumed;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &consumed);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &consumed);
> + if (ret)
> + return ret;
>
> /* set bit only */
> if (!consumed)
> @@ -300,9 +302,9 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
> if (!pmt_crashlog_complete(crashlog))
> return -EEXIST;
>
> - pmt_crashlog_set_consumed(crashlog);
> + ret = pmt_crashlog_set_consumed(crashlog);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(consumed);
>
> @@ -321,19 +323,19 @@ enable_store(struct device *dev, struct device_attribute *attr,
> {
> struct crashlog_entry *crashlog;
> bool enabled;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &enabled);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &enabled);
> + if (ret)
> + return ret;
>
> guard(mutex)(&crashlog->control_mutex);
>
> - pmt_crashlog_set_disable(crashlog, !enabled);
> + ret = pmt_crashlog_set_disable(crashlog, !enabled);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(enable);
>
> @@ -362,13 +364,13 @@ rearm_store(struct device *dev, struct device_attribute *attr, const char *buf,
> {
> struct crashlog_entry *crashlog;
> bool rearm;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &rearm);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &rearm);
> + if (ret)
> + return ret;
>
> /* set only */
> if (!rearm)
> @@ -376,9 +378,9 @@ rearm_store(struct device *dev, struct device_attribute *attr, const char *buf,
>
> guard(mutex)(&crashlog->control_mutex);
>
> - pmt_crashlog_set_rearm(crashlog);
> + ret = pmt_crashlog_set_rearm(crashlog);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(rearm);
>
> @@ -400,13 +402,13 @@ trigger_store(struct device *dev, struct device_attribute *attr,
> {
> struct crashlog_entry *crashlog;
> bool trigger;
> - int result;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
>
> - result = kstrtobool(buf, &trigger);
> - if (result)
> - return result;
> + ret = kstrtobool(buf, &trigger);
> + if (ret)
> + return ret;
>
> guard(mutex)(&crashlog->control_mutex);
>
> @@ -415,17 +417,17 @@ trigger_store(struct device *dev, struct device_attribute *attr,
> return -EBUSY;
>
> if (!trigger) {
> - pmt_crashlog_set_clear(crashlog);
> - return count;
> + ret = pmt_crashlog_set_clear(crashlog);
> + return ret ? ret : count;
> }
>
> /* we cannot trigger a new crash if one is still pending */
> if (pmt_crashlog_complete(crashlog))
> return -EEXIST;
>
> - pmt_crashlog_set_execute(crashlog);
> + ret = pmt_crashlog_set_execute(crashlog);
>
> - return count;
> + return ret ? ret : count;
> }
> static DEVICE_ATTR_RW(trigger);
>
>
--
i.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 03/18] platform/x86/intel/pmt: refactor rc with a return value
2026-09-01 19:27 ` [PATCH v4 03/18] platform/x86/intel/pmt: refactor rc " Michael J. Ruhl
@ 2026-09-02 9:08 ` Ilpo Järvinen
0 siblings, 0 replies; 24+ messages in thread
From: Ilpo Järvinen @ 2026-09-02 9:08 UTC (permalink / raw)
To: Michael J. Ruhl
Cc: platform-driver-x86, intel-xe, Hans de Goede, matthew.brost,
rodrigo.vivi, thomas.hellstrom, airlied, simona, david.e.box,
anoop.c.vijay, badal.nilawar, matthew.d.roper, james.ausmus,
karthik.poosa
On Tue, 1 Sep 2026, Michael J. Ruhl wrote:
> Upcoming changes will include possible failures from HW
> accesses.
>
> Refactor pmt_crashlog_rw with a return value.
>
> Update all necessary usage to use the return code.
>
> Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
> ---
> drivers/platform/x86/intel/pmt/crashlog.c | 109 +++++++++++++++-------
> 1 file changed, 77 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
> index ebc7880d95bd..83323b1ce4a9 100644
> --- a/drivers/platform/x86/intel/pmt/crashlog.c
> +++ b/drivers/platform/x86/intel/pmt/crashlog.c
> @@ -144,27 +144,29 @@ static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
> }
>
> /* Read the status register and see if the specified @bit is set */
> -static bool pmt_crashlog_rc(struct crashlog_entry *crashlog, u32 bit)
> +static int pmt_crashlog_rc(struct crashlog_entry *crashlog, u32 bit, bool *state)
> {
> const struct crashlog_status *status = &crashlog->info->status;
> u32 reg = readl(crashlog->entry.disc_table + status->offset);
>
> - return !!(reg & bit);
> + *state = !!(reg & bit);
> +
> + return 0;
> }
>
> -static bool pmt_crashlog_complete(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_complete(struct crashlog_entry *crashlog, bool *state)
> {
> /* return current value of the crashlog complete flag */
> - return pmt_crashlog_rc(crashlog, crashlog->info->status.complete);
> + return pmt_crashlog_rc(crashlog, crashlog->info->status.complete, state);
> }
>
> -static bool pmt_crashlog_disabled(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_disabled(struct crashlog_entry *crashlog, bool *state)
> {
> /* return current value of the crashlog disabled flag */
> - return pmt_crashlog_rc(crashlog, crashlog->info->status.disabled);
> + return pmt_crashlog_rc(crashlog, crashlog->info->status.disabled, state);
> }
>
> -static bool pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_type, u32 *version)
> +static int pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_type, u32 *version)
> {
> u32 discovery_header = readl(entry->disc_table + CONTROL_OFFSET);
>
> @@ -184,7 +186,7 @@ static bool pmt_crashlog_supported(struct intel_pmt_entry *entry, u32 *crash_typ
> }
>
> static int pmt_crashlog_set_disable(struct crashlog_entry *crashlog,
> - bool disable)
> + bool disable)
> {
> return pmt_crashlog_rmw(crashlog, crashlog->info->control.disable, disable);
> }
> @@ -199,14 +201,14 @@ static int pmt_crashlog_set_execute(struct crashlog_entry *crashlog)
> return pmt_crashlog_rmw(crashlog, crashlog->info->control.manual, true);
> }
>
> -static bool pmt_crashlog_cleared(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_cleared(struct crashlog_entry *crashlog, bool *state)
> {
> - return pmt_crashlog_rc(crashlog, crashlog->info->status.cleared);
> + return pmt_crashlog_rc(crashlog, crashlog->info->status.cleared, state);
> }
>
> -static bool pmt_crashlog_consumed(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_consumed(struct crashlog_entry *crashlog, bool *state)
> {
> - return pmt_crashlog_rc(crashlog, crashlog->info->status.consumed);
> + return pmt_crashlog_rc(crashlog, crashlog->info->status.consumed, state);
> }
>
> static int pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
> @@ -214,14 +216,14 @@ static int pmt_crashlog_set_consumed(struct crashlog_entry *crashlog)
> return pmt_crashlog_rmw(crashlog, crashlog->info->control.consume, true);
> }
>
> -static bool pmt_crashlog_error(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_error(struct crashlog_entry *crashlog, bool *state)
> {
> - return pmt_crashlog_rc(crashlog, crashlog->info->status.error);
> + return pmt_crashlog_rc(crashlog, crashlog->info->status.error, state);
> }
>
> -static bool pmt_crashlog_rearm(struct crashlog_entry *crashlog)
> +static int pmt_crashlog_rearm(struct crashlog_entry *crashlog, bool *state)
> {
> - return pmt_crashlog_rc(crashlog, crashlog->info->status.rearmed);
> + return pmt_crashlog_rc(crashlog, crashlog->info->status.rearmed, state);
> }
>
> static int pmt_crashlog_set_rearm(struct crashlog_entry *crashlog)
> @@ -236,9 +238,14 @@ static ssize_t
> clear_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct crashlog_entry *crashlog = dev_get_drvdata(dev);
> - bool cleared = pmt_crashlog_cleared(crashlog);
> + bool cleared;
> + int ret;
>
> - return sysfs_emit(buf, "%d\n", cleared);
> + ret = pmt_crashlog_cleared(crashlog, &cleared);
> + if (ret)
> + return sysfs_emit(buf, "read error: %d\n", ret);
Never emit errors like this but just return the error code from a _show()
function.
--
i.
> + else
> + return sysfs_emit(buf, "%d\n", cleared);
> }
>
> static ssize_t
> @@ -271,9 +278,14 @@ static ssize_t
> consumed_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct crashlog_entry *crashlog = dev_get_drvdata(dev);
> - bool consumed = pmt_crashlog_consumed(crashlog);
> + bool consumed;
> + int ret;
>
> - return sysfs_emit(buf, "%d\n", consumed);
> + ret = pmt_crashlog_consumed(crashlog, &consumed);
> + if (ret)
> + return sysfs_emit(buf, "read error: %d\n", ret);
> + else
> + return sysfs_emit(buf, "%d\n", consumed);
> }
>
> static ssize_t
> @@ -281,7 +293,9 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
> size_t count)
> {
> struct crashlog_entry *crashlog;
> + bool complete;
> bool consumed;
> + bool disabled;
> int ret;
>
> crashlog = dev_get_drvdata(dev);
> @@ -296,10 +310,16 @@ consumed_store(struct device *dev, struct device_attribute *attr, const char *bu
>
> guard(mutex)(&crashlog->control_mutex);
>
> - if (pmt_crashlog_disabled(crashlog))
> + ret = pmt_crashlog_disabled(crashlog, &disabled);
> + if (ret)
> + return ret;
> + if (disabled)
> return -EBUSY;
>
> - if (!pmt_crashlog_complete(crashlog))
> + ret = pmt_crashlog_complete(crashlog, &complete);
> + if (ret)
> + return ret;
> + if (!complete)
> return -EEXIST;
>
> ret = pmt_crashlog_set_consumed(crashlog);
> @@ -312,9 +332,14 @@ static ssize_t
> enable_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct crashlog_entry *crashlog = dev_get_drvdata(dev);
> - bool enabled = !pmt_crashlog_disabled(crashlog);
> + bool enabled;
> + int ret;
>
> - return sprintf(buf, "%d\n", enabled);
> + ret = pmt_crashlog_disabled(crashlog, &enabled);
> + if (ret)
> + return sysfs_emit(buf, "error: %d\n", ret);
> + else
> + return sysfs_emit(buf, "%d\n", enabled);
> }
>
> static ssize_t
> @@ -343,9 +368,14 @@ static ssize_t
> error_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct crashlog_entry *crashlog = dev_get_drvdata(dev);
> - bool error = pmt_crashlog_error(crashlog);
> + bool error;
> + int ret;
>
> - return sysfs_emit(buf, "%d\n", error);
> + ret = pmt_crashlog_error(crashlog, &error);
> + if (ret)
> + return sysfs_emit(buf, "read error: %d\n", ret);
> + else
> + return sysfs_emit(buf, "%d\n", error);
> }
> static DEVICE_ATTR_RO(error);
>
> @@ -353,9 +383,14 @@ static ssize_t
> rearm_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct crashlog_entry *crashlog = dev_get_drvdata(dev);
> - int rearmed = pmt_crashlog_rearm(crashlog);
> + bool rearmed;
> + int ret;
>
> - return sysfs_emit(buf, "%d\n", rearmed);
> + ret = pmt_crashlog_rearm(crashlog, &rearmed);
> + if (ret)
> + return sysfs_emit(buf, "read error: %d\n", ret);
> + else
> + return sysfs_emit(buf, "%d\n", rearmed);
> }
>
> static ssize_t
> @@ -389,11 +424,15 @@ trigger_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct crashlog_entry *crashlog;
> bool trigger;
> + int ret;
>
> crashlog = dev_get_drvdata(dev);
> - trigger = pmt_crashlog_complete(crashlog);
>
> - return sprintf(buf, "%d\n", trigger);
> + ret = pmt_crashlog_complete(crashlog, &trigger);
> + if (ret)
> + return sysfs_emit(buf, "read error: %d\n", ret);
> + else
> + return sysfs_emit(buf, "%d\n", trigger);
> }
>
> static ssize_t
> @@ -401,6 +440,8 @@ trigger_store(struct device *dev, struct device_attribute *attr,
> const char *buf, size_t count)
> {
> struct crashlog_entry *crashlog;
> + bool complete;
> + bool disabled;
> bool trigger;
> int ret;
>
> @@ -413,7 +454,10 @@ trigger_store(struct device *dev, struct device_attribute *attr,
> guard(mutex)(&crashlog->control_mutex);
>
> /* if device is currently disabled, return busy */
> - if (pmt_crashlog_disabled(crashlog))
> + ret = pmt_crashlog_disabled(crashlog, &disabled);
> + if (ret)
> + return ret;
> + if (disabled)
> return -EBUSY;
>
> if (!trigger) {
> @@ -422,7 +466,8 @@ trigger_store(struct device *dev, struct device_attribute *attr,
> }
>
> /* we cannot trigger a new crash if one is still pending */
> - if (pmt_crashlog_complete(crashlog))
> + ret = pmt_crashlog_complete(crashlog, &complete);
> + if (complete)
> return -EEXIST;
>
> ret = pmt_crashlog_set_execute(crashlog);
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 05/18] platform/x86/intel/pmt: Add helpers for callback info
2026-09-01 19:27 ` [PATCH v4 05/18] platform/x86/intel/pmt: Add helpers for callback info Michael J. Ruhl
@ 2026-09-02 9:10 ` Ilpo Järvinen
0 siblings, 0 replies; 24+ messages in thread
From: Ilpo Järvinen @ 2026-09-02 9:10 UTC (permalink / raw)
To: Michael J. Ruhl
Cc: platform-driver-x86, intel-xe, Hans de Goede, matthew.brost,
rodrigo.vivi, thomas.hellstrom, airlied, simona, david.e.box,
anoop.c.vijay, badal.nilawar, matthew.d.roper, james.ausmus,
karthik.poosa
On Tue, 1 Sep 2026, Michael J. Ruhl wrote:
> Refactor some open coded checks into helpers.
>
> Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
> ---
> drivers/platform/x86/intel/pmt/class.c | 2 +-
> drivers/platform/x86/intel/pmt/class.h | 15 +++++++++++++++
> drivers/platform/x86/intel/pmt/crashlog.c | 4 ++--
> 3 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
> index 402d51df834a..af7c951b569a 100644
> --- a/drivers/platform/x86/intel/pmt/class.c
> +++ b/drivers/platform/x86/intel/pmt/class.c
> @@ -64,7 +64,7 @@ pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count)
> 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)
> + if (is_cb_read_telem(cb))
> return cb->read_telem(dev, guid, buf, off, count);
>
> addr += off;
> diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
> index 258cb460e61c..d8291a5f08a7 100644
> --- a/drivers/platform/x86/intel/pmt/class.h
> +++ b/drivers/platform/x86/intel/pmt/class.h
> @@ -71,6 +71,21 @@ struct intel_pmt_namespace {
> struct intel_pmt_entry *entry);
> };
>
> +static inline bool is_cb_read_telem(struct pmt_callbacks *cb)
> +{
> + return cb && cb->read_telem ? true : false;
> +}
> +
> +static inline bool is_cb_read_reg(struct pmt_callbacks *cb)
> +{
> + return cb && cb->read_reg ? true : false;
> +}
> +
> +static inline bool is_cb_write_reg(struct pmt_callbacks *cb)
> +{
> + return cb && cb->write_reg ? true : false;
> +}
> +
> 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);
> diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
> index 142c368a60f8..32f6a7d42b8d 100644
> --- a/drivers/platform/x86/intel/pmt/crashlog.c
> +++ b/drivers/platform/x86/intel/pmt/crashlog.c
> @@ -132,7 +132,7 @@ static int pmt_crashlog_read_reg(struct intel_pmt_entry *entry, u32 *reg, u32 of
>
> *reg = 0;
>
> - if (entry->cb && entry->cb->read_reg) {
> + if (is_cb_read_reg(entry->cb)) {
> ret = entry->cb->read_reg(entry->dev, entry->header.guid, reg, offset);
> if (ret) {
> pr_err_ratelimited("failed to read reg: %d\n", ret);
> @@ -164,7 +164,7 @@ static int pmt_crashlog_rmw(struct crashlog_entry *crashlog, u32 bit, bool set)
> else
> reg &= ~bit;
>
> - if (entry->cb && entry->cb->write_reg) {
> + if (is_cb_write_reg(entry->cb)) {
> ret = entry->cb->write_reg(entry->dev, entry->header.guid, reg, control->offset);
> if (ret) {
> pr_err_ratelimited("failed to write reg: %d\n", ret);
>
This change doesn't look an improvement to me as they obfuscate the
callback present check (and does not really make it that much shorter
either).
--
i.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 06/18] platform/x86/intel/pmt: Do not remap when using callbacks
2026-09-01 19:27 ` [PATCH v4 06/18] platform/x86/intel/pmt: Do not remap when using callbacks Michael J. Ruhl
@ 2026-09-02 9:18 ` Ilpo Järvinen
0 siblings, 0 replies; 24+ messages in thread
From: Ilpo Järvinen @ 2026-09-02 9:18 UTC (permalink / raw)
To: Michael J. Ruhl
Cc: platform-driver-x86, intel-xe, Hans de Goede, matthew.brost,
rodrigo.vivi, thomas.hellstrom, airlied, simona, david.e.box,
anoop.c.vijay, badal.nilawar, matthew.d.roper, james.ausmus,
karthik.poosa
On Tue, 1 Sep 2026, Michael J. Ruhl wrote:
> A callback indicates that the parent driver is responsible
> for accessing the data area. Creating a PMT memory remap
> is redundant.
>
> If a read_telem callback has been provided, do not create a
> remap.
>
> Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
> ---
> drivers/platform/x86/intel/pmt/class.c | 19 +++++++++++--------
> 1 file changed, 11 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
> index af7c951b569a..350129121ff1 100644
> --- a/drivers/platform/x86/intel/pmt/class.c
> +++ b/drivers/platform/x86/intel/pmt/class.c
> @@ -373,7 +373,6 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
> struct device *parent)
> {
> struct intel_vsec_device *ivdev = dev_to_ivdev(parent);
> - struct resource res = {0};
> struct device *dev;
> int ret;
>
> @@ -403,14 +402,18 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
> if (!entry->size)
> return 0;
>
> - res.start = entry->base_addr;
> - res.end = res.start + entry->size - 1;
> - res.flags = IORESOURCE_MEM;
> + if (!is_cb_read_telem(entry->cb)) {
> + struct resource res = {0};
I see you're copying this from the existing one, but this is wrong on
multiple counts:
- For general initialization to default values, = {} should be used
(the extra zero is snakeoil).
- HOWEVER, with struct resource, that won't produce a valid resource!
In this case, DEFINE_RES_MEM() should be used as you've everything
available to setup it right away.
> - entry->base = devm_ioremap_resource(dev, &res);
> - if (IS_ERR(entry->base)) {
> - ret = PTR_ERR(entry->base);
> - goto fail_ioremap;
> + res.start = entry->base_addr;
> + res.end = res.start + entry->size - 1;
For the record, there would also be resource_set_range() but since you're
going to use DEFINE_RES_MEM(), that isn't necessary here.
> + res.flags = IORESOURCE_MEM;
> +
> + entry->base = devm_ioremap_resource(dev, &res);
> + if (IS_ERR(entry->base)) {
> + ret = PTR_ERR(entry->base);
> + goto fail_ioremap;
> + }
> }
>
> sysfs_bin_attr_init(&entry->pmt_bin_attr);
>
--
i.
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2026-09-02 9:18 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 19:27 [PATCH v4 00/18] Crescent Island PMT support Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 01/18] platform/x86/intel/pmt: complete pcidev to device update Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 02/18] platform/x86/intel/pmt: refactor rmw with a return value Michael J. Ruhl
2026-09-02 9:05 ` Ilpo Järvinen
2026-09-02 9:07 ` Ilpo Järvinen
2026-09-01 19:27 ` [PATCH v4 03/18] platform/x86/intel/pmt: refactor rc " Michael J. Ruhl
2026-09-02 9:08 ` Ilpo Järvinen
2026-09-01 19:27 ` [PATCH v4 04/18] platform/x86/intel/pmt: Add register access callbacks Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 05/18] platform/x86/intel/pmt: Add helpers for callback info Michael J. Ruhl
2026-09-02 9:10 ` Ilpo Järvinen
2026-09-01 19:27 ` [PATCH v4 06/18] platform/x86/intel/pmt: Do not remap when using callbacks Michael J. Ruhl
2026-09-02 9:18 ` Ilpo Järvinen
2026-09-01 19:27 ` [PATCH v4 07/18] drm/xe/vsec: Do not register BMG PMT for VF Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 08/18] drm/xe/vsec: Correct locking order Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 09/18] drm/xe/vsec: Use correct pm state get Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 10/18] drm/xe/vsec: Support possible hotplug exit Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 11/18] drm/xe/vsec: Support Crescent Island PMT Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 12/18] drm/xe/vsec: Refactor BattleMage PMT defines Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 13/18] drm/xe/vsec: Crescent Island PMT decode Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 14/18] drm/xe/vsec: Crescent Island PMT callbacks Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 15/18] drm/xe/vsec: Support late bind fw information Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 16/18] drm/xe/vsec: Add PMT GUID internal access Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 17/18] drm/xe/vsec: Update PMT " Michael J. Ruhl
2026-09-01 19:27 ` [PATCH v4 18/18] drm/xe/vsec: Refactor platform check Michael J. Ruhl
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox