//gpio_request申请gpio口

int gpio_request(unsigned gpio, const char *label)
{
struct gpio_desc *desc;
struct gpio_chip *chip;
int status = -EINVAL;
unsigned long flags; spin_lock_irqsave(&gpio_lock, flags); // gpio_lock是自旋锁,上锁,保存FLAG在flags变量
if (!gpio_is_valid(gpio))
goto done;
desc = &gpio_desc[gpio];
chip = desc->chip;
if (chip == NULL)
goto done; if (!try_module_get(chip->owner)) // 该函数用于增加模块使用计数;若返回为0,表示调用失败,希望使用的模块没有被加载或正在被卸载中 goto done; /* NOTE: gpio_request() can be called in early boot,
* before IRQs are enabled, for non-sleeping (SOC) GPIOs.
*/ if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == ) { // 原子操作,将flags的第FLAG_REQUESTED位置1,并返回其原值
desc_set_label(desc, label ? : "?");// 如果原来的值是0, 执行desc_set_label, 对desc->chip.label赋值,如果label有定义,直接用定义,比如上面的“temporary”,否则用“?”
status = 0;
} else {
status = -EBUSY;
module_put(chip->owner); // 该函数用于减少模块使用计数goto done;
} if (chip->request) {// chip->request在linux初始化时是没有指向的 /* chip->request may sleep */
spin_unlock_irqrestore(&gpio_lock, flags);// 如果chip->request不为0, 解锁,因为后面调用的chip->request有可能睡眠
status = chip->request(chip, gpio - chip->base);
spin_lock_irqsave(&gpio_lock, flags); if (status < ) {
desc_set_label(desc, NULL);
module_put(chip->owner);
clear_bit(FLAG_REQUESTED, &desc->flags);
}
} 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); void gpio_free(unsigned gpio)
{
unsigned long flags;
struct gpio_desc *desc;
struct gpio_chip *chip; might_sleep(); if (!gpio_is_valid(gpio)) {
WARN_ON(extra_checks);
return;
} gpio_unexport(gpio); spin_lock_irqsave(&gpio_lock, flags); desc = &gpio_desc[gpio];
chip = desc->chip;
if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) {
if (chip->free) {
spin_unlock_irqrestore(&gpio_lock, flags);
might_sleep_if(extra_checks && chip->can_sleep);
chip->free(chip, gpio - chip->base);
spin_lock_irqsave(&gpio_lock, flags);
}
desc_set_label(desc, NULL);
module_put(desc->chip->owner);
clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
clear_bit(FLAG_REQUESTED, &desc->flags);
} else
WARN_ON(extra_checks); spin_unlock_irqrestore(&gpio_lock, flags);
}
EXPORT_SYMBOL_GPL(gpio_free);

Linux下GPIO驱动(四) ----gpio_request();gpio_free();的更多相关文章

  1. 很好的linux下GPIO驱动详解文章

    原文地址  http://blog.csdn.net/llxmedici/article/details/6282372 打算跟着友善之臂的<mini2440 linux移植开发指南>来做 ...

  2. Linux下GPIO驱动(三) ----gpio_desc()的分析

    上篇最后提出的疑问是结构体gpio_chip中的成员函数set等是怎么实现的,在回答之前先介绍下gpio_desc这个结构体. 如上图所示,右上方部分为GPIO驱动对其它驱动提供的GPIO操作接口,其 ...

  3. Linux下GPIO驱动(一) ----一个简单的LED驱动

    /******************************* * *杂项设备驱动:miscdevice *majior=10; * * *****************************/ ...

  4. Linux下GPIO驱动

    编写驱动程序,首先要了解是什么类型的设备.linux下的设备分为三类,分别为:字符设备,块设备和网络设备.字符设备类型是根据是否以字符流为数据的交换方式,大部分设备都是字符设备,如键盘,串口等,块设备 ...

  5. Linux下GPIO驱动(五) ----misc_register();

    // struct miscdevice { int minor; const char *name; const struct file_operations *fops; struct list_ ...

  6. Linux下GPIO驱动(二) ----s3c_gpio_cfgpin();gpio_set_value();

    首先来看s3c_gpio_cfgpin(); int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) { struct s3c_gpio_ ...

  7. 飞思卡尔imx6开发板Linux下GPIO驱动

    控制GPIO_1_28的输出: #define MY_BOMB_GPIO       IMX_GPIO_NR(1, 28) 配置为输出方式: gpio_direction_output (MY_BOM ...

  8. Linux 下wifi 驱动开发(四)—— USB接口WiFi驱动浅析

    源: Linux 下wifi 驱动开发(四)—— USB接口WiFi驱动浅析

  9. 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之一

    /** ****************************************************************************** * @author    暴走的小 ...

随机推荐

  1. mac中vmware tools进行磁盘压缩和vmware-tools-cli的使用方法

    前言: 高高兴兴的在vmware9.0中安装了mac10.8系统,然后学习iphone开发,但是发现下载的pdf都是基于xcode3.2.5的,又在10.8上面安装3.2.5,出现“五国”无法解决,最 ...

  2. C#_mvc_ajax_return data

    假设cshtml文件中是这样的: <script type="text/javascript"> $(document).ready(function(){ $(&qu ...

  3. 如何用 PHPMailer 来发送邮件?

    <?php require_once('mantisbt-1.2.15/library/phpmailer/class.phpmailer.php'); $mail= new PHPMailer ...

  4. Kali安全测试相关书籍

    Kali安全测试相关书籍http://www.automationqa.com/forum.php?mod=viewthread&tid=4052&fromuid=2

  5. PowerShell 批量增加ACL

    $serviceName="云服务名称"$vmName="虚拟机名称"$endPoint="终结点名称"$acl=New-AzureAclC ...

  6. Callable、Future和FutureTask使用说明

    普通的创建线程,一种是直接继承Thread,另外一种就是实现Runnable接口.但是这两种都无法在执行完任务之后获取执行结果,Callable.Future就提供了这样的便利.   Future的方 ...

  7. JVM垃圾回收日志结构分析

    我们在我们Server的gc log上经常看到下面的这个日志: 总结一下各个字段表达的是什么意思:  Young GC Full GC: top -H -P $PID  动态查看java线程的消耗情况 ...

  8. 一个用ASP生成html的新方法

    目前已经有很多生成html的新闻系统,但是都是用的模板,本函数实现把asp页面产生的html代码保存成为一个html文件,这样就没有必要改动原来的页面就可以轻松完成一个生成html的新闻系统了.^_^ ...

  9. 陷阱~SQL全表扫描与聚集索引扫描

    SqlServer中在查询时,我们为了优化性能,通常会为where条件的字段建立索引,如果条件比较固定还会建立组合索引,接下来,我们来看一下索引与查询的相关知识及相关陷阱. SQL表自动为主键加聚集索 ...

  10. OC1_数组创建

    // // main.m // OC1_数组创建 // // Created by zhangxueming on 15/6/11. // Copyright (c) 2015年 zhangxuemi ...