From 8a1ac5dc7be09883051b1bf89a5e57d7ad850fa5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 13 Oct 2017 15:57:40 -0700 Subject: include/linux/of.h: provide of_n_{addr,size}_cells wrappers for !CONFIG_OF The pci-rcar driver is enabled for compile tests, and this has shown that the driver cannot build without CONFIG_OF, following the inclusion of commit f8f2fe7355fb ("PCI: rcar: Use new OF interrupt mapping when possible"): drivers/pci/host/pcie-rcar.c: In function 'pci_dma_range_parser_init': drivers/pci/host/pcie-rcar.c:1039:2: error: implicit declaration of function 'of_n_addr_cells' [-Werror=implicit-function-declaration] parser->pna = of_n_addr_cells(node); ^ As pointed out by Ben Dooks and Geert Uytterhoeven, this is actually supposed to build fine, which we can achieve if we make the declaration of of_irq_parse_and_map_pci conditional on CONFIG_OF and provide an empty inline function otherwise, as we do for a lot of other of interfaces. This lets us build the rcar_pci driver again without CONFIG_OF for build testing. All platforms using this driver select OF, so this doesn't change anything for the users. [akpm@linux-foundation.org: be consistent with surrounding code] Link: http://lkml.kernel.org/r/20170911200805.3363318-1-arnd@arndb.de Fixes: c25da4778803 ("PCI: rcar: Add Renesas R-Car PCIe driver") Signed-off-by: Arnd Bergmann Reviewed-by: Frank Rowand Acked-by: Geert Uytterhoeven Cc: Bjorn Helgaas Cc: Magnus Damm Cc: Ben Dooks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/of.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index cfc34117fc92..b240ed69dc96 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -734,6 +734,16 @@ static inline struct device_node *of_get_cpu_node(int cpu, return NULL; } +static inline int of_n_addr_cells(struct device_node *np) +{ + return 0; + +} +static inline int of_n_size_cells(struct device_node *np) +{ + return 0; +} + static inline int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value) { -- cgit v1.2.3 From 36689ecd2c065a8879035e5bf1b4a0f4d5b65160 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 29 Sep 2017 20:08:28 -0500 Subject: of: remove struct property.unique_id for FDT Only Sparc uses unique_id, so remove it for FDT builds and shrink struct property a bit making the unflattened DT less of a memory hog. Tested-by: Nicolas Pitre Reviewed-by: Frank Rowand Acked-by: Grant Likely Signed-off-by: Rob Herring --- include/linux/of.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index cfc34117fc92..8f9e96752837 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -38,7 +38,9 @@ struct property { void *value; struct property *next; unsigned long _flags; +#if defined(CONFIG_OF_PROMTREE) unsigned int unique_id; +#endif struct bin_attribute attr; }; -- cgit v1.2.3 From 16bba30eab137aaa37538349c0a7496720e90c66 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 4 Oct 2017 14:30:02 -0500 Subject: of: make struct property _flags field configurable Only Sparc and CONFIG_OF_DYNAMIC use the struct property._flags field, so make it conditional shrinking struct property a bit. Tested-by: Nicolas Pitre Reviewed-by: Frank Rowand Acked-by: Grant Likely Signed-off-by: Rob Herring --- include/linux/of.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index 8f9e96752837..7eb94b7fbcf3 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -37,7 +37,9 @@ struct property { int length; void *value; struct property *next; +#if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC) unsigned long _flags; +#endif #if defined(CONFIG_OF_PROMTREE) unsigned int unique_id; #endif @@ -205,6 +207,7 @@ static inline void of_node_clear_flag(struct device_node *n, unsigned long flag) clear_bit(flag, &n->_flags); } +#if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC) static inline int of_property_check_flag(struct property *p, unsigned long flag) { return test_bit(flag, &p->_flags); @@ -219,6 +222,7 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag { clear_bit(flag, &p->_flags); } +#endif extern struct device_node *__of_find_all_nodes(struct device_node *prev); extern struct device_node *of_find_all_nodes(struct device_node *prev); -- cgit v1.2.3 From 0c3c234b95fa7f1dfa19e1456a47ebafc300dd6b Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 4 Oct 2017 14:04:01 -0500 Subject: of: wrap accesses to device_node kobject In preparation to make kobject element in struct device_node optional, provide and use a macro to return the kobject pointer. The only user outside the DT core is the driver core. Acked-by: Greg Kroah-Hartman Tested-by: Nicolas Pitre Reviewed-by: Frank Rowand Acked-by: Grant Likely Signed-off-by: Rob Herring --- include/linux/of.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index 7eb94b7fbcf3..2d685e769409 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -111,6 +111,8 @@ static inline void of_node_init(struct device_node *node) node->fwnode.ops = &of_fwnode_ops; } +#define of_node_kobj(n) (&(n)->kobj) + /* true when node is initialized */ static inline int of_node_is_initialized(struct device_node *node) { -- cgit v1.2.3 From b56b5528f5b3c3d47e7c0ca67318c45e980d93f0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 4 Oct 2017 14:09:40 -0500 Subject: of: make kobject and bin_attribute support configurable Having device_nodes be kobjects is only needed if sysfs or OF_DYNAMIC is enabled. Otherwise, having a kobject in struct device_node is unnecessary bloat in minimal kernel configurations. Likewise, bin_attribute is only needed in struct property when sysfs is enabled, so we can make it configurable too. Tested-by: Nicolas Pitre Reviewed-by: Frank Rowand Acked-by: Grant Likely Signed-off-by: Rob Herring --- include/linux/of.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index 2d685e769409..7b0f17be7830 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -43,7 +43,9 @@ struct property { #if defined(CONFIG_OF_PROMTREE) unsigned int unique_id; #endif +#if defined(CONFIG_OF_KOBJ) struct bin_attribute attr; +#endif }; #if defined(CONFIG_SPARC) @@ -62,7 +64,9 @@ struct device_node { struct device_node *parent; struct device_node *child; struct device_node *sibling; +#if defined(CONFIG_OF_KOBJ) struct kobject kobj; +#endif unsigned long _flags; void *data; #if defined(CONFIG_SPARC) @@ -107,23 +111,17 @@ extern struct kobj_type of_node_ktype; extern const struct fwnode_operations of_fwnode_ops; static inline void of_node_init(struct device_node *node) { +#if defined(CONFIG_OF_KOBJ) kobject_init(&node->kobj, &of_node_ktype); +#endif node->fwnode.ops = &of_fwnode_ops; } +#if defined(CONFIG_OF_KOBJ) #define of_node_kobj(n) (&(n)->kobj) - -/* true when node is initialized */ -static inline int of_node_is_initialized(struct device_node *node) -{ - return node && node->kobj.state_initialized; -} - -/* true when node is attached (i.e. present on sysfs) */ -static inline int of_node_is_attached(struct device_node *node) -{ - return node && node->kobj.state_in_sysfs; -} +#else +#define of_node_kobj(n) NULL +#endif #ifdef CONFIG_OF_DYNAMIC extern struct device_node *of_node_get(struct device_node *node); -- cgit v1.2.3 From 0290c4ca2536a35e55c53cfb9058465b1f987b17 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Tue, 17 Oct 2017 16:36:23 -0700 Subject: of: overlay: rename identifiers to more reflect what they do This patch is aimed primarily at drivers/of/overlay.c, but those changes also have a small impact in a few other files. overlay.c is difficult to read and maintain. Improve readability: - Rename functions, types and variables to better reflect what they do and to be consistent with names in other places, such as the device tree overlay FDT (flattened device tree), and make the algorithms more clear - Use the same names consistently throughout the file - Update comments for name changes - Fix incorrect comments This patch is intended to not introduce any functional change. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- include/linux/of.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index 7b0f17be7830..7569e9cc45de 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1312,26 +1312,26 @@ struct of_overlay_notify_data { #ifdef CONFIG_OF_OVERLAY /* ID based overlays; the API for external users */ -int of_overlay_create(struct device_node *tree); -int of_overlay_destroy(int id); -int of_overlay_destroy_all(void); +int of_overlay_apply(struct device_node *tree); +int of_overlay_remove(int id); +int of_overlay_remove_all(void); int of_overlay_notifier_register(struct notifier_block *nb); int of_overlay_notifier_unregister(struct notifier_block *nb); #else -static inline int of_overlay_create(struct device_node *tree) +static inline int of_overlay_apply(struct device_node *tree) { return -ENOTSUPP; } -static inline int of_overlay_destroy(int id) +static inline int of_overlay_remove(int id) { return -ENOTSUPP; } -static inline int of_overlay_destroy_all(void) +static inline int of_overlay_remove_all(void) { return -ENOTSUPP; } -- cgit v1.2.3 From 24789c5ce5a373dd55640f9cd79117fcc3ccc46d Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Tue, 17 Oct 2017 16:36:26 -0700 Subject: of: overlay: detect cases where device tree may become corrupt When an attempt to apply an overlay changeset fails, an effort is made to revert any partial application of the changeset. When an attempt to remove an overlay changeset fails, an effort is made to re-apply any partial reversion of the changeset. The existing code does not check for failure to recover a failed overlay changeset application or overlay changeset revert. Add the missing checks and flag the devicetree as corrupt if the state of the devicetree can not be determined. Improve and expand the returned errors to more fully reflect the result of the effort to undo the partial effects of a failed attempt to apply or remove an overlay changeset. If the device tree might be corrupt, do not allow further attempts to apply or remove an overlay changeset. When creating an overlay changeset from an overlay device tree, add some additional warnings if the state of the overlay device tree is not as expected. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- include/linux/of.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index 7569e9cc45de..96edda95c6b0 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1298,7 +1298,7 @@ static inline bool of_device_is_system_power_controller(const struct device_node */ enum of_overlay_notify_action { - OF_OVERLAY_PRE_APPLY, + OF_OVERLAY_PRE_APPLY = 0, OF_OVERLAY_POST_APPLY, OF_OVERLAY_PRE_REMOVE, OF_OVERLAY_POST_REMOVE, @@ -1312,8 +1312,8 @@ struct of_overlay_notify_data { #ifdef CONFIG_OF_OVERLAY /* ID based overlays; the API for external users */ -int of_overlay_apply(struct device_node *tree); -int of_overlay_remove(int id); +int of_overlay_apply(struct device_node *tree, int *ovcs_id); +int of_overlay_remove(int *ovcs_id); int of_overlay_remove_all(void); int of_overlay_notifier_register(struct notifier_block *nb); @@ -1321,12 +1321,12 @@ int of_overlay_notifier_unregister(struct notifier_block *nb); #else -static inline int of_overlay_apply(struct device_node *tree) +static inline int of_overlay_apply(struct device_node *tree, int *ovcs_id) { return -ENOTSUPP; } -static inline int of_overlay_remove(int id) +static inline int of_overlay_remove(int *ovcs_id) { return -ENOTSUPP; } -- cgit v1.2.3 From f948d6d8b792bb90041edc12eac35faf83030994 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Tue, 17 Oct 2017 16:36:29 -0700 Subject: of: overlay: avoid race condition between applying multiple overlays The process of applying an overlay consists of: - unflatten an overlay FDT (flattened device tree) into an EDT (expanded device tree) - fixup the phandle values in the overlay EDT to fit in a range above the phandle values in the live device tree - create the overlay changeset to reflect the contents of the overlay EDT - apply the overlay changeset, to modify the live device tree, potentially changing the maximum phandle value in the live device tree There is currently no protection against two overlay applies concurrently determining what range of phandle values are in use in the live device tree, and subsequently changing that range. Add a mutex to prevent multiple overlay applies from occurring simultaneously. Move of_resolve_phandles() into of_overlay_apply() so that it does not have to be duplicated by each caller of of_overlay_apply(). The test in of_resolve_phandles() that the overlay tree is detached is temporarily disabled so that old style overlay unittests do not fail. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- include/linux/of.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index 96edda95c6b0..ef4c9ff5955a 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1279,9 +1279,6 @@ static inline int of_reconfig_get_state_change(unsigned long action, } #endif /* CONFIG_OF_DYNAMIC */ -/* CONFIG_OF_RESOLVE api */ -extern int of_resolve_phandles(struct device_node *tree); - /** * of_device_is_system_power_controller - Tells if system-power-controller is found for device_node * @np: Pointer to the given device_node -- cgit v1.2.3 From 96c623e51f1c40bf524decc48c6fac7ce5dd41f7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 6 Nov 2017 14:26:10 +0100 Subject: of: add of_property_read_variable_* dummy helpers Commit a67e9472da42 ("of: Add array read functions with min/max size limits") added a new interface for reading variable-length arrays from DT properties. One user was added in dsa recently and this causes a build error because that code can be built with CONFIG_OF disabled: net/dsa/dsa2.c: In function 'dsa_switch_parse_member_of': net/dsa/dsa2.c:678:7: error: implicit declaration of function 'of_property_read_variable_u32_array'; did you mean 'of_property_read_u32_array'? [-Werror=implicit-function-declaration] This adds a dummy functions for of_property_read_variable_u32_array() and a few others that had been missing here. I decided to move of_property_read_string() and of_property_read_string_helper() in the process to make it easier to compare the two sets of function prototypes to make sure they match. Fixes: 975e6e32215e ("net: dsa: rework switch parsing") Signed-off-by: Arnd Bergmann Acked-by: Rob Herring Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- include/linux/of.h | 62 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 12 deletions(-) (limited to 'include/linux/of.h') diff --git a/include/linux/of.h b/include/linux/of.h index b240ed69dc96..b32d418d011a 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -675,12 +675,6 @@ static inline int of_property_count_elems_of_size(const struct device_node *np, return -ENOSYS; } -static inline int of_property_read_u32_index(const struct device_node *np, - const char *propname, u32 index, u32 *out_value) -{ - return -ENOSYS; -} - static inline int of_property_read_u8_array(const struct device_node *np, const char *propname, u8 *out_values, size_t sz) { @@ -707,16 +701,14 @@ static inline int of_property_read_u64_array(const struct device_node *np, return -ENOSYS; } -static inline int of_property_read_string(const struct device_node *np, - const char *propname, - const char **out_string) +static inline int of_property_read_u32_index(const struct device_node *np, + const char *propname, u32 index, u32 *out_value) { return -ENOSYS; } -static inline int of_property_read_string_helper(const struct device_node *np, - const char *propname, - const char **out_strs, size_t sz, int index) +static inline int of_property_read_u64_index(const struct device_node *np, + const char *propname, u32 index, u64 *out_value) { return -ENOSYS; } @@ -744,12 +736,51 @@ static inline int of_n_size_cells(struct device_node *np) return 0; } +static inline int of_property_read_variable_u8_array(const struct device_node *np, + const char *propname, u8 *out_values, + size_t sz_min, size_t sz_max) +{ + return -ENOSYS; +} + +static inline int of_property_read_variable_u16_array(const struct device_node *np, + const char *propname, u16 *out_values, + size_t sz_min, size_t sz_max) +{ + return -ENOSYS; +} + +static inline int of_property_read_variable_u32_array(const struct device_node *np, + const char *propname, + u32 *out_values, + size_t sz_min, + size_t sz_max) +{ + return -ENOSYS; +} + static inline int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value) { return -ENOSYS; } +static inline int of_property_read_variable_u64_array(const struct device_node *np, + const char *propname, + u64 *out_values, + size_t sz_min, + size_t sz_max) +{ + return -ENOSYS; +} + +static inline int of_property_read_string(const struct device_node *np, + const char *propname, + const char **out_string) +{ + return -ENOSYS; +} + static inline int of_property_match_string(const struct device_node *np, const char *propname, const char *string) @@ -757,6 +788,13 @@ static inline int of_property_match_string(const struct device_node *np, return -ENOSYS; } +static inline int of_property_read_string_helper(const struct device_node *np, + const char *propname, + const char **out_strs, size_t sz, int index) +{ + return -ENOSYS; +} + static inline struct device_node *of_parse_phandle(const struct device_node *np, const char *phandle_name, int index) -- cgit v1.2.3