总线下的子设备的注册

这段代码展示了在Linux环境中,通过设备树节点遍历,为I2C和SPI总线注册子设备的过程。`for_each_available_child_of_node`循环用于获取每个子设备节点,并调用`i2c_new_device`或`of_register_spi_device`进行注册。注册过程中涉及设备地址解析、中断处理和模块加载等功能。
摘要由CSDN通过智能技术生成
static void of_i2c_register_devices(struct i2c_adapter *adap)
{
        void *result;
        struct device_node *node;

        /* Only register child devices if the adapter has a node pointer set */
        if (!adap->dev.of_node)
                return;

        dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");

        for_each_available_child_of_node(adap->dev.of_node, node) {
                struct i2c_board_info info = {};
                struct dev_archdata dev_ad = {};
                const __be32 *addr;
                int len;

                dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);

                if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
                        dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
                                node->full_name);
                        continue;
                }

                addr = of_get_property(node, "reg", &len);
                if (!addr || (len < sizeof(int))) {
                        dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
                                node->full_name);
                        continue;
                }

                info.addr = be32_to_cpup(addr);
                if (info.addr > (1 << 10) - 1) {
                        dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
                                info.addr, node->full_name);
                        continue;
                }

                info.irq = irq_of_parse_and_map(node, 0);
                info.of_node = of_node_get(node);
                info.archdata = &dev_ad;

                if (of_get_property(node, "wakeup-source", NULL))
                        info.flags |= I2C_CLIENT_WAKE;

                request_module("%s%s", I2C_MODULE_PREFIX, info.type);

                result = i2c_new_device(adap, &info);
                if (result == NULL) {
                        dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
                                node->full_name);
                        of_node_put(node);
                        irq_dispose_mapping(info.irq);
                        continue;
                }
        }
}

 或

	spi_register_master(spi_master_get(master));
		of_spi_register_master(master);
			of_gpio_named_count(np, "cs-gpios");
		spi_master_initialize_queue(master);
			master->transfer = spi_queued_transfer;
		list_add_tail(&master->list, &spi_master_list);
		of_register_spi_devices(master);
			struct spi_device *spi;
			struct device_node *nc;
			for_each_available_child_of_node(master->dev.of_node, nc) {
				spi = of_register_spi_device(master, nc);
			}

 

都是通过for_each_available_child_of_node来遍历总线节点下的子设备节点,从而达到注册每一个子设备的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值