dev/watchdog和dev/watchdog0 是同一个设备
来源:互联网 发布:微赢专业数据代理平台 编辑:程序博客网 时间:2024/06/11 09:33
dev/watchdog 下会有watchdog 和 watchdog0等等。这里先给出结论watchdog和watchdog0代表的是同一个硬件,即使他们的字符设备的major和minor 不一样
linux-hice:~ # ls /dev/watchdog
watchdog watchdog0 watchdog1
linux-hice:/dev # ls -al | grep watchdog
crw------- 1 root root 10, 130 Jun 7 04:38 watchdog
crw------- 1 root root 252, 0 Jun 7 04:38 watchdog0
crw------- 1 root root 252, 1 Jun 7 04:38 watchdog1
一般在watchdog的probe函数中都会调用watchdog_register_device 来在dev下注册设备,就是如上面的/dev/watchdog等
watchdog_register_device->__watchdog_register_device->watchdog_dev_register
int watchdog_dev_register(struct watchdog_device *wdd)
{
struct device *dev;
dev_t devno;
int ret;
devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
ret = watchdog_cdev_register(wdd, devno);
if (ret)
return ret;
//这里就注册dev/watchdog0
dev = device_create_with_groups(&watchdog_class, wdd->parent,
devno, wdd, wdd->groups,
"watchdog%d", wdd->id);
if (IS_ERR(dev)) {
watchdog_cdev_unregister(wdd);
return PTR_ERR(dev);
}
ret = watchdog_register_pretimeout(wdd);
if (ret) {
device_destroy(&watchdog_class, devno);
watchdog_cdev_unregister(wdd);
}
return ret;
}
static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
{
struct watchdog_core_data *wd_data;
int err;
wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL);
if (!wd_data)
return -ENOMEM;
kref_init(&wd_data->kref);
mutex_init(&wd_data->lock);
wd_data->wdd = wdd;
wdd->wd_data = wd_data;
if (!watchdog_wq)
return -ENODEV;
INIT_DELAYED_WORK(&wd_data->work, watchdog_ping_work);
//如果id是0的话,就调用misc_register 来注册/dev/watchdog,注意这个/dev/watchdog 对应的watchdog_device *wdd 和调用cdev_add 添加的字符设备用的同一个watchdog_device *wdd,所以才说他们对应的是同一个hw,以上层应用不管是打开dev/watchdog还是dev/watchdog0 都是一样的.
if (wdd->id == 0) {
old_wd_data = wd_data;
watchdog_miscdev.parent = wdd->parent;
err = misc_register(&watchdog_miscdev);
if (err != 0) {
pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n",
wdd->info->identity, WATCHDOG_MINOR, err);
if (err == -EBUSY)
pr_err("%s: a legacy watchdog module is probably present.\n",
wdd->info->identity);
old_wd_data = NULL;
kfree(wd_data);
return err;
}
}
/* Fill in the data structures */
cdev_init(&wd_data->cdev, &watchdog_fops);
wd_data->cdev.owner = wdd->ops->owner;
/* Add the device */
err = cdev_add(&wd_data->cdev, devno, 1);
if (err) {
pr_err("watchdog%d unable to add device %d:%d\n",
wdd->id, MAJOR(watchdog_devt), wdd->id);
if (wdd->id == 0) {
misc_deregister(&watchdog_miscdev);
old_wd_data = NULL;
kref_put(&wd_data->kref, watchdog_core_data_release);
}
return err;
}
/* Record time of most recent heartbeat as 'just before now'. */
wd_data->last_hw_keepalive = jiffies - 1;
/*
* If the watchdog is running, prevent its driver from being unloaded,
* and schedule an immediate ping.
*/
if (watchdog_hw_running(wdd)) {
__module_get(wdd->ops->owner);
kref_get(&wd_data->kref);
queue_delayed_work(watchdog_wq, &wd_data->work, 0);
}
return 0;
}
之所以要注册/dev/watchog 是为来兼容老的接口
linux-hice:~ # ls /dev/watchdog
watchdog watchdog0 watchdog1
linux-hice:/dev # ls -al | grep watchdog
crw------- 1 root root 10, 130 Jun 7 04:38 watchdog
crw------- 1 root root 252, 0 Jun 7 04:38 watchdog0
crw------- 1 root root 252, 1 Jun 7 04:38 watchdog1
一般在watchdog的probe函数中都会调用watchdog_register_device 来在dev下注册设备,就是如上面的/dev/watchdog等
watchdog_register_device->__watchdog_register_device->watchdog_dev_register
int watchdog_dev_register(struct watchdog_device *wdd)
{
struct device *dev;
dev_t devno;
int ret;
devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
ret = watchdog_cdev_register(wdd, devno);
if (ret)
return ret;
//这里就注册dev/watchdog0
dev = device_create_with_groups(&watchdog_class, wdd->parent,
devno, wdd, wdd->groups,
"watchdog%d", wdd->id);
if (IS_ERR(dev)) {
watchdog_cdev_unregister(wdd);
return PTR_ERR(dev);
}
ret = watchdog_register_pretimeout(wdd);
if (ret) {
device_destroy(&watchdog_class, devno);
watchdog_cdev_unregister(wdd);
}
return ret;
}
static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
{
struct watchdog_core_data *wd_data;
int err;
wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL);
if (!wd_data)
return -ENOMEM;
kref_init(&wd_data->kref);
mutex_init(&wd_data->lock);
wd_data->wdd = wdd;
wdd->wd_data = wd_data;
if (!watchdog_wq)
return -ENODEV;
INIT_DELAYED_WORK(&wd_data->work, watchdog_ping_work);
//如果id是0的话,就调用misc_register 来注册/dev/watchdog,注意这个/dev/watchdog 对应的watchdog_device *wdd 和调用cdev_add 添加的字符设备用的同一个watchdog_device *wdd,所以才说他们对应的是同一个hw,以上层应用不管是打开dev/watchdog还是dev/watchdog0 都是一样的.
if (wdd->id == 0) {
old_wd_data = wd_data;
watchdog_miscdev.parent = wdd->parent;
err = misc_register(&watchdog_miscdev);
if (err != 0) {
pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n",
wdd->info->identity, WATCHDOG_MINOR, err);
if (err == -EBUSY)
pr_err("%s: a legacy watchdog module is probably present.\n",
wdd->info->identity);
old_wd_data = NULL;
kfree(wd_data);
return err;
}
}
/* Fill in the data structures */
cdev_init(&wd_data->cdev, &watchdog_fops);
wd_data->cdev.owner = wdd->ops->owner;
/* Add the device */
err = cdev_add(&wd_data->cdev, devno, 1);
if (err) {
pr_err("watchdog%d unable to add device %d:%d\n",
wdd->id, MAJOR(watchdog_devt), wdd->id);
if (wdd->id == 0) {
misc_deregister(&watchdog_miscdev);
old_wd_data = NULL;
kref_put(&wd_data->kref, watchdog_core_data_release);
}
return err;
}
/* Record time of most recent heartbeat as 'just before now'. */
wd_data->last_hw_keepalive = jiffies - 1;
/*
* If the watchdog is running, prevent its driver from being unloaded,
* and schedule an immediate ping.
*/
if (watchdog_hw_running(wdd)) {
__module_get(wdd->ops->owner);
kref_get(&wd_data->kref);
queue_delayed_work(watchdog_wq, &wd_data->work, 0);
}
return 0;
}
之所以要注册/dev/watchog 是为来兼容老的接口
阅读全文
0 0
- dev/watchdog和dev/watchdog0 是同一个设备
- /dev/null, /dev/zero 是指什么设备?
- 特殊设备文件 /dev/null 和 /dev/zero
- /dev/null 和/dev/zero 设备文件说明 (
- Linux 中的 /dev/null 和 /dev/zero 设备
- /dev/console,/dev/tty 和 /dev/null
- /dev/console,/dev/tty和/dev/null
- Dev
- dev
- dev
- dev
- dev
- /dev/tty0和/dev/console
- /dev/tty0和/dev/console
- /dev/tty0和/dev/console
- /dev/zero和/dev/null
- /dev/null和/dev/zero
- dev/console和/dev/tty
- bzoj3143/洛谷3434 游走 高斯消元求期望
- 从《人民的名义》看智慧园区运行监控可视化
- 多线程总结
- matplotlib基础
- 十分钟快速理解依赖注入
- dev/watchdog和dev/watchdog0 是同一个设备
- codeforces_814B.An express train to reveries
- html5 video标签不能播放mp4的问题
- httpclient
- ASCII码表
- okhttp上传返回的加密信息解析错误
- 第六章 贯彻执行
- Hdu3853
- 在Linux和Windows系统上安装Nginx服务器的教程