Chinaunix首页 | 论坛 | 博客
  • 博客访问: 312523
  • 博文数量: 101
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 774
  • 用 户 组: 普通用户
  • 注册时间: 2018-10-15 14:13
个人简介

搭建一个和linux开发者知识共享和学习的平台

文章分类

全部博文(101)

文章存档

2024年(15)

2023年(24)

2022年(27)

2019年(8)

2018年(27)

分类: LINUX

2022-09-06 15:34:37

int generic_handle_irq(unsigned int irq)
{
    struct irq_desc *desc = irq_to_desc(irq);

     if (!desc)
        return -EINVAL;
    generic_handle_irq_desc(irq, desc);
    return 0;
}
    该函数通过软中断号来索引数组irq_desc,得到一个struct irq_desc类型的指针变量desc,然后调用其成员函数handle_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),
    }
};

int __init early_irq_init(void)
{
    int count, i, node = first_online_node;
    struct irq_desc *desc;

    init_irq_default_affinity();
    printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);

    desc = irq_desc;
    count = ARRAY_SIZE(irq_desc);
     for (i = 0; i < count; i++)
    {
         desc[i].kstat_irqs = alloc_percpu(unsigned int);
         alloc_masks(&desc[i], GFP_KERNEL, node);
         raw_spin_lock_init(&desc[i].lock);
         lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
         desc_set_defaults(i, &desc[i], node, NULL);
    }
    return arch_early_irq_init();
}
    linux操作系统在系统初始化期间通过调用early_irq_init函数来初始化irq_desc数组。

struct irq_data
{
    u32 mask;
    unsigned int irq;
    unsigned long hwirq;
    unsigned int node;
    unsigned int state_use_accessors;
    struct irq_chip *chip;
    struct irq_domain *domain;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
    struct irq_data *parent_data;
#endif
    void *handler_data;
    void *chip_data;
    struct msi_desc *msi_desc;
    cpumask_var_t affinity;
};
    结构体成员的irq表示软中断号,chip表示当前中断来自的PIC,linux通过封装在struct irq_data中的chip来屏蔽各种不同硬件平台上PIC的差异,给上层的软件提供统一的对PIC操作的接口。利用PIC中封装的函数,可以屏蔽或启用当前中断,设定外部设备中断触发电信号的类型。

    irq_desc中的action是针对某一具体设备的中断处理的抽象。设备驱动程序会通过request_irq来向其中挂载设备特定的中断处理函数。从通用中断处理函数发起的对某一中断处理,实际上被分成了两个层次,第一层是handle_irq函数,它与软中断号irq一一对应,代表了对IRQ line上的处理动作,而action则代表与具体设备相关的中断处理,也是设备驱动程序开发者要直接与之打交道的对象,通过action成员,可以在一条IRQ line上挂载多个设备。


阅读(718) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~