* Copy all nodes and properties from one DT subtree into another. This is a * shallow copy so both trees will point to the same property data afterwards. * * @params dst Destination subtree to copy into. * @params src Source subtree to copy from. * @params upd 1 to overwrite same-name properties, 0 to discard them. */
| 1953 | * @params upd 1 to overwrite same-name properties, 0 to discard them. |
| 1954 | */ |
| 1955 | static void dt_copy_subtree(struct device_tree_node *dst, |
| 1956 | struct device_tree_node *src, int upd) |
| 1957 | { |
| 1958 | struct device_tree_property *prop; |
| 1959 | struct device_tree_property *src_prop; |
| 1960 | list_for_each(src_prop, src->properties, list_node) { |
| 1961 | if (dt_prop_is_phandle(src_prop) || |
| 1962 | !strcmp(src_prop->prop.name, "name")) { |
| 1963 | printk(BIOS_DEBUG, |
| 1964 | "WARNING: ignoring illegal overlay prop '%s'\n", |
| 1965 | src_prop->prop.name); |
| 1966 | continue; |
| 1967 | } |
| 1968 | |
| 1969 | struct device_tree_property *dst_prop = NULL; |
| 1970 | list_for_each(prop, dst->properties, list_node) |
| 1971 | if (!strcmp(prop->prop.name, src_prop->prop.name)) { |
| 1972 | dst_prop = prop; |
| 1973 | break; |
| 1974 | } |
| 1975 | |
| 1976 | if (dst_prop) { |
| 1977 | if (!upd) { |
| 1978 | printk(BIOS_DEBUG, |
| 1979 | "WARNING: ignoring prop update '%s'\n", |
| 1980 | src_prop->prop.name); |
| 1981 | continue; |
| 1982 | } |
| 1983 | } else { |
| 1984 | dst_prop = alloc_prop(); |
| 1985 | list_insert_after(&dst_prop->list_node, |
| 1986 | &dst->properties); |
| 1987 | } |
| 1988 | |
| 1989 | dst_prop->prop = src_prop->prop; |
| 1990 | } |
| 1991 | |
| 1992 | struct device_tree_node *node; |
| 1993 | struct device_tree_node *src_node; |
| 1994 | list_for_each(src_node, src->children, list_node) { |
| 1995 | struct device_tree_node *dst_node = NULL; |
| 1996 | list_for_each(node, dst->children, list_node) |
| 1997 | if (!strcmp(node->name, src_node->name)) { |
| 1998 | dst_node = node; |
| 1999 | break; |
| 2000 | } |
| 2001 | |
| 2002 | if (!dst_node) { |
| 2003 | dst_node = alloc_node(); |
| 2004 | dst_node->name = src_node->name; |
| 2005 | dst_node->phandle = src_node->phandle; |
| 2006 | list_move(&dst_node->properties, &src_node->properties); |
| 2007 | list_move(&dst_node->children, &src_node->children); |
| 2008 | list_insert_after(&dst_node->list_node, &dst->children); |
| 2009 | } else { |
| 2010 | dt_copy_subtree(dst_node, src_node, upd); |
| 2011 | } |
| 2012 | } |
no test coverage detected