--- /dev/null
+From c745253e2a691a40c66790defe85c104a887e14a Mon Sep 17 00:00:00 2001
+From: Tony Lindgren <tony@atomide.com>
+Date: Wed, 5 May 2021 14:09:15 +0300
+Subject: PM: runtime: Fix unpaired parent child_count for force_resume
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit c745253e2a691a40c66790defe85c104a887e14a upstream.
+
+As pm_runtime_need_not_resume() relies also on usage_count, it can return
+a different value in pm_runtime_force_suspend() compared to when called in
+pm_runtime_force_resume(). Different return values can happen if anything
+calls PM runtime functions in between, and causes the parent child_count
+to increase on every resume.
+
+So far I've seen the issue only for omapdrm that does complicated things
+with PM runtime calls during system suspend for legacy reasons:
+
+omap_atomic_commit_tail() for omapdrm.0
+ dispc_runtime_get()
+ wakes up 58000000.dss as it's the dispc parent
+ dispc_runtime_resume()
+ rpm_resume() increases parent child_count
+ dispc_runtime_put() won't idle, PM runtime suspend blocked
+pm_runtime_force_suspend() for 58000000.dss, !pm_runtime_need_not_resume()
+ __update_runtime_status()
+system suspended
+pm_runtime_force_resume() for 58000000.dss, pm_runtime_need_not_resume()
+ pm_runtime_enable() only called because of pm_runtime_need_not_resume()
+omap_atomic_commit_tail() for omapdrm.0
+ dispc_runtime_get()
+ wakes up 58000000.dss as it's the dispc parent
+ dispc_runtime_resume()
+ rpm_resume() increases parent child_count
+ dispc_runtime_put() won't idle, PM runtime suspend blocked
+...
+rpm_suspend for 58000000.dss but parent child_count is now unbalanced
+
+Let's fix the issue by adding a flag for needs_force_resume and use it in
+pm_runtime_force_resume() instead of pm_runtime_need_not_resume().
+
+Additionally omapdrm system suspend could be simplified later on to avoid
+lots of unnecessary PM runtime calls and the complexity it adds. The
+driver can just use internal functions that are shared between the PM
+runtime and system suspend related functions.
+
+Fixes: 4918e1f87c5f ("PM / runtime: Rework pm_runtime_force_suspend/resume()")
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Tested-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Cc: 4.16+ <stable@vger.kernel.org> # 4.16+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/power/runtime.c | 10 +++++++---
+ include/linux/pm.h | 1 +
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -1610,6 +1610,7 @@ void pm_runtime_init(struct device *dev)
+ dev->power.request_pending = false;
+ dev->power.request = RPM_REQ_NONE;
+ dev->power.deferred_resume = false;
++ dev->power.needs_force_resume = 0;
+ INIT_WORK(&dev->power.work, pm_runtime_work);
+
+ dev->power.timer_expires = 0;
+@@ -1777,10 +1778,12 @@ int pm_runtime_force_suspend(struct devi
+ * its parent, but set its status to RPM_SUSPENDED anyway in case this
+ * function will be called again for it in the meantime.
+ */
+- if (pm_runtime_need_not_resume(dev))
++ if (pm_runtime_need_not_resume(dev)) {
+ pm_runtime_set_suspended(dev);
+- else
++ } else {
+ __update_runtime_status(dev, RPM_SUSPENDED);
++ dev->power.needs_force_resume = 1;
++ }
+
+ return 0;
+
+@@ -1807,7 +1810,7 @@ int pm_runtime_force_resume(struct devic
+ int (*callback)(struct device *);
+ int ret = 0;
+
+- if (!pm_runtime_status_suspended(dev) || pm_runtime_need_not_resume(dev))
++ if (!pm_runtime_status_suspended(dev) || !dev->power.needs_force_resume)
+ goto out;
+
+ /*
+@@ -1826,6 +1829,7 @@ int pm_runtime_force_resume(struct devic
+
+ pm_runtime_mark_last_busy(dev);
+ out:
++ dev->power.needs_force_resume = 0;
+ pm_runtime_enable(dev);
+ return ret;
+ }
+--- a/include/linux/pm.h
++++ b/include/linux/pm.h
+@@ -608,6 +608,7 @@ struct dev_pm_info {
+ unsigned int idle_notification:1;
+ unsigned int request_pending:1;
+ unsigned int deferred_resume:1;
++ unsigned int needs_force_resume:1;
+ unsigned int runtime_auto:1;
+ bool ignore_children:1;
+ unsigned int no_callbacks:1;