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.wilson@xxxxxxxxx> Reviewed-by: Badal Nilawar <badal.nilawar@xxxxxxxxx> Signed-off-by: Anshuman Gupta <anshuman.gupta@xxxxxxxxx> --- 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