diff options
| author | Grant Likely <grant.likely@secretlab.ca> | 2010-01-29 07:04:33 -0500 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2010-02-09 10:32:42 -0500 |
| commit | fcdeb7fedf89f4bbc2e11959794968080cd8426e (patch) | |
| tree | b549ce78d381f6185d10395afdea9ce8f741fd40 /drivers/of | |
| parent | 580537140568caddbc8a727d4c2f238d38707f68 (diff) | |
of: merge of_attach_node() & of_detach_node()
Merge common code between PowerPC and Microblaze
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'drivers/of')
| -rw-r--r-- | drivers/of/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/of/base.c | 71 |
2 files changed, 75 insertions, 0 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 462825e03123..7cecc8fea9bd 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
| @@ -2,6 +2,10 @@ config OF_FLATTREE | |||
| 2 | bool | 2 | bool |
| 3 | depends on OF | 3 | depends on OF |
| 4 | 4 | ||
| 5 | config OF_DYNAMIC | ||
| 6 | def_bool y | ||
| 7 | depends on OF && PPC_OF | ||
| 8 | |||
| 5 | config OF_DEVICE | 9 | config OF_DEVICE |
| 6 | def_bool y | 10 | def_bool y |
| 7 | depends on OF && (SPARC || PPC_OF || MICROBLAZE) | 11 | depends on OF && (SPARC || PPC_OF || MICROBLAZE) |
diff --git a/drivers/of/base.c b/drivers/of/base.c index cf89ee6253f3..2ce58be314af 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
| @@ -870,3 +870,74 @@ int prom_update_property(struct device_node *np, | |||
| 870 | 870 | ||
| 871 | return 0; | 871 | return 0; |
| 872 | } | 872 | } |
| 873 | |||
| 874 | #if defined(CONFIG_OF_DYNAMIC) | ||
| 875 | /* | ||
| 876 | * Support for dynamic device trees. | ||
| 877 | * | ||
| 878 | * On some platforms, the device tree can be manipulated at runtime. | ||
| 879 | * The routines in this section support adding, removing and changing | ||
| 880 | * device tree nodes. | ||
| 881 | */ | ||
| 882 | |||
| 883 | /** | ||
| 884 | * of_attach_node - Plug a device node into the tree and global list. | ||
| 885 | */ | ||
| 886 | void of_attach_node(struct device_node *np) | ||
| 887 | { | ||
| 888 | unsigned long flags; | ||
| 889 | |||
| 890 | write_lock_irqsave(&devtree_lock, flags); | ||
| 891 | np->sibling = np->parent->child; | ||
| 892 | np->allnext = allnodes; | ||
| 893 | np->parent->child = np; | ||
| 894 | allnodes = np; | ||
| 895 | write_unlock_irqrestore(&devtree_lock, flags); | ||
| 896 | } | ||
| 897 | |||
| 898 | /** | ||
| 899 | * of_detach_node - "Unplug" a node from the device tree. | ||
| 900 | * | ||
| 901 | * The caller must hold a reference to the node. The memory associated with | ||
| 902 | * the node is not freed until its refcount goes to zero. | ||
| 903 | */ | ||
| 904 | void of_detach_node(struct device_node *np) | ||
| 905 | { | ||
| 906 | struct device_node *parent; | ||
| 907 | unsigned long flags; | ||
| 908 | |||
| 909 | write_lock_irqsave(&devtree_lock, flags); | ||
| 910 | |||
| 911 | parent = np->parent; | ||
| 912 | if (!parent) | ||
| 913 | goto out_unlock; | ||
| 914 | |||
| 915 | if (allnodes == np) | ||
| 916 | allnodes = np->allnext; | ||
| 917 | else { | ||
| 918 | struct device_node *prev; | ||
| 919 | for (prev = allnodes; | ||
| 920 | prev->allnext != np; | ||
| 921 | prev = prev->allnext) | ||
| 922 | ; | ||
| 923 | prev->allnext = np->allnext; | ||
| 924 | } | ||
| 925 | |||
| 926 | if (parent->child == np) | ||
| 927 | parent->child = np->sibling; | ||
| 928 | else { | ||
| 929 | struct device_node *prevsib; | ||
| 930 | for (prevsib = np->parent->child; | ||
| 931 | prevsib->sibling != np; | ||
| 932 | prevsib = prevsib->sibling) | ||
| 933 | ; | ||
| 934 | prevsib->sibling = np->sibling; | ||
| 935 | } | ||
| 936 | |||
| 937 | of_node_set_flag(np, OF_DETACHED); | ||
| 938 | |||
| 939 | out_unlock: | ||
| 940 | write_unlock_irqrestore(&devtree_lock, flags); | ||
| 941 | } | ||
| 942 | #endif /* defined(CONFIG_OF_DYNAMIC) */ | ||
| 943 | |||
