博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
内核ACPI函数API之acpi_bind_one和acpi_unbind_one
阅读量:4216 次
发布时间:2019-05-26

本文共 3373 字,大约阅读时间需要 11 分钟。

int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)用于将一个acpi_dev和dev在sys中建立symlink,主要用于hotplug的设备,例如cpu。其源码分析如下:int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev){	struct acpi_device_physical_node *physical_node, *pn;	char physical_node_name[PHYSICAL_NODE_NAME_SIZE];	struct list_head *physnode_list;	unsigned int node_id;	int retval = -EINVAL;	#如果这个dev已经有对应的acpi_dev则退出	if (has_acpi_companion(dev)) {		if (acpi_dev) {			dev_warn(dev, "ACPI companion already set\n");			return -EINVAL;		} else {			acpi_dev = ACPI_COMPANION(dev);		}	}	#如果acpi_dev为null,则退出	if (!acpi_dev)		return -EINVAL;	#分别增加acpi_dev 和dev的引用计数	get_device(&acpi_dev->dev);	get_device(dev);	physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL);	if (!physical_node) {		retval = -ENOMEM;		goto err;	}	mutex_lock(&acpi_dev->physical_node_lock);	/*	 * Keep the list sorted by node_id so that the IDs of removed nodes can	 * be recycled easily.	 */	physnode_list = &acpi_dev->physical_node_list;	node_id = 0;	list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {		/* Sanity check. */		#检查acpi_dev是否已经指向形参dev,如果已经指向的话且dev对应的acpi_dev也匹配的话,则退出		if (pn->dev == dev) {			mutex_unlock(&acpi_dev->physical_node_lock);			dev_warn(dev, "Already associated with ACPI node\n");			kfree(physical_node);			#dev和acpi_dev 不匹配则退出			if (ACPI_COMPANION(dev) != acpi_dev)				goto err;			put_device(dev);			put_device(&acpi_dev->dev);			return 0;		}		if (pn->node_id == node_id) {			physnode_list = &pn->node;			node_id++;		}	}	physical_node->node_id = node_id;	physical_node->dev = dev;	list_add(&physical_node->node, physnode_list);	acpi_dev->physical_node_count++;	#说明dev已经和acpi_dev 绑定了	if (!has_acpi_companion(dev))		ACPI_COMPANION_SET(dev, acpi_dev);	#将node_id 添加到physical_node_name 这个buf表示的name中	acpi_physnode_link_name(physical_node_name, node_id);	#建立acpi_dev 和dev的symlink	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,				   physical_node_name);	if (retval)		dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n",			physical_node_name, retval);	#建立dev和acpi_dev的symlink	retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,				   "firmware_node");	if (retval)		dev_err(dev, "Failed to create link firmware_node (%d)\n",			retval);	mutex_unlock(&acpi_dev->physical_node_lock);	if (acpi_dev->wakeup.flags.valid)		device_set_wakeup_capable(dev, true);	return 0; err:	ACPI_COMPANION_SET(dev, NULL);	put_device(dev);	put_device(&acpi_dev->dev);	return retval;}与acpi_bind_one 对应的是acpi_unbind_one 来取消dev和apci_dev的symlink其源码分析如下:int acpi_unbind_one(struct device *dev){	struct acpi_device *acpi_dev = ACPI_COMPANION(dev);	struct acpi_device_physical_node *entry;	if (!acpi_dev)		return 0;	mutex_lock(&acpi_dev->physical_node_lock);	list_for_each_entry(entry, &acpi_dev->physical_node_list, node)		if (entry->dev == dev) {			char physnode_name[PHYSICAL_NODE_NAME_SIZE];			list_del(&entry->node);			acpi_dev->physical_node_count--;			acpi_physnode_link_name(physnode_name, entry->node_id);			sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name);			sysfs_remove_link(&dev->kobj, "firmware_node");			ACPI_COMPANION_SET(dev, NULL);			/* Drop references taken by acpi_bind_one(). */			put_device(dev);			put_device(&acpi_dev->dev);			kfree(entry);			break;		}	mutex_unlock(&acpi_dev->physical_node_lock);	return 0;}可见主要是调用sysfs_remove_link 来去掉dev和acpi_dev之间的symlink

转载地址:http://vdnmi.baihongyu.com/

你可能感兴趣的文章
《浪潮之巅》5奔腾的芯 英特尔公司
查看>>
《浪潮之巅》7 互联网的金门大桥 -—思科公司
查看>>
《浪潮之巅》8英名不朽---杨致远、菲洛和雅虎公司
查看>>
《浪潮之巅》9硅谷的见证人———惠普公司
查看>>
优秀的人都将是孤独的
查看>>
android 实现摇一摇功能
查看>>
android 侧滑事件的监听
查看>>
创新中国总决赛之行
查看>>
当你厌恶一个人时,你要想一下你是否也是这样的一个人
查看>>
android 数据库sqlite的使用
查看>>
android 腾讯信鸽的使用
查看>>
Android 闹钟的实现详解
查看>>
Android 实现底部导航栏
查看>>
大二新学期开始
查看>>
java 中的集合
查看>>
Html 标签学习
查看>>
《浪潮之巅》 10没落的贵族--摩托罗拉公司
查看>>
《浪潮之巅》11 硅谷的另一面
查看>>
Android activity 之间的数据传递 bundle
查看>>
android Intent 常见用法和使用场景
查看>>