]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - kernel/power/qos.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[karo-tx-linux.git] / kernel / power / qos.c
index d6d6dbd1ecc09f673d987600981c549e5332ad50..6a031e684026f99507946c371544cbae34a35b48 100644 (file)
@@ -229,6 +229,21 @@ int pm_qos_request_active(struct pm_qos_request *req)
 }
 EXPORT_SYMBOL_GPL(pm_qos_request_active);
 
+/**
+ * pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout
+ * @work: work struct for the delayed work (timeout)
+ *
+ * This cancels the timeout request by falling back to the default at timeout.
+ */
+static void pm_qos_work_fn(struct work_struct *work)
+{
+       struct pm_qos_request *req = container_of(to_delayed_work(work),
+                                                 struct pm_qos_request,
+                                                 work);
+
+       pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE);
+}
+
 /**
  * pm_qos_add_request - inserts new qos request into the list
  * @req: pointer to a preallocated handle
@@ -253,6 +268,7 @@ void pm_qos_add_request(struct pm_qos_request *req,
                return;
        }
        req->pm_qos_class = pm_qos_class;
+       INIT_DELAYED_WORK(&req->work, pm_qos_work_fn);
        pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints,
                             &req->node, PM_QOS_ADD_REQ, value);
 }
@@ -279,6 +295,9 @@ void pm_qos_update_request(struct pm_qos_request *req,
                return;
        }
 
+       if (delayed_work_pending(&req->work))
+               cancel_delayed_work_sync(&req->work);
+
        if (new_value != req->node.prio)
                pm_qos_update_target(
                        pm_qos_array[req->pm_qos_class]->constraints,
@@ -286,6 +305,34 @@ void pm_qos_update_request(struct pm_qos_request *req,
 }
 EXPORT_SYMBOL_GPL(pm_qos_update_request);
 
+/**
+ * pm_qos_update_request_timeout - modifies an existing qos request temporarily.
+ * @req : handle to list element holding a pm_qos request to use
+ * @new_value: defines the temporal qos request
+ * @timeout_us: the effective duration of this qos request in usecs.
+ *
+ * After timeout_us, this qos request is cancelled automatically.
+ */
+void pm_qos_update_request_timeout(struct pm_qos_request *req, s32 new_value,
+                                  unsigned long timeout_us)
+{
+       if (!req)
+               return;
+       if (WARN(!pm_qos_request_active(req),
+                "%s called for unknown object.", __func__))
+               return;
+
+       if (delayed_work_pending(&req->work))
+               cancel_delayed_work_sync(&req->work);
+
+       if (new_value != req->node.prio)
+               pm_qos_update_target(
+                       pm_qos_array[req->pm_qos_class]->constraints,
+                       &req->node, PM_QOS_UPDATE_REQ, new_value);
+
+       schedule_delayed_work(&req->work, usecs_to_jiffies(timeout_us));
+}
+
 /**
  * pm_qos_remove_request - modifies an existing qos request
  * @req: handle to request list element
@@ -305,6 +352,9 @@ void pm_qos_remove_request(struct pm_qos_request *req)
                return;
        }
 
+       if (delayed_work_pending(&req->work))
+               cancel_delayed_work_sync(&req->work);
+
        pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints,
                             &req->node, PM_QOS_REMOVE_REQ,
                             PM_QOS_DEFAULT_VALUE);