diff options
25 files changed, 267 insertions, 292 deletions
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index 4748ec551a68..d61b915ce52c 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c | |||
| @@ -211,7 +211,7 @@ static void __init update_fec_mac_prop(enum mac_oui oui) | |||
| 211 | macaddr[4] = (val >> 8) & 0xff; | 211 | macaddr[4] = (val >> 8) & 0xff; |
| 212 | macaddr[5] = (val >> 0) & 0xff; | 212 | macaddr[5] = (val >> 0) & 0xff; |
| 213 | 213 | ||
| 214 | prom_update_property(np, newmac); | 214 | of_update_property(np, newmac); |
| 215 | } | 215 | } |
| 216 | } | 216 | } |
| 217 | 217 | ||
diff --git a/arch/powerpc/include/asm/pSeries_reconfig.h b/arch/powerpc/include/asm/pSeries_reconfig.h deleted file mode 100644 index c07edfe98b98..000000000000 --- a/arch/powerpc/include/asm/pSeries_reconfig.h +++ /dev/null | |||
| @@ -1,47 +0,0 @@ | |||
| 1 | #ifndef _PPC64_PSERIES_RECONFIG_H | ||
| 2 | #define _PPC64_PSERIES_RECONFIG_H | ||
| 3 | #ifdef __KERNEL__ | ||
| 4 | |||
| 5 | #include <linux/notifier.h> | ||
| 6 | |||
| 7 | /* | ||
| 8 | * Use this API if your code needs to know about OF device nodes being | ||
| 9 | * added or removed on pSeries systems. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #define PSERIES_RECONFIG_ADD 0x0001 | ||
| 13 | #define PSERIES_RECONFIG_REMOVE 0x0002 | ||
| 14 | #define PSERIES_DRCONF_MEM_ADD 0x0003 | ||
| 15 | #define PSERIES_DRCONF_MEM_REMOVE 0x0004 | ||
| 16 | #define PSERIES_UPDATE_PROPERTY 0x0005 | ||
| 17 | |||
| 18 | /** | ||
| 19 | * pSeries_reconfig_notify - Notifier value structure for OFDT property updates | ||
| 20 | * | ||
| 21 | * @node: Device tree node which owns the property being updated | ||
| 22 | * @property: Updated property | ||
| 23 | */ | ||
| 24 | struct pSeries_reconfig_prop_update { | ||
| 25 | struct device_node *node; | ||
| 26 | struct property *property; | ||
| 27 | }; | ||
| 28 | |||
| 29 | #ifdef CONFIG_PPC_PSERIES | ||
| 30 | extern int pSeries_reconfig_notifier_register(struct notifier_block *); | ||
| 31 | extern void pSeries_reconfig_notifier_unregister(struct notifier_block *); | ||
| 32 | extern int pSeries_reconfig_notify(unsigned long action, void *p); | ||
| 33 | /* Not the best place to put this, will be fixed when we move some | ||
| 34 | * of the rtas suspend-me stuff to pseries */ | ||
| 35 | extern void pSeries_coalesce_init(void); | ||
| 36 | #else /* !CONFIG_PPC_PSERIES */ | ||
| 37 | static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb) | ||
| 38 | { | ||
| 39 | return 0; | ||
| 40 | } | ||
| 41 | static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } | ||
| 42 | static inline void pSeries_coalesce_init(void) { } | ||
| 43 | #endif /* CONFIG_PPC_PSERIES */ | ||
| 44 | |||
| 45 | |||
| 46 | #endif /* __KERNEL__ */ | ||
| 47 | #endif /* _PPC64_PSERIES_RECONFIG_H */ | ||
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index b5c91901e384..99c92d5363e4 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h | |||
| @@ -58,6 +58,22 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; } | |||
| 58 | 58 | ||
| 59 | extern void of_instantiate_rtc(void); | 59 | extern void of_instantiate_rtc(void); |
| 60 | 60 | ||
| 61 | /* The of_drconf_cell struct defines the layout of the LMB array | ||
| 62 | * specified in the device tree property | ||
| 63 | * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory | ||
| 64 | */ | ||
| 65 | struct of_drconf_cell { | ||
| 66 | u64 base_addr; | ||
| 67 | u32 drc_index; | ||
| 68 | u32 reserved; | ||
| 69 | u32 aa_index; | ||
| 70 | u32 flags; | ||
| 71 | }; | ||
| 72 | |||
| 73 | #define DRCONF_MEM_ASSIGNED 0x00000008 | ||
| 74 | #define DRCONF_MEM_AI_INVALID 0x00000040 | ||
| 75 | #define DRCONF_MEM_RESERVED 0x00000080 | ||
| 76 | |||
| 61 | /* These includes are put at the bottom because they may contain things | 77 | /* These includes are put at the bottom because they may contain things |
| 62 | * that are overridden by this file. Ideally they shouldn't be included | 78 | * that are overridden by this file. Ideally they shouldn't be included |
| 63 | * by this file, but there are a bunch of .c files that currently depend | 79 | * by this file, but there are a bunch of .c files that currently depend |
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 557cff845dee..aef00c675905 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h | |||
| @@ -353,8 +353,13 @@ static inline int page_is_rtas_user_buf(unsigned long pfn) | |||
| 353 | return 1; | 353 | return 1; |
| 354 | return 0; | 354 | return 0; |
| 355 | } | 355 | } |
| 356 | |||
| 357 | /* Not the best place to put pSeries_coalesce_init, will be fixed when we | ||
| 358 | * move some of the rtas suspend-me stuff to pseries */ | ||
| 359 | extern void pSeries_coalesce_init(void); | ||
| 356 | #else | 360 | #else |
| 357 | static inline int page_is_rtas_user_buf(unsigned long pfn) { return 0;} | 361 | static inline int page_is_rtas_user_buf(unsigned long pfn) { return 0;} |
| 362 | static inline void pSeries_coalesce_init(void) { } | ||
| 358 | #endif | 363 | #endif |
| 359 | 364 | ||
| 360 | extern int call_rtas(const char *, int, int, unsigned long *, ...); | 365 | extern int call_rtas(const char *, int, int, unsigned long *, ...); |
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index fa9f6c72f557..e1ec57e87b3b 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c | |||
| @@ -218,23 +218,23 @@ static void __init export_crashk_values(struct device_node *node) | |||
| 218 | * be sure what's in them, so remove them. */ | 218 | * be sure what's in them, so remove them. */ |
| 219 | prop = of_find_property(node, "linux,crashkernel-base", NULL); | 219 | prop = of_find_property(node, "linux,crashkernel-base", NULL); |
| 220 | if (prop) | 220 | if (prop) |
| 221 | prom_remove_property(node, prop); | 221 | of_remove_property(node, prop); |
| 222 | 222 | ||
| 223 | prop = of_find_property(node, "linux,crashkernel-size", NULL); | 223 | prop = of_find_property(node, "linux,crashkernel-size", NULL); |
| 224 | if (prop) | 224 | if (prop) |
| 225 | prom_remove_property(node, prop); | 225 | of_remove_property(node, prop); |
| 226 | 226 | ||
| 227 | if (crashk_res.start != 0) { | 227 | if (crashk_res.start != 0) { |
| 228 | prom_add_property(node, &crashk_base_prop); | 228 | of_add_property(node, &crashk_base_prop); |
| 229 | crashk_size = resource_size(&crashk_res); | 229 | crashk_size = resource_size(&crashk_res); |
| 230 | prom_add_property(node, &crashk_size_prop); | 230 | of_add_property(node, &crashk_size_prop); |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | /* | 233 | /* |
| 234 | * memory_limit is required by the kexec-tools to limit the | 234 | * memory_limit is required by the kexec-tools to limit the |
| 235 | * crash regions to the actual memory used. | 235 | * crash regions to the actual memory used. |
| 236 | */ | 236 | */ |
| 237 | prom_update_property(node, &memory_limit_prop); | 237 | of_update_property(node, &memory_limit_prop); |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | static int __init kexec_setup(void) | 240 | static int __init kexec_setup(void) |
| @@ -249,11 +249,11 @@ static int __init kexec_setup(void) | |||
| 249 | /* remove any stale properties so ours can be found */ | 249 | /* remove any stale properties so ours can be found */ |
| 250 | prop = of_find_property(node, kernel_end_prop.name, NULL); | 250 | prop = of_find_property(node, kernel_end_prop.name, NULL); |
| 251 | if (prop) | 251 | if (prop) |
| 252 | prom_remove_property(node, prop); | 252 | of_remove_property(node, prop); |
| 253 | 253 | ||
| 254 | /* information needed by userspace when using default_machine_kexec */ | 254 | /* information needed by userspace when using default_machine_kexec */ |
| 255 | kernel_end = __pa(_end); | 255 | kernel_end = __pa(_end); |
| 256 | prom_add_property(node, &kernel_end_prop); | 256 | of_add_property(node, &kernel_end_prop); |
| 257 | 257 | ||
| 258 | export_crashk_values(node); | 258 | export_crashk_values(node); |
| 259 | 259 | ||
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index d7f609086a99..7206701b1ff1 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
| @@ -389,14 +389,14 @@ static int __init export_htab_values(void) | |||
| 389 | /* remove any stale propertys so ours can be found */ | 389 | /* remove any stale propertys so ours can be found */ |
| 390 | prop = of_find_property(node, htab_base_prop.name, NULL); | 390 | prop = of_find_property(node, htab_base_prop.name, NULL); |
| 391 | if (prop) | 391 | if (prop) |
| 392 | prom_remove_property(node, prop); | 392 | of_remove_property(node, prop); |
| 393 | prop = of_find_property(node, htab_size_prop.name, NULL); | 393 | prop = of_find_property(node, htab_size_prop.name, NULL); |
| 394 | if (prop) | 394 | if (prop) |
| 395 | prom_remove_property(node, prop); | 395 | of_remove_property(node, prop); |
| 396 | 396 | ||
| 397 | htab_base = __pa(htab_address); | 397 | htab_base = __pa(htab_address); |
| 398 | prom_add_property(node, &htab_base_prop); | 398 | of_add_property(node, &htab_base_prop); |
| 399 | prom_add_property(node, &htab_size_prop); | 399 | of_add_property(node, &htab_size_prop); |
| 400 | 400 | ||
| 401 | of_node_put(node); | 401 | of_node_put(node); |
| 402 | return 0; | 402 | return 0; |
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 4b06ec5a502e..64f526a321f5 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
| @@ -208,7 +208,7 @@ pci_create_OF_bus_map(void) | |||
| 208 | of_prop->name = "pci-OF-bus-map"; | 208 | of_prop->name = "pci-OF-bus-map"; |
| 209 | of_prop->length = 256; | 209 | of_prop->length = 256; |
| 210 | of_prop->value = &of_prop[1]; | 210 | of_prop->value = &of_prop[1]; |
| 211 | prom_add_property(dn, of_prop); | 211 | of_add_property(dn, of_prop); |
| 212 | of_node_put(dn); | 212 | of_node_put(dn); |
| 213 | } | 213 | } |
| 214 | } | 214 | } |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index f5ca76a79c88..8b6f7a99cce2 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
| 33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
| 34 | #include <linux/memblock.h> | 34 | #include <linux/memblock.h> |
| 35 | #include <linux/of.h> | ||
| 35 | 36 | ||
| 36 | #include <asm/prom.h> | 37 | #include <asm/prom.h> |
| 37 | #include <asm/rtas.h> | 38 | #include <asm/rtas.h> |
| @@ -49,7 +50,6 @@ | |||
| 49 | #include <asm/btext.h> | 50 | #include <asm/btext.h> |
| 50 | #include <asm/sections.h> | 51 | #include <asm/sections.h> |
| 51 | #include <asm/machdep.h> | 52 | #include <asm/machdep.h> |
| 52 | #include <asm/pSeries_reconfig.h> | ||
| 53 | #include <asm/pci-bridge.h> | 53 | #include <asm/pci-bridge.h> |
| 54 | #include <asm/kexec.h> | 54 | #include <asm/kexec.h> |
| 55 | #include <asm/opal.h> | 55 | #include <asm/opal.h> |
| @@ -803,7 +803,7 @@ static int prom_reconfig_notifier(struct notifier_block *nb, | |||
| 803 | int err; | 803 | int err; |
| 804 | 804 | ||
| 805 | switch (action) { | 805 | switch (action) { |
| 806 | case PSERIES_RECONFIG_ADD: | 806 | case OF_RECONFIG_ATTACH_NODE: |
| 807 | err = of_finish_dynamic_node(node); | 807 | err = of_finish_dynamic_node(node); |
| 808 | if (err < 0) | 808 | if (err < 0) |
| 809 | printk(KERN_ERR "finish_node returned %d\n", err); | 809 | printk(KERN_ERR "finish_node returned %d\n", err); |
| @@ -822,7 +822,7 @@ static struct notifier_block prom_reconfig_nb = { | |||
| 822 | 822 | ||
| 823 | static int __init prom_reconfig_setup(void) | 823 | static int __init prom_reconfig_setup(void) |
| 824 | { | 824 | { |
| 825 | return pSeries_reconfig_notifier_register(&prom_reconfig_nb); | 825 | return of_reconfig_notifier_register(&prom_reconfig_nb); |
| 826 | } | 826 | } |
| 827 | __initcall(prom_reconfig_setup); | 827 | __initcall(prom_reconfig_setup); |
| 828 | #endif | 828 | #endif |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index fcec38241f79..1fd6e7b2f390 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
| @@ -42,7 +42,6 @@ | |||
| 42 | #include <asm/time.h> | 42 | #include <asm/time.h> |
| 43 | #include <asm/mmu.h> | 43 | #include <asm/mmu.h> |
| 44 | #include <asm/topology.h> | 44 | #include <asm/topology.h> |
| 45 | #include <asm/pSeries_reconfig.h> | ||
| 46 | 45 | ||
| 47 | struct rtas_t rtas = { | 46 | struct rtas_t rtas = { |
| 48 | .lock = __ARCH_SPIN_LOCK_UNLOCKED | 47 | .lock = __ARCH_SPIN_LOCK_UNLOCKED |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 59213cfaeca9..bba87ca2b4d7 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
| @@ -399,18 +399,6 @@ static unsigned long read_n_cells(int n, const unsigned int **buf) | |||
| 399 | return result; | 399 | return result; |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | struct of_drconf_cell { | ||
| 403 | u64 base_addr; | ||
| 404 | u32 drc_index; | ||
| 405 | u32 reserved; | ||
| 406 | u32 aa_index; | ||
| 407 | u32 flags; | ||
| 408 | }; | ||
| 409 | |||
| 410 | #define DRCONF_MEM_ASSIGNED 0x00000008 | ||
| 411 | #define DRCONF_MEM_AI_INVALID 0x00000040 | ||
| 412 | #define DRCONF_MEM_RESERVED 0x00000080 | ||
| 413 | |||
| 414 | /* | 402 | /* |
| 415 | * Read the next memblock list entry from the ibm,dynamic-memory property | 403 | * Read the next memblock list entry from the ibm,dynamic-memory property |
| 416 | * and return the information in the provided of_drconf_cell structure. | 404 | * and return the information in the provided of_drconf_cell structure. |
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 848a3e98e1c1..8fb12570b2f5 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
| @@ -539,7 +539,7 @@ static void __init p1022_ds_setup_arch(void) | |||
| 539 | }; | 539 | }; |
| 540 | 540 | ||
| 541 | /* | 541 | /* |
| 542 | * prom_update_property() is called before | 542 | * of_update_property() is called before |
| 543 | * kmalloc() is available, so the 'new' object | 543 | * kmalloc() is available, so the 'new' object |
| 544 | * should be allocated in the global area. | 544 | * should be allocated in the global area. |
| 545 | * The easiest way is to do that is to | 545 | * The easiest way is to do that is to |
| @@ -548,7 +548,7 @@ static void __init p1022_ds_setup_arch(void) | |||
| 548 | */ | 548 | */ |
| 549 | pr_info("p1022ds: disabling %s node", | 549 | pr_info("p1022ds: disabling %s node", |
| 550 | np2->full_name); | 550 | np2->full_name); |
| 551 | prom_update_property(np2, &nor_status); | 551 | of_update_property(np2, &nor_status); |
| 552 | of_node_put(np2); | 552 | of_node_put(np2); |
| 553 | } | 553 | } |
| 554 | 554 | ||
| @@ -564,7 +564,7 @@ static void __init p1022_ds_setup_arch(void) | |||
| 564 | 564 | ||
| 565 | pr_info("p1022ds: disabling %s node", | 565 | pr_info("p1022ds: disabling %s node", |
| 566 | np2->full_name); | 566 | np2->full_name); |
| 567 | prom_update_property(np2, &nand_status); | 567 | of_update_property(np2, &nand_status); |
| 568 | of_node_put(np2); | 568 | of_node_put(np2); |
| 569 | } | 569 | } |
| 570 | 570 | ||
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c index 56d26bc4fd41..09787139834d 100644 --- a/arch/powerpc/platforms/ps3/os-area.c +++ b/arch/powerpc/platforms/ps3/os-area.c | |||
| @@ -280,13 +280,13 @@ static void os_area_set_property(struct device_node *node, | |||
| 280 | 280 | ||
| 281 | if (tmp) { | 281 | if (tmp) { |
| 282 | pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name); | 282 | pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name); |
| 283 | prom_remove_property(node, tmp); | 283 | of_remove_property(node, tmp); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | result = prom_add_property(node, prop); | 286 | result = of_add_property(node, prop); |
| 287 | 287 | ||
| 288 | if (result) | 288 | if (result) |
| 289 | pr_debug("%s:%d prom_set_property failed\n", __func__, | 289 | pr_debug("%s:%d of_set_property failed\n", __func__, |
| 290 | __LINE__); | 290 | __LINE__); |
| 291 | } | 291 | } |
| 292 | 292 | ||
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 0f1b706506ed..a1a7b9a67ffd 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
| @@ -13,17 +13,16 @@ | |||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/kref.h> | 14 | #include <linux/kref.h> |
| 15 | #include <linux/notifier.h> | 15 | #include <linux/notifier.h> |
| 16 | #include <linux/proc_fs.h> | ||
| 17 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
| 18 | #include <linux/cpu.h> | 17 | #include <linux/cpu.h> |
| 19 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/of.h> | ||
| 20 | #include "offline_states.h" | 20 | #include "offline_states.h" |
| 21 | 21 | ||
| 22 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
| 23 | #include <asm/machdep.h> | 23 | #include <asm/machdep.h> |
| 24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
| 25 | #include <asm/rtas.h> | 25 | #include <asm/rtas.h> |
| 26 | #include <asm/pSeries_reconfig.h> | ||
| 27 | 26 | ||
| 28 | struct cc_workarea { | 27 | struct cc_workarea { |
| 29 | u32 drc_index; | 28 | u32 drc_index; |
| @@ -255,9 +254,6 @@ static struct device_node *derive_parent(const char *path) | |||
| 255 | 254 | ||
| 256 | int dlpar_attach_node(struct device_node *dn) | 255 | int dlpar_attach_node(struct device_node *dn) |
| 257 | { | 256 | { |
| 258 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 259 | struct proc_dir_entry *ent; | ||
| 260 | #endif | ||
| 261 | int rc; | 257 | int rc; |
| 262 | 258 | ||
| 263 | of_node_set_flag(dn, OF_DYNAMIC); | 259 | of_node_set_flag(dn, OF_DYNAMIC); |
| @@ -266,44 +262,26 @@ int dlpar_attach_node(struct device_node *dn) | |||
| 266 | if (!dn->parent) | 262 | if (!dn->parent) |
| 267 | return -ENOMEM; | 263 | return -ENOMEM; |
| 268 | 264 | ||
| 269 | rc = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, dn); | 265 | rc = of_attach_node(dn); |
| 270 | if (rc) { | 266 | if (rc) { |
| 271 | printk(KERN_ERR "Failed to add device node %s\n", | 267 | printk(KERN_ERR "Failed to add device node %s\n", |
| 272 | dn->full_name); | 268 | dn->full_name); |
| 273 | return rc; | 269 | return rc; |
| 274 | } | 270 | } |
| 275 | 271 | ||
| 276 | of_attach_node(dn); | ||
| 277 | |||
| 278 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 279 | ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde); | ||
| 280 | if (ent) | ||
| 281 | proc_device_tree_add_node(dn, ent); | ||
| 282 | #endif | ||
| 283 | |||
| 284 | of_node_put(dn->parent); | 272 | of_node_put(dn->parent); |
| 285 | return 0; | 273 | return 0; |
| 286 | } | 274 | } |
| 287 | 275 | ||
| 288 | int dlpar_detach_node(struct device_node *dn) | 276 | int dlpar_detach_node(struct device_node *dn) |
| 289 | { | 277 | { |
| 290 | #ifdef CONFIG_PROC_DEVICETREE | 278 | int rc; |
| 291 | struct device_node *parent = dn->parent; | ||
| 292 | struct property *prop = dn->properties; | ||
| 293 | |||
| 294 | while (prop) { | ||
| 295 | remove_proc_entry(prop->name, dn->pde); | ||
| 296 | prop = prop->next; | ||
| 297 | } | ||
| 298 | 279 | ||
| 299 | if (dn->pde) | 280 | rc = of_detach_node(dn); |
| 300 | remove_proc_entry(dn->pde->name, parent->pde); | 281 | if (rc) |
| 301 | #endif | 282 | return rc; |
| 302 | 283 | ||
| 303 | pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, dn); | ||
| 304 | of_detach_node(dn); | ||
| 305 | of_node_put(dn); /* Must decrement the refcount */ | 284 | of_node_put(dn); /* Must decrement the refcount */ |
| 306 | |||
| 307 | return 0; | 285 | return 0; |
| 308 | } | 286 | } |
| 309 | 287 | ||
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 64c97d8ac0c5..a38956269fbf 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
| @@ -23,12 +23,12 @@ | |||
| 23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 24 | #include <linux/sched.h> /* for idle_task_exit */ | 24 | #include <linux/sched.h> /* for idle_task_exit */ |
| 25 | #include <linux/cpu.h> | 25 | #include <linux/cpu.h> |
| 26 | #include <linux/of.h> | ||
| 26 | #include <asm/prom.h> | 27 | #include <asm/prom.h> |
| 27 | #include <asm/rtas.h> | 28 | #include <asm/rtas.h> |
| 28 | #include <asm/firmware.h> | 29 | #include <asm/firmware.h> |
| 29 | #include <asm/machdep.h> | 30 | #include <asm/machdep.h> |
| 30 | #include <asm/vdso_datapage.h> | 31 | #include <asm/vdso_datapage.h> |
| 31 | #include <asm/pSeries_reconfig.h> | ||
| 32 | #include <asm/xics.h> | 32 | #include <asm/xics.h> |
| 33 | #include "plpar_wrappers.h" | 33 | #include "plpar_wrappers.h" |
| 34 | #include "offline_states.h" | 34 | #include "offline_states.h" |
| @@ -333,10 +333,10 @@ static int pseries_smp_notifier(struct notifier_block *nb, | |||
| 333 | int err = 0; | 333 | int err = 0; |
| 334 | 334 | ||
| 335 | switch (action) { | 335 | switch (action) { |
| 336 | case PSERIES_RECONFIG_ADD: | 336 | case OF_RECONFIG_ATTACH_NODE: |
| 337 | err = pseries_add_processor(node); | 337 | err = pseries_add_processor(node); |
| 338 | break; | 338 | break; |
| 339 | case PSERIES_RECONFIG_REMOVE: | 339 | case OF_RECONFIG_DETACH_NODE: |
| 340 | pseries_remove_processor(node); | 340 | pseries_remove_processor(node); |
| 341 | break; | 341 | break; |
| 342 | } | 342 | } |
| @@ -399,7 +399,7 @@ static int __init pseries_cpu_hotplug_init(void) | |||
| 399 | 399 | ||
| 400 | /* Processors can be added/removed only on LPAR */ | 400 | /* Processors can be added/removed only on LPAR */ |
| 401 | if (firmware_has_feature(FW_FEATURE_LPAR)) { | 401 | if (firmware_has_feature(FW_FEATURE_LPAR)) { |
| 402 | pSeries_reconfig_notifier_register(&pseries_smp_nb); | 402 | of_reconfig_notifier_register(&pseries_smp_nb); |
| 403 | cpu_maps_update_begin(); | 403 | cpu_maps_update_begin(); |
| 404 | if (cede_offline_enabled && parse_cede_parameters() == 0) { | 404 | if (cede_offline_enabled && parse_cede_parameters() == 0) { |
| 405 | default_offline_state = CPU_STATE_INACTIVE; | 405 | default_offline_state = CPU_STATE_INACTIVE; |
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index ecdb0a6b3171..2372c609fa2b 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | 16 | ||
| 17 | #include <asm/firmware.h> | 17 | #include <asm/firmware.h> |
| 18 | #include <asm/machdep.h> | 18 | #include <asm/machdep.h> |
| 19 | #include <asm/pSeries_reconfig.h> | ||
| 20 | #include <asm/sparsemem.h> | 19 | #include <asm/sparsemem.h> |
| 21 | 20 | ||
| 22 | static unsigned long get_memblock_size(void) | 21 | static unsigned long get_memblock_size(void) |
| @@ -187,42 +186,69 @@ static int pseries_add_memory(struct device_node *np) | |||
| 187 | return (ret < 0) ? -EINVAL : 0; | 186 | return (ret < 0) ? -EINVAL : 0; |
| 188 | } | 187 | } |
| 189 | 188 | ||
| 190 | static int pseries_drconf_memory(unsigned long *base, unsigned int action) | 189 | static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) |
| 191 | { | 190 | { |
| 191 | struct of_drconf_cell *new_drmem, *old_drmem; | ||
| 192 | unsigned long memblock_size; | 192 | unsigned long memblock_size; |
| 193 | int rc; | 193 | u32 entries; |
| 194 | u32 *p; | ||
| 195 | int i, rc = -EINVAL; | ||
| 194 | 196 | ||
| 195 | memblock_size = get_memblock_size(); | 197 | memblock_size = get_memblock_size(); |
| 196 | if (!memblock_size) | 198 | if (!memblock_size) |
| 197 | return -EINVAL; | 199 | return -EINVAL; |
| 198 | 200 | ||
| 199 | if (action == PSERIES_DRCONF_MEM_ADD) { | 201 | p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL); |
| 200 | rc = memblock_add(*base, memblock_size); | 202 | if (!p) |
| 201 | rc = (rc < 0) ? -EINVAL : 0; | 203 | return -EINVAL; |
| 202 | } else if (action == PSERIES_DRCONF_MEM_REMOVE) { | 204 | |
| 203 | rc = pseries_remove_memblock(*base, memblock_size); | 205 | /* The first int of the property is the number of lmb's described |
| 204 | } else { | 206 | * by the property. This is followed by an array of of_drconf_cell |
| 205 | rc = -EINVAL; | 207 | * entries. Get the niumber of entries and skip to the array of |
| 208 | * of_drconf_cell's. | ||
| 209 | */ | ||
| 210 | entries = *p++; | ||
| 211 | old_drmem = (struct of_drconf_cell *)p; | ||
| 212 | |||
| 213 | p = (u32 *)pr->prop->value; | ||
| 214 | p++; | ||
| 215 | new_drmem = (struct of_drconf_cell *)p; | ||
| 216 | |||
| 217 | for (i = 0; i < entries; i++) { | ||
| 218 | if ((old_drmem[i].flags & DRCONF_MEM_ASSIGNED) && | ||
| 219 | (!(new_drmem[i].flags & DRCONF_MEM_ASSIGNED))) { | ||
| 220 | rc = pseries_remove_memblock(old_drmem[i].base_addr, | ||
| 221 | memblock_size); | ||
| 222 | break; | ||
| 223 | } else if ((!(old_drmem[i].flags & DRCONF_MEM_ASSIGNED)) && | ||
| 224 | (new_drmem[i].flags & DRCONF_MEM_ASSIGNED)) { | ||
| 225 | rc = memblock_add(old_drmem[i].base_addr, | ||
| 226 | memblock_size); | ||
| 227 | rc = (rc < 0) ? -EINVAL : 0; | ||
| 228 | break; | ||
| 229 | } | ||
| 206 | } | 230 | } |
| 207 | 231 | ||
| 208 | return rc; | 232 | return rc; |
| 209 | } | 233 | } |
| 210 | 234 | ||
| 211 | static int pseries_memory_notifier(struct notifier_block *nb, | 235 | static int pseries_memory_notifier(struct notifier_block *nb, |
| 212 | unsigned long action, void *node) | 236 | unsigned long action, void *node) |
| 213 | { | 237 | { |
| 238 | struct of_prop_reconfig *pr; | ||
| 214 | int err = 0; | 239 | int err = 0; |
| 215 | 240 | ||
| 216 | switch (action) { | 241 | switch (action) { |
| 217 | case PSERIES_RECONFIG_ADD: | 242 | case OF_RECONFIG_ATTACH_NODE: |
| 218 | err = pseries_add_memory(node); | 243 | err = pseries_add_memory(node); |
| 219 | break; | 244 | break; |
| 220 | case PSERIES_RECONFIG_REMOVE: | 245 | case OF_RECONFIG_DETACH_NODE: |
| 221 | err = pseries_remove_memory(node); | 246 | err = pseries_remove_memory(node); |
| 222 | break; | 247 | break; |
| 223 | case PSERIES_DRCONF_MEM_ADD: | 248 | case OF_RECONFIG_UPDATE_PROPERTY: |
| 224 | case PSERIES_DRCONF_MEM_REMOVE: | 249 | pr = (struct of_prop_reconfig *)node; |
| 225 | err = pseries_drconf_memory(node, action); | 250 | if (!strcmp(pr->prop->name, "ibm,dynamic-memory")) |
| 251 | err = pseries_update_drconf_memory(pr); | ||
| 226 | break; | 252 | break; |
| 227 | } | 253 | } |
| 228 | return notifier_from_errno(err); | 254 | return notifier_from_errno(err); |
| @@ -235,7 +261,7 @@ static struct notifier_block pseries_mem_nb = { | |||
| 235 | static int __init pseries_memory_hotplug_init(void) | 261 | static int __init pseries_memory_hotplug_init(void) |
| 236 | { | 262 | { |
| 237 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 263 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
| 238 | pSeries_reconfig_notifier_register(&pseries_mem_nb); | 264 | of_reconfig_notifier_register(&pseries_mem_nb); |
| 239 | 265 | ||
| 240 | return 0; | 266 | return 0; |
| 241 | } | 267 | } |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 6153eea27ce7..e2685badb5db 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
| @@ -36,13 +36,13 @@ | |||
| 36 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
| 37 | #include <linux/crash_dump.h> | 37 | #include <linux/crash_dump.h> |
| 38 | #include <linux/memory.h> | 38 | #include <linux/memory.h> |
| 39 | #include <linux/of.h> | ||
| 39 | #include <asm/io.h> | 40 | #include <asm/io.h> |
| 40 | #include <asm/prom.h> | 41 | #include <asm/prom.h> |
| 41 | #include <asm/rtas.h> | 42 | #include <asm/rtas.h> |
| 42 | #include <asm/iommu.h> | 43 | #include <asm/iommu.h> |
| 43 | #include <asm/pci-bridge.h> | 44 | #include <asm/pci-bridge.h> |
| 44 | #include <asm/machdep.h> | 45 | #include <asm/machdep.h> |
| 45 | #include <asm/pSeries_reconfig.h> | ||
| 46 | #include <asm/firmware.h> | 46 | #include <asm/firmware.h> |
| 47 | #include <asm/tce.h> | 47 | #include <asm/tce.h> |
| 48 | #include <asm/ppc-pci.h> | 48 | #include <asm/ppc-pci.h> |
| @@ -760,7 +760,7 @@ static void remove_ddw(struct device_node *np) | |||
| 760 | __remove_ddw(np, ddw_avail, liobn); | 760 | __remove_ddw(np, ddw_avail, liobn); |
| 761 | 761 | ||
| 762 | delprop: | 762 | delprop: |
| 763 | ret = prom_remove_property(np, win64); | 763 | ret = of_remove_property(np, win64); |
| 764 | if (ret) | 764 | if (ret) |
| 765 | pr_warning("%s: failed to remove direct window property: %d\n", | 765 | pr_warning("%s: failed to remove direct window property: %d\n", |
| 766 | np->full_name, ret); | 766 | np->full_name, ret); |
| @@ -1070,7 +1070,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
| 1070 | goto out_free_window; | 1070 | goto out_free_window; |
| 1071 | } | 1071 | } |
| 1072 | 1072 | ||
| 1073 | ret = prom_add_property(pdn, win64); | 1073 | ret = of_add_property(pdn, win64); |
| 1074 | if (ret) { | 1074 | if (ret) { |
| 1075 | dev_err(&dev->dev, "unable to add dma window property for %s: %d", | 1075 | dev_err(&dev->dev, "unable to add dma window property for %s: %d", |
| 1076 | pdn->full_name, ret); | 1076 | pdn->full_name, ret); |
| @@ -1294,7 +1294,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti | |||
| 1294 | struct direct_window *window; | 1294 | struct direct_window *window; |
| 1295 | 1295 | ||
| 1296 | switch (action) { | 1296 | switch (action) { |
| 1297 | case PSERIES_RECONFIG_REMOVE: | 1297 | case OF_RECONFIG_DETACH_NODE: |
| 1298 | if (pci && pci->iommu_table) | 1298 | if (pci && pci->iommu_table) |
| 1299 | iommu_free_table(pci->iommu_table, np->full_name); | 1299 | iommu_free_table(pci->iommu_table, np->full_name); |
| 1300 | 1300 | ||
| @@ -1357,7 +1357,7 @@ void iommu_init_early_pSeries(void) | |||
| 1357 | } | 1357 | } |
| 1358 | 1358 | ||
| 1359 | 1359 | ||
| 1360 | pSeries_reconfig_notifier_register(&iommu_reconfig_nb); | 1360 | of_reconfig_notifier_register(&iommu_reconfig_nb); |
| 1361 | register_memory_notifier(&iommu_mem_nb); | 1361 | register_memory_notifier(&iommu_mem_nb); |
| 1362 | 1362 | ||
| 1363 | set_pci_dma_ops(&dma_iommu_ops); | 1363 | set_pci_dma_ops(&dma_iommu_ops); |
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index dd30b12edfe4..6573808cc5f3 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c | |||
| @@ -116,7 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop, | |||
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | if (!more) { | 118 | if (!more) { |
| 119 | prom_update_property(dn, new_prop); | 119 | of_update_property(dn, new_prop); |
| 120 | new_prop = NULL; | 120 | new_prop = NULL; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| @@ -172,7 +172,7 @@ static int update_dt_node(u32 phandle) | |||
| 172 | 172 | ||
| 173 | case 0x80000000: | 173 | case 0x80000000: |
| 174 | prop = of_find_property(dn, prop_name, NULL); | 174 | prop = of_find_property(dn, prop_name, NULL); |
| 175 | prom_remove_property(dn, prop); | 175 | of_remove_property(dn, prop); |
| 176 | prop = NULL; | 176 | prop = NULL; |
| 177 | break; | 177 | break; |
| 178 | 178 | ||
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 39f71fba9b38..30b358dc2beb 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
| @@ -16,55 +16,13 @@ | |||
| 16 | #include <linux/notifier.h> | 16 | #include <linux/notifier.h> |
| 17 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/of.h> | ||
| 19 | 20 | ||
| 20 | #include <asm/prom.h> | 21 | #include <asm/prom.h> |
| 21 | #include <asm/machdep.h> | 22 | #include <asm/machdep.h> |
| 22 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
| 23 | #include <asm/pSeries_reconfig.h> | ||
| 24 | #include <asm/mmu.h> | 24 | #include <asm/mmu.h> |
| 25 | 25 | ||
| 26 | |||
| 27 | |||
| 28 | /* | ||
| 29 | * Routines for "runtime" addition and removal of device tree nodes. | ||
| 30 | */ | ||
| 31 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 32 | /* | ||
| 33 | * Add a node to /proc/device-tree. | ||
| 34 | */ | ||
| 35 | static void add_node_proc_entries(struct device_node *np) | ||
| 36 | { | ||
| 37 | struct proc_dir_entry *ent; | ||
| 38 | |||
| 39 | ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde); | ||
| 40 | if (ent) | ||
| 41 | proc_device_tree_add_node(np, ent); | ||
| 42 | } | ||
| 43 | |||
| 44 | static void remove_node_proc_entries(struct device_node *np) | ||
| 45 | { | ||
| 46 | struct property *pp = np->properties; | ||
| 47 | struct device_node *parent = np->parent; | ||
| 48 | |||
| 49 | while (pp) { | ||
| 50 | remove_proc_entry(pp->name, np->pde); | ||
| 51 | pp = pp->next; | ||
| 52 | } | ||
| 53 | if (np->pde) | ||
| 54 | remove_proc_entry(np->pde->name, parent->pde); | ||
| 55 | } | ||
| 56 | #else /* !CONFIG_PROC_DEVICETREE */ | ||
| 57 | static void add_node_proc_entries(struct device_node *np) | ||
| 58 | { | ||
| 59 | return; | ||
| 60 | } | ||
| 61 | |||
| 62 | static void remove_node_proc_entries(struct device_node *np) | ||
| 63 | { | ||
| 64 | return; | ||
| 65 | } | ||
| 66 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
| 67 | |||
| 68 | /** | 26 | /** |
| 69 | * derive_parent - basically like dirname(1) | 27 | * derive_parent - basically like dirname(1) |
| 70 | * @path: the full_name of a node to be added to the tree | 28 | * @path: the full_name of a node to be added to the tree |
| @@ -97,28 +55,6 @@ static struct device_node *derive_parent(const char *path) | |||
| 97 | return parent; | 55 | return parent; |
| 98 | } | 56 | } |
| 99 | 57 | ||
| 100 | static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain); | ||
| 101 | |||
| 102 | int pSeries_reconfig_notifier_register(struct notifier_block *nb) | ||
| 103 | { | ||
| 104 | return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb); | ||
| 105 | } | ||
| 106 | EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_register); | ||
| 107 | |||
| 108 | void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) | ||
| 109 | { | ||
| 110 | blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb); | ||
| 111 | } | ||
| 112 | EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_unregister); | ||
| 113 | |||
| 114 | int pSeries_reconfig_notify(unsigned long action, void *p) | ||
| 115 | { | ||
| 116 | int err = blocking_notifier_call_chain(&pSeries_reconfig_chain, | ||
| 117 | action, p); | ||
| 118 | |||
| 119 | return notifier_to_errno(err); | ||
| 120 | } | ||
| 121 | |||
| 122 | static int pSeries_reconfig_add_node(const char *path, struct property *proplist) | 58 | static int pSeries_reconfig_add_node(const char *path, struct property *proplist) |
| 123 | { | 59 | { |
| 124 | struct device_node *np; | 60 | struct device_node *np; |
| @@ -142,16 +78,12 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist | |||
| 142 | goto out_err; | 78 | goto out_err; |
| 143 | } | 79 | } |
| 144 | 80 | ||
| 145 | err = pSeries_reconfig_notify(PSERIES_RECONFIG_ADD, np); | 81 | err = of_attach_node(np); |
| 146 | if (err) { | 82 | if (err) { |
| 147 | printk(KERN_ERR "Failed to add device node %s\n", path); | 83 | printk(KERN_ERR "Failed to add device node %s\n", path); |
| 148 | goto out_err; | 84 | goto out_err; |
| 149 | } | 85 | } |
| 150 | 86 | ||
| 151 | of_attach_node(np); | ||
| 152 | |||
| 153 | add_node_proc_entries(np); | ||
| 154 | |||
| 155 | of_node_put(np->parent); | 87 | of_node_put(np->parent); |
| 156 | 88 | ||
| 157 | return 0; | 89 | return 0; |
| @@ -179,11 +111,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np) | |||
| 179 | return -EBUSY; | 111 | return -EBUSY; |
| 180 | } | 112 | } |
| 181 | 113 | ||
| 182 | remove_node_proc_entries(np); | ||
| 183 | |||
| 184 | pSeries_reconfig_notify(PSERIES_RECONFIG_REMOVE, np); | ||
| 185 | of_detach_node(np); | 114 | of_detach_node(np); |
| 186 | |||
| 187 | of_node_put(parent); | 115 | of_node_put(parent); |
| 188 | of_node_put(np); /* Must decrement the refcount */ | 116 | of_node_put(np); /* Must decrement the refcount */ |
| 189 | return 0; | 117 | return 0; |
| @@ -398,7 +326,7 @@ static int do_add_property(char *buf, size_t bufsize) | |||
| 398 | if (!prop) | 326 | if (!prop) |
| 399 | return -ENOMEM; | 327 | return -ENOMEM; |
| 400 | 328 | ||
| 401 | prom_add_property(np, prop); | 329 | of_add_property(np, prop); |
| 402 | 330 | ||
| 403 | return 0; | 331 | return 0; |
| 404 | } | 332 | } |
| @@ -422,16 +350,15 @@ static int do_remove_property(char *buf, size_t bufsize) | |||
| 422 | 350 | ||
| 423 | prop = of_find_property(np, buf, NULL); | 351 | prop = of_find_property(np, buf, NULL); |
| 424 | 352 | ||
| 425 | return prom_remove_property(np, prop); | 353 | return of_remove_property(np, prop); |
| 426 | } | 354 | } |
| 427 | 355 | ||
| 428 | static int do_update_property(char *buf, size_t bufsize) | 356 | static int do_update_property(char *buf, size_t bufsize) |
| 429 | { | 357 | { |
| 430 | struct device_node *np; | 358 | struct device_node *np; |
| 431 | struct pSeries_reconfig_prop_update upd_value; | ||
| 432 | unsigned char *value; | 359 | unsigned char *value; |
| 433 | char *name, *end, *next_prop; | 360 | char *name, *end, *next_prop; |
| 434 | int rc, length; | 361 | int length; |
| 435 | struct property *newprop; | 362 | struct property *newprop; |
| 436 | buf = parse_node(buf, bufsize, &np); | 363 | buf = parse_node(buf, bufsize, &np); |
| 437 | end = buf + bufsize; | 364 | end = buf + bufsize; |
| @@ -453,41 +380,7 @@ static int do_update_property(char *buf, size_t bufsize) | |||
| 453 | if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) | 380 | if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) |
| 454 | slb_set_size(*(int *)value); | 381 | slb_set_size(*(int *)value); |
| 455 | 382 | ||
| 456 | upd_value.node = np; | 383 | return of_update_property(np, newprop); |
| 457 | upd_value.property = newprop; | ||
| 458 | pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value); | ||
| 459 | |||
| 460 | rc = prom_update_property(np, newprop); | ||
| 461 | if (rc) | ||
| 462 | return rc; | ||
| 463 | |||
| 464 | /* For memory under the ibm,dynamic-reconfiguration-memory node | ||
| 465 | * of the device tree, adding and removing memory is just an update | ||
| 466 | * to the ibm,dynamic-memory property instead of adding/removing a | ||
| 467 | * memory node in the device tree. For these cases we still need to | ||
| 468 | * involve the notifier chain. | ||
| 469 | */ | ||
| 470 | if (!strcmp(name, "ibm,dynamic-memory")) { | ||
| 471 | int action; | ||
| 472 | |||
| 473 | next_prop = parse_next_property(next_prop, end, &name, | ||
| 474 | &length, &value); | ||
| 475 | if (!next_prop) | ||
| 476 | return -EINVAL; | ||
| 477 | |||
| 478 | if (!strcmp(name, "add")) | ||
| 479 | action = PSERIES_DRCONF_MEM_ADD; | ||
| 480 | else | ||
| 481 | action = PSERIES_DRCONF_MEM_REMOVE; | ||
| 482 | |||
| 483 | rc = pSeries_reconfig_notify(action, value); | ||
| 484 | if (rc) { | ||
| 485 | prom_update_property(np, newprop); | ||
| 486 | return rc; | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 490 | return 0; | ||
| 491 | } | 384 | } |
| 492 | 385 | ||
| 493 | /** | 386 | /** |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index e3cb7ae61658..e1a5b8a32d25 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/seq_file.h> | 40 | #include <linux/seq_file.h> |
| 41 | #include <linux/root_dev.h> | 41 | #include <linux/root_dev.h> |
| 42 | #include <linux/cpuidle.h> | 42 | #include <linux/cpuidle.h> |
| 43 | #include <linux/of.h> | ||
| 43 | 44 | ||
| 44 | #include <asm/mmu.h> | 45 | #include <asm/mmu.h> |
| 45 | #include <asm/processor.h> | 46 | #include <asm/processor.h> |
| @@ -63,7 +64,6 @@ | |||
| 63 | #include <asm/smp.h> | 64 | #include <asm/smp.h> |
| 64 | #include <asm/firmware.h> | 65 | #include <asm/firmware.h> |
| 65 | #include <asm/eeh.h> | 66 | #include <asm/eeh.h> |
| 66 | #include <asm/pSeries_reconfig.h> | ||
| 67 | 67 | ||
| 68 | #include "plpar_wrappers.h" | 68 | #include "plpar_wrappers.h" |
| 69 | #include "pseries.h" | 69 | #include "pseries.h" |
| @@ -258,7 +258,7 @@ static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long act | |||
| 258 | int err = NOTIFY_OK; | 258 | int err = NOTIFY_OK; |
| 259 | 259 | ||
| 260 | switch (action) { | 260 | switch (action) { |
| 261 | case PSERIES_RECONFIG_ADD: | 261 | case OF_RECONFIG_ATTACH_NODE: |
| 262 | pci = np->parent->data; | 262 | pci = np->parent->data; |
| 263 | if (pci) { | 263 | if (pci) { |
| 264 | update_dn_pci_info(np, pci->phb); | 264 | update_dn_pci_info(np, pci->phb); |
| @@ -389,7 +389,7 @@ static void __init pSeries_setup_arch(void) | |||
| 389 | /* Find and initialize PCI host bridges */ | 389 | /* Find and initialize PCI host bridges */ |
| 390 | init_pci_config_tokens(); | 390 | init_pci_config_tokens(); |
| 391 | find_and_init_phbs(); | 391 | find_and_init_phbs(); |
| 392 | pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb); | 392 | of_reconfig_notifier_register(&pci_dn_reconfig_nb); |
| 393 | 393 | ||
| 394 | pSeries_nvram_init(); | 394 | pSeries_nvram_init(); |
| 395 | 395 | ||
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 71706bc34a0d..9fc0a4941908 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <asm/cputable.h> | 38 | #include <asm/cputable.h> |
| 39 | #include <asm/firmware.h> | 39 | #include <asm/firmware.h> |
| 40 | #include <asm/rtas.h> | 40 | #include <asm/rtas.h> |
| 41 | #include <asm/pSeries_reconfig.h> | ||
| 42 | #include <asm/mpic.h> | 41 | #include <asm/mpic.h> |
| 43 | #include <asm/vdso_datapage.h> | 42 | #include <asm/vdso_datapage.h> |
| 44 | #include <asm/cputhreads.h> | 43 | #include <asm/cputhreads.h> |
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index 0ce625738677..6c4c000671c5 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | 29 | ||
| 30 | #include <asm/page.h> | 30 | #include <asm/page.h> |
| 31 | #include <asm/pSeries_reconfig.h> | ||
| 32 | #include <asm/vio.h> | 31 | #include <asm/vio.h> |
| 33 | 32 | ||
| 34 | #include "nx_csbcpb.h" /* struct nx_csbcpb */ | 33 | #include "nx_csbcpb.h" /* struct nx_csbcpb */ |
| @@ -1014,26 +1013,23 @@ error_out: | |||
| 1014 | * NOTIFY_BAD encoded with error number on failure, use | 1013 | * NOTIFY_BAD encoded with error number on failure, use |
| 1015 | * notifier_to_errno() to decode this value | 1014 | * notifier_to_errno() to decode this value |
| 1016 | */ | 1015 | */ |
| 1017 | static int nx842_OF_notifier(struct notifier_block *np, | 1016 | static int nx842_OF_notifier(struct notifier_block *np, unsigned long action, |
| 1018 | unsigned long action, | 1017 | void *update) |
| 1019 | void *update) | ||
| 1020 | { | 1018 | { |
| 1021 | struct pSeries_reconfig_prop_update *upd; | 1019 | struct of_prop_reconfig *upd = update; |
| 1022 | struct nx842_devdata *local_devdata; | 1020 | struct nx842_devdata *local_devdata; |
| 1023 | struct device_node *node = NULL; | 1021 | struct device_node *node = NULL; |
| 1024 | 1022 | ||
| 1025 | upd = (struct pSeries_reconfig_prop_update *)update; | ||
| 1026 | |||
| 1027 | rcu_read_lock(); | 1023 | rcu_read_lock(); |
| 1028 | local_devdata = rcu_dereference(devdata); | 1024 | local_devdata = rcu_dereference(devdata); |
| 1029 | if (local_devdata) | 1025 | if (local_devdata) |
| 1030 | node = local_devdata->dev->of_node; | 1026 | node = local_devdata->dev->of_node; |
| 1031 | 1027 | ||
| 1032 | if (local_devdata && | 1028 | if (local_devdata && |
| 1033 | action == PSERIES_UPDATE_PROPERTY && | 1029 | action == OF_RECONFIG_UPDATE_PROPERTY && |
| 1034 | !strcmp(upd->node->name, node->name)) { | 1030 | !strcmp(upd->dn->name, node->name)) { |
| 1035 | rcu_read_unlock(); | 1031 | rcu_read_unlock(); |
| 1036 | nx842_OF_upd(upd->property); | 1032 | nx842_OF_upd(upd->prop); |
| 1037 | } else | 1033 | } else |
| 1038 | rcu_read_unlock(); | 1034 | rcu_read_unlock(); |
| 1039 | 1035 | ||
| @@ -1182,7 +1178,7 @@ static int __init nx842_probe(struct vio_dev *viodev, | |||
| 1182 | synchronize_rcu(); | 1178 | synchronize_rcu(); |
| 1183 | kfree(old_devdata); | 1179 | kfree(old_devdata); |
| 1184 | 1180 | ||
| 1185 | pSeries_reconfig_notifier_register(&nx842_of_nb); | 1181 | of_reconfig_notifier_register(&nx842_of_nb); |
| 1186 | 1182 | ||
| 1187 | ret = nx842_OF_upd(NULL); | 1183 | ret = nx842_OF_upd(NULL); |
| 1188 | if (ret && ret != -ENODEV) { | 1184 | if (ret && ret != -ENODEV) { |
| @@ -1228,7 +1224,7 @@ static int __exit nx842_remove(struct vio_dev *viodev) | |||
| 1228 | spin_lock_irqsave(&devdata_mutex, flags); | 1224 | spin_lock_irqsave(&devdata_mutex, flags); |
| 1229 | old_devdata = rcu_dereference_check(devdata, | 1225 | old_devdata = rcu_dereference_check(devdata, |
| 1230 | lockdep_is_held(&devdata_mutex)); | 1226 | lockdep_is_held(&devdata_mutex)); |
| 1231 | pSeries_reconfig_notifier_unregister(&nx842_of_nb); | 1227 | of_reconfig_notifier_unregister(&nx842_of_nb); |
| 1232 | rcu_assign_pointer(devdata, NULL); | 1228 | rcu_assign_pointer(devdata, NULL); |
| 1233 | spin_unlock_irqrestore(&devdata_mutex, flags); | 1229 | spin_unlock_irqrestore(&devdata_mutex, flags); |
| 1234 | synchronize_rcu(); | 1230 | synchronize_rcu(); |
diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c index 638110efae9b..f7a8a16aa7d3 100644 --- a/drivers/crypto/nx/nx.c +++ b/drivers/crypto/nx/nx.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #include <linux/scatterlist.h> | 33 | #include <linux/scatterlist.h> |
| 34 | #include <linux/device.h> | 34 | #include <linux/device.h> |
| 35 | #include <linux/of.h> | 35 | #include <linux/of.h> |
| 36 | #include <asm/pSeries_reconfig.h> | ||
| 37 | #include <asm/hvcall.h> | 36 | #include <asm/hvcall.h> |
| 38 | #include <asm/vio.h> | 37 | #include <asm/vio.h> |
| 39 | 38 | ||
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 7d5a6b40b31c..5b939509db3b 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
| @@ -997,7 +997,7 @@ static struct smu_sdbp_header *smu_create_sdb_partition(int id) | |||
| 997 | "%02x !\n", id, hdr->id); | 997 | "%02x !\n", id, hdr->id); |
| 998 | goto failure; | 998 | goto failure; |
| 999 | } | 999 | } |
| 1000 | if (prom_add_property(smu->of_node, prop)) { | 1000 | if (of_add_property(smu->of_node, prop)) { |
| 1001 | printk(KERN_DEBUG "SMU: Failed creating sdb-partition-%02x " | 1001 | printk(KERN_DEBUG "SMU: Failed creating sdb-partition-%02x " |
| 1002 | "property !\n", id); | 1002 | "property !\n", id); |
| 1003 | goto failure; | 1003 | goto failure; |
diff --git a/drivers/of/base.c b/drivers/of/base.c index af3b22ac7627..02d94c4ea83c 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
| @@ -1028,13 +1028,36 @@ int of_parse_phandle_with_args(struct device_node *np, const char *list_name, | |||
| 1028 | } | 1028 | } |
| 1029 | EXPORT_SYMBOL(of_parse_phandle_with_args); | 1029 | EXPORT_SYMBOL(of_parse_phandle_with_args); |
| 1030 | 1030 | ||
| 1031 | #if defined(CONFIG_OF_DYNAMIC) | ||
| 1032 | static int of_property_notify(int action, struct device_node *np, | ||
| 1033 | struct property *prop) | ||
| 1034 | { | ||
| 1035 | struct of_prop_reconfig pr; | ||
| 1036 | |||
| 1037 | pr.dn = np; | ||
| 1038 | pr.prop = prop; | ||
| 1039 | return of_reconfig_notify(action, &pr); | ||
| 1040 | } | ||
| 1041 | #else | ||
| 1042 | static int of_property_notify(int action, struct device_node *np, | ||
| 1043 | struct property *prop) | ||
| 1044 | { | ||
| 1045 | return 0; | ||
| 1046 | } | ||
| 1047 | #endif | ||
| 1048 | |||
| 1031 | /** | 1049 | /** |
| 1032 | * prom_add_property - Add a property to a node | 1050 | * of_add_property - Add a property to a node |
| 1033 | */ | 1051 | */ |
| 1034 | int prom_add_property(struct device_node *np, struct property *prop) | 1052 | int of_add_property(struct device_node *np, struct property *prop) |
| 1035 | { | 1053 | { |
| 1036 | struct property **next; | 1054 | struct property **next; |
| 1037 | unsigned long flags; | 1055 | unsigned long flags; |
| 1056 | int rc; | ||
| 1057 | |||
| 1058 | rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop); | ||
| 1059 | if (rc) | ||
| 1060 | return rc; | ||
| 1038 | 1061 | ||
| 1039 | prop->next = NULL; | 1062 | prop->next = NULL; |
| 1040 | write_lock_irqsave(&devtree_lock, flags); | 1063 | write_lock_irqsave(&devtree_lock, flags); |
| @@ -1060,18 +1083,23 @@ int prom_add_property(struct device_node *np, struct property *prop) | |||
| 1060 | } | 1083 | } |
| 1061 | 1084 | ||
| 1062 | /** | 1085 | /** |
| 1063 | * prom_remove_property - Remove a property from a node. | 1086 | * of_remove_property - Remove a property from a node. |
| 1064 | * | 1087 | * |
| 1065 | * Note that we don't actually remove it, since we have given out | 1088 | * Note that we don't actually remove it, since we have given out |
| 1066 | * who-knows-how-many pointers to the data using get-property. | 1089 | * who-knows-how-many pointers to the data using get-property. |
| 1067 | * Instead we just move the property to the "dead properties" | 1090 | * Instead we just move the property to the "dead properties" |
| 1068 | * list, so it won't be found any more. | 1091 | * list, so it won't be found any more. |
| 1069 | */ | 1092 | */ |
| 1070 | int prom_remove_property(struct device_node *np, struct property *prop) | 1093 | int of_remove_property(struct device_node *np, struct property *prop) |
| 1071 | { | 1094 | { |
| 1072 | struct property **next; | 1095 | struct property **next; |
| 1073 | unsigned long flags; | 1096 | unsigned long flags; |
| 1074 | int found = 0; | 1097 | int found = 0; |
| 1098 | int rc; | ||
| 1099 | |||
| 1100 | rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop); | ||
| 1101 | if (rc) | ||
| 1102 | return rc; | ||
| 1075 | 1103 | ||
| 1076 | write_lock_irqsave(&devtree_lock, flags); | 1104 | write_lock_irqsave(&devtree_lock, flags); |
| 1077 | next = &np->properties; | 1105 | next = &np->properties; |
| @@ -1101,7 +1129,7 @@ int prom_remove_property(struct device_node *np, struct property *prop) | |||
| 1101 | } | 1129 | } |
| 1102 | 1130 | ||
| 1103 | /* | 1131 | /* |
| 1104 | * prom_update_property - Update a property in a node, if the property does | 1132 | * of_update_property - Update a property in a node, if the property does |
| 1105 | * not exist, add it. | 1133 | * not exist, add it. |
| 1106 | * | 1134 | * |
| 1107 | * Note that we don't actually remove it, since we have given out | 1135 | * Note that we don't actually remove it, since we have given out |
| @@ -1109,19 +1137,22 @@ int prom_remove_property(struct device_node *np, struct property *prop) | |||
| 1109 | * Instead we just move the property to the "dead properties" list, | 1137 | * Instead we just move the property to the "dead properties" list, |
| 1110 | * and add the new property to the property list | 1138 | * and add the new property to the property list |
| 1111 | */ | 1139 | */ |
| 1112 | int prom_update_property(struct device_node *np, | 1140 | int of_update_property(struct device_node *np, struct property *newprop) |
| 1113 | struct property *newprop) | ||
| 1114 | { | 1141 | { |
| 1115 | struct property **next, *oldprop; | 1142 | struct property **next, *oldprop; |
| 1116 | unsigned long flags; | 1143 | unsigned long flags; |
| 1117 | int found = 0; | 1144 | int rc, found = 0; |
| 1145 | |||
| 1146 | rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); | ||
| 1147 | if (rc) | ||
| 1148 | return rc; | ||
| 1118 | 1149 | ||
| 1119 | if (!newprop->name) | 1150 | if (!newprop->name) |
| 1120 | return -EINVAL; | 1151 | return -EINVAL; |
| 1121 | 1152 | ||
| 1122 | oldprop = of_find_property(np, newprop->name, NULL); | 1153 | oldprop = of_find_property(np, newprop->name, NULL); |
| 1123 | if (!oldprop) | 1154 | if (!oldprop) |
| 1124 | return prom_add_property(np, newprop); | 1155 | return of_add_property(np, newprop); |
| 1125 | 1156 | ||
| 1126 | write_lock_irqsave(&devtree_lock, flags); | 1157 | write_lock_irqsave(&devtree_lock, flags); |
| 1127 | next = &np->properties; | 1158 | next = &np->properties; |
| @@ -1160,12 +1191,53 @@ int prom_update_property(struct device_node *np, | |||
| 1160 | * device tree nodes. | 1191 | * device tree nodes. |
| 1161 | */ | 1192 | */ |
| 1162 | 1193 | ||
| 1194 | static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain); | ||
| 1195 | |||
| 1196 | int of_reconfig_notifier_register(struct notifier_block *nb) | ||
| 1197 | { | ||
| 1198 | return blocking_notifier_chain_register(&of_reconfig_chain, nb); | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | int of_reconfig_notifier_unregister(struct notifier_block *nb) | ||
| 1202 | { | ||
| 1203 | return blocking_notifier_chain_unregister(&of_reconfig_chain, nb); | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | int of_reconfig_notify(unsigned long action, void *p) | ||
| 1207 | { | ||
| 1208 | int rc; | ||
| 1209 | |||
| 1210 | rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p); | ||
| 1211 | return notifier_to_errno(rc); | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 1215 | static void of_add_proc_dt_entry(struct device_node *dn) | ||
| 1216 | { | ||
| 1217 | struct proc_dir_entry *ent; | ||
| 1218 | |||
| 1219 | ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde); | ||
| 1220 | if (ent) | ||
| 1221 | proc_device_tree_add_node(dn, ent); | ||
| 1222 | } | ||
| 1223 | #else | ||
| 1224 | static void of_add_proc_dt_entry(struct device_node *dn) | ||
| 1225 | { | ||
| 1226 | return; | ||
| 1227 | } | ||
| 1228 | #endif | ||
| 1229 | |||
| 1163 | /** | 1230 | /** |
| 1164 | * of_attach_node - Plug a device node into the tree and global list. | 1231 | * of_attach_node - Plug a device node into the tree and global list. |
| 1165 | */ | 1232 | */ |
| 1166 | void of_attach_node(struct device_node *np) | 1233 | int of_attach_node(struct device_node *np) |
| 1167 | { | 1234 | { |
| 1168 | unsigned long flags; | 1235 | unsigned long flags; |
| 1236 | int rc; | ||
| 1237 | |||
| 1238 | rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np); | ||
| 1239 | if (rc) | ||
| 1240 | return rc; | ||
| 1169 | 1241 | ||
| 1170 | write_lock_irqsave(&devtree_lock, flags); | 1242 | write_lock_irqsave(&devtree_lock, flags); |
| 1171 | np->sibling = np->parent->child; | 1243 | np->sibling = np->parent->child; |
| @@ -1173,24 +1245,61 @@ void of_attach_node(struct device_node *np) | |||
| 1173 | np->parent->child = np; | 1245 | np->parent->child = np; |
| 1174 | allnodes = np; | 1246 | allnodes = np; |
| 1175 | write_unlock_irqrestore(&devtree_lock, flags); | 1247 | write_unlock_irqrestore(&devtree_lock, flags); |
| 1248 | |||
| 1249 | of_add_proc_dt_entry(np); | ||
| 1250 | return 0; | ||
| 1176 | } | 1251 | } |
| 1177 | 1252 | ||
| 1253 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 1254 | static void of_remove_proc_dt_entry(struct device_node *dn) | ||
| 1255 | { | ||
| 1256 | struct device_node *parent = dn->parent; | ||
| 1257 | struct property *prop = dn->properties; | ||
| 1258 | |||
| 1259 | while (prop) { | ||
| 1260 | remove_proc_entry(prop->name, dn->pde); | ||
| 1261 | prop = prop->next; | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | if (dn->pde) | ||
| 1265 | remove_proc_entry(dn->pde->name, parent->pde); | ||
| 1266 | } | ||
| 1267 | #else | ||
| 1268 | static void of_remove_proc_dt_entry(struct device_node *dn) | ||
| 1269 | { | ||
| 1270 | return; | ||
| 1271 | } | ||
| 1272 | #endif | ||
| 1273 | |||
| 1178 | /** | 1274 | /** |
| 1179 | * of_detach_node - "Unplug" a node from the device tree. | 1275 | * of_detach_node - "Unplug" a node from the device tree. |
| 1180 | * | 1276 | * |
| 1181 | * The caller must hold a reference to the node. The memory associated with | 1277 | * The caller must hold a reference to the node. The memory associated with |
| 1182 | * the node is not freed until its refcount goes to zero. | 1278 | * the node is not freed until its refcount goes to zero. |
| 1183 | */ | 1279 | */ |
| 1184 | void of_detach_node(struct device_node *np) | 1280 | int of_detach_node(struct device_node *np) |
| 1185 | { | 1281 | { |
| 1186 | struct device_node *parent; | 1282 | struct device_node *parent; |
| 1187 | unsigned long flags; | 1283 | unsigned long flags; |
| 1284 | int rc = 0; | ||
| 1285 | |||
| 1286 | rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np); | ||
| 1287 | if (rc) | ||
| 1288 | return rc; | ||
| 1188 | 1289 | ||
| 1189 | write_lock_irqsave(&devtree_lock, flags); | 1290 | write_lock_irqsave(&devtree_lock, flags); |
| 1190 | 1291 | ||
| 1292 | if (of_node_check_flag(np, OF_DETACHED)) { | ||
| 1293 | /* someone already detached it */ | ||
| 1294 | write_unlock_irqrestore(&devtree_lock, flags); | ||
| 1295 | return rc; | ||
| 1296 | } | ||
| 1297 | |||
| 1191 | parent = np->parent; | 1298 | parent = np->parent; |
| 1192 | if (!parent) | 1299 | if (!parent) { |
| 1193 | goto out_unlock; | 1300 | write_unlock_irqrestore(&devtree_lock, flags); |
| 1301 | return rc; | ||
| 1302 | } | ||
| 1194 | 1303 | ||
| 1195 | if (allnodes == np) | 1304 | if (allnodes == np) |
| 1196 | allnodes = np->allnext; | 1305 | allnodes = np->allnext; |
| @@ -1215,9 +1324,10 @@ void of_detach_node(struct device_node *np) | |||
| 1215 | } | 1324 | } |
| 1216 | 1325 | ||
| 1217 | of_node_set_flag(np, OF_DETACHED); | 1326 | of_node_set_flag(np, OF_DETACHED); |
| 1218 | |||
| 1219 | out_unlock: | ||
| 1220 | write_unlock_irqrestore(&devtree_lock, flags); | 1327 | write_unlock_irqrestore(&devtree_lock, flags); |
| 1328 | |||
| 1329 | of_remove_proc_dt_entry(np); | ||
| 1330 | return rc; | ||
| 1221 | } | 1331 | } |
| 1222 | #endif /* defined(CONFIG_OF_DYNAMIC) */ | 1332 | #endif /* defined(CONFIG_OF_DYNAMIC) */ |
| 1223 | 1333 | ||
diff --git a/include/linux/of.h b/include/linux/of.h index 72843b72a2b2..a093b2fe5dfb 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/mod_devicetable.h> | 22 | #include <linux/mod_devicetable.h> |
| 23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
| 24 | #include <linux/topology.h> | 24 | #include <linux/topology.h> |
| 25 | #include <linux/notifier.h> | ||
| 25 | 26 | ||
| 26 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
| 27 | #include <asm/errno.h> | 28 | #include <asm/errno.h> |
| @@ -267,16 +268,28 @@ extern int of_alias_get_id(struct device_node *np, const char *stem); | |||
| 267 | 268 | ||
| 268 | extern int of_machine_is_compatible(const char *compat); | 269 | extern int of_machine_is_compatible(const char *compat); |
| 269 | 270 | ||
| 270 | extern int prom_add_property(struct device_node* np, struct property* prop); | 271 | extern int of_add_property(struct device_node *np, struct property *prop); |
| 271 | extern int prom_remove_property(struct device_node *np, struct property *prop); | 272 | extern int of_remove_property(struct device_node *np, struct property *prop); |
| 272 | extern int prom_update_property(struct device_node *np, | 273 | extern int of_update_property(struct device_node *np, struct property *newprop); |
| 273 | struct property *newprop); | ||
| 274 | 274 | ||
| 275 | #if defined(CONFIG_OF_DYNAMIC) | ||
| 276 | /* For updating the device tree at runtime */ | 275 | /* For updating the device tree at runtime */ |
| 277 | extern void of_attach_node(struct device_node *); | 276 | #define OF_RECONFIG_ATTACH_NODE 0x0001 |
| 278 | extern void of_detach_node(struct device_node *); | 277 | #define OF_RECONFIG_DETACH_NODE 0x0002 |
| 279 | #endif | 278 | #define OF_RECONFIG_ADD_PROPERTY 0x0003 |
| 279 | #define OF_RECONFIG_REMOVE_PROPERTY 0x0004 | ||
| 280 | #define OF_RECONFIG_UPDATE_PROPERTY 0x0005 | ||
| 281 | |||
| 282 | struct of_prop_reconfig { | ||
| 283 | struct device_node *dn; | ||
| 284 | struct property *prop; | ||
| 285 | }; | ||
| 286 | |||
| 287 | extern int of_reconfig_notifier_register(struct notifier_block *); | ||
| 288 | extern int of_reconfig_notifier_unregister(struct notifier_block *); | ||
| 289 | extern int of_reconfig_notify(unsigned long, void *); | ||
| 290 | |||
| 291 | extern int of_attach_node(struct device_node *); | ||
| 292 | extern int of_detach_node(struct device_node *); | ||
| 280 | 293 | ||
| 281 | #define of_match_ptr(_ptr) (_ptr) | 294 | #define of_match_ptr(_ptr) (_ptr) |
| 282 | 295 | ||
