zoukankan      html  css  js  c++  java
  • 字符设备驱动(1)代码分析---之request_irq

    err = request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_BOTH, 
                buttons[i].name, (void *)&buttons[i]);
    static inline int __must_check request_irq(unsigned int irq, 
            irq_handler_t handler, unsigned long flags,const char *name,
                    void *dev)
    {
        return request_threaded_irq(irq, handler, NULL, flags, name, dev);
        ##
        /**
         *    request_threaded_irq - allocate an interrupt line
         *    @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*/
     
        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)
                return -EINVAL;
    
            desc = irq_to_desc(irq);
                ###
                #define NR_IRQS            (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
                //IRQ_EINT(31) = 160 +31-16 = 175
                #define S5P_GPIOINT_COUNT    (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
                #define S5P_GPIOINT_GROUP_COUNT 4
                #define S5P_GPIOINT_GROUP_SIZE    8
                //#define S5P_GPIOINT_COUNT 12
                #define NR_IRQS            (175+12+ 1)
                //#define NR_IRQS            188
                ####
                    #ifndef CONFIG_SPARSE_IRQ
                    extern struct irq_desc irq_desc[NR_IRQS];
                    #endif
                ####
                struct irq_desc *irq_to_desc(unsigned int irq)
                {
                    return (irq < NR_IRQS) ? irq_desc + irq : NULL;
                }
                //desc = irq_desc[irq]
                //irqdesc.c
                #else /* !CONFIG_SPARSE_IRQ */
    
                struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
                    [0 ... NR_IRQS-1] = {
                        .handle_irq    = handle_bad_irq,
                        .depth        = 1,
                        .lock        = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
                    }
                }
                ###
            if (!desc)
                return -EINVAL;
            ###
                static inline bool irq_settings_can_request(struct irq_desc *desc)
                {
                    return !(desc->status_use_accessors & _IRQ_NOREQUEST);
                }
            ###
            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);
            ###
            /**
             * struct irqaction - per interrupt action descriptor
             * @handler:    interrupt handler function
             * @flags:    flags (see IRQF_* above)
             * @name:    name of the device
             * @dev_id:    cookie to identify the device
             * @next:    pointer to the next irqaction for shared interrupts
             * @irq:    interrupt number
             * @dir:    pointer to the proc/irq/NN/name entry
             * @thread_fn:    interrupt handler function for threaded interrupts
             * @thread:    thread pointer for threaded interrupts
             * @thread_flags:    flags related to @thread
             * @thread_mask:    bitmask for keeping track of @thread activity
             */
             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;
            ###
            
            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);
            
            ###
                static int
                __setup_irq(unsigned int irq, struct irq_desc *desc, 
                                    struct irqaction *new)
                {    
                    register_irq_proc(irq, desc);
                    new->dir = NULL;
                    register_handler_proc(irq, new);
                    free_cpumask_var(mask);
                    return 0;
                }
            ###
            chip_bus_sync_unlock(desc);
    
            if (retval)
                kfree(action);
    
            return retval;
        }
        ##
    }    
  • 相关阅读:
    2014--My Plan
    C++操作xls
    fail2ban[防止linux服务器被暴力破解]
    8.1向上转型
    寒假的一个月--实现自己的五部狂奏曲
    浅谈《think in java》:二 一切都是对象
    浅谈《think in java》:一 对象导论总结
    增加Myecllipse内存
    java 容器 集合 用法
    SVN用户切换
  • 原文地址:https://www.cnblogs.com/embeded-linux/p/11063952.html
Copyright © 2011-2022 走看看