aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2015-01-27 15:13:44 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-02-03 16:56:54 -0500
commitf104e1e5ef5788f02de2053bfbd0f02d629b6036 (patch)
treef336adc77a74f738525b3693dcf5bb6fbd08423e
parent3e235685de3f7e53e17d671b2379df10c6dfa4f2 (diff)
PM / Domains: Re-order initialization of generic_pm_domain_data
Move the initialization of the struct generic_pm_domain_data into genpd_alloc_dev_data(), including the assignment of the device's ->pm_domain() callback. Make corresponding changes to genpd_free_dev_data(). These changes will make the related code more readable. It will also decrease the critical regions for where genpd's mutex is being held and for where the device's power related spinlock is being held. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/power/domain.c67
1 files changed, 35 insertions, 32 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 3bd342f22519..0fd5ee127c30 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1377,7 +1377,9 @@ EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
1377 1377
1378#endif /* CONFIG_PM_SLEEP */ 1378#endif /* CONFIG_PM_SLEEP */
1379 1379
1380static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev) 1380static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
1381 struct generic_pm_domain *genpd,
1382 struct gpd_timing_data *td)
1381{ 1383{
1382 struct generic_pm_domain_data *gpd_data; 1384 struct generic_pm_domain_data *gpd_data;
1383 int ret; 1385 int ret;
@@ -1392,8 +1394,32 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)
1392 goto err_put; 1394 goto err_put;
1393 } 1395 }
1394 1396
1397 if (td)
1398 gpd_data->td = *td;
1399
1400 gpd_data->base.dev = dev;
1401 gpd_data->need_restore = -1;
1402 gpd_data->td.constraint_changed = true;
1403 gpd_data->td.effective_constraint_ns = -1;
1404 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
1405
1406 spin_lock_irq(&dev->power.lock);
1407
1408 if (dev->power.subsys_data->domain_data) {
1409 ret = -EINVAL;
1410 goto err_free;
1411 }
1412
1413 dev->power.subsys_data->domain_data = &gpd_data->base;
1414 dev->pm_domain = &genpd->domain;
1415
1416 spin_unlock_irq(&dev->power.lock);
1417
1395 return gpd_data; 1418 return gpd_data;
1396 1419
1420 err_free:
1421 spin_unlock_irq(&dev->power.lock);
1422 kfree(gpd_data);
1397 err_put: 1423 err_put:
1398 dev_pm_put_subsys_data(dev); 1424 dev_pm_put_subsys_data(dev);
1399 return ERR_PTR(ret); 1425 return ERR_PTR(ret);
@@ -1402,6 +1428,13 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)
1402static void genpd_free_dev_data(struct device *dev, 1428static void genpd_free_dev_data(struct device *dev,
1403 struct generic_pm_domain_data *gpd_data) 1429 struct generic_pm_domain_data *gpd_data)
1404{ 1430{
1431 spin_lock_irq(&dev->power.lock);
1432
1433 dev->pm_domain = NULL;
1434 dev->power.subsys_data->domain_data = NULL;
1435
1436 spin_unlock_irq(&dev->power.lock);
1437
1405 kfree(gpd_data); 1438 kfree(gpd_data);
1406 dev_pm_put_subsys_data(dev); 1439 dev_pm_put_subsys_data(dev);
1407} 1440}
@@ -1423,7 +1456,7 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1423 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) 1456 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1424 return -EINVAL; 1457 return -EINVAL;
1425 1458
1426 gpd_data = genpd_alloc_dev_data(dev); 1459 gpd_data = genpd_alloc_dev_data(dev, genpd, td);
1427 if (IS_ERR(gpd_data)) 1460 if (IS_ERR(gpd_data))
1428 return PTR_ERR(gpd_data); 1461 return PTR_ERR(gpd_data);
1429 1462
@@ -1434,35 +1467,13 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1434 goto out; 1467 goto out;
1435 } 1468 }
1436 1469
1437 spin_lock_irq(&dev->power.lock);
1438
1439 if (dev->power.subsys_data->domain_data) {
1440 spin_unlock_irq(&dev->power.lock);
1441 ret = -EINVAL;
1442 goto out;
1443 }
1444
1445 dev->power.subsys_data->domain_data = &gpd_data->base;
1446
1447 if (td)
1448 gpd_data->td = *td;
1449
1450 dev->pm_domain = &genpd->domain;
1451
1452 spin_unlock_irq(&dev->power.lock);
1453
1454 if (genpd->attach_dev) 1470 if (genpd->attach_dev)
1455 genpd->attach_dev(genpd, dev); 1471 genpd->attach_dev(genpd, dev);
1456 1472
1457 genpd->device_count++; 1473 genpd->device_count++;
1458 genpd->max_off_time_changed = true; 1474 genpd->max_off_time_changed = true;
1459 1475
1460 gpd_data->base.dev = dev;
1461 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); 1476 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
1462 gpd_data->need_restore = -1;
1463 gpd_data->td.constraint_changed = true;
1464 gpd_data->td.effective_constraint_ns = -1;
1465 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
1466 1477
1467 out: 1478 out:
1468 genpd_release_lock(genpd); 1479 genpd_release_lock(genpd);
@@ -1524,15 +1535,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1524 if (genpd->detach_dev) 1535 if (genpd->detach_dev)
1525 genpd->detach_dev(genpd, dev); 1536 genpd->detach_dev(genpd, dev);
1526 1537
1527 spin_lock_irq(&dev->power.lock);
1528
1529 dev->pm_domain = NULL;
1530 list_del_init(&pdd->list_node); 1538 list_del_init(&pdd->list_node);
1531 dev->power.subsys_data->domain_data = NULL;
1532
1533 spin_unlock_irq(&dev->power.lock);
1534
1535 pdd->dev = NULL;
1536 1539
1537 genpd_release_lock(genpd); 1540 genpd_release_lock(genpd);
1538 1541