aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-12 18:35:54 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-12 18:35:54 -0400
commit9a9ca16e7a36a9daa93f6d2cf912170091d91ed6 (patch)
treee3c8abf8249d8f6967679510132943454bc19fc6 /drivers/base
parent34a1b99b9b4d81b0d835c08239c1180e83703bb7 (diff)
parent16ba08d5c9ec44f89ec03c67ecf7a9c5e2d204fd (diff)
Merge branch 'device-properties'
* device-properties: device property: Introduce firmware node type for platform data device property: Make it possible to use secondary firmware nodes driver core: Implement device property accessors through fwnode ones driver core: property: Update fwnode_property_read_string_array() driver core: Add comments about returning array counts ACPI: Introduce has_acpi_companion() driver core / ACPI: Represent ACPI companions using fwnode_handle
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c51
-rw-r--r--drivers/base/platform.c2
-rw-r--r--drivers/base/property.c198
3 files changed, 196 insertions, 55 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 07304a3b9ee2..c7e2a9a70865 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>
@@ -2133,3 +2134,53 @@ define_dev_printk_level(dev_notice, KERN_NOTICE);
2133define_dev_printk_level(_dev_info, KERN_INFO); 2134define_dev_printk_level(_dev_info, KERN_INFO);
2134 2135
2135#endif 2136#endif
2137
2138static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
2139{
2140 return fwnode && !IS_ERR(fwnode->secondary);
2141}
2142
2143/**
2144 * set_primary_fwnode - Change the primary firmware node of a given device.
2145 * @dev: Device to handle.
2146 * @fwnode: New primary firmware node of the device.
2147 *
2148 * Set the device's firmware node pointer to @fwnode, but if a secondary
2149 * firmware node of the device is present, preserve it.
2150 */
2151void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
2152{
2153 if (fwnode) {
2154 struct fwnode_handle *fn = dev->fwnode;
2155
2156 if (fwnode_is_primary(fn))
2157 fn = fn->secondary;
2158
2159 fwnode->secondary = fn;
2160 dev->fwnode = fwnode;
2161 } else {
2162 dev->fwnode = fwnode_is_primary(dev->fwnode) ?
2163 dev->fwnode->secondary : NULL;
2164 }
2165}
2166EXPORT_SYMBOL_GPL(set_primary_fwnode);
2167
2168/**
2169 * set_secondary_fwnode - Change the secondary firmware node of a given device.
2170 * @dev: Device to handle.
2171 * @fwnode: New secondary firmware node of the device.
2172 *
2173 * If a primary firmware node of the device is present, set its secondary
2174 * pointer to @fwnode. Otherwise, set the device's firmware node pointer to
2175 * @fwnode.
2176 */
2177void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
2178{
2179 if (fwnode)
2180 fwnode->secondary = ERR_PTR(-ENODEV);
2181
2182 if (fwnode_is_primary(dev->fwnode))
2183 dev->fwnode->secondary = fwnode;
2184 else
2185 dev->fwnode = fwnode;
2186}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 9421fed40905..17f0204fabef 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -454,7 +454,7 @@ struct platform_device *platform_device_register_full(
454 goto err_alloc; 454 goto err_alloc;
455 455
456 pdev->dev.parent = pdevinfo->parent; 456 pdev->dev.parent = pdevinfo->parent;
457 ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); 457 pdev->dev.fwnode = pdevinfo->fwnode;
458 458
459 if (pdevinfo->dma_mask) { 459 if (pdevinfo->dma_mask) {
460 /* 460 /*
diff --git a/drivers/base/property.c b/drivers/base/property.c
index c45845874d4f..6a3f7d8af341 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)