diff options
Diffstat (limited to 'drivers/base/power/domain.c')
| -rw-r--r-- | drivers/base/power/domain.c | 97 |
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 | /** | 1063 | static 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 | */ | ||
| 1069 | int __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 | */ | ||
| 1111 | int __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 | } | ||
| 1110 | EXPORT_SYMBOL_GPL(__pm_genpd_add_device); | 1122 | EXPORT_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 | } |
| 1161 | EXPORT_SYMBOL_GPL(pm_genpd_remove_device); | 1173 | EXPORT_SYMBOL_GPL(pm_genpd_remove_device); |
| 1162 | 1174 | ||
| 1163 | /** | 1175 | static 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 | */ | ||
| 1168 | int 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 | */ | ||
| 1225 | int 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 | } | ||
| 1212 | EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain); | 1236 | EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain); |
| 1213 | 1237 | ||
| 1214 | /** | 1238 | /** |
| @@ -1571,12 +1595,22 @@ static struct generic_pm_domain *genpd_get_from_provider( | |||
| 1571 | int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev) | 1595 | int 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); | 1610 | out: |
| 1611 | mutex_unlock(&gpd_list_lock); | ||
| 1612 | |||
| 1613 | return ret; | ||
| 1580 | } | 1614 | } |
| 1581 | EXPORT_SYMBOL_GPL(of_genpd_add_device); | 1615 | EXPORT_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); | 1648 | out: |
| 1649 | mutex_unlock(&gpd_list_lock); | ||
| 1650 | |||
| 1651 | return ret; | ||
| 1606 | } | 1652 | } |
| 1607 | EXPORT_SYMBOL_GPL(of_genpd_add_subdomain); | 1653 | EXPORT_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", |
