i915 doesn't use pm_suspend_ignore_children(), which warrants that
any runtime active child of i915 will block the runtime suspend
of i915.
i915_runtime_pm_status only exposes i915 runtime pm usage_count,
which is not sufficient to debug in the scenarios when i915 has
zero usage_count but there are runtime active children.
Dump i915 child's runtime pm status to debug such
i915 runtime suspend issues.

v2:
- Added const array of rpm_status strings to avoid switch. [Ashutosh]

Cc: Chris Wilson <chris.p.wil...@intel.com>
Reviewed-by: Badal Nilawar <badal.nila...@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gu...@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 32 +++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 445b4da23950..930815c8b978 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -483,6 +483,34 @@ static int i915_rps_boost_info(struct seq_file *m, void 
*data)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int i915_runtime_dump_child_status(struct device *dev, void *data)
+{
+       struct seq_file *m = data;
+       const char *rpm_status;
+
+       static const char * const status_lookup[] = {
+               [RPM_ACTIVE] = "active",
+               [RPM_RESUMING] = "resuming",
+               [RPM_SUSPENDED] = "suspended",
+               [RPM_SUSPENDING] = "suspending"
+       };
+
+       /* Early return if runtime_pm is disabled */
+       if (dev->power.disable_depth)
+               return 0;
+       else if (dev->power.runtime_status < ARRAY_SIZE(status_lookup))
+               rpm_status = status_lookup[dev->power.runtime_status];
+       else
+               rpm_status = "unknown";
+
+       seq_printf(m, "\t%s %s: Runtime status: %s\n", dev_driver_string(dev),
+                  dev_name(dev), rpm_status);
+
+       return 0;
+}
+#endif
+
 static int i915_runtime_pm_status(struct seq_file *m, void *unused)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -500,6 +528,10 @@ static int i915_runtime_pm_status(struct seq_file *m, void 
*unused)
 #ifdef CONFIG_PM
        seq_printf(m, "Usage count: %d\n",
                   atomic_read(&dev_priv->drm.dev->power.usage_count));
+       seq_printf(m, "Runtime active children: %d\n",
+                  atomic_read(&dev_priv->drm.dev->power.child_count));
+       device_for_each_child(&pdev->dev, m, i915_runtime_dump_child_status);
+
 #else
        seq_printf(m, "Device Power Management (CONFIG_PM) disabled\n");
 #endif
-- 
2.26.2

Reply via email to