diff options
Diffstat (limited to 'arch/powerpc/boot')
| -rw-r--r-- | arch/powerpc/boot/flatdevtree.c | 65 | ||||
| -rw-r--r-- | arch/powerpc/boot/flatdevtree.h | 3 |
2 files changed, 68 insertions, 0 deletions
diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c index 88b178a77e87..f6e37c2ee4dd 100644 --- a/arch/powerpc/boot/flatdevtree.c +++ b/arch/powerpc/boot/flatdevtree.c | |||
| @@ -820,6 +820,71 @@ int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, | |||
| 820 | return -1; | 820 | return -1; |
| 821 | } | 821 | } |
| 822 | 822 | ||
| 823 | void *__ft_find_node_by_prop_value(struct ft_cxt *cxt, void *prev, | ||
| 824 | const char *propname, const char *propval, | ||
| 825 | unsigned int proplen) | ||
| 826 | { | ||
| 827 | struct ft_atom atom; | ||
| 828 | char *p = ft_root_node(cxt); | ||
| 829 | char *next; | ||
| 830 | int past_prev = prev ? 0 : 1; | ||
| 831 | int depth = -1; | ||
| 832 | |||
| 833 | while ((next = ft_next(cxt, p, &atom)) != NULL) { | ||
| 834 | const void *data; | ||
| 835 | unsigned int size; | ||
| 836 | |||
| 837 | switch (atom.tag) { | ||
| 838 | case OF_DT_BEGIN_NODE: | ||
| 839 | depth++; | ||
| 840 | |||
| 841 | if (prev == p) { | ||
| 842 | past_prev = 1; | ||
| 843 | break; | ||
| 844 | } | ||
| 845 | |||
| 846 | if (!past_prev || depth < 1) | ||
| 847 | break; | ||
| 848 | |||
| 849 | data = __ft_get_prop(cxt, p, propname, &size); | ||
| 850 | if (!data || size != proplen) | ||
| 851 | break; | ||
| 852 | if (memcmp(data, propval, size)) | ||
| 853 | break; | ||
| 854 | |||
| 855 | return p; | ||
| 856 | |||
| 857 | case OF_DT_END_NODE: | ||
| 858 | if (depth-- == 0) | ||
| 859 | return NULL; | ||
| 860 | |||
| 861 | break; | ||
| 862 | } | ||
| 863 | |||
| 864 | p = next; | ||
| 865 | } | ||
| 866 | |||
| 867 | return NULL; | ||
| 868 | } | ||
| 869 | |||
| 870 | void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev, | ||
| 871 | const char *propname, const char *propval, | ||
| 872 | int proplen) | ||
| 873 | { | ||
| 874 | void *node = NULL; | ||
| 875 | |||
| 876 | if (prev) { | ||
| 877 | node = ft_node_ph2node(cxt, prev); | ||
| 878 | |||
| 879 | if (!node) | ||
| 880 | return NULL; | ||
| 881 | } | ||
| 882 | |||
| 883 | node = __ft_find_node_by_prop_value(cxt, node, propname, | ||
| 884 | propval, proplen); | ||
| 885 | return ft_get_phandle(cxt, node); | ||
| 886 | } | ||
| 887 | |||
| 823 | int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, | 888 | int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, |
| 824 | const void *buf, const unsigned int buflen) | 889 | const void *buf, const unsigned int buflen) |
| 825 | { | 890 | { |
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h index 950042493fb7..e3e3e79937ff 100644 --- a/arch/powerpc/boot/flatdevtree.h +++ b/arch/powerpc/boot/flatdevtree.h | |||
| @@ -105,5 +105,8 @@ int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, | |||
| 105 | int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, | 105 | int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, |
| 106 | const void *buf, const unsigned int buflen); | 106 | const void *buf, const unsigned int buflen); |
| 107 | void *ft_get_parent(struct ft_cxt *cxt, const void *phandle); | 107 | void *ft_get_parent(struct ft_cxt *cxt, const void *phandle); |
| 108 | void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev, | ||
| 109 | const char *propname, const char *propval, | ||
| 110 | int proplen); | ||
| 108 | 111 | ||
| 109 | #endif /* FLATDEVTREE_H */ | 112 | #endif /* FLATDEVTREE_H */ |
