分析中断注册函数:request_irq

 int butsOpen(struct inode *p, struct file *f)
 {

         int irq;
     int i;
     ;
     printk(KERN_EMERG"butsOpen\r\n");
     ; i < ARRAY_SIZE(buttons); i++) {
         if (!buttons[i].gpio)
             continue;

         irq = gpio_to_irq(buttons[i].gpio);
         err = request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_BOTH,
14                 buttons[i].name, (void *)&buttons[i]);
         if (err)
             break;
     }

     if (err) {
         i--;
         ; i--) {
             if (!buttons[i].gpio)
                 continue;

             irq = gpio_to_irq(buttons[i].gpio);
             disable_irq(irq);
             free_irq(irq, (void *)&buttons[i]);
         }

         return -EBUSY;
     }
     ;
 }
 request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
2         const char *name, void *dev)
 {
     return request_threaded_irq(irq, handler, NULL, flags, name, dev);
 }
 /**
  *    request_threaded_irq - 分配中断线路函数
  *    @irq: Interrupt line to allocate
  *    @handler: Function to be called when the IRQ occurs.
  *          Primary handler for threaded interrupts
  *          If NULL and thread_fn != NULL the default
  *          primary handler is installed
  *    @thread_fn: Function called from the irq handler thread
  *            If NULL, no irq thread is created
  *    @irqflags: Interrupt type flags
  *    @devname: An ascii name for the claiming device
  *    @dev_id: A cookie passed back to the handler function//作为hanler的一个参数
  *
  *    This call allocates interrupt resources and enables the
  *    interrupt line and IRQ handling. From the point this
  *    call is made your handler function may be invoked. Since
  *    your handler function must clear any interrupt the board
  *    raises, you must take care both to initialise your hardware
  *    and to set up the interrupt handler in the right order.
  *
  *    If you want to set up a threaded irq handler for your device
  *    then you need to supply @handler and @thread_fn. @handler ist
  *    still called in hard interrupt context and has to check
  *    whether the interrupt originates from the device. If yes it
  *    needs to disable the interrupt on the device and return
  *    IRQ_WAKE_THREAD which will wake up the handler thread and run
  *    @thread_fn. This split handler design is necessary to support
  *    shared interrupts.
  *
  *    Dev_id must be globally unique. Normally the address of the
  *    device data structure is used as the cookie. Since the handler
  *    receives this value it makes sense to use it.
  *
  *    If your interrupt is shared you must pass a non NULL dev_id
  *    as this is required when freeing the interrupt.
  *
  *    Flags:
  *
  *    IRQF_SHARED        Interrupt is shared
  *    IRQF_SAMPLE_RANDOM    The interrupt can be used for entropy
  *    IRQF_TRIGGER_*        Specify active edge(s) or level
  *
  */ 
 struct irqaction {
     irq_handler_t handler;
     unsigned long flags;
     void *dev_id;
     struct irqaction *next;
     int irq;
     irq_handler_t thread_fn;
     struct task_struct *thread;
     unsigned long thread_flags;
     unsigned long thread_mask;
     const char *name;
     struct proc_dir_entry *dir;
 } ____cacheline_internodealigned_in_smp;

struct irqaction

 /**
  * struct irq_desc - interrupt descriptor
  * @irq_data:        per irq and chip data passed down to chip functions
  * @timer_rand_state:    pointer to timer rand state struct
  * @kstat_irqs:        irq stats per cpu
  * @handle_irq:        highlevel irq-events handler
  * @preflow_handler:    handler called before the flow handler (currently used by sparc)
  * @action:        the irq action chain
  * @status:        status information
  * @core_internal_state__do_not_mess_with_it: core internal status information
  * @depth:        disable-depth, for nested irq_disable() calls
  * @wake_depth:        enable depth, for multiple irq_set_irq_wake() callers
  * @irq_count:        stats field to detect stalled irqs
  * @last_unhandled:    aging timer for unhandled count
  * @irqs_unhandled:    stats field for spurious unhandled interrupts
  * @lock:        locking for SMP
  * @affinity_hint:    hint to user space for preferred irq affinity
  * @affinity_notify:    context for notification of affinity changes
  * @pending_mask:    pending rebalanced interrupts
  * @threads_oneshot:    bitfield to handle shared oneshot threads
  * @threads_active:    number of irqaction threads currently running
  * @wait_for_threads:    wait queue for sync_irq to wait for threaded handlers
  * @dir:        /proc/irq/ procfs entry
  * @name:        flow handler name for /proc/interrupts output
  */
 struct irq_desc {
     struct irq_data        irq_data;
     struct timer_rand_state *timer_rand_state;
     unsigned int __percpu    *kstat_irqs;
     irq_flow_handler_t    handle_irq;
 #ifdef CONFIG_IRQ_PREFLOW_FASTEOI
     irq_preflow_handler_t    preflow_handler;
 #endif
     struct irqaction    *action;    /* IRQ action list */
     unsigned int        status_use_accessors;
     unsigned int        core_internal_state__do_not_mess_with_it;
     unsigned int        depth;        /* nested irq disables */
     unsigned int        wake_depth;    /* nested wake enables */
     unsigned int        irq_count;    /* For detecting broken IRQs */
     unsigned long        last_unhandled;    /* Aging timer for unhandled count */
     unsigned int        irqs_unhandled;
     raw_spinlock_t        lock;
 #ifdef CONFIG_SMP
     const struct cpumask    *affinity_hint;
     struct irq_affinity_notify *affinity_notify;
 #ifdef CONFIG_GENERIC_PENDING_IRQ
     cpumask_var_t        pending_mask;
 #endif
 #endif
     unsigned long        threads_oneshot;
     atomic_t        threads_active;
     wait_queue_head_t       wait_for_threads;
 #ifdef CONFIG_PROC_FS
     struct proc_dir_entry    *dir;
 #endif
     const char        *name;
 } ____cacheline_internodealigned_in_smp;

struct irq_desc

 int request_threaded_irq(unsigned int irq, irq_handler_t handler,
              irq_handler_t thread_fn, unsigned long irqflags,
              const char *devname, void *dev_id)
 {
     struct irqaction *action;
     struct irq_desc *desc;
     int retval;

     /*
      * Sanity-check: shared interrupts must pass in a real dev-ID,
      * otherwise we'll have trouble later trying to figure out
      * which interrupt is which (messes up the interrupt freeing
      * logic etc).
      */
     if ((irqflags & IRQF_SHARED) && !dev_id)//若终端标志是共享中断,则设备号dev_id不允许为空
         return -EINVAL;

     desc = irq_to_desc(irq);
     if (!desc)
         return -EINVAL;

     if (!irq_settings_can_request(desc))
         return -EINVAL;

     if (!handler) {
         if (!thread_fn)
             return -EINVAL;
         handler = irq_default_primary_handler;
     }

     action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
     if (!action)
         return -ENOMEM;

     action->handler = handler;
     action->thread_fn = thread_fn;
     action->flags = irqflags;
     action->name = devname;
     action->dev_id = dev_id;

     chip_bus_lock(desc);
     retval = __setup_irq(irq, desc, action);
     chip_bus_sync_unlock(desc);

     if (retval)
         kfree(action);

 #ifdef CONFIG_DEBUG_SHIRQ_FIXME
     if (!retval && (irqflags & IRQF_SHARED)) {
         /*
          * It's a shared IRQ -- the driver ought to be prepared for it
          * to happen immediately, so let's make sure....
          * We disable the irq to make sure that a 'real' IRQ doesn't
          * run in parallel with our fake.
          */
         unsigned long flags;

         disable_irq(irq);
         local_irq_save(flags);

         handler(irq, dev_id);

         local_irq_restore(flags);
         enable_irq(irq);
     }
 #endif
     return retval;
 }
 #define irq_to_desc(irq)    (&irq_desc[irq])

Linux字符设备驱动--No.2的更多相关文章

  1. 深入理解Linux字符设备驱动

    文章从上层应用访问字符设备驱动开始,一步步地深入分析Linux字符设备的软件层次.组成框架和交互.如何编写驱动.设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解.本文整合之前发表的& ...

  2. Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】

    本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...

  3. Smart210学习记录----beep linux字符设备驱动

    今天搞定了beep linux字符设备驱动,心里还是很开心的,哈哈...但在完成的过程中却遇到了一个非常棘手的问题,花费了我大量的时间,,,, 还是把问题描述一下吧,好像这个问题很普遍的,网上许多解决 ...

  4. Linux字符设备驱动实现

    Linux字符设备驱动实现 要求 编写一个字符设备驱动,并利用对字符设备的同步操作,设计实现一个聊天程序.可以有一个读,一个写进程共享该字符设备,进行聊天:也可以由多个读和多个写进程共享该字符设备,进 ...

  5. Linux字符设备驱动基本结构

    1.Linux字符设备驱动的基本结构 Linux系统下具有三种设备,分别是字符设备.块设备和网络设备,Linux下的字符设备是指只能一个字节一个字节读写的设备,不能随机读取设备内存中某一数据,读取数据 ...

  6. (57)Linux驱动开发之三Linux字符设备驱动

    1.一般情况下,对每一种设备驱动都会定义一个软件模块,这个工程模块包含.h和.c文件,前者定义该设备驱动的数据结构并声明外部函数,后者进行设备驱动的具体实现. 2.典型的无操作系统下的逻辑开发程序是: ...

  7. Linux字符设备驱动框架

    字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l ...

  8. Linux 字符设备驱动模型

    一.使用字符设备驱动程序 1. 编译/安装驱动 在Linux系统中,驱动程序通常采用内核模块的程序结构来进行编码.因此,编译/安装一个驱动程序,其实质就是编译/安装一个内核模块 2. 创建设备文件 通 ...

  9. linux字符设备驱动学习笔记(一):简单的字符设备驱动

    最近在鼓捣lnux字符设备驱动,在网上搜集的各种关于linux设备驱动的代码和注释,要么是针对2.4的,要么是错误百出,根本就不能运行成功,真希望大家在发博客的时候能认真核对下代码的正确性,特别是要把 ...

  10. Linux字符设备驱动

    一.字符设备基础 字符设备 二.字符设备驱动与用户空间访问该设备的程序三者之间的关系 三.字符设备模型 1.Linux内核中,使用 struct cdev 来描述一个字符设备 动态申请(构造)cdev ...

随机推荐

  1. 【Leetcode】【Medium】Search a 2D Matrix

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  2. selenium借助send_keys实现上传(以网易邮箱为例)

    #code:utf-8from selenium import webdriverimport time#网易163邮箱dr = webdriver.Firefox()file_path = 'htt ...

  3. February 20 2017 Week 8 Monday

    Behind every beautiful thing, there's some kind of pain. 美丽背后,必有努力. No pains, no gains, and sometime ...

  4. Spring Framework5.0 学习(4)—— Bean的命名id和name区别

    Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...

  5. 更新UI的几种方式

    在学习Handler的过程中牵涉到UI的更新,在这里就总结一下更新UI的四种方式吧,用法都比较简单,直接看代码就可以了. 一.使用Handler的post方法 新建项目,修改MainActivity代 ...

  6. Spark Streamming 基本输入流(二) :Socket

    Spark Streamming 可以通过socket 进行数据监听. socket的输入方可以通过nc 或者自己开发nc功能的程序. 1.系统自带的nc su root a yum install ...

  7. STL - next_permutation 全排列函数

    学习: http://blog.sina.com.cn/s/blog_9f7ea4390101101u.html http://blog.csdn.net/ac_gibson/article/deta ...

  8. sort论文和代码解读

    流程:1.detections和trackers用匈牙利算法进行匹配 2.把匹配中iou < 0.3的过滤成没匹配上的(1.2步共同返回匹配上的,没匹配上的trackers,没匹配上的detec ...

  9. socket相关的开机初始化分析

    针对内核3.9 系统开启时,会使用init/main.c,然后再里面调用kernel_init(),在里面会再调用do_basic_setup(),调用do_initcalls(),调用do_one_ ...

  10. 【luogu P4017 最大食物链计数】 题解

    题目链接:https://www.luogu.org/problemnew/show/P4017 DAG + DP #include <queue> #include <cstdio ...