aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/power/domain.c')
-rw-r--r--drivers/base/power/domain.c97
1 files changed, 73 insertions, 24 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index fc9f11c26eec..1bd8d412db06 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1060,14 +1060,8 @@ static void genpd_free_dev_data(struct device *dev,
1060 dev_pm_put_subsys_data(dev); 1060 dev_pm_put_subsys_data(dev);
1061} 1061}
1062 1062
1063/** 1063static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1064 * __pm_genpd_add_device - Add a device to an I/O PM domain. 1064 struct gpd_timing_data *td)
1065 * @genpd: PM domain to add the device to.
1066 * @dev: Device to be added.
1067 * @td: Set of PM QoS timing parameters to attach to the device.
1068 */
1069int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1070 struct gpd_timing_data *td)
1071{ 1065{
1072 struct generic_pm_domain_data *gpd_data; 1066 struct generic_pm_domain_data *gpd_data;
1073 int ret = 0; 1067 int ret = 0;
@@ -1107,6 +1101,24 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1107 1101
1108 return ret; 1102 return ret;
1109} 1103}
1104
1105/**
1106 * __pm_genpd_add_device - Add a device to an I/O PM domain.
1107 * @genpd: PM domain to add the device to.
1108 * @dev: Device to be added.
1109 * @td: Set of PM QoS timing parameters to attach to the device.
1110 */
1111int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1112 struct gpd_timing_data *td)
1113{
1114 int ret;
1115
1116 mutex_lock(&gpd_list_lock);
1117 ret = genpd_add_device(genpd, dev, td);
1118 mutex_unlock(&gpd_list_lock);
1119
1120 return ret;
1121}
1110EXPORT_SYMBOL_GPL(__pm_genpd_add_device); 1122EXPORT_SYMBOL_GPL(__pm_genpd_add_device);
1111 1123
1112/** 1124/**
@@ -1160,13 +1172,8 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1160} 1172}
1161EXPORT_SYMBOL_GPL(pm_genpd_remove_device); 1173EXPORT_SYMBOL_GPL(pm_genpd_remove_device);
1162 1174
1163/** 1175static int genpd_add_subdomain(struct generic_pm_domain *genpd,
1164 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain. 1176 struct generic_pm_domain *subdomain)
1165 * @genpd: Master PM domain to add the subdomain to.
1166 * @subdomain: Subdomain to be added.
1167 */
1168int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
1169 struct generic_pm_domain *subdomain)
1170{ 1177{
1171 struct gpd_link *link, *itr; 1178 struct gpd_link *link, *itr;
1172 int ret = 0; 1179 int ret = 0;
@@ -1209,6 +1216,23 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
1209 kfree(link); 1216 kfree(link);
1210 return ret; 1217 return ret;
1211} 1218}
1219
1220/**
1221 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1222 * @genpd: Master PM domain to add the subdomain to.
1223 * @subdomain: Subdomain to be added.
1224 */
1225int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
1226 struct generic_pm_domain *subdomain)
1227{
1228 int ret;
1229
1230 mutex_lock(&gpd_list_lock);
1231 ret = genpd_add_subdomain(genpd, subdomain);
1232 mutex_unlock(&gpd_list_lock);
1233
1234 return ret;
1235}
1212EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain); 1236EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain);
1213 1237
1214/** 1238/**
@@ -1571,12 +1595,22 @@ static struct generic_pm_domain *genpd_get_from_provider(
1571int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev) 1595int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev)
1572{ 1596{
1573 struct generic_pm_domain *genpd; 1597 struct generic_pm_domain *genpd;
1598 int ret;
1599
1600 mutex_lock(&gpd_list_lock);
1574 1601
1575 genpd = genpd_get_from_provider(genpdspec); 1602 genpd = genpd_get_from_provider(genpdspec);
1576 if (IS_ERR(genpd)) 1603 if (IS_ERR(genpd)) {
1577 return PTR_ERR(genpd); 1604 ret = PTR_ERR(genpd);
1605 goto out;
1606 }
1607
1608 ret = genpd_add_device(genpd, dev, NULL);
1578 1609
1579 return pm_genpd_add_device(genpd, dev); 1610out:
1611 mutex_unlock(&gpd_list_lock);
1612
1613 return ret;
1580} 1614}
1581EXPORT_SYMBOL_GPL(of_genpd_add_device); 1615EXPORT_SYMBOL_GPL(of_genpd_add_device);
1582 1616
@@ -1593,16 +1627,28 @@ int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
1593 struct of_phandle_args *subdomain_spec) 1627 struct of_phandle_args *subdomain_spec)
1594{ 1628{
1595 struct generic_pm_domain *parent, *subdomain; 1629 struct generic_pm_domain *parent, *subdomain;
1630 int ret;
1631
1632 mutex_lock(&gpd_list_lock);
1596 1633
1597 parent = genpd_get_from_provider(parent_spec); 1634 parent = genpd_get_from_provider(parent_spec);
1598 if (IS_ERR(parent)) 1635 if (IS_ERR(parent)) {
1599 return PTR_ERR(parent); 1636 ret = PTR_ERR(parent);
1637 goto out;
1638 }
1600 1639
1601 subdomain = genpd_get_from_provider(subdomain_spec); 1640 subdomain = genpd_get_from_provider(subdomain_spec);
1602 if (IS_ERR(subdomain)) 1641 if (IS_ERR(subdomain)) {
1603 return PTR_ERR(subdomain); 1642 ret = PTR_ERR(subdomain);
1643 goto out;
1644 }
1645
1646 ret = genpd_add_subdomain(parent, subdomain);
1604 1647
1605 return pm_genpd_add_subdomain(parent, subdomain); 1648out:
1649 mutex_unlock(&gpd_list_lock);
1650
1651 return ret;
1606} 1652}
1607EXPORT_SYMBOL_GPL(of_genpd_add_subdomain); 1653EXPORT_SYMBOL_GPL(of_genpd_add_subdomain);
1608 1654
@@ -1701,9 +1747,11 @@ int genpd_dev_pm_attach(struct device *dev)
1701 return -ENOENT; 1747 return -ENOENT;
1702 } 1748 }
1703 1749
1750 mutex_lock(&gpd_list_lock);
1704 pd = genpd_get_from_provider(&pd_args); 1751 pd = genpd_get_from_provider(&pd_args);
1705 of_node_put(pd_args.np); 1752 of_node_put(pd_args.np);
1706 if (IS_ERR(pd)) { 1753 if (IS_ERR(pd)) {
1754 mutex_unlock(&gpd_list_lock);
1707 dev_dbg(dev, "%s() failed to find PM domain: %ld\n", 1755 dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
1708 __func__, PTR_ERR(pd)); 1756 __func__, PTR_ERR(pd));
1709 return -EPROBE_DEFER; 1757 return -EPROBE_DEFER;
@@ -1712,13 +1760,14 @@ int genpd_dev_pm_attach(struct device *dev)
1712 dev_dbg(dev, "adding to PM domain %s\n", pd->name); 1760 dev_dbg(dev, "adding to PM domain %s\n", pd->name);
1713 1761
1714 for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) { 1762 for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) {
1715 ret = pm_genpd_add_device(pd, dev); 1763 ret = genpd_add_device(pd, dev, NULL);
1716 if (ret != -EAGAIN) 1764 if (ret != -EAGAIN)
1717 break; 1765 break;
1718 1766
1719 mdelay(i); 1767 mdelay(i);
1720 cond_resched(); 1768 cond_resched();
1721 } 1769 }
1770 mutex_unlock(&gpd_list_lock);
1722 1771
1723 if (ret < 0) { 1772 if (ret < 0) {
1724 dev_err(dev, "failed to add to PM domain %s: %d", 1773 dev_err(dev, "failed to add to PM domain %s: %d",