一些内核中断API (2)

//卸载IRQ链表中与输入参数相对应的 irqaction 描述符
void remove_irq(unsigned int irq, struct irqaction *act)
{
struct irq_desc *desc = irq_to_desc(irq);


if (desc && !WARN_ON(irq_settings_is_per_cpu_devid(desc)))
    __free_irq(irq, act->dev_id);
}


//动态申请及注册一个中断(动态创建一个irqaction描述符,把该描述

//符加入到IRQ链表中)

//0-创建成功  -16-中断号被占用
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);
}
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;


if ((irqflags & IRQF_SHARED) && !dev_id)
return -EINVAL;


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


if (!irq_settings_can_request(desc) ||
    WARN_ON(irq_settings_is_per_cpu_devid(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)) {
unsigned long flags;


disable_irq(irq);
local_irq_save(flags);


handler(irq, dev_id);


local_irq_restore(flags);
enable_irq(irq);
}
#endif
return retval;
}


//将一个中断描述符加入到IRQ链表中

int setup_irq(unsigned int irq, struct irqaction *act)
{
int retval;
struct irq_desc *desc = irq_to_desc(irq);


if (WARN_ON(irq_settings_is_per_cpu_devid(desc)))
return -EINVAL;
chip_bus_lock(desc);
retval = __setup_irq(irq, desc, act);
chip_bus_sync_unlock(desc);


return retval;
}


//将 tasklet_struct 的count字段加1,使软中断睡眠,不能响应对应的

//中断

//tasklet_enable相反
static inline void tasklet_disable(struct tasklet_struct *t)
{
tasklet_disable_nosync(t);
tasklet_unlock_wait(t);
smp_mb();
}
static inline void tasklet_enable(struct tasklet_struct *t)
{
smp_mb__before_atomic();
atomic_dec(&t->count);
}


//初始化一个 struct tasklet_struct 软中断结构体变量,将其 state 和 

//count 字段都清零

void tasklet_init(struct tasklet_struct *t   ,
          void (*func)(unsigned long), unsigned long data)
{
t->next = NULL;
t->state = 0;
atomic_set(&t->count, 0);
t->func = func;
t->data = data;
}


//阻塞当前进程,等待中断处理函数的执行完毕(yield)
void tasklet_kill(struct tasklet_struct *t)
{
if (in_interrupt())
pr_notice("Attempt to kill tasklet from interrupt\n");


while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
do {
yield();
} while (test_bit(TASKLET_STATE_SCHED, &t->state));
}
tasklet_unlock_wait(t);
clear_bit(TASKLET_STATE_SCHED, &t->state);
}

猜你喜欢

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