1. 删除property,以删除power-led下yellow下面的default-state为例:
struct device_node *np np = of_find_node_by_name(NULL, "power-led"); np = of_find_node_by_name(np, "yellow"); prop = of_find_property(np, "default-state", NULL); of_remove_property(np, prop);
2. 删除node, 以删除power-led下green这个node为例:
struct device_node *np, *np1, * np2 np = of_find_node_by_name(NULL, "power-led"); np1 = of_find_node_by_name(np, "blue"); np2 = of_find_node_by_name(np, "yellow"); np1->sibling = np2; np1->next = np2; np1->allnext = np2;
3. 添加property, 以添加yellow下enable=true为例:
np = of_find_node_by_name(NULL, "power-led"); np = of_find_node_by_name(np, "yellow"); prop = create_new_property("enable", "true", sizeof("true")); of_add_property(np, prop);
由于用到了early_init_dt_alloc_memory_arch相关的接口,所以贴一下所有这些接口,包含申请device-node和property的封装接口:
static void *unflatten_dt_alloc(void mem, unsigned long size, unsigned long align) { void *res; *mem = PTR_ALIGN(*mem, align); res = (void *)*mem; *mem += size; return res; }
/*we ignore type and data here for basic use.*/ static struct device_node * __init create_new_node(const char* name, unsigned int phandle, const char* full_name, unsigned long _flags) { struct device_node *new_node; void *mem; int malloc_size = 0; char* new_name; char* new_full_name; /*1. calc the whole malloc memory size*/ malloc_size = strlen(name)+1; malloc_size += strlen(full_name)+1; malloc_size += sizeof(struct device_node); /*2 alloc the memory*/ mem = early_init_dt_alloc_memory_arch(malloc_size + 4, 4); memset(mem, 0, malloc_size + 4); new_node = unflatten_dt_alloc(&mem, sizeof(struct device_node), __alignof__(struct device_node)); new_name = unflatten_dt_alloc(&mem, strlen(name)+1, 1); new_full_name = unflatten_dt_alloc(&mem, strlen(full_name)+1, 1); /* 3. fill the data*/ of_node_init(new_node); strcpy(new_name, name); strcpy(new_full_name, full_name); new_node->name = new_name; new_node->full_name = new_full_name; new_node->phandle = phandle; new_node->_flags = _flags; return new_node; }
static struct property * __init create_new_property(char* name, void *value, int value_len) { struct property *new_prop; void *mem; int malloc_size = 0; /* 1. calc the whole malloc memory size */ malloc_size = strlen(name)+1; malloc_size += value_len; malloc_size += sizeof(struct property); /* 2. alloc the memory*/ mem = early_init_dt_alloc_memory_arch(malloc_size + 4, 4); memset(mem, 0, malloc_size + 4); new_prop = unflatten_dt_alloc(&mem, sizeof(struct property), __alignof__(struct property)); new_prop->value = unflatten_dt_alloc(&mem, value_len, 1); new_prop->name = (char*)unflatten_dt_alloc(&mem, strlen(name)+1, 1); /* 3. fill the data*/ memcpy(new_prop->value, value, value_len); new_prop->length = value_len; strcpy(new_prop->name, name); return new_prop; }
4. 添加device_node, 以在key后,添加一个如下wireless-modem的节点为例:
/* add node wireless-modem after key: wireless-modem { compatible = "modem-platdata"; status = "okay"; }; */ np = of_find_node_by_name(NULL, "key"); new_node = create_new_node("wireless-modem", 0, "/wireless-modem", 0); new_node->parent = np->parent; new_node->child = NULL; new_node->sibling = np->sibling; np->sibling = new_node; new_node->next = NULL; new_node->allnext = np->allnext; np->allnext = new_node; /*set compatible = "modem-platdata"*/ np = of_find_node_by_name(NULL, "wireless-modem"); prop = create_new_property("compatible", "modem-platdata", sizeof("modem-platdata")) of_add_property(np, prop); /*set status = "okay"*/ prop = create_new_property("status", "okay", sizeof("okay")); of_add_property(np, prop);
5. 修改property: 以将yellow下default-state=on 改为off为例:
np = of_find_node_by_name(NULL, "power-led"); np = of_find_node_by_name(np, "yellow"); prop = create_new_property("default-state", "off", sizeof("off")); of_update_property(np, new_prop);
6.修改node,参见上面添加,删除node,这里就不再赘述。
另外,需要注意的一点,如果要修改的内容是一个引用结果,比如要将blue中”gpios = <&gpio1 GPIO_A2 GPIO_ACTIVE_HIGH>;“,&gpio1改为&gpio2, 这个就比较麻烦了,因为dts中,这些都是引用,&gpio1其实是一个“linux,phandle”的值,所有被引用的值,如果没有手动设定phandle,那么系统在编译dts->dtb的过程中,会从0,1,2。。。开始自动分配,由于dts引用顺序我们不知道,所以不会知道系统分配个gpio2的是一个什么引用值(虽然这个值在dts确定后,自动生成顺序有管联性,其实是个缺定值),要解决这个问题,那么我们最好事先在gpio1,gpio2。。等可能需要作为被修改值的结构里面,人工指定phandle值,如下,这里指定了phandle,那么,我们在修改或者添加property的时候,就可以直接指定我们手动指定的phandle值了:
gpio2: gpio2@ { compatible = "stm32,gpio-bank"; compatible = "stm32,gpio-bank"; reg = <0x 0x100>; interrupts =
53 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk_gates9
10>; gpio-controller; interrupt-controller; linux,phandle = <
0x00010004>;
//手动设定phandle phandle = <
0x00010004>;
//手动设定phandle };
/* gpios = <&gpio2 GPIO_A2 GPIO_ACTIVE_HIGH>; gpio2 phandle: 0x00010004 */ gpio_data[
0] = be32_to_cpu(
0x00010004);
//直接设定手动设定的phandle,注意大小端配置 gpio_data[
1] = be32_to_cpu(
23);
//GPIO_A2 gpio_data[
2] = be32_to_cpu(
0);
//GPIO_ACTIVE_HIGH prop = create_new_property(
"MODEM,reset_gpio", gpio_data,
sizeof(gpio_data)); of_add_property(np, prop);
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/224190.html原文链接:https://javaforall.net
