All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pranay Samala <pranay.samala@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: kunal1.joshi@intel.com, sameer.lattannavar@intel.com,
	pranay.samala@intel.com
Subject: [PATCH i-g-t v3 5/7] lib/igt_pm: Add power/wakeup_active_count accessor
Date: Tue, 20 Oct 2026 19:41:49 +0530	[thread overview]
Message-ID: <20261020141151.753331-6-pranay.samala@intel.com> (raw)
In-Reply-To: <20261020141151.753331-1-pranay.samala@intel.com>

Add igt_pm_get_wakeup_active_count(), the number of times the device's
wakeup source was activated.

Every PCI PME delivery route ends in pci_wakeup_event(), which bumps
this count: the native PCIe PME interrupt, an ACPI GPE, and the PCI
core PME poll (pci_pme_list_scan(), every 1s), which is the likely
route for an integrated GPU without a GPE. An increment across a
suspended window therefore means the device woke itself with a PME,
rather than the host waking it.

power/wakeup_count does not work for this, as it only moves during
system suspend, and neither does PME_Status, which the PCI core clears
while handling the wakeup.

The count is unavailable while power/wakeup is disabled. Since 0 is a
valid count, return -1 then, so callers can tell "no wakeup source"
from "no PME".

v3:
- Mention the PCI core PME poll route, and correct the PCIe route, which
  is pcie_pme_handle_request() rather than pci_pme_wakeup() (Kunal)
- Return int64_t, -1 when there is no wakeup source, instead of 0 (Kunal)

Signed-off-by: Pranay Samala <pranay.samala@intel.com>
---
 lib/igt_pm.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_pm.h |  1 +
 2 files changed, 54 insertions(+)

diff --git a/lib/igt_pm.c b/lib/igt_pm.c
index 1173b2b68..f4d5d5c7b 100644
--- a/lib/igt_pm.c
+++ b/lib/igt_pm.c
@@ -1498,6 +1498,35 @@ int igt_pm_get_runtime_usage(struct pci_device *pci_dev)
 	return usage;
 }
 
+/*
+ * Read an unsigned power attribute of @pci_dev, returning -1 if the attribute
+ * does not exist or does not hold a number.
+ *
+ * The latter is not hypothetical: the wakeup counters exist for every wakeup
+ * capable device, but the PM core emits a bare newline for them while the
+ * device has no wakeup source, i.e. while power/wakeup is disabled. Since 0 is
+ * a valid count, that case has to be told apart from it.
+ */
+static int64_t igt_pm_read_power_attr_u64(struct pci_device *pci_dev,
+					  const char *attr)
+{
+	char buf[64];
+	int64_t val;
+	int fd;
+
+	fd = __igt_pm_get_power_attr_fd(pci_dev, attr, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	if (!igt_pm_read_power_attr(fd, buf, sizeof(buf), false) ||
+	    sscanf(buf, "%" SCNd64, &val) != 1 || val < 0)
+		val = -1;
+
+	close(fd);
+
+	return val;
+}
+
 #define IGT_PM_WAKEUP_ENABLED_STR "enabled\n"
 #define IGT_PM_WAKEUP_DISABLED_STR "disabled\n"
 
@@ -1638,6 +1667,30 @@ void igt_pm_restore_wakeup(void)
 	__igt_pm_wakeup.pci_dev = NULL;
 }
 
+/**
+ * igt_pm_get_wakeup_active_count:
+ * @pci_dev: PCI device struct
+ *
+ * Reads power/wakeup_active_count, the number of times the device's wakeup
+ * source was activated. An increment across a runtime suspended window means
+ * the resume was signalled by the device, i.e. a PME arrived, rather than
+ * initiated by something host side such as HPD polling.
+ *
+ * Use this and not power/wakeup_count, which is only incremented under
+ * events_check_enabled and so never moves for a runtime resume.
+ *
+ * The count only exists while the device has a wakeup source, i.e. while
+ * power/wakeup is enabled, and restarts from 0 each time one is created. See
+ * igt_pm_set_wakeup_enabled().
+ *
+ * Return: the wakeup active count, or -1 if the device is not wakeup capable,
+ * has power/wakeup disabled, or the count could not be read.
+ */
+int64_t igt_pm_get_wakeup_active_count(struct pci_device *pci_dev)
+{
+	return igt_pm_read_power_attr_u64(pci_dev, "wakeup_active_count");
+}
+
 /**
  * igt_pm_ignore_slpc_efficient_freq:
  * @i915: open i915 drm file descriptor
diff --git a/lib/igt_pm.h b/lib/igt_pm.h
index c3facbd69..3d857080a 100644
--- a/lib/igt_pm.h
+++ b/lib/igt_pm.h
@@ -106,6 +106,7 @@ int igt_pm_get_runtime_usage(struct pci_device *pci_dev);
 bool igt_pm_has_wakeup_support(struct pci_device *pci_dev);
 void igt_pm_set_wakeup_enabled(struct pci_device *pci_dev, bool enable);
 void igt_pm_restore_wakeup(void);
+int64_t igt_pm_get_wakeup_active_count(struct pci_device *pci_dev);
 void igt_pm_ignore_slpc_efficient_freq(int i915, int gtfd, bool val);
 bool igt_has_pci_pm_capability(struct pci_device *pci_dev);
 bool igt_pm_pci_pme_supported(struct pci_device *pci_dev,
-- 
2.53.0


  parent reply	other threads:[~2026-10-20 14:14 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20 14:11 [PATCH i-g-t v3 0/7] Validate PM_PME signalling on display hotplug Pranay Samala
2026-10-20 14:11 ` [PATCH i-g-t v3 1/7] lib/igt_pci: Add PCI Power Management capability register layout Pranay Samala
2026-10-20 14:11 ` [PATCH i-g-t v3 2/7] lib/igt_pm: Add PCI PME capability and D state accessors Pranay Samala
2026-10-23  8:58   ` Joshi, Kunal1
2026-10-20 14:11 ` [PATCH i-g-t v3 3/7] lib/igt_pm: Factor out power attribute path construction Pranay Samala
2026-10-20 14:11 ` [PATCH i-g-t v3 4/7] lib/igt_pm: Add power/wakeup accessors Pranay Samala
2026-10-23  9:01   ` Joshi, Kunal1
2026-10-20 14:11 ` Pranay Samala [this message]
2026-10-23  9:03   ` [PATCH i-g-t v3 5/7] lib/igt_pm: Add power/wakeup_active_count accessor Joshi, Kunal1
2026-10-20 14:11 ` [PATCH i-g-t v3 6/7] lib/igt_kms: Add drm_kms_helper.poll save/restore helpers Pranay Samala
2026-10-23  9:05   ` Joshi, Kunal1
2026-10-20 14:11 ` [PATCH i-g-t v3 7/7] tests/chamelium/kms_chamelium_hpd: Add HPD from runtime suspended D3hot Pranay Samala
2026-10-23  9:07   ` Joshi, Kunal1
2026-10-20 15:40 ` ✓ Xe.CI.BAT: success for Validate PM_PME signalling on display hotplug (rev4) Patchwork
2026-10-20 15:59 ` ✓ i915.CI.BAT: " Patchwork
2026-10-20 20:46 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-10-20 23:07 ` ✓ i915.CI.Full: success " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261020141151.753331-6-pranay.samala@intel.com \
    --to=pranay.samala@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=kunal1.joshi@intel.com \
    --cc=sameer.lattannavar@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.