linux 驱动中几个驱动注册的实体函数
2017-08-15 10:47
603 查看
misc_register() 调用device_create_with_groups()(新内核, 旧的为device_create()) 函数进行注册,
misc_deregister() 代码为
device_create_with_groups() 及 device_create() 是两个常用的创建及注册设备, 同时创建/sys/文件系统的的函数, 如/sys/class/gpio/* 中的文件,通过读写文件可以控制相关驱动及设备
device_create_with_groups() 及 device_create() 最终调用 device_create_groups_vargs()函数;
cdev_add() 增加一个字符型设备, 通用方法
int misc_register(struct miscdevice * misc) { dev_t dev; int err = 0; bool is_dynamic = (misc->minor == MISC_DYNAMIC_MINOR); INIT_LIST_HEAD(&misc->list); mutex_lock(&misc_mtx); if (is_dynamic) { int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); if (i >= DYNAMIC_MINORS) { err = -EBUSY; goto out; } misc->minor = DYNAMIC_MINORS - i - 1; set_bit(i, misc_minors); } else { struct miscdevice *c; list_for_each_entry(c, &misc_list, list) { if (c->minor == misc->minor) { err = -EBUSY; goto out; } } } dev = MKDEV(MISC_MAJOR, misc->minor); misc->this_device = device_create_with_groups(misc_class, misc->parent, dev, misc, misc->groups, "%s", misc->name); if (IS_ERR(misc->this_device)) { if (is_dynamic) { int i = DYNAMIC_MINORS - misc->minor - 1; if (i < DYNAMIC_MINORS && i >= 0) clear_bit(i, misc_minors); misc->minor = MISC_DYNAMIC_MINOR; } err = PTR_ERR(misc->this_device); goto out; } /* * Add it to the front, so that later devices can "override" * earlier defaults */ list_add(&misc->list, &misc_list); out: mutex_unlock(&misc_mtx); return err; }
misc_deregister() 代码为
void misc_deregister(struct miscdevice *misc) { int i = DYNAMIC_MINORS - misc->minor - 1; if (WARN_ON(list_empty(&misc->list))) return; mutex_lock(&misc_mtx); list_del(&misc->list); device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); if (i < DYNAMIC_MINORS && i >= 0) clear_bit(i, misc_minors); mutex_unlock(&misc_mtx); }
device_create_with_groups() 及 device_create() 是两个常用的创建及注册设备, 同时创建/sys/文件系统的的函数, 如/sys/class/gpio/* 中的文件,通过读写文件可以控制相关驱动及设备
device_create_with_groups() 及 device_create() 最终调用 device_create_groups_vargs()函数;
static struct device * device_create_groups_vargs(struct class *class, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, va_list args) { struct device *dev = NULL; int retval = -ENODEV; if (class == NULL || IS_ERR(class)) goto error; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { retval = -ENOMEM; goto error; } device_initialize(dev); dev->devt = devt; dev->class = class; dev->parent = parent; dev->groups = groups; dev->release = device_create_release; dev_set_drvdata(dev, drvdata); retval = kobject_set_name_vargs(&dev->kobj, fmt, args); //创建文件系统 if (retval) goto error; retval = device_add(dev); //注册设备 if (retval) goto error; return dev; error: put_device(dev); return ERR_PTR(retval); }
cdev_add() 增加一个字符型设备, 通用方法
int err, devno = MKDEV(globalmem_major, index); cdev_init(&dev->cdev, &globalmem_fops); dev->cdev.owner = THIS_MODULE; err = cdev_add(&dev->cdev, devno, 1);
相关文章推荐
- Linux驱动-注册和卸载设备函数
- 浅析linux 2.6.23驱动注册函数driver_register()
- linux驱动注册的相关函数
- linux驱动编程--几个重要函数及概念
- 浅析linux 2.6.23驱动注册函数driver_register()
- linux-i2c驱动 之 i2c设备层的注册过程probe函数如何被调用分析
- linux2.4和2.6在注册设备驱动函数…
- Linux 字符设备驱动开发基础(四)—— ioctl() 函数解析
- 我的第一个简单的linux打印输出驱动(文件自动注册有问题)
- linux中platform总线解析(四)(platform设备注册后自动匹配驱动)
- linux 线程创建函数pthread_create的几个传参方式
- 关于Linux下I2C驱动的Probe方式没有自动生成i2c_client且没有自动调用i2c_driver的.probe指向的函数的问题解决
- linux驱动的入口函数module_init的加载和释放
- linux设备驱动之mmap函数
- 【linux驱动分析】之dm9000驱动分析(五):另外几个重要的结构体
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- 3、Linux设备驱动---轮询操作poll()函数
- LINUX驱动注册过程失败处理不当引起的恶果
- Linux驱动开发中常见的几个不好的习惯
- linux 下platform设备和驱动注册的先后顺序