aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 00:17:00 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 00:17:00 -0500
commit92a578b064d0227a3a7fbbdb9e29dbab7f8d400e (patch)
tree1979a62f38e24997a7312c4ce753860cc95b389b /drivers/base
parentc75059c46293adf1560162c17148ab94624f5ed2 (diff)
parente3d857e1ae787a5e268bc89425aadae09c8e95a4 (diff)
Merge tag 'pm+acpi-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael Wysocki: "This time we have some more new material than we used to have during the last couple of development cycles. The most important part of it to me is the introduction of a unified interface for accessing device properties provided by platform firmware. It works with Device Trees and ACPI in a uniform way and drivers using it need not worry about where the properties come from as long as the platform firmware (either DT or ACPI) makes them available. It covers both devices and "bare" device node objects without struct device representation as that turns out to be necessary in some cases. This has been in the works for quite a few months (and development cycles) and has been approved by all of the relevant maintainers. On top of that, some drivers are switched over to the new interface (at25, leds-gpio, gpio_keys_polled) and some additional changes are made to the core GPIO subsystem to allow device drivers to manipulate GPIOs in the "canonical" way on platforms that provide GPIO information in their ACPI tables, but don't assign names to GPIO lines (in which case the driver needs to do that on the basis of what it knows about the device in question). That also has been approved by the GPIO core maintainers and the rfkill driver is now going to use it. Second is support for hardware P-states in the intel_pstate driver. It uses CPUID to detect whether or not the feature is supported by the processor in which case it will be enabled by default. However, it can be disabled entirely from the kernel command line if necessary. Next is support for a platform firmware interface based on ACPI operation regions used by the PMIC (Power Management Integrated Circuit) chips on the Intel Baytrail-T and Baytrail-T-CR platforms. That interface is used for manipulating power resources and for thermal management: sensor temperature reporting, trip point setting and so on. Also the ACPI core is now going to support the _DEP configuration information in a limited way. Basically, _DEP it supposed to reflect off-the-hierarchy dependencies between devices which may be very indirect, like when AML for one device accesses locations in an operation region handled by another device's driver (usually, the device depended on this way is a serial bus or GPIO controller). The support added this time is sufficient to make the ACPI battery driver work on Asus T100A, but it is general enough to be able to cover some other use cases in the future. Finally, we have a new cpufreq driver for the Loongson1B processor. In addition to the above, there are fixes and cleanups all over the place as usual and a traditional ACPICA update to a recent upstream release. As far as the fixes go, the ACPI LPSS (Low-power Subsystem) driver for Intel platforms should be able to handle power management of the DMA engine correctly, the cpufreq-dt driver should interact with the thermal subsystem in a better way and the ACPI backlight driver should handle some more corner cases, among other things. On top of the ACPICA update there are fixes for race conditions in the ACPICA's interrupt handling code which might lead to some random and strange looking failures on some systems. In the cleanups department the most visible part is the series of commits targeted at getting rid of the CONFIG_PM_RUNTIME configuration option. That was triggered by a discussion regarding the generic power domains code during which we realized that trying to support certain combinations of PM config options was painful and not really worth it, because nobody would use them in production anyway. For this reason, we decided to make CONFIG_PM_SLEEP select CONFIG_PM_RUNTIME and that lead to the conclusion that the latter became redundant and CONFIG_PM could be used instead of it. The material here makes that replacement in a major part of the tree, but there will be at least one more batch of that in the second part of the merge window. Specifics: - Support for retrieving device properties information from ACPI _DSD device configuration objects and a unified device properties interface for device drivers (and subsystems) on top of that. As stated above, this works with Device Trees and ACPI and allows device drivers to be written in a platform firmware (DT or ACPI) agnostic way. The at25, leds-gpio and gpio_keys_polled drivers are now going to use this new interface and the GPIO subsystem is additionally modified to allow device drivers to assign names to GPIO resources returned by ACPI _CRS objects (in case _DSD is not present or does not provide the expected data). The changes in this set are mostly from Mika Westerberg, Rafael J Wysocki, Aaron Lu, and Darren Hart with some fixes from others (Fabio Estevam, Geert Uytterhoeven). - Support for Hardware Managed Performance States (HWP) as described in Volume 3, section 14.4, of the Intel SDM in the intel_pstate driver. CPUID is used to detect whether or not the feature is supported by the processor. If supported, it will be enabled automatically unless the intel_pstate=no_hwp switch is present in the kernel command line. From Dirk Brandewie. - New Intel Broadwell-H ID for intel_pstate (Dirk Brandewie). - Support for firmware interface based on ACPI operation regions used by the PMIC chips on the Intel Baytrail-T and Baytrail-T-CR platforms for power resource control and thermal management (Aaron Lu). - Limited support for retrieving off-the-hierarchy dependencies between devices from ACPI _DEP device configuration objects and deferred probing support for the ACPI battery driver based on the _DEP information to make that driver work on Asus T100A (Lan Tianyu). - New cpufreq driver for the Loongson1B processor (Kelvin Cheung). - ACPICA update to upstream revision 20141107 which only affects tools (Bob Moore). - Fixes for race conditions in the ACPICA's interrupt handling code and in the ACPI code related to system suspend and resume (Lv Zheng and Rafael J Wysocki). - ACPI core fix for an RCU-related issue in the ioremap() regions management code that slowed down significantly after CPUs had been allowed to enter idle states even if they'd had RCU callbakcs queued and triggered some problems in certain proprietary graphics driver (and elsewhere). The fix replaces synchronize_rcu() in that code with synchronize_rcu_expedited() which makes the issue go away. From Konstantin Khlebnikov. - ACPI LPSS (Low-Power Subsystem) driver fix to handle power management of the DMA engine included into the LPSS correctly. The problem is that the DMA engine doesn't have ACPI PM support of its own and it simply is turned off when the last LPSS device having ACPI PM support goes into D3cold. To work around that, the PM domain used by the ACPI LPSS driver is redesigned so at least one device with ACPI PM support will be on as long as the DMA engine is in use. From Andy Shevchenko. - ACPI backlight driver fix to avoid using it on "Win8-compatible" systems where it doesn't work and where it was used by default by mistake (Aaron Lu). - Assorted minor ACPI core fixes and cleanups from Tomasz Nowicki, Sudeep Holla, Huang Rui, Hanjun Guo, Fabian Frederick, and Ashwin Chaugule (mostly related to the upcoming ARM64 support). - Intel RAPL (Running Average Power Limit) power capping driver fixes and improvements including new processor IDs (Jacob Pan). - Generic power domains modification to power up domains after attaching devices to them to meet the expectations of device drivers and bus types assuming devices to be accessible at probe time (Ulf Hansson). - Preliminary support for controlling device clocks from the generic power domains core code and modifications of the ARM/shmobile platform to use that feature (Ulf Hansson). - Assorted minor fixes and cleanups of the generic power domains core code (Ulf Hansson, Geert Uytterhoeven). - Assorted minor fixes and cleanups of the device clocks control code in the PM core (Geert Uytterhoeven, Grygorii Strashko). - Consolidation of device power management Kconfig options by making CONFIG_PM_SLEEP select CONFIG_PM_RUNTIME and removing the latter which is now redundant (Rafael J Wysocki and Kevin Hilman). That is the first batch of the changes needed for this purpose. - Core device runtime power management support code cleanup related to the execution of callbacks (Andrzej Hajda). - cpuidle ARM support improvements (Lorenzo Pieralisi). - cpuidle cleanup related to the CPUIDLE_FLAG_TIME_VALID flag and a new MAINTAINERS entry for ARM Exynos cpuidle (Daniel Lezcano and Bartlomiej Zolnierkiewicz). - New cpufreq driver callback (->ready) to be executed when the cpufreq core is ready to use a given policy object and cpufreq-dt driver modification to use that callback for cooling device registration (Viresh Kumar). - cpufreq core fixes and cleanups (Viresh Kumar, Vince Hsu, James Geboski, Tomeu Vizoso). - Assorted fixes and cleanups in the cpufreq-pcc, intel_pstate, cpufreq-dt, pxa2xx cpufreq drivers (Lenny Szubowicz, Ethan Zhao, Stefan Wahren, Petr Cvek). - OPP (Operating Performance Points) framework modification to allow OPPs to be removed too and update of a few cpufreq drivers (cpufreq-dt, exynos5440, imx6q, cpufreq) to remove OPPs (added during initialization) on driver removal (Viresh Kumar). - Hibernation core fixes and cleanups (Tina Ruchandani and Markus Elfring). - PM Kconfig fix related to CPU power management (Pankaj Dubey). - cpupower tool fix (Prarit Bhargava)" * tag 'pm+acpi-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (120 commits) i2c-omap / PM: Drop CONFIG_PM_RUNTIME from i2c-omap.c dmaengine / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM tools: cpupower: fix return checks for sysfs_get_idlestate_count() drivers: sh / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM e1000e / igb / PM: Eliminate CONFIG_PM_RUNTIME MMC / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM MFD / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM misc / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM media / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM input / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM leds: leds-gpio: Fix multiple instances registration without 'label' property iio / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM hsi / OMAP / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM i2c-hid / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM drm / exynos / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM gpio / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM hwrandom / exynos / PM: Use CONFIG_PM in #ifdef block / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM USB / PM: Drop CONFIG_PM_RUNTIME from the USB core PM: Merge the SET*_RUNTIME_PM_OPS() macros ...
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/opp.c196
-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
10 files changed, 771 insertions, 322 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/opp.c b/drivers/base/power/opp.c
index 89ced955fafa..2d195f3a1998 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -49,11 +49,12 @@
49 * are protected by the dev_opp_list_lock for integrity. 49 * are protected by the dev_opp_list_lock for integrity.
50 * IMPORTANT: the opp nodes should be maintained in increasing 50 * IMPORTANT: the opp nodes should be maintained in increasing
51 * order. 51 * order.
52 * @dynamic: not-created from static DT entries.
52 * @available: true/false - marks if this OPP as available or not 53 * @available: true/false - marks if this OPP as available or not
53 * @rate: Frequency in hertz 54 * @rate: Frequency in hertz
54 * @u_volt: Nominal voltage in microvolts corresponding to this OPP 55 * @u_volt: Nominal voltage in microvolts corresponding to this OPP
55 * @dev_opp: points back to the device_opp struct this opp belongs to 56 * @dev_opp: points back to the device_opp struct this opp belongs to
56 * @head: RCU callback head used for deferred freeing 57 * @rcu_head: RCU callback head used for deferred freeing
57 * 58 *
58 * This structure stores the OPP information for a given device. 59 * This structure stores the OPP information for a given device.
59 */ 60 */
@@ -61,11 +62,12 @@ struct dev_pm_opp {
61 struct list_head node; 62 struct list_head node;
62 63
63 bool available; 64 bool available;
65 bool dynamic;
64 unsigned long rate; 66 unsigned long rate;
65 unsigned long u_volt; 67 unsigned long u_volt;
66 68
67 struct device_opp *dev_opp; 69 struct device_opp *dev_opp;
68 struct rcu_head head; 70 struct rcu_head rcu_head;
69}; 71};
70 72
71/** 73/**
@@ -76,7 +78,8 @@ struct dev_pm_opp {
76 * RCU usage: nodes are not modified in the list of device_opp, 78 * RCU usage: nodes are not modified in the list of device_opp,
77 * however addition is possible and is secured by dev_opp_list_lock 79 * however addition is possible and is secured by dev_opp_list_lock
78 * @dev: device pointer 80 * @dev: device pointer
79 * @head: notifier head to notify the OPP availability changes. 81 * @srcu_head: notifier head to notify the OPP availability changes.
82 * @rcu_head: RCU callback head used for deferred freeing
80 * @opp_list: list of opps 83 * @opp_list: list of opps
81 * 84 *
82 * This is an internal data structure maintaining the link to opps attached to 85 * This is an internal data structure maintaining the link to opps attached to
@@ -87,7 +90,8 @@ struct device_opp {
87 struct list_head node; 90 struct list_head node;
88 91
89 struct device *dev; 92 struct device *dev;
90 struct srcu_notifier_head head; 93 struct srcu_notifier_head srcu_head;
94 struct rcu_head rcu_head;
91 struct list_head opp_list; 95 struct list_head opp_list;
92}; 96};
93 97
@@ -378,30 +382,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
378} 382}
379EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); 383EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
380 384
381/** 385static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq,
382 * dev_pm_opp_add() - Add an OPP table from a table definitions 386 unsigned long u_volt, bool dynamic)
383 * @dev: device for which we do this operation
384 * @freq: Frequency in Hz for this OPP
385 * @u_volt: Voltage in uVolts for this OPP
386 *
387 * This function adds an opp definition to the opp list and returns status.
388 * The opp is made available by default and it can be controlled using
389 * dev_pm_opp_enable/disable functions.
390 *
391 * Locking: The internal device_opp and opp structures are RCU protected.
392 * Hence this function internally uses RCU updater strategy with mutex locks
393 * to keep the integrity of the internal data structures. Callers should ensure
394 * that this function is *NOT* called under RCU protection or in contexts where
395 * mutex cannot be locked.
396 *
397 * Return:
398 * 0: On success OR
399 * Duplicate OPPs (both freq and volt are same) and opp->available
400 * -EEXIST: Freq are same and volt are different OR
401 * Duplicate OPPs (both freq and volt are same) and !opp->available
402 * -ENOMEM: Memory allocation failure
403 */
404int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
405{ 387{
406 struct device_opp *dev_opp = NULL; 388 struct device_opp *dev_opp = NULL;
407 struct dev_pm_opp *opp, *new_opp; 389 struct dev_pm_opp *opp, *new_opp;
@@ -417,6 +399,13 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
417 /* Hold our list modification lock here */ 399 /* Hold our list modification lock here */
418 mutex_lock(&dev_opp_list_lock); 400 mutex_lock(&dev_opp_list_lock);
419 401
402 /* populate the opp table */
403 new_opp->dev_opp = dev_opp;
404 new_opp->rate = freq;
405 new_opp->u_volt = u_volt;
406 new_opp->available = true;
407 new_opp->dynamic = dynamic;
408
420 /* Check for existing list for 'dev' */ 409 /* Check for existing list for 'dev' */
421 dev_opp = find_device_opp(dev); 410 dev_opp = find_device_opp(dev);
422 if (IS_ERR(dev_opp)) { 411 if (IS_ERR(dev_opp)) {
@@ -436,19 +425,15 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
436 } 425 }
437 426
438 dev_opp->dev = dev; 427 dev_opp->dev = dev;
439 srcu_init_notifier_head(&dev_opp->head); 428 srcu_init_notifier_head(&dev_opp->srcu_head);
440 INIT_LIST_HEAD(&dev_opp->opp_list); 429 INIT_LIST_HEAD(&dev_opp->opp_list);
441 430
442 /* Secure the device list modification */ 431 /* Secure the device list modification */
443 list_add_rcu(&dev_opp->node, &dev_opp_list); 432 list_add_rcu(&dev_opp->node, &dev_opp_list);
433 head = &dev_opp->opp_list;
434 goto list_add;
444 } 435 }
445 436
446 /* populate the opp table */
447 new_opp->dev_opp = dev_opp;
448 new_opp->rate = freq;
449 new_opp->u_volt = u_volt;
450 new_opp->available = true;
451
452 /* 437 /*
453 * Insert new OPP in order of increasing frequency 438 * Insert new OPP in order of increasing frequency
454 * and discard if already present 439 * and discard if already present
@@ -474,6 +459,7 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
474 return ret; 459 return ret;
475 } 460 }
476 461
462list_add:
477 list_add_rcu(&new_opp->node, head); 463 list_add_rcu(&new_opp->node, head);
478 mutex_unlock(&dev_opp_list_lock); 464 mutex_unlock(&dev_opp_list_lock);
479 465
@@ -481,11 +467,109 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
481 * Notify the changes in the availability of the operable 467 * Notify the changes in the availability of the operable
482 * frequency/voltage list. 468 * frequency/voltage list.
483 */ 469 */
484 srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp); 470 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp);
485 return 0; 471 return 0;
486} 472}
473
474/**
475 * dev_pm_opp_add() - Add an OPP table from a table definitions
476 * @dev: device for which we do this operation
477 * @freq: Frequency in Hz for this OPP
478 * @u_volt: Voltage in uVolts for this OPP
479 *
480 * This function adds an opp definition to the opp list and returns status.
481 * The opp is made available by default and it can be controlled using
482 * dev_pm_opp_enable/disable functions.
483 *
484 * Locking: The internal device_opp and opp structures are RCU protected.
485 * Hence this function internally uses RCU updater strategy with mutex locks
486 * to keep the integrity of the internal data structures. Callers should ensure
487 * that this function is *NOT* called under RCU protection or in contexts where
488 * mutex cannot be locked.
489 *
490 * Return:
491 * 0: On success OR
492 * Duplicate OPPs (both freq and volt are same) and opp->available
493 * -EEXIST: Freq are same and volt are different OR
494 * Duplicate OPPs (both freq and volt are same) and !opp->available
495 * -ENOMEM: Memory allocation failure
496 */
497int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
498{
499 return dev_pm_opp_add_dynamic(dev, freq, u_volt, true);
500}
487EXPORT_SYMBOL_GPL(dev_pm_opp_add); 501EXPORT_SYMBOL_GPL(dev_pm_opp_add);
488 502
503static void kfree_opp_rcu(struct rcu_head *head)
504{
505 struct dev_pm_opp *opp = container_of(head, struct dev_pm_opp, rcu_head);
506
507 kfree_rcu(opp, rcu_head);
508}
509
510static void kfree_device_rcu(struct rcu_head *head)
511{
512 struct device_opp *device_opp = container_of(head, struct device_opp, rcu_head);
513
514 kfree(device_opp);
515}
516
517void __dev_pm_opp_remove(struct device_opp *dev_opp, struct dev_pm_opp *opp)
518{
519 /*
520 * Notify the changes in the availability of the operable
521 * frequency/voltage list.
522 */
523 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_REMOVE, opp);
524 list_del_rcu(&opp->node);
525 call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, kfree_opp_rcu);
526
527 if (list_empty(&dev_opp->opp_list)) {
528 list_del_rcu(&dev_opp->node);
529 call_srcu(&dev_opp->srcu_head.srcu, &dev_opp->rcu_head,
530 kfree_device_rcu);
531 }
532}
533
534/**
535 * dev_pm_opp_remove() - Remove an OPP from OPP list
536 * @dev: device for which we do this operation
537 * @freq: OPP to remove with matching 'freq'
538 *
539 * This function removes an opp from the opp list.
540 */
541void dev_pm_opp_remove(struct device *dev, unsigned long freq)
542{
543 struct dev_pm_opp *opp;
544 struct device_opp *dev_opp;
545 bool found = false;
546
547 /* Hold our list modification lock here */
548 mutex_lock(&dev_opp_list_lock);
549
550 dev_opp = find_device_opp(dev);
551 if (IS_ERR(dev_opp))
552 goto unlock;
553
554 list_for_each_entry(opp, &dev_opp->opp_list, node) {
555 if (opp->rate == freq) {
556 found = true;
557 break;
558 }
559 }
560
561 if (!found) {
562 dev_warn(dev, "%s: Couldn't find OPP with freq: %lu\n",
563 __func__, freq);
564 goto unlock;
565 }
566
567 __dev_pm_opp_remove(dev_opp, opp);
568unlock:
569 mutex_unlock(&dev_opp_list_lock);
570}
571EXPORT_SYMBOL_GPL(dev_pm_opp_remove);
572
489/** 573/**
490 * opp_set_availability() - helper to set the availability of an opp 574 * opp_set_availability() - helper to set the availability of an opp
491 * @dev: device for which we do this operation 575 * @dev: device for which we do this operation
@@ -557,14 +641,14 @@ static int opp_set_availability(struct device *dev, unsigned long freq,
557 641
558 list_replace_rcu(&opp->node, &new_opp->node); 642 list_replace_rcu(&opp->node, &new_opp->node);
559 mutex_unlock(&dev_opp_list_lock); 643 mutex_unlock(&dev_opp_list_lock);
560 kfree_rcu(opp, head); 644 call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, kfree_opp_rcu);
561 645
562 /* Notify the change of the OPP availability */ 646 /* Notify the change of the OPP availability */
563 if (availability_req) 647 if (availability_req)
564 srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ENABLE, 648 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ENABLE,
565 new_opp); 649 new_opp);
566 else 650 else
567 srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_DISABLE, 651 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_DISABLE,
568 new_opp); 652 new_opp);
569 653
570 return 0; 654 return 0;
@@ -629,7 +713,7 @@ struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev)
629 if (IS_ERR(dev_opp)) 713 if (IS_ERR(dev_opp))
630 return ERR_CAST(dev_opp); /* matching type */ 714 return ERR_CAST(dev_opp); /* matching type */
631 715
632 return &dev_opp->head; 716 return &dev_opp->srcu_head;
633} 717}
634 718
635#ifdef CONFIG_OF 719#ifdef CONFIG_OF
@@ -666,7 +750,7 @@ int of_init_opp_table(struct device *dev)
666 unsigned long freq = be32_to_cpup(val++) * 1000; 750 unsigned long freq = be32_to_cpup(val++) * 1000;
667 unsigned long volt = be32_to_cpup(val++); 751 unsigned long volt = be32_to_cpup(val++);
668 752
669 if (dev_pm_opp_add(dev, freq, volt)) 753 if (dev_pm_opp_add_dynamic(dev, freq, volt, false))
670 dev_warn(dev, "%s: Failed to add OPP %ld\n", 754 dev_warn(dev, "%s: Failed to add OPP %ld\n",
671 __func__, freq); 755 __func__, freq);
672 nr -= 2; 756 nr -= 2;
@@ -675,4 +759,34 @@ int of_init_opp_table(struct device *dev)
675 return 0; 759 return 0;
676} 760}
677EXPORT_SYMBOL_GPL(of_init_opp_table); 761EXPORT_SYMBOL_GPL(of_init_opp_table);
762
763/**
764 * of_free_opp_table() - Free OPP table entries created from static DT entries
765 * @dev: device pointer used to lookup device OPPs.
766 *
767 * Free OPPs created using static entries present in DT.
768 */
769void of_free_opp_table(struct device *dev)
770{
771 struct device_opp *dev_opp = find_device_opp(dev);
772 struct dev_pm_opp *opp, *tmp;
773
774 /* Check for existing list for 'dev' */
775 dev_opp = find_device_opp(dev);
776 if (WARN(IS_ERR(dev_opp), "%s: dev_opp: %ld\n", dev_name(dev),
777 PTR_ERR(dev_opp)))
778 return;
779
780 /* Hold our list modification lock here */
781 mutex_lock(&dev_opp_list_lock);
782
783 /* Free static OPPs */
784 list_for_each_entry_safe(opp, tmp, &dev_opp->opp_list, node) {
785 if (!opp->dynamic)
786 __dev_pm_opp_remove(dev_opp, opp);
787 }
788
789 mutex_unlock(&dev_opp_list_lock);
790}
791EXPORT_SYMBOL_GPL(of_free_opp_table);
678#endif 792#endif
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);