在driver/acpi/fan.c 中有注册cool device
module_platform_driver(acpi_fan_driver);
所以我们看看acpi_fan_driver的probe函数
static struct platform_driver acpi_fan_driver = {
.probe = acpi_fan_probe,
.remove = acpi_fan_remove,
.driver = {
.name = "acpi-fan",
.acpi_match_table = fan_device_ids,
.pm = FAN_PM_OPS_PTR,
},
};
这里的probe函数是acpi_fan_probe
static int acpi_fan_probe(struct platform_device *pdev)
{
int result = 0;
struct thermal_cooling_device *cdev;
struct acpi_fan *fan;
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
char *name;
//这里用struct acpi_fan 代表fan
fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
if (!fan) {
dev_err(&device->dev, "No memory for fan\n");
return -ENOMEM;
}
device->driver_data = fan;
platform_set_drvdata(pdev, fan);
//看是否是acpi4,如果是acpi4的话,则fan的控制是在bios中做的,kernel通过runtime service来看之fan设备
if (acpi_fan_is_acpi4(device)) {
if (acpi_fan_get_fif(device) || acpi_fan_get_fps(device))
goto end;
fan->acpi4 = true;
} else {
result = acpi_device_update_power(device, NULL);
if (result) {
dev_err(&device->dev, "Failed to set initial power state\n");
goto end;
}
}
//判断name是否是PNP0C0B。如果不是的话,则name是通过acpi_device_bid的到bus id
if (!strncmp(pdev->name, "PNP0C0B", strlen("PNP0C0B")))
name = "Fan";
else
name = acpi_device_bid(device);
//重点函数,注册cool device。另外一个重点是fan_cooling_ops。最终通过fan_cooling_ops结构体的set_cur_state来设置fan
cdev = thermal_cooling_device_register(name, device,
&fan_cooling_ops);
if (IS_ERR(cdev)) {
result = PTR_ERR(cdev);
goto end;
}
dev_dbg(&pdev->dev, "registered as cooling_device%d\n", cdev->id);
fan->cdev = cdev;
//添加sys文件接口
result = sysfs_create_link(&pdev->dev.kobj,
&cdev->device.kobj,
"thermal_cooling");
if (result)
dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n");
result = sysfs_create_link(&cdev->device.kobj,
&pdev->dev.kobj,
"device");
if (result)
dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n");
end:
return result;
}
如何判断是否是acpi4 这个版本呢?
static bool acpi_fan_is_acpi4(struct acpi_device *device)
{
return acpi_has_method(device->handle, "_FIF") &&
acpi_has_method(device->handle, "_FPS") &&
acpi_has_method(device->handle, "_FSL") &&
acpi_has_method(device->handle, "_FST");
}
原来是看BIOS是否提供个_FIF,_FPS,_FSL,_FST方法
下来看看thermal_cooling_device_register 具体都做了啥
thermal_cooling_device_register->__thermal_cooling_device_register
static struct thermal_cooling_device *
__thermal_cooling_device_register(struct device_node *np,
char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
{
struct thermal_cooling_device *cdev;
struct thermal_zone_device *pos = NULL;
int result;
if (type && strlen(type) >= THERMAL_NAME_LENGTH)
return ERR_PTR(-EINVAL);
if (!ops || !ops->get_max_state || !ops->get_cur_state ||
!ops->set_cur_state)
return ERR_PTR(-EINVAL);
cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
if (!cdev)
return ERR_PTR(-ENOMEM);
result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
if (result < 0) {
kfree(cdev);
return ERR_PTR(result);
}
cdev->id = result;
strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
mutex_init(&cdev->lock);
INIT_LIST_HEAD(&cdev->thermal_instances);
// 这里用struct thermal_cooling_device *cdev表示一个cool device
cdev->np = np;
cdev->ops = ops;
cdev->updated = false;
cdev->device.class = &thermal_class;
thermal_cooling_device_setup_sysfs(cdev);
cdev->devdata = devdata;
dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
//注册device
result = device_register(&cdev->device);
if (result) {
ida_simple_remove(&thermal_cdev_ida, cdev->id);
kfree(cdev);
return ERR_PTR(result);
}
//所有的cool device都放在thermal_cdev_list 这个list中
/* Add 'this' new cdev to the global cdev list */
mutex_lock(&thermal_list_lock);
list_add(&cdev->node, &thermal_cdev_list);
mutex_unlock(&thermal_list_lock);
//如果这个cool device已经绑定了zone device,则重新执行绑定的动作,因为cool device的参数可能有更新
/* Update binding information for 'this' new cdev */
bind_cdev(cdev);
mutex_lock(&thermal_list_lock);
list_for_each_entry(pos, &thermal_tz_list, node)
if (atomic_cmpxchg(&pos->need_update, 1, 0))
thermal_zone_device_update(pos,
THERMAL_EVENT_UNSPECIFIED);
mutex_unlock(&thermal_list_lock);
return cdev;
}
cool device(风扇)的注册
最新推荐文章于 2024-01-18 09:43:34 发布