aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@linux.intel.com>2017-07-21 07:39:31 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-07-21 18:04:50 -0400
commitdb3e50f3234ba1a477413f56a9e5800a73dca786 (patch)
tree87c3c735dd51f68e77d3189186094ee216204a76
parentb81b729164445cd94c4dd6fc4d6f10487434df4a (diff)
device property: Get rid of struct fwnode_handle type field
Instead of relying on the struct fwnode_handle type field, define fwnode_operations structs for all separate types of fwnodes. To find out the type, compare to the ops field to relevant ops structs. This change has two benefits: 1. it avoids adding the type field to each and every instance of struct fwnode_handle, thus saving memory and 2. makes the ops field the single factor that defines both the types of the fwnode as well as defines the implementation of its operations, decreasing the possibility of bugs when developing code dealing with fwnode internals. Suggested-by: Rob Herring <robh@kernel.org> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/property.c47
-rw-r--r--drivers/acpi/scan.c3
-rw-r--r--drivers/base/property.c5
-rw-r--r--drivers/of/property.c1
-rw-r--r--include/acpi/acpi_bus.h20
-rw-r--r--include/linux/acpi.h8
-rw-r--r--include/linux/fwnode.h11
-rw-r--r--include/linux/irqdomain.h4
-rw-r--r--include/linux/of.h3
-rw-r--r--kernel/irq/irqdomain.c10
10 files changed, 60 insertions, 52 deletions
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index 917c789f953d..cb6a3b38ded2 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -56,8 +56,7 @@ static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
56 return false; 56 return false;
57 57
58 dn->name = link->package.elements[0].string.pointer; 58 dn->name = link->package.elements[0].string.pointer;
59 dn->fwnode.type = FWNODE_ACPI_DATA; 59 dn->fwnode.ops = &acpi_data_fwnode_ops;
60 dn->fwnode.ops = &acpi_fwnode_ops;
61 dn->parent = parent; 60 dn->parent = parent;
62 INIT_LIST_HEAD(&dn->data.subnodes); 61 INIT_LIST_HEAD(&dn->data.subnodes);
63 62
@@ -469,10 +468,10 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_property);
469 468
470static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode) 469static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode)
471{ 470{
472 if (fwnode->type == FWNODE_ACPI) { 471 if (is_acpi_device_node(fwnode)) {
473 struct acpi_device *adev = to_acpi_device_node(fwnode); 472 struct acpi_device *adev = to_acpi_device_node(fwnode);
474 return &adev->data; 473 return &adev->data;
475 } else if (fwnode->type == FWNODE_ACPI_DATA) { 474 } else if (is_acpi_data_node(fwnode)) {
476 struct acpi_data_node *dn = to_acpi_data_node(fwnode); 475 struct acpi_data_node *dn = to_acpi_data_node(fwnode);
477 return &dn->data; 476 return &dn->data;
478 } 477 }
@@ -903,7 +902,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode,
903 struct acpi_device *adev = to_acpi_device_node(fwnode); 902 struct acpi_device *adev = to_acpi_device_node(fwnode);
904 struct list_head *head, *next; 903 struct list_head *head, *next;
905 904
906 if (!child || child->type == FWNODE_ACPI) { 905 if (!child || is_acpi_device_node(child)) {
907 if (adev) 906 if (adev)
908 head = &adev->children; 907 head = &adev->children;
909 else 908 else
@@ -927,7 +926,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode,
927 } 926 }
928 927
929 nondev: 928 nondev:
930 if (!child || child->type == FWNODE_ACPI_DATA) { 929 if (!child || is_acpi_data_node(child)) {
931 struct acpi_data_node *data = to_acpi_data_node(fwnode); 930 struct acpi_data_node *data = to_acpi_data_node(fwnode);
932 struct acpi_data_node *dn; 931 struct acpi_data_node *dn;
933 932
@@ -1223,16 +1222,26 @@ static int acpi_fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode,
1223 return 0; 1222 return 0;
1224} 1223}
1225 1224
1226const struct fwnode_operations acpi_fwnode_ops = { 1225#define DECLARE_ACPI_FWNODE_OPS(ops) \
1227 .device_is_available = acpi_fwnode_device_is_available, 1226 const struct fwnode_operations ops = { \
1228 .property_present = acpi_fwnode_property_present, 1227 .device_is_available = acpi_fwnode_device_is_available, \
1229 .property_read_int_array = acpi_fwnode_property_read_int_array, 1228 .property_present = acpi_fwnode_property_present, \
1230 .property_read_string_array = acpi_fwnode_property_read_string_array, 1229 .property_read_int_array = \
1231 .get_parent = acpi_node_get_parent, 1230 acpi_fwnode_property_read_int_array, \
1232 .get_next_child_node = acpi_get_next_subnode, 1231 .property_read_string_array = \
1233 .get_named_child_node = acpi_fwnode_get_named_child_node, 1232 acpi_fwnode_property_read_string_array, \
1234 .graph_get_next_endpoint = acpi_fwnode_graph_get_next_endpoint, 1233 .get_parent = acpi_node_get_parent, \
1235 .graph_get_remote_endpoint = acpi_fwnode_graph_get_remote_endpoint, 1234 .get_next_child_node = acpi_get_next_subnode, \
1236 .graph_get_port_parent = acpi_node_get_parent, 1235 .get_named_child_node = acpi_fwnode_get_named_child_node, \
1237 .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, 1236 .graph_get_next_endpoint = \
1238}; 1237 acpi_fwnode_graph_get_next_endpoint, \
1238 .graph_get_remote_endpoint = \
1239 acpi_fwnode_graph_get_remote_endpoint, \
1240 .graph_get_port_parent = acpi_node_get_parent, \
1241 .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \
1242 }; \
1243 EXPORT_SYMBOL_GPL(ops)
1244
1245DECLARE_ACPI_FWNODE_OPS(acpi_device_fwnode_ops);
1246DECLARE_ACPI_FWNODE_OPS(acpi_data_fwnode_ops);
1247const struct fwnode_operations acpi_static_fwnode_ops;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 33897298f03e..943536c9a2a8 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1467,8 +1467,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
1467 device->device_type = type; 1467 device->device_type = type;
1468 device->handle = handle; 1468 device->handle = handle;
1469 device->parent = acpi_bus_get_parent(handle); 1469 device->parent = acpi_bus_get_parent(handle);
1470 device->fwnode.type = FWNODE_ACPI; 1470 device->fwnode.ops = &acpi_device_fwnode_ops;
1471 device->fwnode.ops = &acpi_fwnode_ops;
1472 acpi_set_device_status(device, sta); 1471 acpi_set_device_status(device, sta);
1473 acpi_device_get_busid(device); 1472 acpi_device_get_busid(device);
1474 acpi_set_pnp_ids(handle, &device->pnp, type); 1473 acpi_set_pnp_ids(handle, &device->pnp, type);
diff --git a/drivers/base/property.c b/drivers/base/property.c
index edf02c1b5845..857e4d39add6 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -25,9 +25,11 @@ struct property_set {
25 const struct property_entry *properties; 25 const struct property_entry *properties;
26}; 26};
27 27
28static const struct fwnode_operations pset_fwnode_ops;
29
28static inline bool is_pset_node(struct fwnode_handle *fwnode) 30static inline bool is_pset_node(struct fwnode_handle *fwnode)
29{ 31{
30 return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA; 32 return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &pset_fwnode_ops;
31} 33}
32 34
33static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode) 35static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode)
@@ -900,7 +902,6 @@ int device_add_properties(struct device *dev,
900 if (IS_ERR(p)) 902 if (IS_ERR(p))
901 return PTR_ERR(p); 903 return PTR_ERR(p);
902 904
903 p->fwnode.type = FWNODE_PDATA;
904 p->fwnode.ops = &pset_fwnode_ops; 905 p->fwnode.ops = &pset_fwnode_ops;
905 set_secondary_fwnode(dev, &p->fwnode); 906 set_secondary_fwnode(dev, &p->fwnode);
906 return 0; 907 return 0;
diff --git a/drivers/of/property.c b/drivers/of/property.c
index eda50b4be934..2d5988820405 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -952,3 +952,4 @@ const struct fwnode_operations of_fwnode_ops = {
952 .graph_get_port_parent = of_fwnode_graph_get_port_parent, 952 .graph_get_port_parent = of_fwnode_graph_get_port_parent,
953 .graph_parse_endpoint = of_fwnode_graph_parse_endpoint, 953 .graph_parse_endpoint = of_fwnode_graph_parse_endpoint,
954}; 954};
955EXPORT_SYMBOL_GPL(of_fwnode_ops);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 7569123475b3..91b1e58e5189 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -395,15 +395,21 @@ struct acpi_data_node {
395 struct completion kobj_done; 395 struct completion kobj_done;
396}; 396};
397 397
398extern const struct fwnode_operations acpi_device_fwnode_ops;
399extern const struct fwnode_operations acpi_data_fwnode_ops;
400extern const struct fwnode_operations acpi_static_fwnode_ops;
401
398static inline bool is_acpi_node(struct fwnode_handle *fwnode) 402static inline bool is_acpi_node(struct fwnode_handle *fwnode)
399{ 403{
400 return !IS_ERR_OR_NULL(fwnode) && (fwnode->type == FWNODE_ACPI 404 return !IS_ERR_OR_NULL(fwnode) &&
401 || fwnode->type == FWNODE_ACPI_DATA); 405 (fwnode->ops == &acpi_device_fwnode_ops
406 || fwnode->ops == &acpi_data_fwnode_ops);
402} 407}
403 408
404static inline bool is_acpi_device_node(struct fwnode_handle *fwnode) 409static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
405{ 410{
406 return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_ACPI; 411 return !IS_ERR_OR_NULL(fwnode) &&
412 fwnode->ops == &acpi_device_fwnode_ops;
407} 413}
408 414
409static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode) 415static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
@@ -414,7 +420,7 @@ static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwno
414 420
415static inline bool is_acpi_data_node(struct fwnode_handle *fwnode) 421static inline bool is_acpi_data_node(struct fwnode_handle *fwnode)
416{ 422{
417 return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_ACPI_DATA; 423 return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &acpi_data_fwnode_ops;
418} 424}
419 425
420static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode) 426static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode)
@@ -423,6 +429,12 @@ static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwn
423 container_of(fwnode, struct acpi_data_node, fwnode) : NULL; 429 container_of(fwnode, struct acpi_data_node, fwnode) : NULL;
424} 430}
425 431
432static inline bool is_acpi_static_node(struct fwnode_handle *fwnode)
433{
434 return !IS_ERR_OR_NULL(fwnode) &&
435 fwnode->ops == &acpi_static_fwnode_ops;
436}
437
426static inline bool acpi_data_node_match(struct fwnode_handle *fwnode, 438static inline bool acpi_data_node_match(struct fwnode_handle *fwnode,
427 const char *name) 439 const char *name)
428{ 440{
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index c749eef1daa1..71b763f0bee9 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -57,9 +57,6 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
57 acpi_fwnode_handle(adev) : NULL) 57 acpi_fwnode_handle(adev) : NULL)
58#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) 58#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev))
59 59
60
61extern const struct fwnode_operations acpi_fwnode_ops;
62
63static inline struct fwnode_handle *acpi_alloc_fwnode_static(void) 60static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
64{ 61{
65 struct fwnode_handle *fwnode; 62 struct fwnode_handle *fwnode;
@@ -68,15 +65,14 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
68 if (!fwnode) 65 if (!fwnode)
69 return NULL; 66 return NULL;
70 67
71 fwnode->type = FWNODE_ACPI_STATIC; 68 fwnode->ops = &acpi_static_fwnode_ops;
72 fwnode->ops = &acpi_fwnode_ops;
73 69
74 return fwnode; 70 return fwnode;
75} 71}
76 72
77static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode) 73static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode)
78{ 74{
79 if (WARN_ON(!fwnode || fwnode->type != FWNODE_ACPI_STATIC)) 75 if (WARN_ON(!is_acpi_static_node(fwnode)))
80 return; 76 return;
81 77
82 kfree(fwnode); 78 kfree(fwnode);
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 50893a1646cf..c5dbc48b55dd 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -14,20 +14,9 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17enum fwnode_type {
18 FWNODE_INVALID = 0,
19 FWNODE_OF,
20 FWNODE_ACPI,
21 FWNODE_ACPI_DATA,
22 FWNODE_ACPI_STATIC,
23 FWNODE_PDATA,
24 FWNODE_IRQCHIP
25};
26
27struct fwnode_operations; 17struct fwnode_operations;
28 18
29struct fwnode_handle { 19struct fwnode_handle {
30 enum fwnode_type type;
31 struct fwnode_handle *secondary; 20 struct fwnode_handle *secondary;
32 const struct fwnode_operations *ops; 21 const struct fwnode_operations *ops;
33}; 22};
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index cac77a5c5555..d24273840b79 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -265,9 +265,11 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
265 return node ? &node->fwnode : NULL; 265 return node ? &node->fwnode : NULL;
266} 266}
267 267
268extern const struct fwnode_operations irqchip_fwnode_ops;
269
268static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode) 270static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
269{ 271{
270 return fwnode && fwnode->type == FWNODE_IRQCHIP; 272 return fwnode && fwnode->ops == &irqchip_fwnode_ops;
271} 273}
272 274
273extern void irq_domain_update_bus_token(struct irq_domain *domain, 275extern void irq_domain_update_bus_token(struct irq_domain *domain,
diff --git a/include/linux/of.h b/include/linux/of.h
index 4a8a70916237..cfc34117fc92 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -104,7 +104,6 @@ extern const struct fwnode_operations of_fwnode_ops;
104static inline void of_node_init(struct device_node *node) 104static inline void of_node_init(struct device_node *node)
105{ 105{
106 kobject_init(&node->kobj, &of_node_ktype); 106 kobject_init(&node->kobj, &of_node_ktype);
107 node->fwnode.type = FWNODE_OF;
108 node->fwnode.ops = &of_fwnode_ops; 107 node->fwnode.ops = &of_fwnode_ops;
109} 108}
110 109
@@ -152,7 +151,7 @@ void of_core_init(void);
152 151
153static inline bool is_of_node(const struct fwnode_handle *fwnode) 152static inline bool is_of_node(const struct fwnode_handle *fwnode)
154{ 153{
155 return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_OF; 154 return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &of_fwnode_ops;
156} 155}
157 156
158#define to_of_node(__fwnode) \ 157#define to_of_node(__fwnode) \
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index f1f251479aa6..e064fd1390f1 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -41,6 +41,8 @@ static inline void debugfs_add_domain_dir(struct irq_domain *d) { }
41static inline void debugfs_remove_domain_dir(struct irq_domain *d) { } 41static inline void debugfs_remove_domain_dir(struct irq_domain *d) { }
42#endif 42#endif
43 43
44const struct fwnode_operations irqchip_fwnode_ops;
45
44/** 46/**
45 * irq_domain_alloc_fwnode - Allocate a fwnode_handle suitable for 47 * irq_domain_alloc_fwnode - Allocate a fwnode_handle suitable for
46 * identifying an irq domain 48 * identifying an irq domain
@@ -86,7 +88,7 @@ struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id,
86 fwid->type = type; 88 fwid->type = type;
87 fwid->name = n; 89 fwid->name = n;
88 fwid->data = data; 90 fwid->data = data;
89 fwid->fwnode.type = FWNODE_IRQCHIP; 91 fwid->fwnode.ops = &irqchip_fwnode_ops;
90 return &fwid->fwnode; 92 return &fwid->fwnode;
91} 93}
92EXPORT_SYMBOL_GPL(__irq_domain_alloc_fwnode); 94EXPORT_SYMBOL_GPL(__irq_domain_alloc_fwnode);
@@ -193,10 +195,8 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
193 } 195 }
194 196
195 if (!domain->name) { 197 if (!domain->name) {
196 if (fwnode) { 198 if (fwnode)
197 pr_err("Invalid fwnode type (%d) for irqdomain\n", 199 pr_err("Invalid fwnode type for irqdomain\n");
198 fwnode->type);
199 }
200 domain->name = kasprintf(GFP_KERNEL, "unknown-%d", 200 domain->name = kasprintf(GFP_KERNEL, "unknown-%d",
201 atomic_inc_return(&unknown_domains)); 201 atomic_inc_return(&unknown_domains));
202 if (!domain->name) { 202 if (!domain->name) {