diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2012-09-17 14:25:33 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-09-17 14:25:33 -0400 |
commit | 079d364b042afbe811c4bb0cb57fcbf4f1cfab6d (patch) | |
tree | e31d0b06bc05cfe5bdabb30c8249489226153860 /drivers/base | |
parent | 8592013bbd3858e9427ea2c5fb23a2c983b4dcaa (diff) | |
parent | b3d3b9fb6016e6eacd3ae49fb786806d00c43e7b (diff) |
Merge branch 'pm-domains'
* pm-domains:
PM / Domains: Fix compilation warning related to genpd_start_dev_no_timing()
PM / Domains: Operations related to cpuidle using domain names
PM / Domains: Document cpuidle-related functions and change their names
PM / Domains: Add power-on function using names to identify domains
PM / Domains: Make it possible to use names when adding subdomains
PM / Domains: Make it possible to use domain names when adding devices
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/domain.c | 126 |
1 files changed, 117 insertions, 9 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 5f4606f13be6..c22b869245d9 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -53,6 +53,24 @@ | |||
53 | static LIST_HEAD(gpd_list); | 53 | static LIST_HEAD(gpd_list); |
54 | static DEFINE_MUTEX(gpd_list_lock); | 54 | static DEFINE_MUTEX(gpd_list_lock); |
55 | 55 | ||
56 | static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name) | ||
57 | { | ||
58 | struct generic_pm_domain *genpd = NULL, *gpd; | ||
59 | |||
60 | if (IS_ERR_OR_NULL(domain_name)) | ||
61 | return NULL; | ||
62 | |||
63 | mutex_lock(&gpd_list_lock); | ||
64 | list_for_each_entry(gpd, &gpd_list, gpd_list_node) { | ||
65 | if (!strcmp(gpd->name, domain_name)) { | ||
66 | genpd = gpd; | ||
67 | break; | ||
68 | } | ||
69 | } | ||
70 | mutex_unlock(&gpd_list_lock); | ||
71 | return genpd; | ||
72 | } | ||
73 | |||
56 | #ifdef CONFIG_PM | 74 | #ifdef CONFIG_PM |
57 | 75 | ||
58 | struct generic_pm_domain *dev_to_genpd(struct device *dev) | 76 | struct generic_pm_domain *dev_to_genpd(struct device *dev) |
@@ -75,12 +93,6 @@ static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev) | |||
75 | start_latency_ns, "start"); | 93 | start_latency_ns, "start"); |
76 | } | 94 | } |
77 | 95 | ||
78 | static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd, | ||
79 | struct device *dev) | ||
80 | { | ||
81 | return GENPD_DEV_CALLBACK(genpd, int, start, dev); | ||
82 | } | ||
83 | |||
84 | static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) | 96 | static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) |
85 | { | 97 | { |
86 | bool ret = false; | 98 | bool ret = false; |
@@ -262,10 +274,28 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd) | |||
262 | return ret; | 274 | return ret; |
263 | } | 275 | } |
264 | 276 | ||
277 | /** | ||
278 | * pm_genpd_name_poweron - Restore power to a given PM domain and its masters. | ||
279 | * @domain_name: Name of the PM domain to power up. | ||
280 | */ | ||
281 | int pm_genpd_name_poweron(const char *domain_name) | ||
282 | { | ||
283 | struct generic_pm_domain *genpd; | ||
284 | |||
285 | genpd = pm_genpd_lookup_name(domain_name); | ||
286 | return genpd ? pm_genpd_poweron(genpd) : -EINVAL; | ||
287 | } | ||
288 | |||
265 | #endif /* CONFIG_PM */ | 289 | #endif /* CONFIG_PM */ |
266 | 290 | ||
267 | #ifdef CONFIG_PM_RUNTIME | 291 | #ifdef CONFIG_PM_RUNTIME |
268 | 292 | ||
293 | static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd, | ||
294 | struct device *dev) | ||
295 | { | ||
296 | return GENPD_DEV_CALLBACK(genpd, int, start, dev); | ||
297 | } | ||
298 | |||
269 | static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) | 299 | static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) |
270 | { | 300 | { |
271 | return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev, | 301 | return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev, |
@@ -1465,6 +1495,19 @@ int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev, | |||
1465 | return __pm_genpd_add_device(genpd, dev, td); | 1495 | return __pm_genpd_add_device(genpd, dev, td); |
1466 | } | 1496 | } |
1467 | 1497 | ||
1498 | |||
1499 | /** | ||
1500 | * __pm_genpd_name_add_device - Find I/O PM domain and add a device to it. | ||
1501 | * @domain_name: Name of the PM domain to add the device to. | ||
1502 | * @dev: Device to be added. | ||
1503 | * @td: Set of PM QoS timing parameters to attach to the device. | ||
1504 | */ | ||
1505 | int __pm_genpd_name_add_device(const char *domain_name, struct device *dev, | ||
1506 | struct gpd_timing_data *td) | ||
1507 | { | ||
1508 | return __pm_genpd_add_device(pm_genpd_lookup_name(domain_name), dev, td); | ||
1509 | } | ||
1510 | |||
1468 | /** | 1511 | /** |
1469 | * pm_genpd_remove_device - Remove a device from an I/O PM domain. | 1512 | * pm_genpd_remove_device - Remove a device from an I/O PM domain. |
1470 | * @genpd: PM domain to remove the device from. | 1513 | * @genpd: PM domain to remove the device from. |
@@ -1557,7 +1600,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, | |||
1557 | struct gpd_link *link; | 1600 | struct gpd_link *link; |
1558 | int ret = 0; | 1601 | int ret = 0; |
1559 | 1602 | ||
1560 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) | 1603 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain) |
1604 | || genpd == subdomain) | ||
1561 | return -EINVAL; | 1605 | return -EINVAL; |
1562 | 1606 | ||
1563 | start: | 1607 | start: |
@@ -1604,6 +1648,35 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, | |||
1604 | } | 1648 | } |
1605 | 1649 | ||
1606 | /** | 1650 | /** |
1651 | * pm_genpd_add_subdomain_names - Add a subdomain to an I/O PM domain. | ||
1652 | * @master_name: Name of the master PM domain to add the subdomain to. | ||
1653 | * @subdomain_name: Name of the subdomain to be added. | ||
1654 | */ | ||
1655 | int pm_genpd_add_subdomain_names(const char *master_name, | ||
1656 | const char *subdomain_name) | ||
1657 | { | ||
1658 | struct generic_pm_domain *master = NULL, *subdomain = NULL, *gpd; | ||
1659 | |||
1660 | if (IS_ERR_OR_NULL(master_name) || IS_ERR_OR_NULL(subdomain_name)) | ||
1661 | return -EINVAL; | ||
1662 | |||
1663 | mutex_lock(&gpd_list_lock); | ||
1664 | list_for_each_entry(gpd, &gpd_list, gpd_list_node) { | ||
1665 | if (!master && !strcmp(gpd->name, master_name)) | ||
1666 | master = gpd; | ||
1667 | |||
1668 | if (!subdomain && !strcmp(gpd->name, subdomain_name)) | ||
1669 | subdomain = gpd; | ||
1670 | |||
1671 | if (master && subdomain) | ||
1672 | break; | ||
1673 | } | ||
1674 | mutex_unlock(&gpd_list_lock); | ||
1675 | |||
1676 | return pm_genpd_add_subdomain(master, subdomain); | ||
1677 | } | ||
1678 | |||
1679 | /** | ||
1607 | * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. | 1680 | * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. |
1608 | * @genpd: Master PM domain to remove the subdomain from. | 1681 | * @genpd: Master PM domain to remove the subdomain from. |
1609 | * @subdomain: Subdomain to be removed. | 1682 | * @subdomain: Subdomain to be removed. |
@@ -1756,7 +1829,16 @@ int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td) | |||
1756 | } | 1829 | } |
1757 | EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks); | 1830 | EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks); |
1758 | 1831 | ||
1759 | int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) | 1832 | /** |
1833 | * pm_genpd_attach_cpuidle - Connect the given PM domain with cpuidle. | ||
1834 | * @genpd: PM domain to be connected with cpuidle. | ||
1835 | * @state: cpuidle state this domain can disable/enable. | ||
1836 | * | ||
1837 | * Make a PM domain behave as though it contained a CPU core, that is, instead | ||
1838 | * of calling its power down routine it will enable the given cpuidle state so | ||
1839 | * that the cpuidle subsystem can power it down (if possible and desirable). | ||
1840 | */ | ||
1841 | int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) | ||
1760 | { | 1842 | { |
1761 | struct cpuidle_driver *cpuidle_drv; | 1843 | struct cpuidle_driver *cpuidle_drv; |
1762 | struct gpd_cpu_data *cpu_data; | 1844 | struct gpd_cpu_data *cpu_data; |
@@ -1805,7 +1887,24 @@ int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) | |||
1805 | goto out; | 1887 | goto out; |
1806 | } | 1888 | } |
1807 | 1889 | ||
1808 | int genpd_detach_cpuidle(struct generic_pm_domain *genpd) | 1890 | /** |
1891 | * pm_genpd_name_attach_cpuidle - Find PM domain and connect cpuidle to it. | ||
1892 | * @name: Name of the domain to connect to cpuidle. | ||
1893 | * @state: cpuidle state this domain can manipulate. | ||
1894 | */ | ||
1895 | int pm_genpd_name_attach_cpuidle(const char *name, int state) | ||
1896 | { | ||
1897 | return pm_genpd_attach_cpuidle(pm_genpd_lookup_name(name), state); | ||
1898 | } | ||
1899 | |||
1900 | /** | ||
1901 | * pm_genpd_detach_cpuidle - Remove the cpuidle connection from a PM domain. | ||
1902 | * @genpd: PM domain to remove the cpuidle connection from. | ||
1903 | * | ||
1904 | * Remove the cpuidle connection set up by pm_genpd_attach_cpuidle() from the | ||
1905 | * given PM domain. | ||
1906 | */ | ||
1907 | int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd) | ||
1809 | { | 1908 | { |
1810 | struct gpd_cpu_data *cpu_data; | 1909 | struct gpd_cpu_data *cpu_data; |
1811 | struct cpuidle_state *idle_state; | 1910 | struct cpuidle_state *idle_state; |
@@ -1836,6 +1935,15 @@ int genpd_detach_cpuidle(struct generic_pm_domain *genpd) | |||
1836 | return ret; | 1935 | return ret; |
1837 | } | 1936 | } |
1838 | 1937 | ||
1938 | /** | ||
1939 | * pm_genpd_name_detach_cpuidle - Find PM domain and disconnect cpuidle from it. | ||
1940 | * @name: Name of the domain to disconnect cpuidle from. | ||
1941 | */ | ||
1942 | int pm_genpd_name_detach_cpuidle(const char *name) | ||
1943 | { | ||
1944 | return pm_genpd_detach_cpuidle(pm_genpd_lookup_name(name)); | ||
1945 | } | ||
1946 | |||
1839 | /* Default device callbacks for generic PM domains. */ | 1947 | /* Default device callbacks for generic PM domains. */ |
1840 | 1948 | ||
1841 | /** | 1949 | /** |