在drivers/acpi/button.c中会通过
module_acpi_driver(acpi_button_driver);来注册device
module_acpi_driver 定义如下:
#define module_acpi_driver(__acpi_driver) \
module_driver(__acpi_driver, acpi_bus_register_driver, \
acpi_bus_unregister_driver)
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);
可以最终还是调用module_init 来初始化话,在module_init 中会调用acpi_bus_register_driver 住注册device。
int acpi_bus_register_driver(struct acpi_driver *driver)
{
int ret;
if (acpi_disabled)
return -ENODEV;
driver->drv.name = driver->name;
driver->drv.bus = &acpi_bus_type;
driver->drv.owner = driver->owner;
ret = driver_register(&driver->drv);
return ret;
}
acpi_bus_register_driver 中最重要的是driver->drv.bus = &acpi_bus_type;
struct bus_type acpi_bus_type = {
.name = "acpi",
.match = acpi_bus_match,
.probe = acpi_device_probe,
.remove = acpi_device_remove,
.uevent = acpi_device_uevent,
};
我们看看最重要的match函数
static int acpi_bus_match(struct device *dev, struct device_driver *drv)
{
struct acpi_device *acpi_dev = to_acpi_device(dev);
struct acpi_driver *acpi_drv = to_acpi_driver(drv);
return acpi_dev->flags.match_driver
&& !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
}
原来是通过是通过acpi_dev->flags.match_driver 和 acpi_match_device_ids(acpi_dev, acpi_drv->ids); 来让device和driver匹配
其中acpi_match_device_ids->__acpi_match_device
static const struct acpi_device_id *__acpi_match_device(
struct acpi_device *device,
const struct acpi_device_id *ids,
const struct of_device_id *of_ids)
{
const struct acpi_device_id *id;
struct acpi_hardware_id *hwid;
/*
* If the device is not present, it is unnecessary to load device
* driver for it.
*/
if (!device || !device->status.present)
return NULL;
list_for_each_entry(hwid, &device->pnp.ids, list) {
/* First, check the ACPI/PNP IDs provided by the caller. */
for (id = ids; id->id[0] || id->cls; id++) {
if (id->id[0] && !strcmp((char *) id->id, hwid->id))
return id;
else if (id->cls && __acpi_match_device_cls(id, hwid))
return id;
}
/*
* Next, check ACPI_DT_NAMESPACE_HID and try to match the
* "compatible" property if found.
*
* The id returned by the below is not valid, but the only
* caller passing non-NULL of_ids here is only interested in
* whether or not the return value is NULL.
*/
if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id)
&& acpi_of_match_device(device, of_ids))
return id;
}
return NULL;
}
从__acpi_match_device 中可知原来是通过下面三种方法判断的
第一:id->id == hwid->id
if (id->id[0] && !strcmp((char *) id->id, hwid->id))
return id;
第二:cls相等
(id->cls && __acpi_match_device_cls(id, hwid))
第三:"compatible" property.相等
if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id)&& acpi_of_match_device(device, of_ids))
我们回到button.c中
static struct acpi_driver acpi_button_driver = {
.name = "button",
.class = ACPI_BUTTON_CLASS,
.ids = button_device_ids,
.ops = {
.add = acpi_button_add,
.remove = acpi_button_remove,
.notify = acpi_button_notify,
},
.drv.pm = &acpi_button_pm,
};
可见button_device_ids 中的cls没有赋值,因此button 的device 和 driver的配对主要是通过id->id == hwid->id 来判断的.
static const struct acpi_device_id button_device_ids[] = {
{ACPI_BUTTON_HID_LID, 0},
{ACPI_BUTTON_HID_SLEEP, 0},
{ACPI_BUTTON_HID_SLEEPF, 0},
{ACPI_BUTTON_HID_POWER, 0},
{ACPI_BUTTON_HID_POWERF, 0},
{"", 0},
};
那具体是哪个device 和power button的driver配对呢?也就是power button的device是什么时候注册的呢?
acpi_bus_scan->acpi_bus_check_add->acpi_add_single_object->acpi_bus_get_power_flags->acpi_bus_init_power_state
->acpi_extract_power_resources->acpi_add_power_resource->acpi_device_add->acpi_device_add
int acpi_device_add(struct acpi_device *device,
void (*release)(struct device *))
{
if (device->parent)
device->dev.parent = &device->parent->dev;
device->dev.bus = &acpi_bus_type;
device->dev.release = release;
result = device_add(&device->dev);
if (result) {
dev_err(&device->dev, "Error registering device\n");
goto err;
}
result = acpi_device_setup_files(device);
if (result)
printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
dev_name(&device->dev));
return 0;
}
acpi_device_add 这个函数会调用device_add 来注册device,注意这个device->dev.bus = &acpi_bus_type 和power button 是同一个bus type
module_acpi_driver(acpi_button_driver);来注册device
module_acpi_driver 定义如下:
#define module_acpi_driver(__acpi_driver) \
module_driver(__acpi_driver, acpi_bus_register_driver, \
acpi_bus_unregister_driver)
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);
可以最终还是调用module_init 来初始化话,在module_init 中会调用acpi_bus_register_driver 住注册device。
int acpi_bus_register_driver(struct acpi_driver *driver)
{
int ret;
if (acpi_disabled)
return -ENODEV;
driver->drv.name = driver->name;
driver->drv.bus = &acpi_bus_type;
driver->drv.owner = driver->owner;
ret = driver_register(&driver->drv);
return ret;
}
acpi_bus_register_driver 中最重要的是driver->drv.bus = &acpi_bus_type;
struct bus_type acpi_bus_type = {
.name = "acpi",
.match = acpi_bus_match,
.probe = acpi_device_probe,
.remove = acpi_device_remove,
.uevent = acpi_device_uevent,
};
我们看看最重要的match函数
static int acpi_bus_match(struct device *dev, struct device_driver *drv)
{
struct acpi_device *acpi_dev = to_acpi_device(dev);
struct acpi_driver *acpi_drv = to_acpi_driver(drv);
return acpi_dev->flags.match_driver
&& !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
}
原来是通过是通过acpi_dev->flags.match_driver 和 acpi_match_device_ids(acpi_dev, acpi_drv->ids); 来让device和driver匹配
其中acpi_match_device_ids->__acpi_match_device
static const struct acpi_device_id *__acpi_match_device(
struct acpi_device *device,
const struct acpi_device_id *ids,
const struct of_device_id *of_ids)
{
const struct acpi_device_id *id;
struct acpi_hardware_id *hwid;
/*
* If the device is not present, it is unnecessary to load device
* driver for it.
*/
if (!device || !device->status.present)
return NULL;
list_for_each_entry(hwid, &device->pnp.ids, list) {
/* First, check the ACPI/PNP IDs provided by the caller. */
for (id = ids; id->id[0] || id->cls; id++) {
if (id->id[0] && !strcmp((char *) id->id, hwid->id))
return id;
else if (id->cls && __acpi_match_device_cls(id, hwid))
return id;
}
/*
* Next, check ACPI_DT_NAMESPACE_HID and try to match the
* "compatible" property if found.
*
* The id returned by the below is not valid, but the only
* caller passing non-NULL of_ids here is only interested in
* whether or not the return value is NULL.
*/
if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id)
&& acpi_of_match_device(device, of_ids))
return id;
}
return NULL;
}
从__acpi_match_device 中可知原来是通过下面三种方法判断的
第一:id->id == hwid->id
if (id->id[0] && !strcmp((char *) id->id, hwid->id))
return id;
第二:cls相等
(id->cls && __acpi_match_device_cls(id, hwid))
第三:"compatible" property.相等
if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id)&& acpi_of_match_device(device, of_ids))
我们回到button.c中
static struct acpi_driver acpi_button_driver = {
.name = "button",
.class = ACPI_BUTTON_CLASS,
.ids = button_device_ids,
.ops = {
.add = acpi_button_add,
.remove = acpi_button_remove,
.notify = acpi_button_notify,
},
.drv.pm = &acpi_button_pm,
};
可见button_device_ids 中的cls没有赋值,因此button 的device 和 driver的配对主要是通过id->id == hwid->id 来判断的.
static const struct acpi_device_id button_device_ids[] = {
{ACPI_BUTTON_HID_LID, 0},
{ACPI_BUTTON_HID_SLEEP, 0},
{ACPI_BUTTON_HID_SLEEPF, 0},
{ACPI_BUTTON_HID_POWER, 0},
{ACPI_BUTTON_HID_POWERF, 0},
{"", 0},
};
那具体是哪个device 和power button的driver配对呢?也就是power button的device是什么时候注册的呢?
acpi_bus_scan->acpi_bus_check_add->acpi_add_single_object->acpi_bus_get_power_flags->acpi_bus_init_power_state
->acpi_extract_power_resources->acpi_add_power_resource->acpi_device_add->acpi_device_add
int acpi_device_add(struct acpi_device *device,
void (*release)(struct device *))
{
if (device->parent)
device->dev.parent = &device->parent->dev;
device->dev.bus = &acpi_bus_type;
device->dev.release = release;
result = device_add(&device->dev);
if (result) {
dev_err(&device->dev, "Error registering device\n");
goto err;
}
result = acpi_device_setup_files(device);
if (result)
printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
dev_name(&device->dev));
return 0;
}
acpi_device_add 这个函数会调用device_add 来注册device,注意这个device->dev.bus = &acpi_bus_type 和power button 是同一个bus type