一些内核中断API (1)

//软终端描述符
struct tasklet_struct
{
struct tasklet_struct *next;   //指向下一个元素
unsigned long state;           //TASKLET_STATE_SCHED TASKLET_STATE_RUN
atomic_t count;                //计数字段,=0才可以进行中断处理
void (*func)(unsigned long);   //指向中断处理函数
unsigned long data;            //func参数
};


//中断三大结构体 irq_desc,irqaction,irq_chip
struct irq_chip {
const char *name;
unsigned int (*irq_startup)(struct irq_data *data);
void (*irq_shutdown)(struct irq_data *data);
void (*irq_enable)(struct irq_data *data);
void (*irq_disable)(struct irq_data *data);


void (*irq_ack)(struct irq_data *data);
void (*irq_mask)(struct irq_data *data);
void (*irq_mask_ack)(struct irq_data *data);
void (*irq_unmask)(struct irq_data *data);
void (*irq_eoi)(struct irq_data *data);


int (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest, bool force);
int (*irq_retrigger)(struct irq_data *data);
int (*irq_set_type)(struct irq_data *data, unsigned int flow_type);
int (*irq_set_wake)(struct irq_data *data, unsigned int on);


void (*irq_bus_lock)(struct irq_data *data);
void (*irq_bus_sync_unlock)(struct irq_data *data);


void (*irq_cpu_online)(struct irq_data *data);
void (*irq_cpu_offline)(struct irq_data *data);


void (*irq_suspend)(struct irq_data *data);
void (*irq_resume)(struct irq_data *data);
void (*irq_pm_shutdown)(struct irq_data *data);


void (*irq_calc_mask)(struct irq_data *data);


void (*irq_print_chip)(struct irq_data *data, struct seq_file *p);
int (*irq_request_resources)(struct irq_data *data);
void (*irq_release_resources)(struct irq_data *data);


void (*irq_compose_msi_msg)(struct irq_data *data, struct msi_msg *msg);
void (*irq_write_msi_msg)(struct irq_data *data, struct msi_msg *msg);


unsigned long flags;
};
struct irq_desc {
struct irq_data irq_data;
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;
atomic_t threads_handled;
int threads_handled_last;
raw_spinlock_t lock;
struct cpumask *percpu_enabled;
#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_PM_SLEEP
unsigned int nr_actions;
unsigned int no_suspend_depth;
unsigned int force_resume_depth;
#endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
int parent_irq;
struct module *owner;
const char *name;
} ____cacheline_internodealigned_in_smp;


//将 t 添加到[高优先级]软中断描述符链表,优先得到CPU响应
void __tasklet_hi_schedule(struct tasklet_struct *t)
{
unsigned long flags;


local_irq_save(flags);
t->next = NULL;
*__this_cpu_read(tasklet_hi_vec.tail) = t;
__this_cpu_write(tasklet_hi_vec.tail,  &(t->next));
raise_softirq_irqoff(HI_SOFTIRQ);
local_irq_restore(flags);
}


//将 t 添加到[普通优先级]软中断描述符链表(不这样做,软中断服务函

数将不会得到响应)

void __tasklet_schedule(struct tasklet_struct *t)
{
unsigned long flags;


local_irq_save(flags);
t->next = NULL;
*__this_cpu_read(tasklet_vec.tail) = t;
__this_cpu_write(tasklet_vec.tail, &(t->next));
raise_softirq_irqoff(TASKLET_SOFTIRQ);
local_irq_restore(flags);
}


//irq 中断号,和中断服务函数一一对应
//disable_irq将中断深度加1,enable_irq将中断深度减1
void disable_irq(unsigned int irq);
void enable_irq(unsigned int irq);


//request_threaded_irq 中断的动态申请和注册,free_irq释放申请的中断
void free_irq(unsigned int irq,void* dev);
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          )


//设置中断irq的触发方式, type 如下
int irq_set_irq_type(unsigned int irq, unsigned int type)
{
unsigned long flags;
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
int ret = 0;


if (!desc)
return -EINVAL;


type &= IRQ_TYPE_SENSE_MASK;
ret = __irq_set_trigger(desc, irq, type);
irq_put_desc_busunlock(desc, flags);
return ret;
}
    IRQ_TYPE_NONE     = 0x00000000,//默认
IRQ_TYPE_EDGE_RISING = 0x00000001,//上升沿触发
IRQ_TYPE_EDGE_FALLING = 0x00000002,//下降沿触发
IRQ_TYPE_EDGE_BOTH     = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING),//双边沿触发
IRQ_TYPE_LEVEL_HIGH     = 0x00000004,//高电平触发
IRQ_TYPE_LEVEL_LOW     = 0x00000008,//低电平触发
IRQ_TYPE_LEVEL_MASK     = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH),//高低电平均可触发
IRQ_TYPE_SENSE_MASK     = 0x0000000f,//以上任意一种方式
IRQ_TYPE_DEFAULT     = IRQ_TYPE_SENSE_MASK,//以上任意一种方式


IRQ_TYPE_PROBE     = 0x00000010,//查询中断

猜你喜欢

转载自blog.csdn.net/dummkopfer/article/details/80482180