linux gpio接口

来源:互联网 发布:答题软件 编辑:程序博客网 时间:2024/05/03 21:56
一.相关结构体 
1.gpio_chip代表一个芯片的一个gpio bank
struct gpio_chip {//gpio bankconst char*label;//bank名struct device*dev;//设备文件struct module*owner;//模块所有者int(*request)(struct gpio_chip *chip,unsigned offset);void(*free)(struct gpio_chip *chip,unsigned offset);int(*direction_input)(struct gpio_chip *chip,unsigned offset);//配置gpio为输入int(*get)(struct gpio_chip *chip,unsigned offset);//获取值int(*direction_output)(struct gpio_chip *chip,unsigned offset, int value);//配置gpio为输出int(*direction_output_array)(struct gpio_chip*chip, unsigned value, unsigned mask);int(*set_debounce)(struct gpio_chip *chip,unsigned offset, unsigned debounce);//去抖动时间void(*set)(struct gpio_chip *chip,unsigned offset, int value);//设置gpio值int(*to_irq)(struct gpio_chip *chip,unsigned offset);//中断void(*dbg_show)(struct seq_file *s,struct gpio_chip *chip);intbase;//gpio基数u16ngpio;//gpio个数const char*const *names;unsignedcan_sleep:1;//能否睡眠unsignedexported:1;#if defined(CONFIG_OF_GPIO)struct device_node *of_node;int of_gpio_n_cells;int (*of_xlate)(struct gpio_chip *gc, struct device_node *np,const void *gpio_spec, u32 *flags);#endif};

2.gpio_desc 代表一个gpio口
struct gpio_desc {//GPIO描述符 struct gpio_chip*chip;//所属gpio_chipunsigned longflags;//gpio标志#ifdef CONFIG_DEBUG_FSconst char*label;#endif};

2.1 gpio_desc flags标志
#define FLAG_REQUESTED0//已请求资源#define FLAG_IS_OUT1//输出io#define FLAG_RESERVED2//保留#define FLAG_EXPORT3/* protected by sysfs_lock */#define FLAG_SYSFS4/* exported via /sys/class/gpio/control */#define FLAG_TRIG_FALL5/* trigger on falling edge */#define FLAG_TRIG_RISE6/* trigger on rising edge */#define FLAG_ACTIVE_LOW7/* sysfs value has active low */

2.2 全局gpio_desc数组
static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];

3.gpio类
static struct class gpio_class = {.name ="gpio",.owner =THIS_MODULE,.class_attrs =gpio_class_attrs,};

二.api接口
int gpiochip_add(struct gpio_chip *chip)//添加初始化gpio_chip管理的gpio_descint gpiochip_remove(struct gpio_chip *chip)//清空gpio_chip管理的全局gpio_desc数组项struct gpio_chip *gpiochip_find(void *data,int (*match)(struct gpio_chip *chip, void *data))//查找获取gpio_chipint gpio_request(unsigned gpio, const char *label)//请求gpio资源void gpio_free(unsigned gpio)//释放gpio资源int gpio_set_debounce(unsigned gpio, unsigned debounce)//设置去抖动时间int gpio_direction_input(unsigned gpio)//设置gpio为输入ioint gpio_direction_output(unsigned gpio, int value)//设置gpio为输出ioint gpio_cansleep(unsigned gpio)//判断gpio可否睡眠int gpio_get_value_cansleep(unsigned gpio)//获取gpio值(gpio可睡眠)void gpio_set_value_cansleep(unsigned gpio, int value)//设置gpio值(gpio可睡眠)int gpio_get_value(unsigned gpio)//获取gpio值(gpio不可睡眠)int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)//请求一个gpio资源int gpio_request_array(struct gpio *array, size_t num)//请求一组gpio资源void gpio_free_array(struct gpio *array, size_t num)//释放一组gpio资源int gpio_to_irq(unsigned gpio)//根据gpio号获取对应的中断号int gpio_export(unsigned gpio, bool direction_may_change)//gpio创建用户接口void gpio_unexport(unsigned gpio)//gpio移除用户接口

三.api及调用到的相关函数解析 
1.设置gpio_chip管理的全局gpio_desc数组项
int gpiochip_add(struct gpio_chip *chip){unsigned longflags;intstatus = 0;unsignedid;intbase = chip->base;//获取gpio_chip基数//验证gpio的基数,gpio的最后一个io的编号正确性if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio - 1))&& base >= 0) {status = -EINVAL;goto fail;}spin_lock_irqsave(&gpio_lock, flags);//上自旋锁if (base < 0) {//若gpio的基数小于0base = gpiochip_find_base(chip->ngpio);//根据gpio个数分配新的基数if (base < 0) {status = base;goto unlock;}chip->base = base;//设置新的基数}for (id = base; id < base + chip->ngpio; id++) {if (gpio_desc[id].chip != NULL) {//判断gpio_desc是否给其他gpio_chip管理status = -EBUSY;break;}}if (status == 0) {for (id = base; id < base + chip->ngpio; id++) {//填充对应的全局gpio_desc数组项gpio_desc[id].chip = chip;//gpio_chipgpio_desc[id].flags = !chip->direction_input?(1 << FLAG_IS_OUT):0;//设置输入输出标志位}}of_gpiochip_add(chip);unlock:spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁if (status)goto fail;status = gpiochip_export(chip);//gpio_chip创建用户接口if (status)goto fail;return 0;fail:pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",chip->base,chip->base+chip->ngpio-1,chip->label?:"generic");return status;}EXPORT_SYMBOL_GPL(gpiochip_add);

2.清空gpio_chip管理的全局gpio_desc数组项
int gpiochip_remove(struct gpio_chip *chip){unsigned longflags;intstatus = 0;unsignedid;spin_lock_irqsave(&gpio_lock, flags);//上自旋锁of_gpiochip_remove(chip);for (id = chip->base; id < chip->base + chip->ngpio; id++) {//查找对应全局gpio_desc数组项if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {//判断是否存在标志含FLAG_REQUESTED的gpio口status = -EBUSY;break;}}if (status == 0) {for (id = chip->base; id < chip->base + chip->ngpio; id++)//清空对应全局gpio_desc数组项gpio_desc[id].chip = NULL;}spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁if (status == 0)gpiochip_unexport(chip);//gpio_chip移除用户接口return status;}EXPORT_SYMBOL_GPL(gpiochip_remove);

3.查找获取gpio_chip
struct gpio_chip *gpiochip_find(void *data,int (*match)(struct gpio_chip *chip, void *data)){struct gpio_chip *chip = NULL;unsigned long flags;int i;spin_lock_irqsave(&gpio_lock, flags);//上自旋锁for (i = 0; i < ARCH_NR_GPIOS; i++) {//遍历整个全局gpio_desc数组if (!gpio_desc[i].chip)//若没被某个gpio_chip管理,则跳过继续continue;if (match(gpio_desc[i].chip, data)) {//调用传递进来的匹配函数chip = gpio_desc[i].chip;//匹配则获取其gpio_chipbreak;}}spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁return chip;//返回查找到的gpio_chip指针}

4.验证gpio号是否正确
static inline int gpio_is_valid(int number){return ((unsigned)number) < ARCH_NR_GPIOS;}

5.请求gpio资源
int gpio_request(unsigned gpio, const char *label){struct gpio_desc*desc;struct gpio_chip*chip;intstatus = -EINVAL;unsigned longflags;spin_lock_irqsave(&gpio_lock, flags);//上自旋锁if (!gpio_is_valid(gpio))//验证gpio号是否正确goto done;desc = &gpio_desc[gpio];//获取gpio描述符chip = desc->chip;//获取gpio_chipif (chip == NULL)//获取gpio_chip失败goto done;if (!try_module_get(chip->owner))//增加模块引用计数goto done;if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {//测试并设置gpio_desc的FLAG_REQUESTED标志desc_set_label(desc, label ? : "?");//设置gpio_desc的labelstatus = 0;} else {status = -EBUSY;module_put(chip->owner);//减少模块引用计数goto done;}if (chip->request) {//gpio_chip存在request方法spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁status = chip->request(chip, gpio - chip->base);//调用gpio_chip的request方法spin_lock_irqsave(&gpio_lock, flags);//上自旋锁if (status < 0) {desc_set_label(desc, NULL);//清除gpio_desc的labelmodule_put(chip->owner);//减少模块引用计数clear_bit(FLAG_REQUESTED, &desc->flags);//清除gpio_chip的FLAG_REQUESTED标志}}done:if (status)pr_debug("gpio_request: gpio-%d (%s) status %d\n",gpio, label ? : "?", status);spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁return status;}EXPORT_SYMBOL_GPL(gpio_request);

6.释放gpio资源
void gpio_free(unsigned gpio){unsigned longflags;struct gpio_desc*desc;struct gpio_chip*chip;might_sleep();if (!gpio_is_valid(gpio)) {//验证gpio号WARN_ON(extra_checks);return;}gpio_unexport(gpio);//gpio移除用户接口spin_lock_irqsave(&gpio_lock, flags);//上自旋锁desc = &gpio_desc[gpio];//获取gpio_descchip = desc->chip;//获取gpio_chipif (chip && test_bit(FLAG_REQUESTED, &desc->flags)) {//测试gpio_desc的FLAG_REQUESTED标志if (chip->free) {//gpio_chip存在free方法spin_unlock_irqrestore(&gpio_lock, flags);//上自旋锁might_sleep_if(chip->can_sleep);chip->free(chip, gpio - chip->base);//调用gpio_chip的free方法spin_lock_irqsave(&gpio_lock, flags);//解自旋锁}desc_set_label(desc, NULL);//清除gpio_desc的label信息module_put(desc->chip->owner);//减少模块引用计数clear_bit(FLAG_ACTIVE_LOW, &desc->flags);//清除FLAG_ACTIVE_LOW的标志clear_bit(FLAG_REQUESTED, &desc->flags);//清除FLAG_REQUESTED的标志} elseWARN_ON(extra_checks);spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁}EXPORT_SYMBOL_GPL(gpio_free);

7.设置去抖动时间
int gpio_set_debounce(unsigned gpio, unsigned debounce){unsigned longflags;struct gpio_chip*chip;struct gpio_desc*desc = &gpio_desc[gpio];//获取gpio_desc项intstatus = -EINVAL;spin_lock_irqsave(&gpio_lock, flags);//上自旋锁if (!gpio_is_valid(gpio))//验证gpio号goto fail;chip = desc->chip;//获取gpio_chipif (!chip || !chip->set || !chip->set_debounce)//判断gpio_chip是否存在且是否存在set和set_debounce方法goto fail;gpio -= chip->base;//计算gpio在该gpio_chip的偏移量if (gpio >= chip->ngpio)//超过该gpio_chip的gpio数范围goto fail;status = gpio_ensure_requested(desc, gpio);//确保gpio是request请求过了的if (status < 0)goto fail;/* now we know the gpio is valid and chip won't vanish */spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁might_sleep_if(chip->can_sleep);return chip->set_debounce(chip, gpio, debounce);//调用gpio_chip的set_debounce方法fail:spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁if (status)pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);return status;}EXPORT_SYMBOL_GPL(gpio_set_debounce);

8.设置gpio为输入io
int gpio_direction_input(unsigned gpio){unsigned longflags;struct gpio_chip*chip;struct gpio_desc*desc = &gpio_desc[gpio];//获取gpio_desc项intstatus = -EINVAL;spin_lock_irqsave(&gpio_lock, flags);//上自旋锁if (!gpio_is_valid(gpio))goto fail;chip = desc->chip;//获取gpio_chipif (!chip || !chip->get || !chip->direction_input)//判断gpio_chip是否存在且存在get和directon_input方法goto fail;gpio -= chip->base;//计算gpio在该gpio_chip的偏移量if (gpio >= chip->ngpio)//超过该gpio_chip的gpio数范围goto fail;status = gpio_ensure_requested(desc, gpio);//确保gpio是request请求过了的if (status < 0)goto fail;/* now we know the gpio is valid and chip won't vanish */spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁might_sleep_if(chip->can_sleep);if (status) {status = chip->request(chip, gpio);//调用chip_gpio的request方法if (status < 0) {pr_debug("GPIO-%d: chip request fail, %d\n",chip->base + gpio, status);goto lose;}}status = chip->direction_input(chip, gpio);//调用chip_gpio的direction_input方法if (status == 0)clear_bit(FLAG_IS_OUT, &desc->flags);lose:return status;fail:spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁if (status)pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);return status;}EXPORT_SYMBOL_GPL(gpio_direction_input);

9.设备gpio为输出io
int gpio_direction_output(unsigned gpio, int value){unsigned longflags;struct gpio_chip*chip;struct gpio_desc*desc = &gpio_desc[gpio];//获取gpio_desc项intstatus = -EINVAL;spin_lock_irqsave(&gpio_lock, flags);//上自旋锁if (!gpio_is_valid(gpio))goto fail;chip = desc->chip;//获取gpio_chipif (!chip || !chip->set || !chip->direction_output)//判断gpio_chip是否存在且存在set和direction_output方法goto fail;gpio -= chip->base;//计算gpio在该gpio_chip的偏移量if (gpio >= chip->ngpio)//超过该gpio_chip的gpio数范围goto fail;status = gpio_ensure_requested(desc, gpio);//确保gpio是request请求过了的if (status < 0)goto fail;spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁might_sleep_if(chip->can_sleep);if (status) {status = chip->request(chip, gpio);//调用gpio_chip的request方法if (status < 0) {pr_debug("GPIO-%d: chip request fail, %d\n",chip->base + gpio, status);goto lose;}}status = chip->direction_output(chip, gpio, value);//调用gpio_chip的direction_output方法if (status == 0)set_bit(FLAG_IS_OUT, &desc->flags);lose:return status;fail:spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁if (status)pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);return status;}EXPORT_SYMBOL_GPL(gpio_direction_output);

10.判断gpio可否睡眠
#define gpio_cansleep  __gpio_cansleepint __gpio_cansleep(unsigned gpio){struct gpio_chip*chip;chip = gpio_to_chip(gpio);//获取gpio_chipreturn chip->can_sleep;//调用gpio_chip的can_sleep方法}EXPORT_SYMBOL_GPL(__gpio_cansleep);

11.获取gpio值(gpio可睡眠)
int gpio_get_value_cansleep(unsigned gpio){struct gpio_chip*chip;might_sleep_if(extra_checks);chip = gpio_to_chip(gpio);//获取gpio_chipreturn chip->get ? chip->get(chip, gpio - chip->base) : 0;//若存在gpio_chip的get方法则调用该方法}EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);

12.设置gpio值(gpio可睡眠)
void gpio_set_value_cansleep(unsigned gpio, int value){struct gpio_chip*chip;might_sleep_if(extra_checks);chip = gpio_to_chip(gpio);//获取gpio_chipchip->set(chip, gpio - chip->base, value);//调用gpio_chip的set方法}EXPORT_SYMBOL_GPL(gpio_set_value_cansleep);

13.获取gpio值(gpio不可睡眠)
#define gpio_get_value  __gpio_get_valueint __gpio_get_value(unsigned gpio){struct gpio_chip*chip;chip = gpio_to_chip(gpio);//获取gpio_chipWARN_ON(chip->can_sleep);return chip->get ? chip->get(chip, gpio - chip->base) : 0;//若存在gpio_chip的get方法则调用该方法}EXPORT_SYMBOL_GPL(__gpio_get_value);

14.设置gpio值(gpio不可睡眠)
#define gpio_set_value  __gpio_set_valuevoid __gpio_set_value(unsigned gpio, int value){struct gpio_chip*chip;chip = gpio_to_chip(gpio);//获取gpio_chipWARN_ON(chip->can_sleep);chip->set(chip, gpio - chip->base, value);//调用gpio_chip的set方法}EXPORT_SYMBOL_GPL(__gpio_set_value);

15.请求一个gpio资源
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label){int err;err = gpio_request(gpio, label);//请求gpio资源if (err)return err;if (flags & GPIOF_DIR_IN)//输入gpioerr = gpio_direction_input(gpio);//设置gpio为输入else//输出gpioerr = gpio_direction_output(gpio,(flags & GPIOF_INIT_HIGH) ? 1 : 0);//设置gpio为输出if (err)//出错gpio_free(gpio);//释放gpio资源return err;}EXPORT_SYMBOL_GPL(gpio_request_one);

16.请求一组gpio资源
int gpio_request_array(struct gpio *array, size_t num){int i, err;for (i = 0; i < num; i++, array++) {//批量请求gpio资源err = gpio_request_one(array->gpio, array->flags, array->label);if (err)goto err_free;}return 0;err_free:while (i--)gpio_free((--array)->gpio);//释放gpio资源return err;}EXPORT_SYMBOL_GPL(gpio_request_array);

17.释放一组gpio资源
void gpio_free_array(struct gpio *array, size_t num){while (num--)gpio_free((array++)->gpio);//批量是否gpio资源}EXPORT_SYMBOL_GPL(gpio_free_array);

18.根据gpio号获取对应的中断号
int __gpio_to_irq(unsigned gpio){struct gpio_chip*chip;chip = gpio_to_chip(gpio);//获取gpio_chipreturn chip->to_irq?chip->to_irq(chip,gpio-chip->base):-ENXIO;//若gpio_chip的to_irq方法存在则调用其方法}EXPORT_SYMBOL_GPL(__gpio_to_irq);

19.gpio_chip创建用户接口
static int gpiochip_export(struct gpio_chip *chip){intstatus;struct device*dev;if (!gpio_class.p)return 0;mutex_lock(&sysfs_lock);//上互斥锁dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,"gpiochip%d", chip->base);//创建设备if (!IS_ERR(dev)) {status = sysfs_create_group(&dev->kobj,&gpiochip_attr_group);} elsestatus = PTR_ERR(dev);chip->exported = (status == 0);//设置gpio_chip的exported标志mutex_unlock(&sysfs_lock);//解互斥锁if (status) {unsigned longflags;unsignedgpio;spin_lock_irqsave(&gpio_lock, flags);//上自旋锁gpio = chip->base;//获取gpio_chip的基数while (gpio_desc[gpio].chip == chip)//遍历该gpio_chip管理的所有gpio_descgpio_desc[gpio++].chip = NULL;//清除该gpio_desc的chip成员spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁pr_debug("%s: chip %s status %d\n", __func__,chip->label, status);}return status;}

20.gpio_chip移除用户接口
static void gpiochip_unexport(struct gpio_chip *chip){intstatus;struct device*dev;mutex_lock(&sysfs_lock);//上互斥锁dev = class_find_device(&gpio_class, NULL, chip, match_export);//找到export的gpio_chip的设备文件if (dev) {put_device(dev);//减少引用计数device_unregister(dev);//注销设备文件chip->exported = 0;//清除export标志status = 0;//设置status} elsestatus = -ENODEV;mutex_unlock(&sysfs_lock);//解互斥锁if (status)pr_debug("%s: chip %s status %d\n", __func__,chip->label, status);}

21.gpio创建用户接口
int gpio_export(unsigned gpio, bool direction_may_change){unsigned longflags;struct gpio_desc*desc;intstatus = -EINVAL;const char*ioname = NULL;if (!gpio_class.p) {pr_debug("%s: called too early!\n", __func__);return -ENOENT;}if (!gpio_is_valid(gpio))//验证gpio号的正确性goto done;mutex_lock(&sysfs_lock);//上互斥锁spin_lock_irqsave(&gpio_lock, flags);//上自旋锁desc = &gpio_desc[gpio];//获取gpio_desc数组项if (test_bit(FLAG_REQUESTED, &desc->flags)&& !test_bit(FLAG_EXPORT, &desc->flags)) {//已请求但没exportstatus = 0;if (!desc->chip->direction_input|| !desc->chip->direction_output)//gpio_chip不存在direction_input和direction_output方法direction_may_change = false;//那么gpio的方向不可能会改变}spin_unlock_irqrestore(&gpio_lock, flags);//解自旋锁if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])//gpio_chip存在名字数组且存在对应数组项的名字ioname = desc->chip->names[gpio - desc->chip->base];//设置gpio名if (status == 0) {struct device*dev;dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),desc, ioname ? ioname : "gpio%u", gpio);//创建设备文件if (!IS_ERR(dev)) {status = sysfs_create_group(&dev->kobj,&gpio_attr_group);//创建属性if (!status && direction_may_change)//gpio方向可能会改变status = device_create_file(dev,&dev_attr_direction);//则创建跟方向相关的属性if (!status && gpio_to_irq(gpio) >= 0&& (direction_may_change|| !test_bit(FLAG_IS_OUT,&desc->flags)))//可设置中断的引荐status = device_create_file(dev,&dev_attr_edge);//则创建跟中断触发相关的属性if (status != 0)device_unregister(dev);//注销设备} elsestatus = PTR_ERR(dev);if (status == 0)set_bit(FLAG_EXPORT, &desc->flags);//设置export标志}mutex_unlock(&sysfs_lock);//解互斥锁done:if (status)pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);return status;}EXPORT_SYMBOL_GPL(gpio_export);

22.gpio移除用户接口
void gpio_unexport(unsigned gpio){struct gpio_desc*desc;intstatus = 0;if (!gpio_is_valid(gpio)) {//验证gpio号的正确性status = -EINVAL;goto done;}mutex_lock(&sysfs_lock);//上锁互斥锁desc = &gpio_desc[gpio];//获取gpio_descif (test_bit(FLAG_EXPORT, &desc->flags)) {//判断是否exportstruct device*dev = NULL;dev = class_find_device(&gpio_class, NULL, desc, match_export);//获取设备文件if (dev) {gpio_setup_irq(desc, dev, 0);//中断gpio的处理clear_bit(FLAG_EXPORT, &desc->flags);//清除export标志put_device(dev);//增加dev引用计数device_unregister(dev);//注销设备} elsestatus = -ENODEV;}mutex_unlock(&sysfs_lock);//解锁互斥锁done:if (status)pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);}EXPORT_SYMBOL_GPL(gpio_unexport);

23.中断gpio处理
static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,unsigned long gpio_flags){struct sysfs_dirent*value_sd;unsigned longirq_flags;intret, irq, id;if ((desc->flags & GPIO_TRIGGER_MASK) == gpio_flags)//有FLAG_TRIG_FALL或FLAG_TRIG_RISE标志return 0;irq = gpio_to_irq(desc - gpio_desc);//根据gpio获取对应的中断号if (irq < 0)return -EIO;id = desc->flags >> ID_SHIFT;//#define ID_SHIFT16value_sd = idr_find(&dirent_idr, id);//获取设备idif (value_sd)//获取设备id成功,说明是申请过gpio中断的了free_irq(irq, value_sd);//释放中断desc->flags &= ~GPIO_TRIGGER_MASK;//屏蔽gpio_desc标志位FLAG_TRIG_FALL或FLAG_TRIG_RISEif (!gpio_flags) {//gpio_unexport中的gpio_setup_irq跑到这里返回ret = 0;goto free_id;}irq_flags = IRQF_SHARED;//设置为共享中断类型if (test_bit(FLAG_TRIG_FALL, &gpio_flags))//FLAG_TRIG_FALL 下降沿触发irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;if (test_bit(FLAG_TRIG_RISE, &gpio_flags))//FLAG_TRIG_RISE 上升沿触发irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;if (!value_sd) {//获取设备id不成功value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value");//获取设备idif (!value_sd) {ret = -ENODEV;goto err_out;}do {ret = -ENOMEM;if (idr_pre_get(&dirent_idr, GFP_KERNEL))ret = idr_get_new_above(&dirent_idr, value_sd,1, &id);} while (ret == -EAGAIN);//id机制中获取新的id该id指向value_sdif (ret)goto free_sd;desc->flags &= GPIO_FLAGS_MASK;//设置gpio_desc标志desc->flags |= (unsigned long)id << ID_SHIFT;//或上idr机制获取的idif (desc->flags >> ID_SHIFT != id) {//验证下是否id存放正确ret = -ERANGE;goto free_id;}}ret = request_any_context_irq(irq, gpio_sysfs_irq, irq_flags,"gpiolib", value_sd);//申请中断if (ret < 0)goto free_id;desc->flags |= gpio_flags;//gpio_desc设置传递进来的标志return 0;free_id:idr_remove(&dirent_idr, id);desc->flags &= GPIO_FLAGS_MASK;free_sd:if (value_sd)sysfs_put(value_sd);err_out:return ret;}

四.sysfs的初始化
static int __init gpiolib_sysfs_init(void){intstatus;unsigned longflags;unsignedgpio;status = class_register(&gpio_class);//注册gpio_classif (status < 0)return status;spin_lock_irqsave(&gpio_lock, flags);for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) {//遍历全局gpio_desc数组struct gpio_chip*chip;chip = gpio_desc[gpio].chip;//获取数组项的gpio_chipif (!chip || chip->exported)//gpio_chip为空或已经exported了continue;spin_unlock_irqrestore(&gpio_lock, flags);//上自旋锁status = gpiochip_export(chip);//exported该项spin_lock_irqsave(&gpio_lock, flags);//解自旋锁}spin_unlock_irqrestore(&gpio_lock, flags);return status;}postcore_initcall(gpiolib_sysfs_init);
原创粉丝点击