diff options
Diffstat (limited to 'drivers/of/base.c')
| -rw-r--r-- | drivers/of/base.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c index e6627b2320f1..ec56739eb247 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
| @@ -658,3 +658,119 @@ err0: | |||
| 658 | return ret; | 658 | return ret; |
| 659 | } | 659 | } |
| 660 | EXPORT_SYMBOL(of_parse_phandles_with_args); | 660 | EXPORT_SYMBOL(of_parse_phandles_with_args); |
| 661 | |||
| 662 | /** | ||
| 663 | * prom_add_property - Add a property to a node | ||
| 664 | */ | ||
| 665 | int prom_add_property(struct device_node *np, struct property *prop) | ||
| 666 | { | ||
| 667 | struct property **next; | ||
| 668 | unsigned long flags; | ||
| 669 | |||
| 670 | prop->next = NULL; | ||
| 671 | write_lock_irqsave(&devtree_lock, flags); | ||
| 672 | next = &np->properties; | ||
| 673 | while (*next) { | ||
| 674 | if (strcmp(prop->name, (*next)->name) == 0) { | ||
| 675 | /* duplicate ! don't insert it */ | ||
| 676 | write_unlock_irqrestore(&devtree_lock, flags); | ||
| 677 | return -1; | ||
| 678 | } | ||
| 679 | next = &(*next)->next; | ||
| 680 | } | ||
| 681 | *next = prop; | ||
| 682 | write_unlock_irqrestore(&devtree_lock, flags); | ||
| 683 | |||
| 684 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 685 | /* try to add to proc as well if it was initialized */ | ||
| 686 | if (np->pde) | ||
| 687 | proc_device_tree_add_prop(np->pde, prop); | ||
| 688 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
| 689 | |||
| 690 | return 0; | ||
| 691 | } | ||
| 692 | |||
| 693 | /** | ||
| 694 | * prom_remove_property - Remove a property from a node. | ||
| 695 | * | ||
| 696 | * Note that we don't actually remove it, since we have given out | ||
| 697 | * who-knows-how-many pointers to the data using get-property. | ||
| 698 | * Instead we just move the property to the "dead properties" | ||
| 699 | * list, so it won't be found any more. | ||
| 700 | */ | ||
| 701 | int prom_remove_property(struct device_node *np, struct property *prop) | ||
| 702 | { | ||
| 703 | struct property **next; | ||
| 704 | unsigned long flags; | ||
| 705 | int found = 0; | ||
| 706 | |||
| 707 | write_lock_irqsave(&devtree_lock, flags); | ||
| 708 | next = &np->properties; | ||
| 709 | while (*next) { | ||
| 710 | if (*next == prop) { | ||
| 711 | /* found the node */ | ||
| 712 | *next = prop->next; | ||
| 713 | prop->next = np->deadprops; | ||
| 714 | np->deadprops = prop; | ||
| 715 | found = 1; | ||
| 716 | break; | ||
| 717 | } | ||
| 718 | next = &(*next)->next; | ||
| 719 | } | ||
| 720 | write_unlock_irqrestore(&devtree_lock, flags); | ||
| 721 | |||
| 722 | if (!found) | ||
| 723 | return -ENODEV; | ||
| 724 | |||
| 725 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 726 | /* try to remove the proc node as well */ | ||
| 727 | if (np->pde) | ||
| 728 | proc_device_tree_remove_prop(np->pde, prop); | ||
| 729 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
| 730 | |||
| 731 | return 0; | ||
| 732 | } | ||
| 733 | |||
| 734 | /* | ||
| 735 | * prom_update_property - Update a property in a node. | ||
| 736 | * | ||
| 737 | * Note that we don't actually remove it, since we have given out | ||
| 738 | * who-knows-how-many pointers to the data using get-property. | ||
| 739 | * Instead we just move the property to the "dead properties" list, | ||
| 740 | * and add the new property to the property list | ||
| 741 | */ | ||
| 742 | int prom_update_property(struct device_node *np, | ||
| 743 | struct property *newprop, | ||
| 744 | struct property *oldprop) | ||
| 745 | { | ||
| 746 | struct property **next; | ||
| 747 | unsigned long flags; | ||
| 748 | int found = 0; | ||
| 749 | |||
| 750 | write_lock_irqsave(&devtree_lock, flags); | ||
| 751 | next = &np->properties; | ||
| 752 | while (*next) { | ||
| 753 | if (*next == oldprop) { | ||
| 754 | /* found the node */ | ||
| 755 | newprop->next = oldprop->next; | ||
| 756 | *next = newprop; | ||
| 757 | oldprop->next = np->deadprops; | ||
| 758 | np->deadprops = oldprop; | ||
| 759 | found = 1; | ||
| 760 | break; | ||
| 761 | } | ||
| 762 | next = &(*next)->next; | ||
| 763 | } | ||
| 764 | write_unlock_irqrestore(&devtree_lock, flags); | ||
| 765 | |||
| 766 | if (!found) | ||
| 767 | return -ENODEV; | ||
| 768 | |||
| 769 | #ifdef CONFIG_PROC_DEVICETREE | ||
| 770 | /* try to add to proc as well if it was initialized */ | ||
| 771 | if (np->pde) | ||
| 772 | proc_device_tree_update_prop(np->pde, newprop, oldprop); | ||
| 773 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
| 774 | |||
| 775 | return 0; | ||
| 776 | } | ||
