diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2016-05-03 09:22:51 -0400 |
---|---|---|
committer | Rob Herring <robh@kernel.org> | 2016-05-16 08:22:35 -0400 |
commit | 83262418b0ef8bda66eca7c72d4c24ae6f7b230e (patch) | |
tree | e0eca40010efc061ba901a13ca42ec12a461eec0 | |
parent | c4263233f30e72f2645ff83c9074c994f88b015a (diff) |
drivers/of: Return allocated memory from of_fdt_unflatten_tree()
This returns the allocate memory chunk, storing the unflattened device
tree, from of_fdt_unflatten_tree() so that memory chunk can be released
on demand in PowerNV PCI hotplug driver.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Rob Herring <robh@kernel.org>
-rw-r--r-- | drivers/of/fdt.c | 33 | ||||
-rw-r--r-- | include/linux/of_fdt.h | 6 |
2 files changed, 25 insertions, 14 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 0d53687d4b8c..ef1ccee51af8 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -454,11 +454,14 @@ static int unflatten_dt_nodes(const void *blob, | |||
454 | * @mynodes: The device_node tree created by the call | 454 | * @mynodes: The device_node tree created by the call |
455 | * @dt_alloc: An allocator that provides a virtual address to memory | 455 | * @dt_alloc: An allocator that provides a virtual address to memory |
456 | * for the resulting tree | 456 | * for the resulting tree |
457 | * | ||
458 | * Returns NULL on failure or the memory chunk containing the unflattened | ||
459 | * device tree on success. | ||
457 | */ | 460 | */ |
458 | static void __unflatten_device_tree(const void *blob, | 461 | static void *__unflatten_device_tree(const void *blob, |
459 | struct device_node *dad, | 462 | struct device_node *dad, |
460 | struct device_node **mynodes, | 463 | struct device_node **mynodes, |
461 | void * (*dt_alloc)(u64 size, u64 align)) | 464 | void *(*dt_alloc)(u64 size, u64 align)) |
462 | { | 465 | { |
463 | int size; | 466 | int size; |
464 | void *mem; | 467 | void *mem; |
@@ -467,7 +470,7 @@ static void __unflatten_device_tree(const void *blob, | |||
467 | 470 | ||
468 | if (!blob) { | 471 | if (!blob) { |
469 | pr_debug("No device tree pointer\n"); | 472 | pr_debug("No device tree pointer\n"); |
470 | return; | 473 | return NULL; |
471 | } | 474 | } |
472 | 475 | ||
473 | pr_debug("Unflattening device tree:\n"); | 476 | pr_debug("Unflattening device tree:\n"); |
@@ -477,13 +480,13 @@ static void __unflatten_device_tree(const void *blob, | |||
477 | 480 | ||
478 | if (fdt_check_header(blob)) { | 481 | if (fdt_check_header(blob)) { |
479 | pr_err("Invalid device tree blob header\n"); | 482 | pr_err("Invalid device tree blob header\n"); |
480 | return; | 483 | return NULL; |
481 | } | 484 | } |
482 | 485 | ||
483 | /* First pass, scan for size */ | 486 | /* First pass, scan for size */ |
484 | size = unflatten_dt_nodes(blob, NULL, dad, NULL); | 487 | size = unflatten_dt_nodes(blob, NULL, dad, NULL); |
485 | if (size < 0) | 488 | if (size < 0) |
486 | return; | 489 | return NULL; |
487 | 490 | ||
488 | size = ALIGN(size, 4); | 491 | size = ALIGN(size, 4); |
489 | pr_debug(" size is %d, allocating...\n", size); | 492 | pr_debug(" size is %d, allocating...\n", size); |
@@ -503,6 +506,7 @@ static void __unflatten_device_tree(const void *blob, | |||
503 | be32_to_cpup(mem + size)); | 506 | be32_to_cpup(mem + size)); |
504 | 507 | ||
505 | pr_debug(" <- unflatten_device_tree()\n"); | 508 | pr_debug(" <- unflatten_device_tree()\n"); |
509 | return mem; | ||
506 | } | 510 | } |
507 | 511 | ||
508 | static void *kernel_tree_alloc(u64 size, u64 align) | 512 | static void *kernel_tree_alloc(u64 size, u64 align) |
@@ -522,14 +526,21 @@ static DEFINE_MUTEX(of_fdt_unflatten_mutex); | |||
522 | * tree of struct device_node. It also fills the "name" and "type" | 526 | * tree of struct device_node. It also fills the "name" and "type" |
523 | * pointers of the nodes so the normal device-tree walking functions | 527 | * pointers of the nodes so the normal device-tree walking functions |
524 | * can be used. | 528 | * can be used. |
529 | * | ||
530 | * Returns NULL on failure or the memory chunk containing the unflattened | ||
531 | * device tree on success. | ||
525 | */ | 532 | */ |
526 | void of_fdt_unflatten_tree(const unsigned long *blob, | 533 | void *of_fdt_unflatten_tree(const unsigned long *blob, |
527 | struct device_node *dad, | 534 | struct device_node *dad, |
528 | struct device_node **mynodes) | 535 | struct device_node **mynodes) |
529 | { | 536 | { |
537 | void *mem; | ||
538 | |||
530 | mutex_lock(&of_fdt_unflatten_mutex); | 539 | mutex_lock(&of_fdt_unflatten_mutex); |
531 | __unflatten_device_tree(blob, dad, mynodes, &kernel_tree_alloc); | 540 | mem = __unflatten_device_tree(blob, dad, mynodes, &kernel_tree_alloc); |
532 | mutex_unlock(&of_fdt_unflatten_mutex); | 541 | mutex_unlock(&of_fdt_unflatten_mutex); |
542 | |||
543 | return mem; | ||
533 | } | 544 | } |
534 | EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); | 545 | EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); |
535 | 546 | ||
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index 1bffcbd56f8e..901ec01c9fba 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h | |||
@@ -37,9 +37,9 @@ extern bool of_fdt_is_big_endian(const void *blob, | |||
37 | unsigned long node); | 37 | unsigned long node); |
38 | extern int of_fdt_match(const void *blob, unsigned long node, | 38 | extern int of_fdt_match(const void *blob, unsigned long node, |
39 | const char *const *compat); | 39 | const char *const *compat); |
40 | extern void of_fdt_unflatten_tree(const unsigned long *blob, | 40 | extern void *of_fdt_unflatten_tree(const unsigned long *blob, |
41 | struct device_node *dad, | 41 | struct device_node *dad, |
42 | struct device_node **mynodes); | 42 | struct device_node **mynodes); |
43 | 43 | ||
44 | /* TBD: Temporary export of fdt globals - remove when code fully merged */ | 44 | /* TBD: Temporary export of fdt globals - remove when code fully merged */ |
45 | extern int __initdata dt_root_addr_cells; | 45 | extern int __initdata dt_root_addr_cells; |