Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 360899
b: refs/heads/master
c: b81ea1b
h: refs/heads/master
i:
  360897: 5b912c3
  360895: 067f9b2
v: v3
  • Loading branch information
Rafael J. Wysocki committed Mar 4, 2013
1 parent de0d43c commit 8008dad
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f5f43dcfff3a3c7f7de4a0cfca0106a0ccd58bd7
refs/heads/master: b81ea1b5ac4d3c6a628158b736dd4a98c46c29d9
129 changes: 87 additions & 42 deletions trunk/drivers/base/power/qos.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,13 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
s32 curr_value;
int ret = 0;

if (!req) /*guard against callers passing in null */
return -EINVAL;

if (WARN(!dev_pm_qos_request_active(req),
"%s() called for unknown object\n", __func__))
return -EINVAL;

if (!req->dev->power.qos)
return -ENODEV;

Expand Down Expand Up @@ -386,20 +393,33 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value)
{
int ret;

mutex_lock(&dev_pm_qos_mtx);
ret = __dev_pm_qos_update_request(req, new_value);
mutex_unlock(&dev_pm_qos_mtx);
return ret;
}
EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);

static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
{
int ret = 0;

if (!req) /*guard against callers passing in null */
return -EINVAL;

if (WARN(!dev_pm_qos_request_active(req),
"%s() called for unknown object\n", __func__))
return -EINVAL;

mutex_lock(&dev_pm_qos_mtx);
ret = __dev_pm_qos_update_request(req, new_value);
mutex_unlock(&dev_pm_qos_mtx);

if (req->dev->power.qos) {
ret = apply_constraint(req, PM_QOS_REMOVE_REQ,
PM_QOS_DEFAULT_VALUE);
memset(req, 0, sizeof(*req));
} else {
ret = -ENODEV;
}
return ret;
}
EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);

/**
* dev_pm_qos_remove_request - modifies an existing qos request
Expand All @@ -418,26 +438,10 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
*/
int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
{
int ret = 0;

if (!req) /*guard against callers passing in null */
return -EINVAL;

if (WARN(!dev_pm_qos_request_active(req),
"%s() called for unknown object\n", __func__))
return -EINVAL;
int ret;

mutex_lock(&dev_pm_qos_mtx);

if (req->dev->power.qos) {
ret = apply_constraint(req, PM_QOS_REMOVE_REQ,
PM_QOS_DEFAULT_VALUE);
memset(req, 0, sizeof(*req));
} else {
/* Return if the device has been removed */
ret = -ENODEV;
}

ret = __dev_pm_qos_remove_request(req);
mutex_unlock(&dev_pm_qos_mtx);
return ret;
}
Expand Down Expand Up @@ -563,16 +567,20 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);
static void __dev_pm_qos_drop_user_request(struct device *dev,
enum dev_pm_qos_req_type type)
{
struct dev_pm_qos_request *req = NULL;

switch(type) {
case DEV_PM_QOS_LATENCY:
dev_pm_qos_remove_request(dev->power.qos->latency_req);
req = dev->power.qos->latency_req;
dev->power.qos->latency_req = NULL;
break;
case DEV_PM_QOS_FLAGS:
dev_pm_qos_remove_request(dev->power.qos->flags_req);
req = dev->power.qos->flags_req;
dev->power.qos->flags_req = NULL;
break;
}
__dev_pm_qos_remove_request(req);
kfree(req);
}

/**
Expand All @@ -588,22 +596,36 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
if (!device_is_registered(dev) || value < 0)
return -EINVAL;

if (dev->power.qos && dev->power.qos->latency_req)
return -EEXIST;

req = kzalloc(sizeof(*req), GFP_KERNEL);
if (!req)
return -ENOMEM;

ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value);
if (ret < 0)
if (ret < 0) {
kfree(req);
return ret;
}

mutex_lock(&dev_pm_qos_mtx);

if (!dev->power.qos)
ret = -ENODEV;
else if (dev->power.qos->latency_req)
ret = -EEXIST;

if (ret < 0) {
__dev_pm_qos_remove_request(req);
kfree(req);
goto out;
}

dev->power.qos->latency_req = req;
ret = pm_qos_sysfs_add_latency(dev);
if (ret)
__dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);

out:
mutex_unlock(&dev_pm_qos_mtx);
return ret;
}
EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit);
Expand All @@ -614,10 +636,14 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit);
*/
void dev_pm_qos_hide_latency_limit(struct device *dev)
{
mutex_lock(&dev_pm_qos_mtx);

if (dev->power.qos && dev->power.qos->latency_req) {
pm_qos_sysfs_remove_latency(dev);
__dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
}

mutex_unlock(&dev_pm_qos_mtx);
}
EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit);

Expand All @@ -634,24 +660,37 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val)
if (!device_is_registered(dev))
return -EINVAL;

if (dev->power.qos && dev->power.qos->flags_req)
return -EEXIST;

req = kzalloc(sizeof(*req), GFP_KERNEL);
if (!req)
return -ENOMEM;

pm_runtime_get_sync(dev);
ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val);
if (ret < 0)
goto fail;
if (ret < 0) {
kfree(req);
return ret;
}

pm_runtime_get_sync(dev);
mutex_lock(&dev_pm_qos_mtx);

if (!dev->power.qos)
ret = -ENODEV;
else if (dev->power.qos->flags_req)
ret = -EEXIST;

if (ret < 0) {
__dev_pm_qos_remove_request(req);
kfree(req);
goto out;
}

dev->power.qos->flags_req = req;
ret = pm_qos_sysfs_add_flags(dev);
if (ret)
__dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);

fail:
out:
mutex_unlock(&dev_pm_qos_mtx);
pm_runtime_put(dev);
return ret;
}
Expand All @@ -663,12 +702,16 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags);
*/
void dev_pm_qos_hide_flags(struct device *dev)
{
pm_runtime_get_sync(dev);
mutex_lock(&dev_pm_qos_mtx);

if (dev->power.qos && dev->power.qos->flags_req) {
pm_qos_sysfs_remove_flags(dev);
pm_runtime_get_sync(dev);
__dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
pm_runtime_put(dev);
}

mutex_unlock(&dev_pm_qos_mtx);
pm_runtime_put(dev);
}
EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags);

Expand All @@ -683,12 +726,14 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set)
s32 value;
int ret;

if (!dev->power.qos || !dev->power.qos->flags_req)
return -EINVAL;

pm_runtime_get_sync(dev);
mutex_lock(&dev_pm_qos_mtx);

if (!dev->power.qos || !dev->power.qos->flags_req) {
ret = -EINVAL;
goto out;
}

value = dev_pm_qos_requested_flags(dev);
if (set)
value |= mask;
Expand All @@ -697,9 +742,9 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set)

ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value);

out:
mutex_unlock(&dev_pm_qos_mtx);
pm_runtime_put(dev);

return ret;
}
#endif /* CONFIG_PM_RUNTIME */

0 comments on commit 8008dad

Please sign in to comment.