Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

of: Move dynamic node fixups out of powerpc and into common code

PowerPC does an odd thing with dynamic nodes. It uses a notifier to
catch new node additions and set some of the values like name and type.
This makes no sense since that same code can be put directly into
of_attach_node(). Besides, all dynamic node users need this, not just
powerpc. Fix this problem by moving the logic out of arch/powerpc and
into drivers/of/dynamic.c.

It is also important to remove this notifier because we want to move the
firing of notifiers from before the tree is modified to after so that
the receiver gets a consistent view of the tree, but that is
incompatible with notifiers that modify the node.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
Cc: Nathan Fontenot <nfont@austin.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>

+17 -72
-70
arch/powerpc/kernel/prom.c
··· 821 821 } 822 822 EXPORT_SYMBOL(cpu_to_chip_id); 823 823 824 - #ifdef CONFIG_PPC_PSERIES 825 - /* 826 - * Fix up the uninitialized fields in a new device node: 827 - * name, type and pci-specific fields 828 - */ 829 - 830 - static int of_finish_dynamic_node(struct device_node *node) 831 - { 832 - struct device_node *parent = of_get_parent(node); 833 - int err = 0; 834 - const phandle *ibm_phandle; 835 - 836 - node->name = of_get_property(node, "name", NULL); 837 - node->type = of_get_property(node, "device_type", NULL); 838 - 839 - if (!node->name) 840 - node->name = "<NULL>"; 841 - if (!node->type) 842 - node->type = "<NULL>"; 843 - 844 - if (!parent) { 845 - err = -ENODEV; 846 - goto out; 847 - } 848 - 849 - /* We don't support that function on PowerMac, at least 850 - * not yet 851 - */ 852 - if (machine_is(powermac)) 853 - return -ENODEV; 854 - 855 - /* fix up new node's phandle field */ 856 - if ((ibm_phandle = of_get_property(node, "ibm,phandle", NULL))) 857 - node->phandle = *ibm_phandle; 858 - 859 - out: 860 - of_node_put(parent); 861 - return err; 862 - } 863 - 864 - static int prom_reconfig_notifier(struct notifier_block *nb, 865 - unsigned long action, void *node) 866 - { 867 - int err; 868 - 869 - switch (action) { 870 - case OF_RECONFIG_ATTACH_NODE: 871 - err = of_finish_dynamic_node(node); 872 - if (err < 0) 873 - printk(KERN_ERR "finish_node returned %d\n", err); 874 - break; 875 - default: 876 - err = 0; 877 - break; 878 - } 879 - return notifier_from_errno(err); 880 - } 881 - 882 - static struct notifier_block prom_reconfig_nb = { 883 - .notifier_call = prom_reconfig_notifier, 884 - .priority = 10, /* This one needs to run first */ 885 - }; 886 - 887 - static int __init prom_reconfig_setup(void) 888 - { 889 - return of_reconfig_notifier_register(&prom_reconfig_nb); 890 - } 891 - __initcall(prom_reconfig_setup); 892 - #endif 893 - 894 824 bool arch_match_cpu_phys_id(int cpu, u64 phys_id) 895 825 { 896 826 return (int)phys_id == get_hard_smp_processor_id(cpu);
+2 -2
drivers/of/base.c
··· 266 266 * Find a property with a given name for a given node 267 267 * and return the value. 268 268 */ 269 - static const void *__of_get_property(const struct device_node *np, 270 - const char *name, int *lenp) 269 + const void *__of_get_property(const struct device_node *np, 270 + const char *name, int *lenp) 271 271 { 272 272 struct property *pp = __of_find_property(np, name, lenp); 273 273
+13
drivers/of/dynamic.c
··· 98 98 99 99 void __of_attach_node(struct device_node *np) 100 100 { 101 + const __be32 *phandle; 102 + int sz; 103 + 104 + np->name = __of_get_property(np, "name", NULL) ? : "<NULL>"; 105 + np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>"; 106 + 107 + phandle = __of_get_property(np, "phandle", &sz); 108 + if (!phandle) 109 + phandle = __of_get_property(np, "linux,phandle", &sz); 110 + if (IS_ENABLED(PPC_PSERIES) && !phandle) 111 + phandle = __of_get_property(np, "ibm,phandle", &sz); 112 + np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0; 113 + 101 114 np->child = NULL; 102 115 np->sibling = np->parent->child; 103 116 np->allnext = np->parent->allnext;
+2
drivers/of/of_private.h
··· 63 63 struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags); 64 64 struct device_node *__of_node_alloc(const char *full_name, gfp_t allocflags); 65 65 66 + extern const void *__of_get_property(const struct device_node *np, 67 + const char *name, int *lenp); 66 68 extern int __of_add_property(struct device_node *np, struct property *prop); 67 69 extern int __of_add_property_sysfs(struct device_node *np, 68 70 struct property *prop);