分析中断注册函数: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])

最新文章

  1. Hawk 4.7 单步调试
  2. 树莓派3B更新软件
  3. supervisor centos安装
  4. 惩罚因子(penalty term)与损失函数(loss function)
  5. 【OpenStack】OpenStack系列1之OpenStack本地开发环境搭建&amp;&amp;向社区贡献代码
  6. Ubuntu各版本下载地址
  7. 【MYSQL】创建虚表来辅助数据库查询
  8. js一些实用例子
  9. 手机APP上下滚动翻页效果
  10. cluster maintain manager Software群集管理软件
  11. 【第五篇】Volley代码修改之图片二级缓存以及相关源码阅读(重写ImageLoader.ImageCache)
  12. CIFAR-10 dataset 的下载与使用
  13. DevExpress.XtraEditors.TextEdit 设为密码输入框
  14. Bootstrap中的data-toggle,data-target
  15. php5.4之分布式缓存memcache(windows7下安装配置)
  16. JustOj 1415: 字符串解压
  17. 2019/3/25 wen 包,对象的行为
  18. Day5作业及默写
  19. asp.net mvc中的用户登录验证过滤器
  20. windows下安装pytorch

热门文章

  1. 放弃setInterval-说说定时器
  2. php生成csv文件并提供下载及相关注意事项
  3. BZOJ2342:[SHOI2011]双倍回文(Manacher)
  4. Linux总结(十二)set_uid set_gid stic_bit 软链接 硬链接
  5. Java中线程同步的理解
  6. Jmeter--JDBC请求(sqlserver)
  7. Jmeter--HTTPS请求
  8. HDU 4864 Task(经典贪心)
  9. UVALive4682 XOR Sum
  10. asp.net mvc 如何在View中获取Url参数的值