path: root/kernel
diff options
authorTejun Heo <tj@kernel.org>2016-09-05 08:38:13 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-09-05 15:07:53 +0200
commitc86d06ba2818c5126078cb0cf4e0175ec381045b (patch)
tree52f90ab2cbd248e6d958de791671ee4aa78d90a8 /kernel
parentc6935931c1894ff857616ff8549b61236a19148f (diff)
PM / QoS: avoid calling cancel_delayed_work_sync() during early boot
of_clk_init() ends up calling into pm_qos_update_request() very early during boot where irq is expected to stay disabled. pm_qos_update_request() uses cancel_delayed_work_sync() which correctly assumes that irq is enabled on invocation and unconditionally disables and re-enables it. Gate cancel_delayed_work_sync() invocation with kevented_up() to avoid enabling irq unexpectedly during early boot. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-and-tested-by: Qiao Zhou <qiaozhou@asrmicro.com> Link: http://lkml.kernel.org/r/d2501c4c-8e7b-bea3-1b01-000b36b5dfe9@asrmicro.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'kernel')
1 files changed, 10 insertions, 1 deletions
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 97b0df71303e..168ff442ebde 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -482,7 +482,16 @@ void pm_qos_update_request(struct pm_qos_request *req,
- cancel_delayed_work_sync(&req->work);
+ /*
+ * This function may be called very early during boot, for example,
+ * from of_clk_init(), where irq needs to stay disabled.
+ * cancel_delayed_work_sync() assumes that irq is enabled on
+ * invocation and re-enables it on return. Avoid calling it until
+ * workqueue is initialized.
+ */
+ if (keventd_up())
+ cancel_delayed_work_sync(&req->work);
__pm_qos_update_request(req, new_value);