aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-09-17 14:25:33 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-09-17 14:25:33 -0400
commit079d364b042afbe811c4bb0cb57fcbf4f1cfab6d (patch)
treee31d0b06bc05cfe5bdabb30c8249489226153860
parent8592013bbd3858e9427ea2c5fb23a2c983b4dcaa (diff)
parentb3d3b9fb6016e6eacd3ae49fb786806d00c43e7b (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
-rw-r--r--drivers/base/power/domain.c126
-rw-r--r--include/linux/pm_domain.h73
2 files changed, 173 insertions, 26 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 @@
53static LIST_HEAD(gpd_list); 53static LIST_HEAD(gpd_list);
54static DEFINE_MUTEX(gpd_list_lock); 54static DEFINE_MUTEX(gpd_list_lock);
55 55
56static 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
58struct generic_pm_domain *dev_to_genpd(struct device *dev) 76struct 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
78static 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
84static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) 96static 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 */
281int 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
293static 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
269static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) 299static 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 */
1505int __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 */
1655int 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}
1757EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks); 1830EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
1758 1831
1759int 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 */
1841int 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
1808int 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 */
1895int 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 */
1907int 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 */
1942int 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/**
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 08adf8e5a80e..7c1d252b20c0 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -138,35 +138,32 @@ extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
138 struct device *dev, 138 struct device *dev,
139 struct gpd_timing_data *td); 139 struct gpd_timing_data *td);
140 140
141static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, 141extern int __pm_genpd_name_add_device(const char *domain_name,
142 struct device *dev) 142 struct device *dev,
143{ 143 struct gpd_timing_data *td);
144 return __pm_genpd_add_device(genpd, dev, NULL);
145}
146
147static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
148 struct device *dev)
149{
150 return __pm_genpd_of_add_device(genpd_node, dev, NULL);
151}
152 144
153extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, 145extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
154 struct device *dev); 146 struct device *dev);
155extern void pm_genpd_dev_need_restore(struct device *dev, bool val); 147extern void pm_genpd_dev_need_restore(struct device *dev, bool val);
156extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, 148extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
157 struct generic_pm_domain *new_subdomain); 149 struct generic_pm_domain *new_subdomain);
150extern int pm_genpd_add_subdomain_names(const char *master_name,
151 const char *subdomain_name);
158extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, 152extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
159 struct generic_pm_domain *target); 153 struct generic_pm_domain *target);
160extern int pm_genpd_add_callbacks(struct device *dev, 154extern int pm_genpd_add_callbacks(struct device *dev,
161 struct gpd_dev_ops *ops, 155 struct gpd_dev_ops *ops,
162 struct gpd_timing_data *td); 156 struct gpd_timing_data *td);
163extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td); 157extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);
164extern int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state); 158extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state);
165extern int genpd_detach_cpuidle(struct generic_pm_domain *genpd); 159extern int pm_genpd_name_attach_cpuidle(const char *name, int state);
160extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd);
161extern int pm_genpd_name_detach_cpuidle(const char *name);
166extern void pm_genpd_init(struct generic_pm_domain *genpd, 162extern void pm_genpd_init(struct generic_pm_domain *genpd,
167 struct dev_power_governor *gov, bool is_off); 163 struct dev_power_governor *gov, bool is_off);
168 164
169extern int pm_genpd_poweron(struct generic_pm_domain *genpd); 165extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
166extern int pm_genpd_name_poweron(const char *domain_name);
170 167
171extern bool default_stop_ok(struct device *dev); 168extern bool default_stop_ok(struct device *dev);
172 169
@@ -187,8 +184,15 @@ static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
187{ 184{
188 return -ENOSYS; 185 return -ENOSYS;
189} 186}
190static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, 187static inline int __pm_genpd_of_add_device(struct device_node *genpd_node,
191 struct device *dev) 188 struct device *dev,
189 struct gpd_timing_data *td)
190{
191 return -ENOSYS;
192}
193static inline int __pm_genpd_name_add_device(const char *domain_name,
194 struct device *dev,
195 struct gpd_timing_data *td)
192{ 196{
193 return -ENOSYS; 197 return -ENOSYS;
194} 198}
@@ -203,6 +207,11 @@ static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
203{ 207{
204 return -ENOSYS; 208 return -ENOSYS;
205} 209}
210static inline int pm_genpd_add_subdomain_names(const char *master_name,
211 const char *subdomain_name)
212{
213 return -ENOSYS;
214}
206static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, 215static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
207 struct generic_pm_domain *target) 216 struct generic_pm_domain *target)
208{ 217{
@@ -218,11 +227,19 @@ static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
218{ 227{
219 return -ENOSYS; 228 return -ENOSYS;
220} 229}
221static inline int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st) 230static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st)
231{
232 return -ENOSYS;
233}
234static inline int pm_genpd_name_attach_cpuidle(const char *name, int state)
222{ 235{
223 return -ENOSYS; 236 return -ENOSYS;
224} 237}
225static inline int genpd_detach_cpuidle(struct generic_pm_domain *genpd) 238static inline int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
239{
240 return -ENOSYS;
241}
242static inline int pm_genpd_name_detach_cpuidle(const char *name)
226{ 243{
227 return -ENOSYS; 244 return -ENOSYS;
228} 245}
@@ -234,6 +251,10 @@ static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)
234{ 251{
235 return -ENOSYS; 252 return -ENOSYS;
236} 253}
254static inline int pm_genpd_name_poweron(const char *domain_name)
255{
256 return -ENOSYS;
257}
237static inline bool default_stop_ok(struct device *dev) 258static inline bool default_stop_ok(struct device *dev)
238{ 259{
239 return false; 260 return false;
@@ -242,6 +263,24 @@ static inline bool default_stop_ok(struct device *dev)
242#define pm_domain_always_on_gov NULL 263#define pm_domain_always_on_gov NULL
243#endif 264#endif
244 265
266static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
267 struct device *dev)
268{
269 return __pm_genpd_add_device(genpd, dev, NULL);
270}
271
272static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
273 struct device *dev)
274{
275 return __pm_genpd_of_add_device(genpd_node, dev, NULL);
276}
277
278static inline int pm_genpd_name_add_device(const char *domain_name,
279 struct device *dev)
280{
281 return __pm_genpd_name_add_device(domain_name, dev, NULL);
282}
283
245static inline int pm_genpd_remove_callbacks(struct device *dev) 284static inline int pm_genpd_remove_callbacks(struct device *dev)
246{ 285{
247 return __pm_genpd_remove_callbacks(dev, true); 286 return __pm_genpd_remove_callbacks(dev, true);