aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-01-29 07:04:33 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-02-09 10:32:42 -0500
commitfcdeb7fedf89f4bbc2e11959794968080cd8426e (patch)
treeb549ce78d381f6185d10395afdea9ce8f741fd40
parent580537140568caddbc8a727d4c2f238d38707f68 (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>
-rw-r--r--arch/microblaze/include/asm/prom.h4
-rw-r--r--arch/microblaze/kernel/prom.c59
-rw-r--r--arch/powerpc/include/asm/prom.h4
-rw-r--r--arch/powerpc/kernel/prom.c59
-rw-r--r--drivers/of/Kconfig4
-rw-r--r--drivers/of/base.c71
-rw-r--r--include/linux/of.h6
7 files changed, 81 insertions, 126 deletions
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 07d1063f9aae..6c6b386cf3c6 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -39,10 +39,6 @@ extern struct device_node *of_chosen;
39 39
40extern rwlock_t devtree_lock; /* temporary while merging */ 40extern rwlock_t devtree_lock; /* temporary while merging */
41 41
42/* For updating the device tree at runtime */
43extern void of_attach_node(struct device_node *);
44extern void of_detach_node(struct device_node *);
45
46/* Other Prototypes */ 42/* Other Prototypes */
47extern int early_uartlite_console(void); 43extern int early_uartlite_console(void);
48 44
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index cd158ef5b583..8171282a0b0d 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -197,65 +197,6 @@ struct device_node *of_find_node_by_phandle(phandle handle)
197} 197}
198EXPORT_SYMBOL(of_find_node_by_phandle); 198EXPORT_SYMBOL(of_find_node_by_phandle);
199 199
200/*
201 * Plug a device node into the tree and global list.
202 */
203void of_attach_node(struct device_node *np)
204{
205 unsigned long flags;
206
207 write_lock_irqsave(&devtree_lock, flags);
208 np->sibling = np->parent->child;
209 np->allnext = allnodes;
210 np->parent->child = np;
211 allnodes = np;
212 write_unlock_irqrestore(&devtree_lock, flags);
213}
214
215/*
216 * "Unplug" a node from the device tree. The caller must hold
217 * a reference to the node. The memory associated with the node
218 * is not freed until its refcount goes to zero.
219 */
220void of_detach_node(struct device_node *np)
221{
222 struct device_node *parent;
223 unsigned long flags;
224
225 write_lock_irqsave(&devtree_lock, flags);
226
227 parent = np->parent;
228 if (!parent)
229 goto out_unlock;
230
231 if (allnodes == np)
232 allnodes = np->allnext;
233 else {
234 struct device_node *prev;
235 for (prev = allnodes;
236 prev->allnext != np;
237 prev = prev->allnext)
238 ;
239 prev->allnext = np->allnext;
240 }
241
242 if (parent->child == np)
243 parent->child = np->sibling;
244 else {
245 struct device_node *prevsib;
246 for (prevsib = np->parent->child;
247 prevsib->sibling != np;
248 prevsib = prevsib->sibling)
249 ;
250 prevsib->sibling = np->sibling;
251 }
252
253 of_node_set_flag(np, OF_DETACHED);
254
255out_unlock:
256 write_unlock_irqrestore(&devtree_lock, flags);
257}
258
259#if defined(CONFIG_DEBUG_FS) && defined(DEBUG) 200#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
260static struct debugfs_blob_wrapper flat_dt_blob; 201static struct debugfs_blob_wrapper flat_dt_blob;
261 202
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 2ab9cbd98826..f384db815ea8 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -34,10 +34,6 @@ extern struct device_node *of_chosen;
34 34
35#define HAVE_ARCH_DEVTREE_FIXUPS 35#define HAVE_ARCH_DEVTREE_FIXUPS
36 36
37/* For updating the device tree at runtime */
38extern void of_attach_node(struct device_node *);
39extern void of_detach_node(struct device_node *);
40
41#ifdef CONFIG_PPC32 37#ifdef CONFIG_PPC32
42/* 38/*
43 * PCI <-> OF matching functions 39 * PCI <-> OF matching functions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 1ed2ec2ea05b..f954c718d7eb 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -817,65 +817,6 @@ struct device_node *of_find_next_cache_node(struct device_node *np)
817 return NULL; 817 return NULL;
818} 818}
819 819
820/*
821 * Plug a device node into the tree and global list.
822 */
823void of_attach_node(struct device_node *np)
824{
825 unsigned long flags;
826
827 write_lock_irqsave(&devtree_lock, flags);
828 np->sibling = np->parent->child;
829 np->allnext = allnodes;
830 np->parent->child = np;
831 allnodes = np;
832 write_unlock_irqrestore(&devtree_lock, flags);
833}
834
835/*
836 * "Unplug" a node from the device tree. The caller must hold
837 * a reference to the node. The memory associated with the node
838 * is not freed until its refcount goes to zero.
839 */
840void of_detach_node(struct device_node *np)
841{
842 struct device_node *parent;
843 unsigned long flags;
844
845 write_lock_irqsave(&devtree_lock, flags);
846
847 parent = np->parent;
848 if (!parent)
849 goto out_unlock;
850
851 if (allnodes == np)
852 allnodes = np->allnext;
853 else {
854 struct device_node *prev;
855 for (prev = allnodes;
856 prev->allnext != np;
857 prev = prev->allnext)
858 ;
859 prev->allnext = np->allnext;
860 }
861
862 if (parent->child == np)
863 parent->child = np->sibling;
864 else {
865 struct device_node *prevsib;
866 for (prevsib = np->parent->child;
867 prevsib->sibling != np;
868 prevsib = prevsib->sibling)
869 ;
870 prevsib->sibling = np->sibling;
871 }
872
873 of_node_set_flag(np, OF_DETACHED);
874
875out_unlock:
876 write_unlock_irqrestore(&devtree_lock, flags);
877}
878
879#ifdef CONFIG_PPC_PSERIES 820#ifdef CONFIG_PPC_PSERIES
880/* 821/*
881 * Fix up the uninitialized fields in a new device node: 822 * Fix up the uninitialized fields in a new device node:
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
5config OF_DYNAMIC
6 def_bool y
7 depends on OF && PPC_OF
8
5config OF_DEVICE 9config 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 */
886void 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 */
904void 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
939out_unlock:
940 write_unlock_irqrestore(&devtree_lock, flags);
941}
942#endif /* defined(CONFIG_OF_DYNAMIC) */
943
diff --git a/include/linux/of.h b/include/linux/of.h
index dbabf86e0b7a..3cc0d7ae290e 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -184,4 +184,10 @@ extern int of_parse_phandles_with_args(struct device_node *np,
184 const char *list_name, const char *cells_name, int index, 184 const char *list_name, const char *cells_name, int index,
185 struct device_node **out_node, const void **out_args); 185 struct device_node **out_node, const void **out_args);
186 186
187#if defined(CONFIG_OF_DYNAMIC)
188/* For updating the device tree at runtime */
189extern void of_attach_node(struct device_node *);
190extern void of_detach_node(struct device_node *);
191#endif
192
187#endif /* _LINUX_OF_H */ 193#endif /* _LINUX_OF_H */