aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c51
-rw-r--r--drivers/base/dd.c14
-rw-r--r--drivers/base/platform.c2
-rw-r--r--drivers/base/power/domain.c70
-rw-r--r--drivers/base/power/main.c20
-rw-r--r--drivers/base/power/trace.c6
-rw-r--r--drivers/base/property.c198
7 files changed, 278 insertions, 83 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index cadf165651d8..21d13038534e 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/fwnode.h>
15#include <linux/init.h> 16#include <linux/init.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
@@ -2144,3 +2145,53 @@ define_dev_printk_level(dev_notice, KERN_NOTICE);
2144define_dev_printk_level(_dev_info, KERN_INFO); 2145define_dev_printk_level(_dev_info, KERN_INFO);
2145 2146
2146#endif 2147#endif
2148
2149static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
2150{
2151 return fwnode && !IS_ERR(fwnode->secondary);
2152}
2153
2154/**
2155 * set_primary_fwnode - Change the primary firmware node of a given device.
2156 * @dev: Device to handle.
2157 * @fwnode: New primary firmware node of the device.
2158 *
2159 * Set the device's firmware node pointer to @fwnode, but if a secondary
2160 * firmware node of the device is present, preserve it.
2161 */
2162void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
2163{
2164 if (fwnode) {
2165 struct fwnode_handle *fn = dev->fwnode;
2166
2167 if (fwnode_is_primary(fn))
2168 fn = fn->secondary;
2169
2170 fwnode->secondary = fn;
2171 dev->fwnode = fwnode;
2172 } else {
2173 dev->fwnode = fwnode_is_primary(dev->fwnode) ?
2174 dev->fwnode->secondary : NULL;
2175 }
2176}
2177EXPORT_SYMBOL_GPL(set_primary_fwnode);
2178
2179/**
2180 * set_secondary_fwnode - Change the secondary firmware node of a given device.
2181 * @dev: Device to handle.
2182 * @fwnode: New secondary firmware node of the device.
2183 *
2184 * If a primary firmware node of the device is present, set its secondary
2185 * pointer to @fwnode. Otherwise, set the device's firmware node pointer to
2186 * @fwnode.
2187 */
2188void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
2189{
2190 if (fwnode)
2191 fwnode->secondary = ERR_PTR(-ENODEV);
2192
2193 if (fwnode_is_primary(dev->fwnode))
2194 dev->fwnode->secondary = fwnode;
2195 else
2196 dev->fwnode = fwnode;
2197}
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 49a4a12fafef..e843fdbe4925 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -298,6 +298,12 @@ static int really_probe(struct device *dev, struct device_driver *drv)
298 goto probe_failed; 298 goto probe_failed;
299 } 299 }
300 300
301 if (dev->pm_domain && dev->pm_domain->activate) {
302 ret = dev->pm_domain->activate(dev);
303 if (ret)
304 goto probe_failed;
305 }
306
301 if (dev->bus->probe) { 307 if (dev->bus->probe) {
302 ret = dev->bus->probe(dev); 308 ret = dev->bus->probe(dev);
303 if (ret) 309 if (ret)
@@ -308,6 +314,9 @@ static int really_probe(struct device *dev, struct device_driver *drv)
308 goto probe_failed; 314 goto probe_failed;
309 } 315 }
310 316
317 if (dev->pm_domain && dev->pm_domain->sync)
318 dev->pm_domain->sync(dev);
319
311 driver_bound(dev); 320 driver_bound(dev);
312 ret = 1; 321 ret = 1;
313 pr_debug("bus: '%s': %s: bound device %s to driver %s\n", 322 pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
@@ -319,6 +328,8 @@ probe_failed:
319 driver_sysfs_remove(dev); 328 driver_sysfs_remove(dev);
320 dev->driver = NULL; 329 dev->driver = NULL;
321 dev_set_drvdata(dev, NULL); 330 dev_set_drvdata(dev, NULL);
331 if (dev->pm_domain && dev->pm_domain->dismiss)
332 dev->pm_domain->dismiss(dev);
322 333
323 switch (ret) { 334 switch (ret) {
324 case -EPROBE_DEFER: 335 case -EPROBE_DEFER:
@@ -529,6 +540,9 @@ static void __device_release_driver(struct device *dev)
529 devres_release_all(dev); 540 devres_release_all(dev);
530 dev->driver = NULL; 541 dev->driver = NULL;
531 dev_set_drvdata(dev, NULL); 542 dev_set_drvdata(dev, NULL);
543 if (dev->pm_domain && dev->pm_domain->dismiss)
544 dev->pm_domain->dismiss(dev);
545
532 klist_remove(&dev->p->knode_driver); 546 klist_remove(&dev->p->knode_driver);
533 if (dev->bus) 547 if (dev->bus)
534 blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 548 blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index e68ab79df28b..ebf034b97278 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -463,7 +463,7 @@ struct platform_device *platform_device_register_full(
463 goto err_alloc; 463 goto err_alloc;
464 464
465 pdev->dev.parent = pdevinfo->parent; 465 pdev->dev.parent = pdevinfo->parent;
466 ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); 466 pdev->dev.fwnode = pdevinfo->fwnode;
467 467
468 if (pdevinfo->dma_mask) { 468 if (pdevinfo->dma_mask) {
469 /* 469 /*
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 45937f88e77c..2327613d4539 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -68,7 +68,36 @@ static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
68 return genpd; 68 return genpd;
69} 69}
70 70
71struct generic_pm_domain *dev_to_genpd(struct device *dev) 71/*
72 * Get the generic PM domain for a particular struct device.
73 * This validates the struct device pointer, the PM domain pointer,
74 * and checks that the PM domain pointer is a real generic PM domain.
75 * Any failure results in NULL being returned.
76 */
77struct generic_pm_domain *pm_genpd_lookup_dev(struct device *dev)
78{
79 struct generic_pm_domain *genpd = NULL, *gpd;
80
81 if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(dev->pm_domain))
82 return NULL;
83
84 mutex_lock(&gpd_list_lock);
85 list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
86 if (&gpd->domain == dev->pm_domain) {
87 genpd = gpd;
88 break;
89 }
90 }
91 mutex_unlock(&gpd_list_lock);
92
93 return genpd;
94}
95
96/*
97 * This should only be used where we are certain that the pm_domain
98 * attached to the device is a genpd domain.
99 */
100static struct generic_pm_domain *dev_to_genpd(struct device *dev)
72{ 101{
73 if (IS_ERR_OR_NULL(dev->pm_domain)) 102 if (IS_ERR_OR_NULL(dev->pm_domain))
74 return ERR_PTR(-EINVAL); 103 return ERR_PTR(-EINVAL);
@@ -173,8 +202,8 @@ static int genpd_power_on(struct generic_pm_domain *genpd)
173 genpd->power_on_latency_ns = elapsed_ns; 202 genpd->power_on_latency_ns = elapsed_ns;
174 genpd->max_off_time_changed = true; 203 genpd->max_off_time_changed = true;
175 genpd_recalc_cpu_exit_latency(genpd); 204 genpd_recalc_cpu_exit_latency(genpd);
176 pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n", 205 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
177 genpd->name, "on", elapsed_ns); 206 genpd->name, "on", elapsed_ns);
178 207
179 return ret; 208 return ret;
180} 209}
@@ -199,8 +228,8 @@ static int genpd_power_off(struct generic_pm_domain *genpd)
199 228
200 genpd->power_off_latency_ns = elapsed_ns; 229 genpd->power_off_latency_ns = elapsed_ns;
201 genpd->max_off_time_changed = true; 230 genpd->max_off_time_changed = true;
202 pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n", 231 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
203 genpd->name, "off", elapsed_ns); 232 genpd->name, "off", elapsed_ns);
204 233
205 return ret; 234 return ret;
206} 235}
@@ -1513,9 +1542,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1513 1542
1514 dev_dbg(dev, "%s()\n", __func__); 1543 dev_dbg(dev, "%s()\n", __func__);
1515 1544
1516 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev) 1545 if (!genpd || genpd != pm_genpd_lookup_dev(dev))
1517 || IS_ERR_OR_NULL(dev->pm_domain)
1518 || pd_to_genpd(dev->pm_domain) != genpd)
1519 return -EINVAL; 1546 return -EINVAL;
1520 1547
1521 /* The above validation also means we have existing domain_data. */ 1548 /* The above validation also means we have existing domain_data. */
@@ -2093,21 +2120,10 @@ EXPORT_SYMBOL_GPL(of_genpd_get_from_provider);
2093 */ 2120 */
2094static void genpd_dev_pm_detach(struct device *dev, bool power_off) 2121static void genpd_dev_pm_detach(struct device *dev, bool power_off)
2095{ 2122{
2096 struct generic_pm_domain *pd = NULL, *gpd; 2123 struct generic_pm_domain *pd;
2097 int ret = 0; 2124 int ret = 0;
2098 2125
2099 if (!dev->pm_domain) 2126 pd = pm_genpd_lookup_dev(dev);
2100 return;
2101
2102 mutex_lock(&gpd_list_lock);
2103 list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
2104 if (&gpd->domain == dev->pm_domain) {
2105 pd = gpd;
2106 break;
2107 }
2108 }
2109 mutex_unlock(&gpd_list_lock);
2110
2111 if (!pd) 2127 if (!pd)
2112 return; 2128 return;
2113 2129
@@ -2130,6 +2146,17 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
2130 genpd_queue_power_off_work(pd); 2146 genpd_queue_power_off_work(pd);
2131} 2147}
2132 2148
2149static void genpd_dev_pm_sync(struct device *dev)
2150{
2151 struct generic_pm_domain *pd;
2152
2153 pd = dev_to_genpd(dev);
2154 if (IS_ERR(pd))
2155 return;
2156
2157 genpd_queue_power_off_work(pd);
2158}
2159
2133/** 2160/**
2134 * genpd_dev_pm_attach - Attach a device to its PM domain using DT. 2161 * genpd_dev_pm_attach - Attach a device to its PM domain using DT.
2135 * @dev: Device to attach. 2162 * @dev: Device to attach.
@@ -2196,6 +2223,7 @@ int genpd_dev_pm_attach(struct device *dev)
2196 } 2223 }
2197 2224
2198 dev->pm_domain->detach = genpd_dev_pm_detach; 2225 dev->pm_domain->detach = genpd_dev_pm_detach;
2226 dev->pm_domain->sync = genpd_dev_pm_sync;
2199 pm_genpd_poweron(pd); 2227 pm_genpd_poweron(pd);
2200 2228
2201 return 0; 2229 return 0;
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 9717d5f20139..3d874eca7104 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -23,7 +23,7 @@
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/pm_runtime.h> 25#include <linux/pm_runtime.h>
26#include <linux/resume-trace.h> 26#include <linux/pm-trace.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/async.h> 29#include <linux/async.h>
@@ -1017,6 +1017,9 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
1017 char *info = NULL; 1017 char *info = NULL;
1018 int error = 0; 1018 int error = 0;
1019 1019
1020 TRACE_DEVICE(dev);
1021 TRACE_SUSPEND(0);
1022
1020 if (async_error) 1023 if (async_error)
1021 goto Complete; 1024 goto Complete;
1022 1025
@@ -1057,6 +1060,7 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
1057 1060
1058Complete: 1061Complete:
1059 complete_all(&dev->power.completion); 1062 complete_all(&dev->power.completion);
1063 TRACE_SUSPEND(error);
1060 return error; 1064 return error;
1061} 1065}
1062 1066
@@ -1078,7 +1082,7 @@ static int device_suspend_noirq(struct device *dev)
1078{ 1082{
1079 reinit_completion(&dev->power.completion); 1083 reinit_completion(&dev->power.completion);
1080 1084
1081 if (pm_async_enabled && dev->power.async_suspend) { 1085 if (is_async(dev)) {
1082 get_device(dev); 1086 get_device(dev);
1083 async_schedule(async_suspend_noirq, dev); 1087 async_schedule(async_suspend_noirq, dev);
1084 return 0; 1088 return 0;
@@ -1157,6 +1161,9 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
1157 char *info = NULL; 1161 char *info = NULL;
1158 int error = 0; 1162 int error = 0;
1159 1163
1164 TRACE_DEVICE(dev);
1165 TRACE_SUSPEND(0);
1166
1160 __pm_runtime_disable(dev, false); 1167 __pm_runtime_disable(dev, false);
1161 1168
1162 if (async_error) 1169 if (async_error)
@@ -1198,6 +1205,7 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
1198 async_error = error; 1205 async_error = error;
1199 1206
1200Complete: 1207Complete:
1208 TRACE_SUSPEND(error);
1201 complete_all(&dev->power.completion); 1209 complete_all(&dev->power.completion);
1202 return error; 1210 return error;
1203} 1211}
@@ -1219,7 +1227,7 @@ static int device_suspend_late(struct device *dev)
1219{ 1227{
1220 reinit_completion(&dev->power.completion); 1228 reinit_completion(&dev->power.completion);
1221 1229
1222 if (pm_async_enabled && dev->power.async_suspend) { 1230 if (is_async(dev)) {
1223 get_device(dev); 1231 get_device(dev);
1224 async_schedule(async_suspend_late, dev); 1232 async_schedule(async_suspend_late, dev);
1225 return 0; 1233 return 0;
@@ -1338,6 +1346,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1338 int error = 0; 1346 int error = 0;
1339 DECLARE_DPM_WATCHDOG_ON_STACK(wd); 1347 DECLARE_DPM_WATCHDOG_ON_STACK(wd);
1340 1348
1349 TRACE_DEVICE(dev);
1350 TRACE_SUSPEND(0);
1351
1341 dpm_wait_for_children(dev, async); 1352 dpm_wait_for_children(dev, async);
1342 1353
1343 if (async_error) 1354 if (async_error)
@@ -1444,6 +1455,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1444 if (error) 1455 if (error)
1445 async_error = error; 1456 async_error = error;
1446 1457
1458 TRACE_SUSPEND(error);
1447 return error; 1459 return error;
1448} 1460}
1449 1461
@@ -1465,7 +1477,7 @@ static int device_suspend(struct device *dev)
1465{ 1477{
1466 reinit_completion(&dev->power.completion); 1478 reinit_completion(&dev->power.completion);
1467 1479
1468 if (pm_async_enabled && dev->power.async_suspend) { 1480 if (is_async(dev)) {
1469 get_device(dev); 1481 get_device(dev);
1470 async_schedule(async_suspend, dev); 1482 async_schedule(async_suspend, dev);
1471 return 0; 1483 return 0;
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c
index d94a1f5121cf..a311cfa4c5bd 100644
--- a/drivers/base/power/trace.c
+++ b/drivers/base/power/trace.c
@@ -7,7 +7,7 @@
7 * devices may be working. 7 * devices may be working.
8 */ 8 */
9 9
10#include <linux/resume-trace.h> 10#include <linux/pm-trace.h>
11#include <linux/export.h> 11#include <linux/export.h>
12#include <linux/rtc.h> 12#include <linux/rtc.h>
13 13
@@ -154,7 +154,7 @@ EXPORT_SYMBOL(set_trace_device);
154 * it's not any guarantee, but it's a high _likelihood_ that 154 * it's not any guarantee, but it's a high _likelihood_ that
155 * the match is valid). 155 * the match is valid).
156 */ 156 */
157void generate_resume_trace(const void *tracedata, unsigned int user) 157void generate_pm_trace(const void *tracedata, unsigned int user)
158{ 158{
159 unsigned short lineno = *(unsigned short *)tracedata; 159 unsigned short lineno = *(unsigned short *)tracedata;
160 const char *file = *(const char **)(tracedata + 2); 160 const char *file = *(const char **)(tracedata + 2);
@@ -164,7 +164,7 @@ void generate_resume_trace(const void *tracedata, unsigned int user)
164 file_hash_value = hash_string(lineno, file, FILEHASH); 164 file_hash_value = hash_string(lineno, file, FILEHASH);
165 set_magic_time(user_hash_value, file_hash_value, dev_hash_value); 165 set_magic_time(user_hash_value, file_hash_value, dev_hash_value);
166} 166}
167EXPORT_SYMBOL(generate_resume_trace); 167EXPORT_SYMBOL(generate_pm_trace);
168 168
169extern char __tracedata_start, __tracedata_end; 169extern char __tracedata_start, __tracedata_end;
170static int show_file_hash(unsigned int value) 170static int show_file_hash(unsigned int value)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 423df593f262..1d0b116cae95 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -10,10 +10,102 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/property.h>
14#include <linux/export.h>
15#include <linux/acpi.h> 13#include <linux/acpi.h>
14#include <linux/export.h>
15#include <linux/kernel.h>
16#include <linux/of.h> 16#include <linux/of.h>
17#include <linux/property.h>
18
19/**
20 * device_add_property_set - Add a collection of properties to a device object.
21 * @dev: Device to add properties to.
22 * @pset: Collection of properties to add.
23 *
24 * Associate a collection of device properties represented by @pset with @dev
25 * as its secondary firmware node.
26 */
27void device_add_property_set(struct device *dev, struct property_set *pset)
28{
29 if (pset)
30 pset->fwnode.type = FWNODE_PDATA;
31
32 set_secondary_fwnode(dev, &pset->fwnode);
33}
34EXPORT_SYMBOL_GPL(device_add_property_set);
35
36static inline bool is_pset(struct fwnode_handle *fwnode)
37{
38 return fwnode && fwnode->type == FWNODE_PDATA;
39}
40
41static inline struct property_set *to_pset(struct fwnode_handle *fwnode)
42{
43 return is_pset(fwnode) ?
44 container_of(fwnode, struct property_set, fwnode) : NULL;
45}
46
47static struct property_entry *pset_prop_get(struct property_set *pset,
48 const char *name)
49{
50 struct property_entry *prop;
51
52 if (!pset || !pset->properties)
53 return NULL;
54
55 for (prop = pset->properties; prop->name; prop++)
56 if (!strcmp(name, prop->name))
57 return prop;
58
59 return NULL;
60}
61
62static int pset_prop_read_array(struct property_set *pset, const char *name,
63 enum dev_prop_type type, void *val, size_t nval)
64{
65 struct property_entry *prop;
66 unsigned int item_size;
67
68 prop = pset_prop_get(pset, name);
69 if (!prop)
70 return -ENODATA;
71
72 if (prop->type != type)
73 return -EPROTO;
74
75 if (!val)
76 return prop->nval;
77
78 if (prop->nval < nval)
79 return -EOVERFLOW;
80
81 switch (type) {
82 case DEV_PROP_U8:
83 item_size = sizeof(u8);
84 break;
85 case DEV_PROP_U16:
86 item_size = sizeof(u16);
87 break;
88 case DEV_PROP_U32:
89 item_size = sizeof(u32);
90 break;
91 case DEV_PROP_U64:
92 item_size = sizeof(u64);
93 break;
94 case DEV_PROP_STRING:
95 item_size = sizeof(const char *);
96 break;
97 default:
98 return -EINVAL;
99 }
100 memcpy(val, prop->value.raw_data, nval * item_size);
101 return 0;
102}
103
104static inline struct fwnode_handle *dev_fwnode(struct device *dev)
105{
106 return IS_ENABLED(CONFIG_OF) && dev->of_node ?
107 &dev->of_node->fwnode : dev->fwnode;
108}
17 109
18/** 110/**
19 * device_property_present - check if a property of a device is present 111 * device_property_present - check if a property of a device is present
@@ -24,10 +116,7 @@
24 */ 116 */
25bool device_property_present(struct device *dev, const char *propname) 117bool device_property_present(struct device *dev, const char *propname)
26{ 118{
27 if (IS_ENABLED(CONFIG_OF) && dev->of_node) 119 return fwnode_property_present(dev_fwnode(dev), propname);
28 return of_property_read_bool(dev->of_node, propname);
29
30 return !acpi_dev_prop_get(ACPI_COMPANION(dev), propname, NULL);
31} 120}
32EXPORT_SYMBOL_GPL(device_property_present); 121EXPORT_SYMBOL_GPL(device_property_present);
33 122
@@ -43,32 +132,22 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
43 else if (is_acpi_node(fwnode)) 132 else if (is_acpi_node(fwnode))
44 return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL); 133 return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL);
45 134
46 return false; 135 return !!pset_prop_get(to_pset(fwnode), propname);
47} 136}
48EXPORT_SYMBOL_GPL(fwnode_property_present); 137EXPORT_SYMBOL_GPL(fwnode_property_present);
49 138
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/** 139/**
62 * device_property_read_u8_array - return a u8 array property of a device 140 * device_property_read_u8_array - return a u8 array property of a device
63 * @dev: Device to get the property of 141 * @dev: Device to get the property of
64 * @propname: Name of the property 142 * @propname: Name of the property
65 * @val: The values are stored here 143 * @val: The values are stored here or %NULL to return the number of values
66 * @nval: Size of the @val array 144 * @nval: Size of the @val array
67 * 145 *
68 * Function reads an array of u8 properties with @propname from the device 146 * Function reads an array of u8 properties with @propname from the device
69 * firmware description and stores them to @val if found. 147 * firmware description and stores them to @val if found.
70 * 148 *
71 * Return: %0 if the property was found (success), 149 * Return: number of values if @val was %NULL,
150 * %0 if the property was found (success),
72 * %-EINVAL if given arguments are not valid, 151 * %-EINVAL if given arguments are not valid,
73 * %-ENODATA if the property does not have a value, 152 * %-ENODATA if the property does not have a value,
74 * %-EPROTO if the property is not an array of numbers, 153 * %-EPROTO if the property is not an array of numbers,
@@ -77,7 +156,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_present);
77int device_property_read_u8_array(struct device *dev, const char *propname, 156int device_property_read_u8_array(struct device *dev, const char *propname,
78 u8 *val, size_t nval) 157 u8 *val, size_t nval)
79{ 158{
80 return DEV_PROP_READ_ARRAY(dev, propname, u8, DEV_PROP_U8, val, nval); 159 return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
81} 160}
82EXPORT_SYMBOL_GPL(device_property_read_u8_array); 161EXPORT_SYMBOL_GPL(device_property_read_u8_array);
83 162
@@ -85,13 +164,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u8_array);
85 * device_property_read_u16_array - return a u16 array property of a device 164 * device_property_read_u16_array - return a u16 array property of a device
86 * @dev: Device to get the property of 165 * @dev: Device to get the property of
87 * @propname: Name of the property 166 * @propname: Name of the property
88 * @val: The values are stored here 167 * @val: The values are stored here or %NULL to return the number of values
89 * @nval: Size of the @val array 168 * @nval: Size of the @val array
90 * 169 *
91 * Function reads an array of u16 properties with @propname from the device 170 * Function reads an array of u16 properties with @propname from the device
92 * firmware description and stores them to @val if found. 171 * firmware description and stores them to @val if found.
93 * 172 *
94 * Return: %0 if the property was found (success), 173 * Return: number of values if @val was %NULL,
174 * %0 if the property was found (success),
95 * %-EINVAL if given arguments are not valid, 175 * %-EINVAL if given arguments are not valid,
96 * %-ENODATA if the property does not have a value, 176 * %-ENODATA if the property does not have a value,
97 * %-EPROTO if the property is not an array of numbers, 177 * %-EPROTO if the property is not an array of numbers,
@@ -100,7 +180,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u8_array);
100int device_property_read_u16_array(struct device *dev, const char *propname, 180int device_property_read_u16_array(struct device *dev, const char *propname,
101 u16 *val, size_t nval) 181 u16 *val, size_t nval)
102{ 182{
103 return DEV_PROP_READ_ARRAY(dev, propname, u16, DEV_PROP_U16, val, nval); 183 return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
104} 184}
105EXPORT_SYMBOL_GPL(device_property_read_u16_array); 185EXPORT_SYMBOL_GPL(device_property_read_u16_array);
106 186
@@ -108,13 +188,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u16_array);
108 * device_property_read_u32_array - return a u32 array property of a device 188 * device_property_read_u32_array - return a u32 array property of a device
109 * @dev: Device to get the property of 189 * @dev: Device to get the property of
110 * @propname: Name of the property 190 * @propname: Name of the property
111 * @val: The values are stored here 191 * @val: The values are stored here or %NULL to return the number of values
112 * @nval: Size of the @val array 192 * @nval: Size of the @val array
113 * 193 *
114 * Function reads an array of u32 properties with @propname from the device 194 * Function reads an array of u32 properties with @propname from the device
115 * firmware description and stores them to @val if found. 195 * firmware description and stores them to @val if found.
116 * 196 *
117 * Return: %0 if the property was found (success), 197 * Return: number of values if @val was %NULL,
198 * %0 if the property was found (success),
118 * %-EINVAL if given arguments are not valid, 199 * %-EINVAL if given arguments are not valid,
119 * %-ENODATA if the property does not have a value, 200 * %-ENODATA if the property does not have a value,
120 * %-EPROTO if the property is not an array of numbers, 201 * %-EPROTO if the property is not an array of numbers,
@@ -123,7 +204,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u16_array);
123int device_property_read_u32_array(struct device *dev, const char *propname, 204int device_property_read_u32_array(struct device *dev, const char *propname,
124 u32 *val, size_t nval) 205 u32 *val, size_t nval)
125{ 206{
126 return DEV_PROP_READ_ARRAY(dev, propname, u32, DEV_PROP_U32, val, nval); 207 return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
127} 208}
128EXPORT_SYMBOL_GPL(device_property_read_u32_array); 209EXPORT_SYMBOL_GPL(device_property_read_u32_array);
129 210
@@ -131,13 +212,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u32_array);
131 * device_property_read_u64_array - return a u64 array property of a device 212 * device_property_read_u64_array - return a u64 array property of a device
132 * @dev: Device to get the property of 213 * @dev: Device to get the property of
133 * @propname: Name of the property 214 * @propname: Name of the property
134 * @val: The values are stored here 215 * @val: The values are stored here or %NULL to return the number of values
135 * @nval: Size of the @val array 216 * @nval: Size of the @val array
136 * 217 *
137 * Function reads an array of u64 properties with @propname from the device 218 * Function reads an array of u64 properties with @propname from the device
138 * firmware description and stores them to @val if found. 219 * firmware description and stores them to @val if found.
139 * 220 *
140 * Return: %0 if the property was found (success), 221 * Return: number of values if @val was %NULL,
222 * %0 if the property was found (success),
141 * %-EINVAL if given arguments are not valid, 223 * %-EINVAL if given arguments are not valid,
142 * %-ENODATA if the property does not have a value, 224 * %-ENODATA if the property does not have a value,
143 * %-EPROTO if the property is not an array of numbers, 225 * %-EPROTO if the property is not an array of numbers,
@@ -146,7 +228,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u32_array);
146int device_property_read_u64_array(struct device *dev, const char *propname, 228int device_property_read_u64_array(struct device *dev, const char *propname,
147 u64 *val, size_t nval) 229 u64 *val, size_t nval)
148{ 230{
149 return DEV_PROP_READ_ARRAY(dev, propname, u64, DEV_PROP_U64, val, nval); 231 return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
150} 232}
151EXPORT_SYMBOL_GPL(device_property_read_u64_array); 233EXPORT_SYMBOL_GPL(device_property_read_u64_array);
152 234
@@ -154,13 +236,14 @@ EXPORT_SYMBOL_GPL(device_property_read_u64_array);
154 * device_property_read_string_array - return a string array property of device 236 * device_property_read_string_array - return a string array property of device
155 * @dev: Device to get the property of 237 * @dev: Device to get the property of
156 * @propname: Name of the property 238 * @propname: Name of the property
157 * @val: The values are stored here 239 * @val: The values are stored here or %NULL to return the number of values
158 * @nval: Size of the @val array 240 * @nval: Size of the @val array
159 * 241 *
160 * Function reads an array of string properties with @propname from the device 242 * Function reads an array of string properties with @propname from the device
161 * firmware description and stores them to @val if found. 243 * firmware description and stores them to @val if found.
162 * 244 *
163 * Return: %0 if the property was found (success), 245 * Return: number of values if @val was %NULL,
246 * %0 if the property was found (success),
164 * %-EINVAL if given arguments are not valid, 247 * %-EINVAL if given arguments are not valid,
165 * %-ENODATA if the property does not have a value, 248 * %-ENODATA if the property does not have a value,
166 * %-EPROTO or %-EILSEQ if the property is not an array of strings, 249 * %-EPROTO or %-EILSEQ if the property is not an array of strings,
@@ -169,10 +252,7 @@ EXPORT_SYMBOL_GPL(device_property_read_u64_array);
169int device_property_read_string_array(struct device *dev, const char *propname, 252int device_property_read_string_array(struct device *dev, const char *propname,
170 const char **val, size_t nval) 253 const char **val, size_t nval)
171{ 254{
172 return IS_ENABLED(CONFIG_OF) && dev->of_node ? 255 return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
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} 256}
177EXPORT_SYMBOL_GPL(device_property_read_string_array); 257EXPORT_SYMBOL_GPL(device_property_read_string_array);
178 258
@@ -193,13 +273,14 @@ EXPORT_SYMBOL_GPL(device_property_read_string_array);
193int device_property_read_string(struct device *dev, const char *propname, 273int device_property_read_string(struct device *dev, const char *propname,
194 const char **val) 274 const char **val)
195{ 275{
196 return IS_ENABLED(CONFIG_OF) && dev->of_node ? 276 return fwnode_property_read_string(dev_fwnode(dev), propname, val);
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} 277}
201EXPORT_SYMBOL_GPL(device_property_read_string); 278EXPORT_SYMBOL_GPL(device_property_read_string);
202 279
280#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
281 (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
282 : of_property_count_elems_of_size((node), (propname), sizeof(type))
283
203#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ 284#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
204({ \ 285({ \
205 int _ret_; \ 286 int _ret_; \
@@ -210,7 +291,8 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
210 _ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \ 291 _ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \
211 _proptype_, _val_, _nval_); \ 292 _proptype_, _val_, _nval_); \
212 else \ 293 else \
213 _ret_ = -ENXIO; \ 294 _ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
295 _proptype_, _val_, _nval_); \
214 _ret_; \ 296 _ret_; \
215}) 297})
216 298
@@ -218,13 +300,14 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
218 * fwnode_property_read_u8_array - return a u8 array property of firmware node 300 * fwnode_property_read_u8_array - return a u8 array property of firmware node
219 * @fwnode: Firmware node to get the property of 301 * @fwnode: Firmware node to get the property of
220 * @propname: Name of the property 302 * @propname: Name of the property
221 * @val: The values are stored here 303 * @val: The values are stored here or %NULL to return the number of values
222 * @nval: Size of the @val array 304 * @nval: Size of the @val array
223 * 305 *
224 * Read an array of u8 properties with @propname from @fwnode and stores them to 306 * Read an array of u8 properties with @propname from @fwnode and stores them to
225 * @val if found. 307 * @val if found.
226 * 308 *
227 * Return: %0 if the property was found (success), 309 * Return: number of values if @val was %NULL,
310 * %0 if the property was found (success),
228 * %-EINVAL if given arguments are not valid, 311 * %-EINVAL if given arguments are not valid,
229 * %-ENODATA if the property does not have a value, 312 * %-ENODATA if the property does not have a value,
230 * %-EPROTO if the property is not an array of numbers, 313 * %-EPROTO if the property is not an array of numbers,
@@ -243,13 +326,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
243 * fwnode_property_read_u16_array - return a u16 array property of firmware node 326 * fwnode_property_read_u16_array - return a u16 array property of firmware node
244 * @fwnode: Firmware node to get the property of 327 * @fwnode: Firmware node to get the property of
245 * @propname: Name of the property 328 * @propname: Name of the property
246 * @val: The values are stored here 329 * @val: The values are stored here or %NULL to return the number of values
247 * @nval: Size of the @val array 330 * @nval: Size of the @val array
248 * 331 *
249 * Read an array of u16 properties with @propname from @fwnode and store them to 332 * Read an array of u16 properties with @propname from @fwnode and store them to
250 * @val if found. 333 * @val if found.
251 * 334 *
252 * Return: %0 if the property was found (success), 335 * Return: number of values if @val was %NULL,
336 * %0 if the property was found (success),
253 * %-EINVAL if given arguments are not valid, 337 * %-EINVAL if given arguments are not valid,
254 * %-ENODATA if the property does not have a value, 338 * %-ENODATA if the property does not have a value,
255 * %-EPROTO if the property is not an array of numbers, 339 * %-EPROTO if the property is not an array of numbers,
@@ -268,13 +352,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
268 * fwnode_property_read_u32_array - return a u32 array property of firmware node 352 * fwnode_property_read_u32_array - return a u32 array property of firmware node
269 * @fwnode: Firmware node to get the property of 353 * @fwnode: Firmware node to get the property of
270 * @propname: Name of the property 354 * @propname: Name of the property
271 * @val: The values are stored here 355 * @val: The values are stored here or %NULL to return the number of values
272 * @nval: Size of the @val array 356 * @nval: Size of the @val array
273 * 357 *
274 * Read an array of u32 properties with @propname from @fwnode store them to 358 * Read an array of u32 properties with @propname from @fwnode store them to
275 * @val if found. 359 * @val if found.
276 * 360 *
277 * Return: %0 if the property was found (success), 361 * Return: number of values if @val was %NULL,
362 * %0 if the property was found (success),
278 * %-EINVAL if given arguments are not valid, 363 * %-EINVAL if given arguments are not valid,
279 * %-ENODATA if the property does not have a value, 364 * %-ENODATA if the property does not have a value,
280 * %-EPROTO if the property is not an array of numbers, 365 * %-EPROTO if the property is not an array of numbers,
@@ -293,13 +378,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
293 * fwnode_property_read_u64_array - return a u64 array property firmware node 378 * fwnode_property_read_u64_array - return a u64 array property firmware node
294 * @fwnode: Firmware node to get the property of 379 * @fwnode: Firmware node to get the property of
295 * @propname: Name of the property 380 * @propname: Name of the property
296 * @val: The values are stored here 381 * @val: The values are stored here or %NULL to return the number of values
297 * @nval: Size of the @val array 382 * @nval: Size of the @val array
298 * 383 *
299 * Read an array of u64 properties with @propname from @fwnode and store them to 384 * Read an array of u64 properties with @propname from @fwnode and store them to
300 * @val if found. 385 * @val if found.
301 * 386 *
302 * Return: %0 if the property was found (success), 387 * Return: number of values if @val was %NULL,
388 * %0 if the property was found (success),
303 * %-EINVAL if given arguments are not valid, 389 * %-EINVAL if given arguments are not valid,
304 * %-ENODATA if the property does not have a value, 390 * %-ENODATA if the property does not have a value,
305 * %-EPROTO if the property is not an array of numbers, 391 * %-EPROTO if the property is not an array of numbers,
@@ -318,13 +404,14 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
318 * fwnode_property_read_string_array - return string array property of a node 404 * fwnode_property_read_string_array - return string array property of a node
319 * @fwnode: Firmware node to get the property of 405 * @fwnode: Firmware node to get the property of
320 * @propname: Name of the property 406 * @propname: Name of the property
321 * @val: The values are stored here 407 * @val: The values are stored here or %NULL to return the number of values
322 * @nval: Size of the @val array 408 * @nval: Size of the @val array
323 * 409 *
324 * Read an string list property @propname from the given firmware node and store 410 * Read an string list property @propname from the given firmware node and store
325 * them to @val if found. 411 * them to @val if found.
326 * 412 *
327 * Return: %0 if the property was found (success), 413 * Return: number of values if @val was %NULL,
414 * %0 if the property was found (success),
328 * %-EINVAL if given arguments are not valid, 415 * %-EINVAL if given arguments are not valid,
329 * %-ENODATA if the property does not have a value, 416 * %-ENODATA if the property does not have a value,
330 * %-EPROTO if the property is not an array of strings, 417 * %-EPROTO if the property is not an array of strings,
@@ -336,13 +423,16 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
336 size_t nval) 423 size_t nval)
337{ 424{
338 if (is_of_node(fwnode)) 425 if (is_of_node(fwnode))
339 return of_property_read_string_array(of_node(fwnode), propname, 426 return val ?
340 val, nval); 427 of_property_read_string_array(of_node(fwnode), propname,
428 val, nval) :
429 of_property_count_strings(of_node(fwnode), propname);
341 else if (is_acpi_node(fwnode)) 430 else if (is_acpi_node(fwnode))
342 return acpi_dev_prop_read(acpi_node(fwnode), propname, 431 return acpi_dev_prop_read(acpi_node(fwnode), propname,
343 DEV_PROP_STRING, val, nval); 432 DEV_PROP_STRING, val, nval);
344 433
345 return -ENXIO; 434 return pset_prop_read_array(to_pset(fwnode), propname,
435 DEV_PROP_STRING, val, nval);
346} 436}
347EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); 437EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
348 438