aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/power/clock_ops.c150
-rw-r--r--drivers/base/power/domain.c147
-rw-r--r--drivers/base/power/domain_governor.c11
-rw-r--r--drivers/base/power/power.h56
-rw-r--r--drivers/base/power/qos.c5
-rw-r--r--drivers/base/power/runtime.c76
-rw-r--r--drivers/base/power/sysfs.c19
-rw-r--r--drivers/base/property.c431
9 files changed, 616 insertions, 281 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 6922cd6850a2..53c3fe1aeb29 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -4,7 +4,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \
4 driver.o class.o platform.o \ 4 driver.o class.o platform.o \
5 cpu.o firmware.o init.o map.o devres.o \ 5 cpu.o firmware.o init.o map.o devres.o \
6 attribute_container.o transport_class.o \ 6 attribute_container.o transport_class.o \
7 topology.o container.o 7 topology.o container.o property.o
8obj-$(CONFIG_DEVTMPFS) += devtmpfs.o 8obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
9obj-$(CONFIG_DMA_CMA) += dma-contiguous.o 9obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
10obj-y += power/ 10obj-y += power/
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c
index 78369305e069..d626576a4f75 100644
--- a/drivers/base/power/clock_ops.c
+++ b/drivers/base/power/clock_ops.c
@@ -12,6 +12,7 @@
12#include <linux/pm.h> 12#include <linux/pm.h>
13#include <linux/pm_clock.h> 13#include <linux/pm_clock.h>
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/clkdev.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/err.h> 17#include <linux/err.h>
17 18
@@ -34,14 +35,20 @@ struct pm_clock_entry {
34/** 35/**
35 * pm_clk_enable - Enable a clock, reporting any errors 36 * pm_clk_enable - Enable a clock, reporting any errors
36 * @dev: The device for the given clock 37 * @dev: The device for the given clock
37 * @clk: The clock being enabled. 38 * @ce: PM clock entry corresponding to the clock.
38 */ 39 */
39static inline int __pm_clk_enable(struct device *dev, struct clk *clk) 40static inline int __pm_clk_enable(struct device *dev, struct pm_clock_entry *ce)
40{ 41{
41 int ret = clk_enable(clk); 42 int ret;
42 if (ret) 43
43 dev_err(dev, "%s: failed to enable clk %p, error %d\n", 44 if (ce->status < PCE_STATUS_ERROR) {
44 __func__, clk, ret); 45 ret = clk_enable(ce->clk);
46 if (!ret)
47 ce->status = PCE_STATUS_ENABLED;
48 else
49 dev_err(dev, "%s: failed to enable clk %p, error %d\n",
50 __func__, ce->clk, ret);
51 }
45 52
46 return ret; 53 return ret;
47} 54}
@@ -53,7 +60,8 @@ static inline int __pm_clk_enable(struct device *dev, struct clk *clk)
53 */ 60 */
54static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) 61static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
55{ 62{
56 ce->clk = clk_get(dev, ce->con_id); 63 if (!ce->clk)
64 ce->clk = clk_get(dev, ce->con_id);
57 if (IS_ERR(ce->clk)) { 65 if (IS_ERR(ce->clk)) {
58 ce->status = PCE_STATUS_ERROR; 66 ce->status = PCE_STATUS_ERROR;
59 } else { 67 } else {
@@ -63,15 +71,8 @@ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
63 } 71 }
64} 72}
65 73
66/** 74static int __pm_clk_add(struct device *dev, const char *con_id,
67 * pm_clk_add - Start using a device clock for power management. 75 struct clk *clk)
68 * @dev: Device whose clock is going to be used for power management.
69 * @con_id: Connection ID of the clock.
70 *
71 * Add the clock represented by @con_id to the list of clocks used for
72 * the power management of @dev.
73 */
74int pm_clk_add(struct device *dev, const char *con_id)
75{ 76{
76 struct pm_subsys_data *psd = dev_to_psd(dev); 77 struct pm_subsys_data *psd = dev_to_psd(dev);
77 struct pm_clock_entry *ce; 78 struct pm_clock_entry *ce;
@@ -93,6 +94,12 @@ int pm_clk_add(struct device *dev, const char *con_id)
93 kfree(ce); 94 kfree(ce);
94 return -ENOMEM; 95 return -ENOMEM;
95 } 96 }
97 } else {
98 if (IS_ERR(ce->clk) || !__clk_get(clk)) {
99 kfree(ce);
100 return -ENOENT;
101 }
102 ce->clk = clk;
96 } 103 }
97 104
98 pm_clk_acquire(dev, ce); 105 pm_clk_acquire(dev, ce);
@@ -104,6 +111,32 @@ int pm_clk_add(struct device *dev, const char *con_id)
104} 111}
105 112
106/** 113/**
114 * pm_clk_add - Start using a device clock for power management.
115 * @dev: Device whose clock is going to be used for power management.
116 * @con_id: Connection ID of the clock.
117 *
118 * Add the clock represented by @con_id to the list of clocks used for
119 * the power management of @dev.
120 */
121int pm_clk_add(struct device *dev, const char *con_id)
122{
123 return __pm_clk_add(dev, con_id, NULL);
124}
125
126/**
127 * pm_clk_add_clk - Start using a device clock for power management.
128 * @dev: Device whose clock is going to be used for power management.
129 * @clk: Clock pointer
130 *
131 * Add the clock to the list of clocks used for the power management of @dev.
132 * It will increment refcount on clock pointer, use clk_put() on it when done.
133 */
134int pm_clk_add_clk(struct device *dev, struct clk *clk)
135{
136 return __pm_clk_add(dev, NULL, clk);
137}
138
139/**
107 * __pm_clk_remove - Destroy PM clock entry. 140 * __pm_clk_remove - Destroy PM clock entry.
108 * @ce: PM clock entry to destroy. 141 * @ce: PM clock entry to destroy.
109 */ 142 */
@@ -223,10 +256,6 @@ void pm_clk_destroy(struct device *dev)
223 } 256 }
224} 257}
225 258
226#endif /* CONFIG_PM */
227
228#ifdef CONFIG_PM_RUNTIME
229
230/** 259/**
231 * pm_clk_suspend - Disable clocks in a device's PM clock list. 260 * pm_clk_suspend - Disable clocks in a device's PM clock list.
232 * @dev: Device to disable the clocks for. 261 * @dev: Device to disable the clocks for.
@@ -266,7 +295,6 @@ int pm_clk_resume(struct device *dev)
266 struct pm_subsys_data *psd = dev_to_psd(dev); 295 struct pm_subsys_data *psd = dev_to_psd(dev);
267 struct pm_clock_entry *ce; 296 struct pm_clock_entry *ce;
268 unsigned long flags; 297 unsigned long flags;
269 int ret;
270 298
271 dev_dbg(dev, "%s()\n", __func__); 299 dev_dbg(dev, "%s()\n", __func__);
272 300
@@ -275,13 +303,8 @@ int pm_clk_resume(struct device *dev)
275 303
276 spin_lock_irqsave(&psd->lock, flags); 304 spin_lock_irqsave(&psd->lock, flags);
277 305
278 list_for_each_entry(ce, &psd->clock_list, node) { 306 list_for_each_entry(ce, &psd->clock_list, node)
279 if (ce->status < PCE_STATUS_ERROR) { 307 __pm_clk_enable(dev, ce);
280 ret = __pm_clk_enable(dev, ce->clk);
281 if (!ret)
282 ce->status = PCE_STATUS_ENABLED;
283 }
284 }
285 308
286 spin_unlock_irqrestore(&psd->lock, flags); 309 spin_unlock_irqrestore(&psd->lock, flags);
287 310
@@ -346,74 +369,7 @@ static int pm_clk_notify(struct notifier_block *nb,
346 return 0; 369 return 0;
347} 370}
348 371
349#else /* !CONFIG_PM_RUNTIME */ 372#else /* !CONFIG_PM */
350
351#ifdef CONFIG_PM
352
353/**
354 * pm_clk_suspend - Disable clocks in a device's PM clock list.
355 * @dev: Device to disable the clocks for.
356 */
357int pm_clk_suspend(struct device *dev)
358{
359 struct pm_subsys_data *psd = dev_to_psd(dev);
360 struct pm_clock_entry *ce;
361 unsigned long flags;
362
363 dev_dbg(dev, "%s()\n", __func__);
364
365 /* If there is no driver, the clocks are already disabled. */
366 if (!psd || !dev->driver)
367 return 0;
368
369 spin_lock_irqsave(&psd->lock, flags);
370
371 list_for_each_entry_reverse(ce, &psd->clock_list, node) {
372 if (ce->status < PCE_STATUS_ERROR) {
373 if (ce->status == PCE_STATUS_ENABLED)
374 clk_disable(ce->clk);
375 ce->status = PCE_STATUS_ACQUIRED;
376 }
377 }
378
379 spin_unlock_irqrestore(&psd->lock, flags);
380
381 return 0;
382}
383
384/**
385 * pm_clk_resume - Enable clocks in a device's PM clock list.
386 * @dev: Device to enable the clocks for.
387 */
388int pm_clk_resume(struct device *dev)
389{
390 struct pm_subsys_data *psd = dev_to_psd(dev);
391 struct pm_clock_entry *ce;
392 unsigned long flags;
393 int ret;
394
395 dev_dbg(dev, "%s()\n", __func__);
396
397 /* If there is no driver, the clocks should remain disabled. */
398 if (!psd || !dev->driver)
399 return 0;
400
401 spin_lock_irqsave(&psd->lock, flags);
402
403 list_for_each_entry(ce, &psd->clock_list, node) {
404 if (ce->status < PCE_STATUS_ERROR) {
405 ret = __pm_clk_enable(dev, ce->clk);
406 if (!ret)
407 ce->status = PCE_STATUS_ENABLED;
408 }
409 }
410
411 spin_unlock_irqrestore(&psd->lock, flags);
412
413 return 0;
414}
415
416#endif /* CONFIG_PM */
417 373
418/** 374/**
419 * enable_clock - Enable a device clock. 375 * enable_clock - Enable a device clock.
@@ -493,7 +449,7 @@ static int pm_clk_notify(struct notifier_block *nb,
493 return 0; 449 return 0;
494} 450}
495 451
496#endif /* !CONFIG_PM_RUNTIME */ 452#endif /* !CONFIG_PM */
497 453
498/** 454/**
499 * pm_clk_add_notifier - Add bus type notifier for power management clocks. 455 * pm_clk_add_notifier - Add bus type notifier for power management clocks.
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index fb83d4acd400..6a103a35ea9b 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -12,6 +12,7 @@
12#include <linux/pm_runtime.h> 12#include <linux/pm_runtime.h>
13#include <linux/pm_domain.h> 13#include <linux/pm_domain.h>
14#include <linux/pm_qos.h> 14#include <linux/pm_qos.h>
15#include <linux/pm_clock.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/err.h> 17#include <linux/err.h>
17#include <linux/sched.h> 18#include <linux/sched.h>
@@ -151,6 +152,59 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
151 genpd->cpuidle_data->idle_state->exit_latency = usecs64; 152 genpd->cpuidle_data->idle_state->exit_latency = usecs64;
152} 153}
153 154
155static int genpd_power_on(struct generic_pm_domain *genpd)
156{
157 ktime_t time_start;
158 s64 elapsed_ns;
159 int ret;
160
161 if (!genpd->power_on)
162 return 0;
163
164 time_start = ktime_get();
165 ret = genpd->power_on(genpd);
166 if (ret)
167 return ret;
168
169 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
170 if (elapsed_ns <= genpd->power_on_latency_ns)
171 return ret;
172
173 genpd->power_on_latency_ns = elapsed_ns;
174 genpd->max_off_time_changed = true;
175 genpd_recalc_cpu_exit_latency(genpd);
176 pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
177 genpd->name, "on", elapsed_ns);
178
179 return ret;
180}
181
182static int genpd_power_off(struct generic_pm_domain *genpd)
183{
184 ktime_t time_start;
185 s64 elapsed_ns;
186 int ret;
187
188 if (!genpd->power_off)
189 return 0;
190
191 time_start = ktime_get();
192 ret = genpd->power_off(genpd);
193 if (ret == -EBUSY)
194 return ret;
195
196 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
197 if (elapsed_ns <= genpd->power_off_latency_ns)
198 return ret;
199
200 genpd->power_off_latency_ns = elapsed_ns;
201 genpd->max_off_time_changed = true;
202 pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
203 genpd->name, "off", elapsed_ns);
204
205 return ret;
206}
207
154/** 208/**
155 * __pm_genpd_poweron - Restore power to a given PM domain and its masters. 209 * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
156 * @genpd: PM domain to power up. 210 * @genpd: PM domain to power up.
@@ -222,25 +276,9 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
222 } 276 }
223 } 277 }
224 278
225 if (genpd->power_on) { 279 ret = genpd_power_on(genpd);
226 ktime_t time_start = ktime_get(); 280 if (ret)
227 s64 elapsed_ns; 281 goto err;
228
229 ret = genpd->power_on(genpd);
230 if (ret)
231 goto err;
232
233 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
234 if (elapsed_ns > genpd->power_on_latency_ns) {
235 genpd->power_on_latency_ns = elapsed_ns;
236 genpd->max_off_time_changed = true;
237 genpd_recalc_cpu_exit_latency(genpd);
238 if (genpd->name)
239 pr_warning("%s: Power-on latency exceeded, "
240 "new value %lld ns\n", genpd->name,
241 elapsed_ns);
242 }
243 }
244 282
245 out: 283 out:
246 genpd_set_active(genpd); 284 genpd_set_active(genpd);
@@ -280,8 +318,6 @@ int pm_genpd_name_poweron(const char *domain_name)
280 return genpd ? pm_genpd_poweron(genpd) : -EINVAL; 318 return genpd ? pm_genpd_poweron(genpd) : -EINVAL;
281} 319}
282 320
283#ifdef CONFIG_PM_RUNTIME
284
285static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd, 321static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
286 struct device *dev) 322 struct device *dev)
287{ 323{
@@ -544,16 +580,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
544 } 580 }
545 581
546 if (genpd->power_off) { 582 if (genpd->power_off) {
547 ktime_t time_start;
548 s64 elapsed_ns;
549
550 if (atomic_read(&genpd->sd_count) > 0) { 583 if (atomic_read(&genpd->sd_count) > 0) {
551 ret = -EBUSY; 584 ret = -EBUSY;
552 goto out; 585 goto out;
553 } 586 }
554 587
555 time_start = ktime_get();
556
557 /* 588 /*
558 * If sd_count > 0 at this point, one of the subdomains hasn't 589 * If sd_count > 0 at this point, one of the subdomains hasn't
559 * managed to call pm_genpd_poweron() for the master yet after 590 * managed to call pm_genpd_poweron() for the master yet after
@@ -562,21 +593,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
562 * the pm_genpd_poweron() restore power for us (this shouldn't 593 * the pm_genpd_poweron() restore power for us (this shouldn't
563 * happen very often). 594 * happen very often).
564 */ 595 */
565 ret = genpd->power_off(genpd); 596 ret = genpd_power_off(genpd);
566 if (ret == -EBUSY) { 597 if (ret == -EBUSY) {
567 genpd_set_active(genpd); 598 genpd_set_active(genpd);
568 goto out; 599 goto out;
569 } 600 }
570
571 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
572 if (elapsed_ns > genpd->power_off_latency_ns) {
573 genpd->power_off_latency_ns = elapsed_ns;
574 genpd->max_off_time_changed = true;
575 if (genpd->name)
576 pr_warning("%s: Power-off latency exceeded, "
577 "new value %lld ns\n", genpd->name,
578 elapsed_ns);
579 }
580 } 601 }
581 602
582 genpd->status = GPD_STATE_POWER_OFF; 603 genpd->status = GPD_STATE_POWER_OFF;
@@ -755,33 +776,15 @@ static int __init genpd_poweroff_unused(void)
755} 776}
756late_initcall(genpd_poweroff_unused); 777late_initcall(genpd_poweroff_unused);
757 778
758#else
759
760static inline int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
761 unsigned long val, void *ptr)
762{
763 return NOTIFY_DONE;
764}
765
766static inline void
767genpd_queue_power_off_work(struct generic_pm_domain *genpd) {}
768
769static inline void genpd_power_off_work_fn(struct work_struct *work) {}
770
771#define pm_genpd_runtime_suspend NULL
772#define pm_genpd_runtime_resume NULL
773
774#endif /* CONFIG_PM_RUNTIME */
775
776#ifdef CONFIG_PM_SLEEP 779#ifdef CONFIG_PM_SLEEP
777 780
778/** 781/**
779 * pm_genpd_present - Check if the given PM domain has been initialized. 782 * pm_genpd_present - Check if the given PM domain has been initialized.
780 * @genpd: PM domain to check. 783 * @genpd: PM domain to check.
781 */ 784 */
782static bool pm_genpd_present(struct generic_pm_domain *genpd) 785static bool pm_genpd_present(const struct generic_pm_domain *genpd)
783{ 786{
784 struct generic_pm_domain *gpd; 787 const struct generic_pm_domain *gpd;
785 788
786 if (IS_ERR_OR_NULL(genpd)) 789 if (IS_ERR_OR_NULL(genpd))
787 return false; 790 return false;
@@ -822,8 +825,7 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
822 || atomic_read(&genpd->sd_count) > 0) 825 || atomic_read(&genpd->sd_count) > 0)
823 return; 826 return;
824 827
825 if (genpd->power_off) 828 genpd_power_off(genpd);
826 genpd->power_off(genpd);
827 829
828 genpd->status = GPD_STATE_POWER_OFF; 830 genpd->status = GPD_STATE_POWER_OFF;
829 831
@@ -854,8 +856,7 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
854 genpd_sd_counter_inc(link->master); 856 genpd_sd_counter_inc(link->master);
855 } 857 }
856 858
857 if (genpd->power_on) 859 genpd_power_on(genpd);
858 genpd->power_on(genpd);
859 860
860 genpd->status = GPD_STATE_ACTIVE; 861 genpd->status = GPD_STATE_ACTIVE;
861} 862}
@@ -1277,8 +1278,7 @@ static int pm_genpd_restore_noirq(struct device *dev)
1277 * If the domain was off before the hibernation, make 1278 * If the domain was off before the hibernation, make
1278 * sure it will be off going forward. 1279 * sure it will be off going forward.
1279 */ 1280 */
1280 if (genpd->power_off) 1281 genpd_power_off(genpd);
1281 genpd->power_off(genpd);
1282 1282
1283 return 0; 1283 return 0;
1284 } 1284 }
@@ -1364,7 +1364,7 @@ void pm_genpd_syscore_poweron(struct device *dev)
1364} 1364}
1365EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron); 1365EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
1366 1366
1367#else 1367#else /* !CONFIG_PM_SLEEP */
1368 1368
1369#define pm_genpd_prepare NULL 1369#define pm_genpd_prepare NULL
1370#define pm_genpd_suspend NULL 1370#define pm_genpd_suspend NULL
@@ -1929,6 +1929,12 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
1929 genpd->domain.ops.complete = pm_genpd_complete; 1929 genpd->domain.ops.complete = pm_genpd_complete;
1930 genpd->dev_ops.save_state = pm_genpd_default_save_state; 1930 genpd->dev_ops.save_state = pm_genpd_default_save_state;
1931 genpd->dev_ops.restore_state = pm_genpd_default_restore_state; 1931 genpd->dev_ops.restore_state = pm_genpd_default_restore_state;
1932
1933 if (genpd->flags & GENPD_FLAG_PM_CLK) {
1934 genpd->dev_ops.stop = pm_clk_suspend;
1935 genpd->dev_ops.start = pm_clk_resume;
1936 }
1937
1932 mutex_lock(&gpd_list_lock); 1938 mutex_lock(&gpd_list_lock);
1933 list_add(&genpd->gpd_list_node, &gpd_list); 1939 list_add(&genpd->gpd_list_node, &gpd_list);
1934 mutex_unlock(&gpd_list_lock); 1940 mutex_unlock(&gpd_list_lock);
@@ -2216,11 +2222,12 @@ int genpd_dev_pm_attach(struct device *dev)
2216 } 2222 }
2217 2223
2218 dev->pm_domain->detach = genpd_dev_pm_detach; 2224 dev->pm_domain->detach = genpd_dev_pm_detach;
2225 pm_genpd_poweron(pd);
2219 2226
2220 return 0; 2227 return 0;
2221} 2228}
2222EXPORT_SYMBOL_GPL(genpd_dev_pm_attach); 2229EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
2223#endif 2230#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
2224 2231
2225 2232
2226/*** debugfs support ***/ 2233/*** debugfs support ***/
@@ -2236,10 +2243,8 @@ static struct dentry *pm_genpd_debugfs_dir;
2236 2243
2237/* 2244/*
2238 * TODO: This function is a slightly modified version of rtpm_status_show 2245 * TODO: This function is a slightly modified version of rtpm_status_show
2239 * from sysfs.c, but dependencies between PM_GENERIC_DOMAINS and PM_RUNTIME 2246 * from sysfs.c, so generalize it.
2240 * are too loose to generalize it.
2241 */ 2247 */
2242#ifdef CONFIG_PM_RUNTIME
2243static void rtpm_status_str(struct seq_file *s, struct device *dev) 2248static void rtpm_status_str(struct seq_file *s, struct device *dev)
2244{ 2249{
2245 static const char * const status_lookup[] = { 2250 static const char * const status_lookup[] = {
@@ -2261,12 +2266,6 @@ static void rtpm_status_str(struct seq_file *s, struct device *dev)
2261 2266
2262 seq_puts(s, p); 2267 seq_puts(s, p);
2263} 2268}
2264#else
2265static void rtpm_status_str(struct seq_file *s, struct device *dev)
2266{
2267 seq_puts(s, "active");
2268}
2269#endif
2270 2269
2271static int pm_genpd_summary_one(struct seq_file *s, 2270static int pm_genpd_summary_one(struct seq_file *s,
2272 struct generic_pm_domain *gpd) 2271 struct generic_pm_domain *gpd)
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c
index d88a62e104d4..2a4154a09e4d 100644
--- a/drivers/base/power/domain_governor.c
+++ b/drivers/base/power/domain_governor.c
@@ -11,8 +11,6 @@
11#include <linux/pm_qos.h> 11#include <linux/pm_qos.h>
12#include <linux/hrtimer.h> 12#include <linux/hrtimer.h>
13 13
14#ifdef CONFIG_PM_RUNTIME
15
16static int dev_update_qos_constraint(struct device *dev, void *data) 14static int dev_update_qos_constraint(struct device *dev, void *data)
17{ 15{
18 s64 *constraint_ns_p = data; 16 s64 *constraint_ns_p = data;
@@ -227,15 +225,6 @@ static bool always_on_power_down_ok(struct dev_pm_domain *domain)
227 return false; 225 return false;
228} 226}
229 227
230#else /* !CONFIG_PM_RUNTIME */
231
232static inline bool default_stop_ok(struct device *dev) { return false; }
233
234#define default_power_down_ok NULL
235#define always_on_power_down_ok NULL
236
237#endif /* !CONFIG_PM_RUNTIME */
238
239struct dev_power_governor simple_qos_governor = { 228struct dev_power_governor simple_qos_governor = {
240 .stop_ok = default_stop_ok, 229 .stop_ok = default_stop_ok,
241 .power_down_ok = default_power_down_ok, 230 .power_down_ok = default_power_down_ok,
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index a21223d95926..b6b8a273c5da 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -9,7 +9,7 @@ static inline void device_pm_init_common(struct device *dev)
9 } 9 }
10} 10}
11 11
12#ifdef CONFIG_PM_RUNTIME 12#ifdef CONFIG_PM
13 13
14static inline void pm_runtime_early_init(struct device *dev) 14static inline void pm_runtime_early_init(struct device *dev)
15{ 15{
@@ -20,7 +20,21 @@ static inline void pm_runtime_early_init(struct device *dev)
20extern void pm_runtime_init(struct device *dev); 20extern void pm_runtime_init(struct device *dev);
21extern void pm_runtime_remove(struct device *dev); 21extern void pm_runtime_remove(struct device *dev);
22 22
23#else /* !CONFIG_PM_RUNTIME */ 23/*
24 * sysfs.c
25 */
26
27extern int dpm_sysfs_add(struct device *dev);
28extern void dpm_sysfs_remove(struct device *dev);
29extern void rpm_sysfs_remove(struct device *dev);
30extern int wakeup_sysfs_add(struct device *dev);
31extern void wakeup_sysfs_remove(struct device *dev);
32extern int pm_qos_sysfs_add_resume_latency(struct device *dev);
33extern void pm_qos_sysfs_remove_resume_latency(struct device *dev);
34extern int pm_qos_sysfs_add_flags(struct device *dev);
35extern void pm_qos_sysfs_remove_flags(struct device *dev);
36
37#else /* CONFIG_PM */
24 38
25static inline void pm_runtime_early_init(struct device *dev) 39static inline void pm_runtime_early_init(struct device *dev)
26{ 40{
@@ -30,7 +44,15 @@ static inline void pm_runtime_early_init(struct device *dev)
30static inline void pm_runtime_init(struct device *dev) {} 44static inline void pm_runtime_init(struct device *dev) {}
31static inline void pm_runtime_remove(struct device *dev) {} 45static inline void pm_runtime_remove(struct device *dev) {}
32 46
33#endif /* !CONFIG_PM_RUNTIME */ 47static inline int dpm_sysfs_add(struct device *dev) { return 0; }
48static inline void dpm_sysfs_remove(struct device *dev) {}
49static inline void rpm_sysfs_remove(struct device *dev) {}
50static inline int wakeup_sysfs_add(struct device *dev) { return 0; }
51static inline void wakeup_sysfs_remove(struct device *dev) {}
52static inline int pm_qos_sysfs_add(struct device *dev) { return 0; }
53static inline void pm_qos_sysfs_remove(struct device *dev) {}
54
55#endif
34 56
35#ifdef CONFIG_PM_SLEEP 57#ifdef CONFIG_PM_SLEEP
36 58
@@ -77,31 +99,3 @@ static inline void device_pm_init(struct device *dev)
77 device_pm_sleep_init(dev); 99 device_pm_sleep_init(dev);
78 pm_runtime_init(dev); 100 pm_runtime_init(dev);
79} 101}
80
81#ifdef CONFIG_PM
82
83/*
84 * sysfs.c
85 */
86
87extern int dpm_sysfs_add(struct device *dev);
88extern void dpm_sysfs_remove(struct device *dev);
89extern void rpm_sysfs_remove(struct device *dev);
90extern int wakeup_sysfs_add(struct device *dev);
91extern void wakeup_sysfs_remove(struct device *dev);
92extern int pm_qos_sysfs_add_resume_latency(struct device *dev);
93extern void pm_qos_sysfs_remove_resume_latency(struct device *dev);
94extern int pm_qos_sysfs_add_flags(struct device *dev);
95extern void pm_qos_sysfs_remove_flags(struct device *dev);
96
97#else /* CONFIG_PM */
98
99static inline int dpm_sysfs_add(struct device *dev) { return 0; }
100static inline void dpm_sysfs_remove(struct device *dev) {}
101static inline void rpm_sysfs_remove(struct device *dev) {}
102static inline int wakeup_sysfs_add(struct device *dev) { return 0; }
103static inline void wakeup_sysfs_remove(struct device *dev) {}
104static inline int pm_qos_sysfs_add(struct device *dev) { return 0; }
105static inline void pm_qos_sysfs_remove(struct device *dev) {}
106
107#endif
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index 36b9eb4862cb..a8fe4c1a8d07 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -599,7 +599,6 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
599} 599}
600EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); 600EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);
601 601
602#ifdef CONFIG_PM_RUNTIME
603static void __dev_pm_qos_drop_user_request(struct device *dev, 602static void __dev_pm_qos_drop_user_request(struct device *dev,
604 enum dev_pm_qos_req_type type) 603 enum dev_pm_qos_req_type type)
605{ 604{
@@ -880,7 +879,3 @@ int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val)
880 mutex_unlock(&dev_pm_qos_mtx); 879 mutex_unlock(&dev_pm_qos_mtx);
881 return ret; 880 return ret;
882} 881}
883#else /* !CONFIG_PM_RUNTIME */
884static void __dev_pm_qos_hide_latency_limit(struct device *dev) {}
885static void __dev_pm_qos_hide_flags(struct device *dev) {}
886#endif /* CONFIG_PM_RUNTIME */
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 67c7938e430b..5070c4fe8542 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -13,43 +13,38 @@
13#include <trace/events/rpm.h> 13#include <trace/events/rpm.h>
14#include "power.h" 14#include "power.h"
15 15
16#define RPM_GET_CALLBACK(dev, cb) \ 16typedef int (*pm_callback_t)(struct device *);
17({ \
18 int (*__rpm_cb)(struct device *__d); \
19 \
20 if (dev->pm_domain) \
21 __rpm_cb = dev->pm_domain->ops.cb; \
22 else if (dev->type && dev->type->pm) \
23 __rpm_cb = dev->type->pm->cb; \
24 else if (dev->class && dev->class->pm) \
25 __rpm_cb = dev->class->pm->cb; \
26 else if (dev->bus && dev->bus->pm) \
27 __rpm_cb = dev->bus->pm->cb; \
28 else \
29 __rpm_cb = NULL; \
30 \
31 if (!__rpm_cb && dev->driver && dev->driver->pm) \
32 __rpm_cb = dev->driver->pm->cb; \
33 \
34 __rpm_cb; \
35})
36
37static int (*rpm_get_suspend_cb(struct device *dev))(struct device *)
38{
39 return RPM_GET_CALLBACK(dev, runtime_suspend);
40}
41 17
42static int (*rpm_get_resume_cb(struct device *dev))(struct device *) 18static pm_callback_t __rpm_get_callback(struct device *dev, size_t cb_offset)
43{ 19{
44 return RPM_GET_CALLBACK(dev, runtime_resume); 20 pm_callback_t cb;
45} 21 const struct dev_pm_ops *ops;
22
23 if (dev->pm_domain)
24 ops = &dev->pm_domain->ops;
25 else if (dev->type && dev->type->pm)
26 ops = dev->type->pm;
27 else if (dev->class && dev->class->pm)
28 ops = dev->class->pm;
29 else if (dev->bus && dev->bus->pm)
30 ops = dev->bus->pm;
31 else
32 ops = NULL;
46 33
47#ifdef CONFIG_PM_RUNTIME 34 if (ops)
48static int (*rpm_get_idle_cb(struct device *dev))(struct device *) 35 cb = *(pm_callback_t *)((void *)ops + cb_offset);
49{ 36 else
50 return RPM_GET_CALLBACK(dev, runtime_idle); 37 cb = NULL;
38
39 if (!cb && dev->driver && dev->driver->pm)
40 cb = *(pm_callback_t *)((void *)dev->driver->pm + cb_offset);
41
42 return cb;
51} 43}
52 44
45#define RPM_GET_CALLBACK(dev, callback) \
46 __rpm_get_callback(dev, offsetof(struct dev_pm_ops, callback))
47
53static int rpm_resume(struct device *dev, int rpmflags); 48static int rpm_resume(struct device *dev, int rpmflags);
54static int rpm_suspend(struct device *dev, int rpmflags); 49static int rpm_suspend(struct device *dev, int rpmflags);
55 50
@@ -347,7 +342,7 @@ static int rpm_idle(struct device *dev, int rpmflags)
347 342
348 dev->power.idle_notification = true; 343 dev->power.idle_notification = true;
349 344
350 callback = rpm_get_idle_cb(dev); 345 callback = RPM_GET_CALLBACK(dev, runtime_idle);
351 346
352 if (callback) 347 if (callback)
353 retval = __rpm_callback(callback, dev); 348 retval = __rpm_callback(callback, dev);
@@ -517,7 +512,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
517 512
518 __update_runtime_status(dev, RPM_SUSPENDING); 513 __update_runtime_status(dev, RPM_SUSPENDING);
519 514
520 callback = rpm_get_suspend_cb(dev); 515 callback = RPM_GET_CALLBACK(dev, runtime_suspend);
521 516
522 retval = rpm_callback(callback, dev); 517 retval = rpm_callback(callback, dev);
523 if (retval) 518 if (retval)
@@ -737,7 +732,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
737 732
738 __update_runtime_status(dev, RPM_RESUMING); 733 __update_runtime_status(dev, RPM_RESUMING);
739 734
740 callback = rpm_get_resume_cb(dev); 735 callback = RPM_GET_CALLBACK(dev, runtime_resume);
741 736
742 retval = rpm_callback(callback, dev); 737 retval = rpm_callback(callback, dev);
743 if (retval) { 738 if (retval) {
@@ -1402,7 +1397,6 @@ void pm_runtime_remove(struct device *dev)
1402 if (dev->power.irq_safe && dev->parent) 1397 if (dev->power.irq_safe && dev->parent)
1403 pm_runtime_put(dev->parent); 1398 pm_runtime_put(dev->parent);
1404} 1399}
1405#endif
1406 1400
1407/** 1401/**
1408 * pm_runtime_force_suspend - Force a device into suspend state if needed. 1402 * pm_runtime_force_suspend - Force a device into suspend state if needed.
@@ -1422,16 +1416,10 @@ int pm_runtime_force_suspend(struct device *dev)
1422 int ret = 0; 1416 int ret = 0;
1423 1417
1424 pm_runtime_disable(dev); 1418 pm_runtime_disable(dev);
1425
1426 /*
1427 * Note that pm_runtime_status_suspended() returns false while
1428 * !CONFIG_PM_RUNTIME, which means the device will be put into low
1429 * power state.
1430 */
1431 if (pm_runtime_status_suspended(dev)) 1419 if (pm_runtime_status_suspended(dev))
1432 return 0; 1420 return 0;
1433 1421
1434 callback = rpm_get_suspend_cb(dev); 1422 callback = RPM_GET_CALLBACK(dev, runtime_suspend);
1435 1423
1436 if (!callback) { 1424 if (!callback) {
1437 ret = -ENOSYS; 1425 ret = -ENOSYS;
@@ -1467,7 +1455,7 @@ int pm_runtime_force_resume(struct device *dev)
1467 int (*callback)(struct device *); 1455 int (*callback)(struct device *);
1468 int ret = 0; 1456 int ret = 0;
1469 1457
1470 callback = rpm_get_resume_cb(dev); 1458 callback = RPM_GET_CALLBACK(dev, runtime_resume);
1471 1459
1472 if (!callback) { 1460 if (!callback) {
1473 ret = -ENOSYS; 1461 ret = -ENOSYS;
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index a9d26ed11bf4..d2be3f9c211c 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -95,7 +95,6 @@
95const char power_group_name[] = "power"; 95const char power_group_name[] = "power";
96EXPORT_SYMBOL_GPL(power_group_name); 96EXPORT_SYMBOL_GPL(power_group_name);
97 97
98#ifdef CONFIG_PM_RUNTIME
99static const char ctrl_auto[] = "auto"; 98static const char ctrl_auto[] = "auto";
100static const char ctrl_on[] = "on"; 99static const char ctrl_on[] = "on";
101 100
@@ -330,7 +329,6 @@ static ssize_t pm_qos_remote_wakeup_store(struct device *dev,
330 329
331static DEVICE_ATTR(pm_qos_remote_wakeup, 0644, 330static DEVICE_ATTR(pm_qos_remote_wakeup, 0644,
332 pm_qos_remote_wakeup_show, pm_qos_remote_wakeup_store); 331 pm_qos_remote_wakeup_show, pm_qos_remote_wakeup_store);
333#endif /* CONFIG_PM_RUNTIME */
334 332
335#ifdef CONFIG_PM_SLEEP 333#ifdef CONFIG_PM_SLEEP
336static const char _enabled[] = "enabled"; 334static const char _enabled[] = "enabled";
@@ -531,8 +529,6 @@ static DEVICE_ATTR(wakeup_prevent_sleep_time_ms, 0444,
531#endif /* CONFIG_PM_SLEEP */ 529#endif /* CONFIG_PM_SLEEP */
532 530
533#ifdef CONFIG_PM_ADVANCED_DEBUG 531#ifdef CONFIG_PM_ADVANCED_DEBUG
534#ifdef CONFIG_PM_RUNTIME
535
536static ssize_t rtpm_usagecount_show(struct device *dev, 532static ssize_t rtpm_usagecount_show(struct device *dev,
537 struct device_attribute *attr, char *buf) 533 struct device_attribute *attr, char *buf)
538{ 534{
@@ -562,10 +558,7 @@ static DEVICE_ATTR(runtime_usage, 0444, rtpm_usagecount_show, NULL);
562static DEVICE_ATTR(runtime_active_kids, 0444, rtpm_children_show, NULL); 558static DEVICE_ATTR(runtime_active_kids, 0444, rtpm_children_show, NULL);
563static DEVICE_ATTR(runtime_enabled, 0444, rtpm_enabled_show, NULL); 559static DEVICE_ATTR(runtime_enabled, 0444, rtpm_enabled_show, NULL);
564 560
565#endif
566
567#ifdef CONFIG_PM_SLEEP 561#ifdef CONFIG_PM_SLEEP
568
569static ssize_t async_show(struct device *dev, struct device_attribute *attr, 562static ssize_t async_show(struct device *dev, struct device_attribute *attr,
570 char *buf) 563 char *buf)
571{ 564{
@@ -595,7 +588,7 @@ static ssize_t async_store(struct device *dev, struct device_attribute *attr,
595 588
596static DEVICE_ATTR(async, 0644, async_show, async_store); 589static DEVICE_ATTR(async, 0644, async_show, async_store);
597 590
598#endif 591#endif /* CONFIG_PM_SLEEP */
599#endif /* CONFIG_PM_ADVANCED_DEBUG */ 592#endif /* CONFIG_PM_ADVANCED_DEBUG */
600 593
601static struct attribute *power_attrs[] = { 594static struct attribute *power_attrs[] = {
@@ -603,12 +596,10 @@ static struct attribute *power_attrs[] = {
603#ifdef CONFIG_PM_SLEEP 596#ifdef CONFIG_PM_SLEEP
604 &dev_attr_async.attr, 597 &dev_attr_async.attr,
605#endif 598#endif
606#ifdef CONFIG_PM_RUNTIME
607 &dev_attr_runtime_status.attr, 599 &dev_attr_runtime_status.attr,
608 &dev_attr_runtime_usage.attr, 600 &dev_attr_runtime_usage.attr,
609 &dev_attr_runtime_active_kids.attr, 601 &dev_attr_runtime_active_kids.attr,
610 &dev_attr_runtime_enabled.attr, 602 &dev_attr_runtime_enabled.attr,
611#endif
612#endif /* CONFIG_PM_ADVANCED_DEBUG */ 603#endif /* CONFIG_PM_ADVANCED_DEBUG */
613 NULL, 604 NULL,
614}; 605};
@@ -640,7 +631,6 @@ static struct attribute_group pm_wakeup_attr_group = {
640}; 631};
641 632
642static struct attribute *runtime_attrs[] = { 633static struct attribute *runtime_attrs[] = {
643#ifdef CONFIG_PM_RUNTIME
644#ifndef CONFIG_PM_ADVANCED_DEBUG 634#ifndef CONFIG_PM_ADVANCED_DEBUG
645 &dev_attr_runtime_status.attr, 635 &dev_attr_runtime_status.attr,
646#endif 636#endif
@@ -648,7 +638,6 @@ static struct attribute *runtime_attrs[] = {
648 &dev_attr_runtime_suspended_time.attr, 638 &dev_attr_runtime_suspended_time.attr,
649 &dev_attr_runtime_active_time.attr, 639 &dev_attr_runtime_active_time.attr,
650 &dev_attr_autosuspend_delay_ms.attr, 640 &dev_attr_autosuspend_delay_ms.attr,
651#endif /* CONFIG_PM_RUNTIME */
652 NULL, 641 NULL,
653}; 642};
654static struct attribute_group pm_runtime_attr_group = { 643static struct attribute_group pm_runtime_attr_group = {
@@ -657,9 +646,7 @@ static struct attribute_group pm_runtime_attr_group = {
657}; 646};
658 647
659static struct attribute *pm_qos_resume_latency_attrs[] = { 648static struct attribute *pm_qos_resume_latency_attrs[] = {
660#ifdef CONFIG_PM_RUNTIME
661 &dev_attr_pm_qos_resume_latency_us.attr, 649 &dev_attr_pm_qos_resume_latency_us.attr,
662#endif /* CONFIG_PM_RUNTIME */
663 NULL, 650 NULL,
664}; 651};
665static struct attribute_group pm_qos_resume_latency_attr_group = { 652static struct attribute_group pm_qos_resume_latency_attr_group = {
@@ -668,9 +655,7 @@ static struct attribute_group pm_qos_resume_latency_attr_group = {
668}; 655};
669 656
670static struct attribute *pm_qos_latency_tolerance_attrs[] = { 657static struct attribute *pm_qos_latency_tolerance_attrs[] = {
671#ifdef CONFIG_PM_RUNTIME
672 &dev_attr_pm_qos_latency_tolerance_us.attr, 658 &dev_attr_pm_qos_latency_tolerance_us.attr,
673#endif /* CONFIG_PM_RUNTIME */
674 NULL, 659 NULL,
675}; 660};
676static struct attribute_group pm_qos_latency_tolerance_attr_group = { 661static struct attribute_group pm_qos_latency_tolerance_attr_group = {
@@ -679,10 +664,8 @@ static struct attribute_group pm_qos_latency_tolerance_attr_group = {
679}; 664};
680 665
681static struct attribute *pm_qos_flags_attrs[] = { 666static struct attribute *pm_qos_flags_attrs[] = {
682#ifdef CONFIG_PM_RUNTIME
683 &dev_attr_pm_qos_no_power_off.attr, 667 &dev_attr_pm_qos_no_power_off.attr,
684 &dev_attr_pm_qos_remote_wakeup.attr, 668 &dev_attr_pm_qos_remote_wakeup.attr,
685#endif /* CONFIG_PM_RUNTIME */
686 NULL, 669 NULL,
687}; 670};
688static struct attribute_group pm_qos_flags_attr_group = { 671static struct attribute_group pm_qos_flags_attr_group = {
diff --git a/drivers/base/property.c b/drivers/base/property.c
new file mode 100644
index 000000000000..c45845874d4f
--- /dev/null
+++ b/drivers/base/property.c
@@ -0,0 +1,431 @@
1/*
2 * property.c - Unified device property interface.
3 *
4 * Copyright (C) 2014, Intel Corporation
5 * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
6 * Mika Westerberg <mika.westerberg@linux.intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/property.h>
14#include <linux/export.h>
15#include <linux/acpi.h>
16#include <linux/of.h>
17
18/**
19 * device_property_present - check if a property of a device is present
20 * @dev: Device whose property is being checked
21 * @propname: Name of the property
22 *
23 * Check if property @propname is present in the device firmware description.
24 */
25bool device_property_present(struct device *dev, const char *propname)
26{
27 if (IS_ENABLED(CONFIG_OF) && dev->of_node)
28 return of_property_read_bool(dev->of_node, propname);
29
30 return !acpi_dev_prop_get(ACPI_COMPANION(dev), propname, NULL);
31}
32EXPORT_SYMBOL_GPL(device_property_present);
33
34/**
35 * fwnode_property_present - check if a property of a firmware node is present
36 * @fwnode: Firmware node whose property to check
37 * @propname: Name of the property
38 */
39bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
40{
41 if (is_of_node(fwnode))
42 return of_property_read_bool(of_node(fwnode), propname);
43 else if (is_acpi_node(fwnode))
44 return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL);
45
46 return false;
47}
48EXPORT_SYMBOL_GPL(fwnode_property_present);
49
50#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
51 (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
52 : of_property_count_elems_of_size((node), (propname), sizeof(type))
53
54#define DEV_PROP_READ_ARRAY(_dev_, _propname_, _type_, _proptype_, _val_, _nval_) \
55 IS_ENABLED(CONFIG_OF) && _dev_->of_node ? \
56 (OF_DEV_PROP_READ_ARRAY(_dev_->of_node, _propname_, _type_, \
57 _val_, _nval_)) : \
58 acpi_dev_prop_read(ACPI_COMPANION(_dev_), _propname_, \
59 _proptype_, _val_, _nval_)
60
61/**
62 * device_property_read_u8_array - return a u8 array property of a device
63 * @dev: Device to get the property of
64 * @propname: Name of the property
65 * @val: The values are stored here
66 * @nval: Size of the @val array
67 *
68 * Function reads an array of u8 properties with @propname from the device
69 * firmware description and stores them to @val if found.
70 *
71 * Return: %0 if the property was found (success),
72 * %-EINVAL if given arguments are not valid,
73 * %-ENODATA if the property does not have a value,
74 * %-EPROTO if the property is not an array of numbers,
75 * %-EOVERFLOW if the size of the property is not as expected.
76 */
77int device_property_read_u8_array(struct device *dev, const char *propname,
78 u8 *val, size_t nval)
79{
80 return DEV_PROP_READ_ARRAY(dev, propname, u8, DEV_PROP_U8, val, nval);
81}
82EXPORT_SYMBOL_GPL(device_property_read_u8_array);
83
84/**
85 * device_property_read_u16_array - return a u16 array property of a device
86 * @dev: Device to get the property of
87 * @propname: Name of the property
88 * @val: The values are stored here
89 * @nval: Size of the @val array
90 *
91 * Function reads an array of u16 properties with @propname from the device
92 * firmware description and stores them to @val if found.
93 *
94 * Return: %0 if the property was found (success),
95 * %-EINVAL if given arguments are not valid,
96 * %-ENODATA if the property does not have a value,
97 * %-EPROTO if the property is not an array of numbers,
98 * %-EOVERFLOW if the size of the property is not as expected.
99 */
100int device_property_read_u16_array(struct device *dev, const char *propname,
101 u16 *val, size_t nval)
102{
103 return DEV_PROP_READ_ARRAY(dev, propname, u16, DEV_PROP_U16, val, nval);
104}
105EXPORT_SYMBOL_GPL(device_property_read_u16_array);
106
107/**
108 * device_property_read_u32_array - return a u32 array property of a device
109 * @dev: Device to get the property of
110 * @propname: Name of the property
111 * @val: The values are stored here
112 * @nval: Size of the @val array
113 *
114 * Function reads an array of u32 properties with @propname from the device
115 * firmware description and stores them to @val if found.
116 *
117 * Return: %0 if the property was found (success),
118 * %-EINVAL if given arguments are not valid,
119 * %-ENODATA if the property does not have a value,
120 * %-EPROTO if the property is not an array of numbers,
121 * %-EOVERFLOW if the size of the property is not as expected.
122 */
123int device_property_read_u32_array(struct device *dev, const char *propname,
124 u32 *val, size_t nval)
125{
126 return DEV_PROP_READ_ARRAY(dev, propname, u32, DEV_PROP_U32, val, nval);
127}
128EXPORT_SYMBOL_GPL(device_property_read_u32_array);
129
130/**
131 * device_property_read_u64_array - return a u64 array property of a device
132 * @dev: Device to get the property of
133 * @propname: Name of the property
134 * @val: The values are stored here
135 * @nval: Size of the @val array
136 *
137 * Function reads an array of u64 properties with @propname from the device
138 * firmware description and stores them to @val if found.
139 *
140 * Return: %0 if the property was found (success),
141 * %-EINVAL if given arguments are not valid,
142 * %-ENODATA if the property does not have a value,
143 * %-EPROTO if the property is not an array of numbers,
144 * %-EOVERFLOW if the size of the property is not as expected.
145 */
146int device_property_read_u64_array(struct device *dev, const char *propname,
147 u64 *val, size_t nval)
148{
149 return DEV_PROP_READ_ARRAY(dev, propname, u64, DEV_PROP_U64, val, nval);
150}
151EXPORT_SYMBOL_GPL(device_property_read_u64_array);
152
153/**
154 * device_property_read_string_array - return a string array property of device
155 * @dev: Device to get the property of
156 * @propname: Name of the property
157 * @val: The values are stored here
158 * @nval: Size of the @val array
159 *
160 * Function reads an array of string properties with @propname from the device
161 * firmware description and stores them to @val if found.
162 *
163 * Return: %0 if the property was found (success),
164 * %-EINVAL if given arguments are not valid,
165 * %-ENODATA if the property does not have a value,
166 * %-EPROTO or %-EILSEQ if the property is not an array of strings,
167 * %-EOVERFLOW if the size of the property is not as expected.
168 */
169int device_property_read_string_array(struct device *dev, const char *propname,
170 const char **val, size_t nval)
171{
172 return IS_ENABLED(CONFIG_OF) && dev->of_node ?
173 of_property_read_string_array(dev->of_node, propname, val, nval) :
174 acpi_dev_prop_read(ACPI_COMPANION(dev), propname,
175 DEV_PROP_STRING, val, nval);
176}
177EXPORT_SYMBOL_GPL(device_property_read_string_array);
178
179/**
180 * device_property_read_string - return a string property of a device
181 * @dev: Device to get the property of
182 * @propname: Name of the property
183 * @val: The value is stored here
184 *
185 * Function reads property @propname from the device firmware description and
186 * stores the value into @val if found. The value is checked to be a string.
187 *
188 * Return: %0 if the property was found (success),
189 * %-EINVAL if given arguments are not valid,
190 * %-ENODATA if the property does not have a value,
191 * %-EPROTO or %-EILSEQ if the property type is not a string.
192 */
193int device_property_read_string(struct device *dev, const char *propname,
194 const char **val)
195{
196 return IS_ENABLED(CONFIG_OF) && dev->of_node ?
197 of_property_read_string(dev->of_node, propname, val) :
198 acpi_dev_prop_read(ACPI_COMPANION(dev), propname,
199 DEV_PROP_STRING, val, 1);
200}
201EXPORT_SYMBOL_GPL(device_property_read_string);
202
203#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
204({ \
205 int _ret_; \
206 if (is_of_node(_fwnode_)) \
207 _ret_ = OF_DEV_PROP_READ_ARRAY(of_node(_fwnode_), _propname_, \
208 _type_, _val_, _nval_); \
209 else if (is_acpi_node(_fwnode_)) \
210 _ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \
211 _proptype_, _val_, _nval_); \
212 else \
213 _ret_ = -ENXIO; \
214 _ret_; \
215})
216
217/**
218 * fwnode_property_read_u8_array - return a u8 array property of firmware node
219 * @fwnode: Firmware node to get the property of
220 * @propname: Name of the property
221 * @val: The values are stored here
222 * @nval: Size of the @val array
223 *
224 * Read an array of u8 properties with @propname from @fwnode and stores them to
225 * @val if found.
226 *
227 * Return: %0 if the property was found (success),
228 * %-EINVAL if given arguments are not valid,
229 * %-ENODATA if the property does not have a value,
230 * %-EPROTO if the property is not an array of numbers,
231 * %-EOVERFLOW if the size of the property is not as expected,
232 * %-ENXIO if no suitable firmware interface is present.
233 */
234int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
235 const char *propname, u8 *val, size_t nval)
236{
237 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8,
238 val, nval);
239}
240EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
241
242/**
243 * fwnode_property_read_u16_array - return a u16 array property of firmware node
244 * @fwnode: Firmware node to get the property of
245 * @propname: Name of the property
246 * @val: The values are stored here
247 * @nval: Size of the @val array
248 *
249 * Read an array of u16 properties with @propname from @fwnode and store them to
250 * @val if found.
251 *
252 * Return: %0 if the property was found (success),
253 * %-EINVAL if given arguments are not valid,
254 * %-ENODATA if the property does not have a value,
255 * %-EPROTO if the property is not an array of numbers,
256 * %-EOVERFLOW if the size of the property is not as expected,
257 * %-ENXIO if no suitable firmware interface is present.
258 */
259int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
260 const char *propname, u16 *val, size_t nval)
261{
262 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16,
263 val, nval);
264}
265EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
266
267/**
268 * fwnode_property_read_u32_array - return a u32 array property of firmware node
269 * @fwnode: Firmware node to get the property of
270 * @propname: Name of the property
271 * @val: The values are stored here
272 * @nval: Size of the @val array
273 *
274 * Read an array of u32 properties with @propname from @fwnode store them to
275 * @val if found.
276 *
277 * Return: %0 if the property was found (success),
278 * %-EINVAL if given arguments are not valid,
279 * %-ENODATA if the property does not have a value,
280 * %-EPROTO if the property is not an array of numbers,
281 * %-EOVERFLOW if the size of the property is not as expected,
282 * %-ENXIO if no suitable firmware interface is present.
283 */
284int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
285 const char *propname, u32 *val, size_t nval)
286{
287 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32,
288 val, nval);
289}
290EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
291
292/**
293 * fwnode_property_read_u64_array - return a u64 array property firmware node
294 * @fwnode: Firmware node to get the property of
295 * @propname: Name of the property
296 * @val: The values are stored here
297 * @nval: Size of the @val array
298 *
299 * Read an array of u64 properties with @propname from @fwnode and store them to
300 * @val if found.
301 *
302 * Return: %0 if the property was found (success),
303 * %-EINVAL if given arguments are not valid,
304 * %-ENODATA if the property does not have a value,
305 * %-EPROTO if the property is not an array of numbers,
306 * %-EOVERFLOW if the size of the property is not as expected,
307 * %-ENXIO if no suitable firmware interface is present.
308 */
309int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
310 const char *propname, u64 *val, size_t nval)
311{
312 return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64,
313 val, nval);
314}
315EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
316
317/**
318 * fwnode_property_read_string_array - return string array property of a node
319 * @fwnode: Firmware node to get the property of
320 * @propname: Name of the property
321 * @val: The values are stored here
322 * @nval: Size of the @val array
323 *
324 * Read an string list property @propname from the given firmware node and store
325 * them to @val if found.
326 *
327 * Return: %0 if the property was found (success),
328 * %-EINVAL if given arguments are not valid,
329 * %-ENODATA if the property does not have a value,
330 * %-EPROTO if the property is not an array of strings,
331 * %-EOVERFLOW if the size of the property is not as expected,
332 * %-ENXIO if no suitable firmware interface is present.
333 */
334int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
335 const char *propname, const char **val,
336 size_t nval)
337{
338 if (is_of_node(fwnode))
339 return of_property_read_string_array(of_node(fwnode), propname,
340 val, nval);
341 else if (is_acpi_node(fwnode))
342 return acpi_dev_prop_read(acpi_node(fwnode), propname,
343 DEV_PROP_STRING, val, nval);
344
345 return -ENXIO;
346}
347EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
348
349/**
350 * fwnode_property_read_string - return a string property of a firmware node
351 * @fwnode: Firmware node to get the property of
352 * @propname: Name of the property
353 * @val: The value is stored here
354 *
355 * Read property @propname from the given firmware node and store the value into
356 * @val if found. The value is checked to be a string.
357 *
358 * Return: %0 if the property was found (success),
359 * %-EINVAL if given arguments are not valid,
360 * %-ENODATA if the property does not have a value,
361 * %-EPROTO or %-EILSEQ if the property is not a string,
362 * %-ENXIO if no suitable firmware interface is present.
363 */
364int fwnode_property_read_string(struct fwnode_handle *fwnode,
365 const char *propname, const char **val)
366{
367 if (is_of_node(fwnode))
368 return of_property_read_string(of_node(fwnode),propname, val);
369 else if (is_acpi_node(fwnode))
370 return acpi_dev_prop_read(acpi_node(fwnode), propname,
371 DEV_PROP_STRING, val, 1);
372
373 return -ENXIO;
374}
375EXPORT_SYMBOL_GPL(fwnode_property_read_string);
376
377/**
378 * device_get_next_child_node - Return the next child node handle for a device
379 * @dev: Device to find the next child node for.
380 * @child: Handle to one of the device's child nodes or a null handle.
381 */
382struct fwnode_handle *device_get_next_child_node(struct device *dev,
383 struct fwnode_handle *child)
384{
385 if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
386 struct device_node *node;
387
388 node = of_get_next_available_child(dev->of_node, of_node(child));
389 if (node)
390 return &node->fwnode;
391 } else if (IS_ENABLED(CONFIG_ACPI)) {
392 struct acpi_device *node;
393
394 node = acpi_get_next_child(dev, acpi_node(child));
395 if (node)
396 return acpi_fwnode_handle(node);
397 }
398 return NULL;
399}
400EXPORT_SYMBOL_GPL(device_get_next_child_node);
401
402/**
403 * fwnode_handle_put - Drop reference to a device node
404 * @fwnode: Pointer to the device node to drop the reference to.
405 *
406 * This has to be used when terminating device_for_each_child_node() iteration
407 * with break or return to prevent stale device node references from being left
408 * behind.
409 */
410void fwnode_handle_put(struct fwnode_handle *fwnode)
411{
412 if (is_of_node(fwnode))
413 of_node_put(of_node(fwnode));
414}
415EXPORT_SYMBOL_GPL(fwnode_handle_put);
416
417/**
418 * device_get_child_node_count - return the number of child nodes for device
419 * @dev: Device to cound the child nodes for
420 */
421unsigned int device_get_child_node_count(struct device *dev)
422{
423 struct fwnode_handle *child;
424 unsigned int count = 0;
425
426 device_for_each_child_node(dev, child)
427 count++;
428
429 return count;
430}
431EXPORT_SYMBOL_GPL(device_get_child_node_count);