aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-05-14 15:45:52 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-05-18 14:45:26 -0400
commitca1d72f033d4a89e60db25f680896c76c721062b (patch)
tree77a5d45a878b85ed3dad23f304b4e10fbfa66129 /drivers/base/power
parentb723b0eb91e08a0ee9a401c0b22c0d52966d9daa (diff)
PM / Domains: Make it possible to add devices to inactive domains
The generic PM domains core code currently requires domains to be in the "power on" state for adding devices to them, but this limitation turns out to be inconvenient in some situations, so remove it. For this purpose, make __pm_genpd_add_device() set the device's need_restore flag if the domain is in the "power off" state, so that the device's "restore state" (usually .runtime_resume()) callback is executed when it is resumed after the domain has been turned on. If the domain is in the "power on" state, the device's need_restore flag will be cleared by __pm_genpd_add_device(), so that its "save state" (usually .runtime_suspend()) callback is executed when the domain is about to be turned off. However, since that default behavior need not be always desirable, add a helper function pm_genpd_dev_need_restore() allowing a device's need_restore flag to be set/unset at any time. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base/power')
-rw-r--r--drivers/base/power/domain.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index c3eaa08a8f96..83aa694a8efe 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1263,11 +1263,6 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1263 1263
1264 genpd_acquire_lock(genpd); 1264 genpd_acquire_lock(genpd);
1265 1265
1266 if (genpd->status == GPD_STATE_POWER_OFF) {
1267 ret = -EINVAL;
1268 goto out;
1269 }
1270
1271 if (genpd->prepared_count > 0) { 1266 if (genpd->prepared_count > 0) {
1272 ret = -EAGAIN; 1267 ret = -EAGAIN;
1273 goto out; 1268 goto out;
@@ -1290,7 +1285,7 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1290 dev->power.subsys_data->domain_data = &gpd_data->base; 1285 dev->power.subsys_data->domain_data = &gpd_data->base;
1291 gpd_data->base.dev = dev; 1286 gpd_data->base.dev = dev;
1292 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); 1287 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
1293 gpd_data->need_restore = false; 1288 gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF;
1294 if (td) 1289 if (td)
1295 gpd_data->td = *td; 1290 gpd_data->td = *td;
1296 1291
@@ -1418,6 +1413,26 @@ void pm_genpd_dev_always_on(struct device *dev, bool val)
1418EXPORT_SYMBOL_GPL(pm_genpd_dev_always_on); 1413EXPORT_SYMBOL_GPL(pm_genpd_dev_always_on);
1419 1414
1420/** 1415/**
1416 * pm_genpd_dev_need_restore - Set/unset the device's "need restore" flag.
1417 * @dev: Device to set/unset the flag for.
1418 * @val: The new value of the device's "need restore" flag.
1419 */
1420void pm_genpd_dev_need_restore(struct device *dev, bool val)
1421{
1422 struct pm_subsys_data *psd;
1423 unsigned long flags;
1424
1425 spin_lock_irqsave(&dev->power.lock, flags);
1426
1427 psd = dev_to_psd(dev);
1428 if (psd && psd->domain_data)
1429 to_gpd_data(psd->domain_data)->need_restore = val;
1430
1431 spin_unlock_irqrestore(&dev->power.lock, flags);
1432}
1433EXPORT_SYMBOL_GPL(pm_genpd_dev_need_restore);
1434
1435/**
1421 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain. 1436 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1422 * @genpd: Master PM domain to add the subdomain to. 1437 * @genpd: Master PM domain to add the subdomain to.
1423 * @subdomain: Subdomain to be added. 1438 * @subdomain: Subdomain to be added.