首页 > 编程知识 正文

设备树compatible,设备树 pinctrl

时间:2023-05-04 14:27:50 阅读:27534 作者:1980

文件路径: kernelarcharmmach-TCC 803 xboard-TCC 803 x.c

structof _ dev _ aux data { char * compatible; resource_size_t phys_addr; char *name; void *平台_ data; (; #defineof_dev_auxdata(_compat、_phys、_name、_pdata ) ({ .compatible=_compat、 phys _ addr= . phys _ addr.platform _ data=_ pdata } staticstructof _ dev _ auxdatatcc 803 x _ aux data _ lookup [ ] _ initdata=nand-v8 )、TCC803X_PA_NFC、' tcc_nand ',NULL )、of_ NULL )、of_dev_auxdata(Telechips,tcc-ehci ) of_dev_auxdata(telechips,tcc-ohci ),TCC_PA_OHCI1,) TCC-ohci.1 ',NULL ),of _ dev _ au au ax data ) of_dev_auxdata(telechips,i2c )、TCC803X_PA_I2C0,i2c.0 )、NULL )、of_dev_auxdata(telechips )。 of_dev_auxdata(telechips,i2c )、TCC803X_PA_I2C2,i2c.2 )、NULL )、of_dev_auxdata(telechips )。 of_dev_auxdata(Telechips,tcc-sdhc ),TCC803X_PA_SDHC0,tcc-sdhc.0 ),NULL ),of _ dev _ au au au au au au au au au axdata OTA tcc-sdhc.2 ),NULL ),of _ dev _ auxdatata of _ dev _ aux data (telechips,wmixer_drv ),1,' wmixer1',NULL null (# ifdef config _ TCC _ attach of _ dev _ aux data (telechips,attach_drv ) )。 attach_drv ',1,' attach1',NULL ),# endif of _ dev _ aux data (' telechips,tcc_wdma ',0,' wdma ',NULL ) conststructof _ device _ idof _ default _ bus _ match _ table [ ]={.com patible=' simple-bus ',},{.com patibus } # endif/* config _ arm _ AMB a*/{ }/* empty teer static void _ init TCC 803 x _ dt _ init (void ) of _ platform _ popu poll of _ default _ bus _ match _ Taba Bach } of _ platform _ populate函数从设备树的根节点开始,用于每个子节点是平台设备的节点波普尔

ate:填充,即根据设备树的设备节点参数填充平台设备。

int of_platform_populate(struct device_node *root,const struct of_device_id *matches,const struct of_dev_auxdata *lookup,struct device *parent){struct device_node *child;int rc = 0; //root为null,所以root= of_find_node_by_path("/")root = root ? of_node_get(root) : of_find_node_by_path("/"); //遍历设备树的"/"节点的所有子节点for_each_child_of_node(root, child) {rc = of_platform_bus_create(child, matches, lookup, parent, true);if (rc) {of_node_put(child);break;}}of_node_set_flag(root, OF_POPULATED_BUS);return rc;}

of_platform_bus_create函数:创建根节点下的某个子节点以及该子节点下的所有子节点对应的平台设备。

static int of_platform_bus_create(struct device_node *bus, const struct of_device_id *matches, const struct of_dev_auxdata *lookup, struct device *parent, bool strict){const struct of_dev_auxdata *auxdata;struct device_node *child;struct platform_device *dev;const char *bus_id = NULL;void *platform_data = NULL;int rc = 0;/* Make sure it has a compatible property */if (strict && (!of_get_property(bus, "compatible", NULL))) {return 0;} //确保该设备节点之前没有被填充过if (of_node_check_flag(bus, OF_POPULATED_BUS)) {return 0;} //查看lookup数组里有没有数组元素与该设备节点的compatile和内存空间首地址匹配, //如果有匹配,返回该数组元素auxdata = of_dev_lookup(lookup, bus);if (auxdata) {bus_id = auxdata->name; //如果设备节点是在lookup数组里,是带有平台数据的, //否则没有平台数据platform_data = auxdata->platform_data;}dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent); //递归创建bus节点的子节点对应的平台设备for_each_child_of_node(bus, child) {rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict);if (rc) {of_node_put(child);break;}} //设置标志,表示该节点填充完of_node_set_flag(bus, OF_POPULATED_BUS);return rc;}

of_dev_lookup函数: 

static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup, struct device_node *np){const struct of_dev_auxdata *auxdata;struct resource res;int compatible = 0;if (!lookup)return NULL;auxdata = lookup; //查看lookup数组里有没有数组元素与该设备节点的compatile和内存空间首地址匹配, //如果有匹配,返回该数组元素for (; auxdata->compatible; auxdata++) { //of_device_is_compatible函数返回0,表示没有匹配上, //返回正整数,表示匹配上。if (!of_device_is_compatible(np, auxdata->compatible))continue;compatible++;if (!of_address_to_resource(np, 0, &res))if (res.start != auxdata->phys_addr)continue;return auxdata;}if (!compatible)return NULL;/* Try compatible match if no phys_addr and name are specified */auxdata = lookup;for (; auxdata->compatible; auxdata++) {if (!of_device_is_compatible(np, auxdata->compatible))continue;if (!auxdata->phys_addr && !auxdata->name) {pr_debug("%pOF: compatible matchn", np);return auxdata;}}return NULL;}

of_device_is_compatible函数:

int of_device_is_compatible(const struct device_node *device,const char *compat){unsigned long flags;int res;raw_spin_lock_irqsave(&devtree_lock, flags);res = __of_device_is_compatible(device, compat, NULL, NULL);raw_spin_unlock_irqrestore(&devtree_lock, flags);return res;}

__of_device_is_compatible函数:

static int __of_device_is_compatible(const struct device_node *device, const char *compat, const char *type, const char *name){struct property *prop;const char *cp;int index = 0, score = 0; //compatible属性匹配优先级最高,所以对应的score分数最大,其次是type,再其次是name。if (compat && compat[0]) {prop = __of_find_property(device, "compatible", NULL); //获取"compatible"节点属性的字符串值,一般只有一个字符串for (cp = of_prop_next_string(prop, NULL); cp; cp = of_prop_next_string(prop, cp), index++) {if (of_compat_cmp(cp, compat, strlen(compat)) == 0) { //score:匹配度的相对分数,正整数,分数越高,越匹配 //如果是0,表示没有匹配上score = INT_MAX/2 - (index << 2);break;}}if (!score)return 0;}//一般type设置为NULL,就是不进行type匹配if (type && type[0]) {if (!device->type || of_node_cmp(type, device->type))return 0;score += 2;}//一般name设置为NULL,就是不进行name匹配if (name && name[0]) {if (!device->name || of_node_cmp(name, device->name))return 0;score++;}return score;}

of_platform_device_create_pdata函数:

static struct platform_device *of_platform_device_create_pdata(struct device_node *np,const char *bus_id,void *platform_data,struct device *parent){struct platform_device *dev; //设备节点的status属性有,且不是"okay"或者"ok"状态,那么返回,不会创建平台设备。if (!of_device_is_available(np) || of_node_test_and_set_flag(np, OF_POPULATED))return NULL; //平台设备对应的结构体的内存分配dev = of_device_alloc(np, bus_id, parent); //总线类型为平台总线类型dev->dev.bus = &platform_bus_type;dev->dev.platform_data = platform_data; //添加设备if (of_device_add(dev) != 0) { ......}return dev;}

of_device_is_available函数:

bool of_device_is_available(const struct device_node *device){unsigned long flags;bool res;raw_spin_lock_irqsave(&devtree_lock, flags);res = __of_device_is_available(device);raw_spin_unlock_irqrestore(&devtree_lock, flags);return res;}

__of_device_is_available函数:

static bool __of_device_is_available(const struct device_node *device){const char *status;int statlen;if (!device)return false; //如果没有status属性,没问题status = __of_get_property(device, "status", &statlen);if (status == NULL)return true; //如果有status属性,且设置成"okay"或者"ok",没问题if (statlen > 0) {if (!strcmp(status, "okay") || !strcmp(status, "ok"))return true;} //否则有问题return false;}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。