···204204205205 This attribute has no effect on system-wide suspend/resume and206206 hibernation.207207+208208+What: /sys/devices/.../power/pm_qos_no_power_off209209+Date: September 2012210210+Contact: Rafael J. Wysocki <rjw@sisk.pl>211211+Description:212212+ The /sys/devices/.../power/pm_qos_no_power_off attribute213213+ is used for manipulating the PM QoS "no power off" flag. If214214+ set, this flag indicates to the kernel that power should not215215+ be removed entirely from the device.216216+217217+ Not all drivers support this attribute. If it isn't supported,218218+ it is not present.219219+220220+ This attribute has no effect on system-wide suspend/resume and221221+ hibernation.222222+223223+What: /sys/devices/.../power/pm_qos_remote_wakeup224224+Date: September 2012225225+Contact: Rafael J. Wysocki <rjw@sisk.pl>226226+Description:227227+ The /sys/devices/.../power/pm_qos_remote_wakeup attribute228228+ is used for manipulating the PM QoS "remote wakeup required"229229+ flag. If set, this flag indicates to the kernel that the230230+ device is a source of user events that have to be signaled from231231+ its low-power states.232232+233233+ Not all drivers support this attribute. If it isn't supported,234234+ it is not present.235235+236236+ This attribute has no effect on system-wide suspend/resume and237237+ hibernation.
+1-1
Documentation/power/pm_qos_interface.txt
···9999100100From kernel mode the use of this interface is the following:101101102102-int dev_pm_qos_add_request(device, handle, value):102102+int dev_pm_qos_add_request(device, handle, type, value):103103Will insert an element into the list for that identified device with the104104target value. Upon change to this list the new target is recomputed and any105105registered notifiers are called only if the target value is now different.
+17-4
drivers/acpi/sleep.c
···1919#include <linux/acpi.h>2020#include <linux/module.h>2121#include <linux/pm_runtime.h>2222+#include <linux/pm_qos.h>22232324#include <asm/io.h>2425···712711 struct acpi_device *adev;713712 char acpi_method[] = "_SxD";714713 unsigned long long d_min, d_max;714714+ bool wakeup = false;715715716716 if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3)717717 return -EINVAL;718718 if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {719719 printk(KERN_DEBUG "ACPI handle has no context!\n");720720 return -ENODEV;721721+ }722722+ if (d_max_in > ACPI_STATE_D3_HOT) {723723+ enum pm_qos_flags_status stat;724724+725725+ stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF);726726+ if (stat == PM_QOS_FLAGS_ALL)727727+ d_max_in = ACPI_STATE_D3_HOT;721728 }722729723730 acpi_method[2] = '0' + acpi_target_sleep_state;···746737 * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer747738 * provided -- that's our fault recovery, we ignore retval.748739 */749749- if (acpi_target_sleep_state > ACPI_STATE_S0)740740+ if (acpi_target_sleep_state > ACPI_STATE_S0) {750741 acpi_evaluate_integer(handle, acpi_method, NULL, &d_min);742742+ wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid743743+ && adev->wakeup.sleep_state >= acpi_target_sleep_state;744744+ } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) !=745745+ PM_QOS_FLAGS_NONE) {746746+ wakeup = adev->wakeup.flags.valid;747747+ }751748752749 /*753750 * If _PRW says we can wake up the system from the target sleep state,···762747 * (ACPI 3.x), it should return the maximum (lowest power) D-state that763748 * can wake the system. _S0W may be valid, too.764749 */765765- if (acpi_target_sleep_state == ACPI_STATE_S0 ||766766- (device_may_wakeup(dev) && adev->wakeup.flags.valid &&767767- adev->wakeup.sleep_state >= acpi_target_sleep_state)) {750750+ if (wakeup) {768751 acpi_status status;769752770753 acpi_method[3] = 'W';
···9393extern void rpm_sysfs_remove(struct device *dev);9494extern int wakeup_sysfs_add(struct device *dev);9595extern void wakeup_sysfs_remove(struct device *dev);9696-extern int pm_qos_sysfs_add(struct device *dev);9797-extern void pm_qos_sysfs_remove(struct device *dev);9696+extern int pm_qos_sysfs_add_latency(struct device *dev);9797+extern void pm_qos_sysfs_remove_latency(struct device *dev);9898+extern int pm_qos_sysfs_add_flags(struct device *dev);9999+extern void pm_qos_sysfs_remove_flags(struct device *dev);9810099101#else /* CONFIG_PM */100102
+246-62
drivers/base/power/qos.c
···4040#include <linux/device.h>4141#include <linux/mutex.h>4242#include <linux/export.h>4343+#include <linux/pm_runtime.h>43444445#include "power.h"45464647static DEFINE_MUTEX(dev_pm_qos_mtx);47484849static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers);5050+5151+/**5252+ * __dev_pm_qos_flags - Check PM QoS flags for a given device.5353+ * @dev: Device to check the PM QoS flags for.5454+ * @mask: Flags to check against.5555+ *5656+ * This routine must be called with dev->power.lock held.5757+ */5858+enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask)5959+{6060+ struct dev_pm_qos *qos = dev->power.qos;6161+ struct pm_qos_flags *pqf;6262+ s32 val;6363+6464+ if (!qos)6565+ return PM_QOS_FLAGS_UNDEFINED;6666+6767+ pqf = &qos->flags;6868+ if (list_empty(&pqf->list))6969+ return PM_QOS_FLAGS_UNDEFINED;7070+7171+ val = pqf->effective_flags & mask;7272+ if (val)7373+ return (val == mask) ? PM_QOS_FLAGS_ALL : PM_QOS_FLAGS_SOME;7474+7575+ return PM_QOS_FLAGS_NONE;7676+}7777+7878+/**7979+ * dev_pm_qos_flags - Check PM QoS flags for a given device (locked).8080+ * @dev: Device to check the PM QoS flags for.8181+ * @mask: Flags to check against.8282+ */8383+enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask)8484+{8585+ unsigned long irqflags;8686+ enum pm_qos_flags_status ret;8787+8888+ spin_lock_irqsave(&dev->power.lock, irqflags);8989+ ret = __dev_pm_qos_flags(dev, mask);9090+ spin_unlock_irqrestore(&dev->power.lock, irqflags);9191+9292+ return ret;9393+}49945095/**5196 * __dev_pm_qos_read_value - Get PM QoS constraint for a given device.···10055 */10156s32 __dev_pm_qos_read_value(struct device *dev)10257{103103- struct pm_qos_constraints *c = dev->power.constraints;104104-105105- return c ? pm_qos_read_value(c) : 0;5858+ return dev->power.qos ? pm_qos_read_value(&dev->power.qos->latency) : 0;10659}1076010861/**···11976 return ret;12077}12178122122-/*123123- * apply_constraint124124- * @req: constraint request to apply125125- * @action: action to perform add/update/remove, of type enum pm_qos_req_action126126- * @value: defines the qos request7979+/**8080+ * apply_constraint - Add/modify/remove device PM QoS request.8181+ * @req: Constraint request to apply8282+ * @action: Action to perform (add/update/remove).8383+ * @value: Value to assign to the QoS request.12784 *12885 * Internal function to update the constraints list using the PM QoS core12986 * code and if needed call the per-device and the global notification13087 * callbacks13188 */13289static int apply_constraint(struct dev_pm_qos_request *req,133133- enum pm_qos_req_action action, int value)9090+ enum pm_qos_req_action action, s32 value)13491{135135- int ret, curr_value;9292+ struct dev_pm_qos *qos = req->dev->power.qos;9393+ int ret;13694137137- ret = pm_qos_update_target(req->dev->power.constraints,138138- &req->node, action, value);139139-140140- if (ret) {141141- /* Call the global callbacks if needed */142142- curr_value = pm_qos_read_value(req->dev->power.constraints);143143- blocking_notifier_call_chain(&dev_pm_notifiers,144144- (unsigned long)curr_value,145145- req);9595+ switch(req->type) {9696+ case DEV_PM_QOS_LATENCY:9797+ ret = pm_qos_update_target(&qos->latency, &req->data.pnode,9898+ action, value);9999+ if (ret) {100100+ value = pm_qos_read_value(&qos->latency);101101+ blocking_notifier_call_chain(&dev_pm_notifiers,102102+ (unsigned long)value,103103+ req);104104+ }105105+ break;106106+ case DEV_PM_QOS_FLAGS:107107+ ret = pm_qos_update_flags(&qos->flags, &req->data.flr,108108+ action, value);109109+ break;110110+ default:111111+ ret = -EINVAL;146112 }147113148114 return ret;···166114 */167115static int dev_pm_qos_constraints_allocate(struct device *dev)168116{117117+ struct dev_pm_qos *qos;169118 struct pm_qos_constraints *c;170119 struct blocking_notifier_head *n;171120172172- c = kzalloc(sizeof(*c), GFP_KERNEL);173173- if (!c)121121+ qos = kzalloc(sizeof(*qos), GFP_KERNEL);122122+ if (!qos)174123 return -ENOMEM;175124176125 n = kzalloc(sizeof(*n), GFP_KERNEL);177126 if (!n) {178178- kfree(c);127127+ kfree(qos);179128 return -ENOMEM;180129 }181130 BLOCKING_INIT_NOTIFIER_HEAD(n);182131132132+ c = &qos->latency;183133 plist_head_init(&c->list);184134 c->target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE;185135 c->default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE;186136 c->type = PM_QOS_MIN;187137 c->notifiers = n;188138139139+ INIT_LIST_HEAD(&qos->flags.list);140140+189141 spin_lock_irq(&dev->power.lock);190190- dev->power.constraints = c;142142+ dev->power.qos = qos;191143 spin_unlock_irq(&dev->power.lock);192144193145 return 0;···207151void dev_pm_qos_constraints_init(struct device *dev)208152{209153 mutex_lock(&dev_pm_qos_mtx);210210- dev->power.constraints = NULL;154154+ dev->power.qos = NULL;211155 dev->power.power_state = PMSG_ON;212156 mutex_unlock(&dev_pm_qos_mtx);213157}···220164 */221165void dev_pm_qos_constraints_destroy(struct device *dev)222166{167167+ struct dev_pm_qos *qos;223168 struct dev_pm_qos_request *req, *tmp;224169 struct pm_qos_constraints *c;225170···233176 mutex_lock(&dev_pm_qos_mtx);234177235178 dev->power.power_state = PMSG_INVALID;236236- c = dev->power.constraints;237237- if (!c)179179+ qos = dev->power.qos;180180+ if (!qos)238181 goto out;239182183183+ c = &qos->latency;240184 /* Flush the constraints list for the device */241241- plist_for_each_entry_safe(req, tmp, &c->list, node) {185185+ plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) {242186 /*243187 * Update constraints list and call the notification244188 * callbacks if needed···249191 }250192251193 spin_lock_irq(&dev->power.lock);252252- dev->power.constraints = NULL;194194+ dev->power.qos = NULL;253195 spin_unlock_irq(&dev->power.lock);254196255197 kfree(c->notifiers);256256- kfree(c);198198+ kfree(qos);257199258200 out:259201 mutex_unlock(&dev_pm_qos_mtx);···263205 * dev_pm_qos_add_request - inserts new qos request into the list264206 * @dev: target device for the constraint265207 * @req: pointer to a preallocated handle208208+ * @type: type of the request266209 * @value: defines the qos request267210 *268211 * This function inserts a new entry in the device constraints list of···277218 * -EINVAL in case of wrong parameters, -ENOMEM if there's not enough memory278219 * to allocate for data structures, -ENODEV if the device has just been removed279220 * from the system.221221+ *222222+ * Callers should ensure that the target device is not RPM_SUSPENDED before223223+ * using this function for requests of type DEV_PM_QOS_FLAGS.280224 */281225int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,282282- s32 value)226226+ enum dev_pm_qos_req_type type, s32 value)283227{284228 int ret = 0;285229···297235298236 mutex_lock(&dev_pm_qos_mtx);299237300300- if (!dev->power.constraints) {238238+ if (!dev->power.qos) {301239 if (dev->power.power_state.event == PM_EVENT_INVALID) {302240 /* The device has been removed from the system. */303241 req->dev = NULL;···313251 }314252 }315253316316- if (!ret)254254+ if (!ret) {255255+ req->type = type;317256 ret = apply_constraint(req, PM_QOS_ADD_REQ, value);257257+ }318258319259 out:320260 mutex_unlock(&dev_pm_qos_mtx);···324260 return ret;325261}326262EXPORT_SYMBOL_GPL(dev_pm_qos_add_request);263263+264264+/**265265+ * __dev_pm_qos_update_request - Modify an existing device PM QoS request.266266+ * @req : PM QoS request to modify.267267+ * @new_value: New value to request.268268+ */269269+static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,270270+ s32 new_value)271271+{272272+ s32 curr_value;273273+ int ret = 0;274274+275275+ if (!req->dev->power.qos)276276+ return -ENODEV;277277+278278+ switch(req->type) {279279+ case DEV_PM_QOS_LATENCY:280280+ curr_value = req->data.pnode.prio;281281+ break;282282+ case DEV_PM_QOS_FLAGS:283283+ curr_value = req->data.flr.flags;284284+ break;285285+ default:286286+ return -EINVAL;287287+ }288288+289289+ if (curr_value != new_value)290290+ ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value);291291+292292+ return ret;293293+}327294328295/**329296 * dev_pm_qos_update_request - modifies an existing qos request···370275 * 0 if the aggregated constraint value has not changed,371276 * -EINVAL in case of wrong parameters, -ENODEV if the device has been372277 * removed from the system278278+ *279279+ * Callers should ensure that the target device is not RPM_SUSPENDED before280280+ * using this function for requests of type DEV_PM_QOS_FLAGS.373281 */374374-int dev_pm_qos_update_request(struct dev_pm_qos_request *req,375375- s32 new_value)282282+int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value)376283{377377- int ret = 0;284284+ int ret;378285379286 if (!req) /*guard against callers passing in null */380287 return -EINVAL;···386289 return -EINVAL;387290388291 mutex_lock(&dev_pm_qos_mtx);389389-390390- if (req->dev->power.constraints) {391391- if (new_value != req->node.prio)392392- ret = apply_constraint(req, PM_QOS_UPDATE_REQ,393393- new_value);394394- } else {395395- /* Return if the device has been removed */396396- ret = -ENODEV;397397- }398398-292292+ ret = __dev_pm_qos_update_request(req, new_value);399293 mutex_unlock(&dev_pm_qos_mtx);294294+400295 return ret;401296}402297EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);···404315 * 0 if the aggregated constraint value has not changed,405316 * -EINVAL in case of wrong parameters, -ENODEV if the device has been406317 * removed from the system318318+ *319319+ * Callers should ensure that the target device is not RPM_SUSPENDED before320320+ * using this function for requests of type DEV_PM_QOS_FLAGS.407321 */408322int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)409323{···421329422330 mutex_lock(&dev_pm_qos_mtx);423331424424- if (req->dev->power.constraints) {332332+ if (req->dev->power.qos) {425333 ret = apply_constraint(req, PM_QOS_REMOVE_REQ,426334 PM_QOS_DEFAULT_VALUE);427335 memset(req, 0, sizeof(*req));···454362455363 mutex_lock(&dev_pm_qos_mtx);456364457457- if (!dev->power.constraints)365365+ if (!dev->power.qos)458366 ret = dev->power.power_state.event != PM_EVENT_INVALID ?459367 dev_pm_qos_constraints_allocate(dev) : -ENODEV;460368461369 if (!ret)462370 ret = blocking_notifier_chain_register(463463- dev->power.constraints->notifiers, notifier);371371+ dev->power.qos->latency.notifiers, notifier);464372465373 mutex_unlock(&dev_pm_qos_mtx);466374 return ret;···485393 mutex_lock(&dev_pm_qos_mtx);486394487395 /* Silently return if the constraints object is not present. */488488- if (dev->power.constraints)396396+ if (dev->power.qos)489397 retval = blocking_notifier_chain_unregister(490490- dev->power.constraints->notifiers,398398+ dev->power.qos->latency.notifiers,491399 notifier);492400493401 mutex_unlock(&dev_pm_qos_mtx);···541449 ancestor = ancestor->parent;542450543451 if (ancestor)544544- error = dev_pm_qos_add_request(ancestor, req, value);452452+ error = dev_pm_qos_add_request(ancestor, req,453453+ DEV_PM_QOS_LATENCY, value);545454546455 if (error)547456 req->dev = NULL;···552459EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);553460554461#ifdef CONFIG_PM_RUNTIME555555-static void __dev_pm_qos_drop_user_request(struct device *dev)462462+static void __dev_pm_qos_drop_user_request(struct device *dev,463463+ enum dev_pm_qos_req_type type)556464{557557- dev_pm_qos_remove_request(dev->power.pq_req);558558- dev->power.pq_req = NULL;465465+ switch(type) {466466+ case DEV_PM_QOS_LATENCY:467467+ dev_pm_qos_remove_request(dev->power.qos->latency_req);468468+ dev->power.qos->latency_req = NULL;469469+ break;470470+ case DEV_PM_QOS_FLAGS:471471+ dev_pm_qos_remove_request(dev->power.qos->flags_req);472472+ dev->power.qos->flags_req = NULL;473473+ break;474474+ }559475}560476561477/**···580478 if (!device_is_registered(dev) || value < 0)581479 return -EINVAL;582480583583- if (dev->power.pq_req)481481+ if (dev->power.qos && dev->power.qos->latency_req)584482 return -EEXIST;585483586484 req = kzalloc(sizeof(*req), GFP_KERNEL);587485 if (!req)588486 return -ENOMEM;589487590590- ret = dev_pm_qos_add_request(dev, req, value);488488+ ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value);591489 if (ret < 0)592490 return ret;593491594594- dev->power.pq_req = req;595595- ret = pm_qos_sysfs_add(dev);492492+ dev->power.qos->latency_req = req;493493+ ret = pm_qos_sysfs_add_latency(dev);596494 if (ret)597597- __dev_pm_qos_drop_user_request(dev);495495+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);598496599497 return ret;600498}···606504 */607505void dev_pm_qos_hide_latency_limit(struct device *dev)608506{609609- if (dev->power.pq_req) {610610- pm_qos_sysfs_remove(dev);611611- __dev_pm_qos_drop_user_request(dev);507507+ if (dev->power.qos && dev->power.qos->latency_req) {508508+ pm_qos_sysfs_remove_latency(dev);509509+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);612510 }613511}614512EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit);513513+514514+/**515515+ * dev_pm_qos_expose_flags - Expose PM QoS flags of a device to user space.516516+ * @dev: Device whose PM QoS flags are to be exposed to user space.517517+ * @val: Initial values of the flags.518518+ */519519+int dev_pm_qos_expose_flags(struct device *dev, s32 val)520520+{521521+ struct dev_pm_qos_request *req;522522+ int ret;523523+524524+ if (!device_is_registered(dev))525525+ return -EINVAL;526526+527527+ if (dev->power.qos && dev->power.qos->flags_req)528528+ return -EEXIST;529529+530530+ req = kzalloc(sizeof(*req), GFP_KERNEL);531531+ if (!req)532532+ return -ENOMEM;533533+534534+ pm_runtime_get_sync(dev);535535+ ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val);536536+ if (ret < 0)537537+ goto fail;538538+539539+ dev->power.qos->flags_req = req;540540+ ret = pm_qos_sysfs_add_flags(dev);541541+ if (ret)542542+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);543543+544544+fail:545545+ pm_runtime_put(dev);546546+ return ret;547547+}548548+EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags);549549+550550+/**551551+ * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space.552552+ * @dev: Device whose PM QoS flags are to be hidden from user space.553553+ */554554+void dev_pm_qos_hide_flags(struct device *dev)555555+{556556+ if (dev->power.qos && dev->power.qos->flags_req) {557557+ pm_qos_sysfs_remove_flags(dev);558558+ pm_runtime_get_sync(dev);559559+ __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);560560+ pm_runtime_put(dev);561561+ }562562+}563563+EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags);564564+565565+/**566566+ * dev_pm_qos_update_flags - Update PM QoS flags request owned by user space.567567+ * @dev: Device to update the PM QoS flags request for.568568+ * @mask: Flags to set/clear.569569+ * @set: Whether to set or clear the flags (true means set).570570+ */571571+int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set)572572+{573573+ s32 value;574574+ int ret;575575+576576+ if (!dev->power.qos || !dev->power.qos->flags_req)577577+ return -EINVAL;578578+579579+ pm_runtime_get_sync(dev);580580+ mutex_lock(&dev_pm_qos_mtx);581581+582582+ value = dev_pm_qos_requested_flags(dev);583583+ if (set)584584+ value |= mask;585585+ else586586+ value &= ~mask;587587+588588+ ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value);589589+590590+ mutex_unlock(&dev_pm_qos_mtx);591591+ pm_runtime_put(dev);592592+593593+ return ret;594594+}615595#endif /* CONFIG_PM_RUNTIME */
···213213}214214215215/**216216+ * pm_qos_flags_remove_req - Remove device PM QoS flags request.217217+ * @pqf: Device PM QoS flags set to remove the request from.218218+ * @req: Request to remove from the set.219219+ */220220+static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf,221221+ struct pm_qos_flags_request *req)222222+{223223+ s32 val = 0;224224+225225+ list_del(&req->node);226226+ list_for_each_entry(req, &pqf->list, node)227227+ val |= req->flags;228228+229229+ pqf->effective_flags = val;230230+}231231+232232+/**233233+ * pm_qos_update_flags - Update a set of PM QoS flags.234234+ * @pqf: Set of flags to update.235235+ * @req: Request to add to the set, to modify, or to remove from the set.236236+ * @action: Action to take on the set.237237+ * @val: Value of the request to add or modify.238238+ *239239+ * Update the given set of PM QoS flags and call notifiers if the aggregate240240+ * value has changed. Returns 1 if the aggregate constraint value has changed,241241+ * 0 otherwise.242242+ */243243+bool pm_qos_update_flags(struct pm_qos_flags *pqf,244244+ struct pm_qos_flags_request *req,245245+ enum pm_qos_req_action action, s32 val)246246+{247247+ unsigned long irqflags;248248+ s32 prev_value, curr_value;249249+250250+ spin_lock_irqsave(&pm_qos_lock, irqflags);251251+252252+ prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags;253253+254254+ switch (action) {255255+ case PM_QOS_REMOVE_REQ:256256+ pm_qos_flags_remove_req(pqf, req);257257+ break;258258+ case PM_QOS_UPDATE_REQ:259259+ pm_qos_flags_remove_req(pqf, req);260260+ case PM_QOS_ADD_REQ:261261+ req->flags = val;262262+ INIT_LIST_HEAD(&req->node);263263+ list_add_tail(&req->node, &pqf->list);264264+ pqf->effective_flags |= val;265265+ break;266266+ default:267267+ /* no action */268268+ ;269269+ }270270+271271+ curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags;272272+273273+ spin_unlock_irqrestore(&pm_qos_lock, irqflags);274274+275275+ return prev_value != curr_value;276276+}277277+278278+/**216279 * pm_qos_request - returns current system wide qos expectation217280 * @pm_qos_class: identification of which qos value is requested218281 *