linux中requst_irq函数参数中的中断号问题

Posted 云鹤比天

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux中requst_irq函数参数中的中断号问题相关的知识,希望对你有一定的参考价值。

坑位:

  硬件同事给了我一个bit,告述我说spi-contrler的中断号是89,让我验一下这个spi-controler是否能用。经过三天,读写功能都测试通过了,但中断就是没法进。我是这样蠢干蛮干的:

requst_irq(89,spi_int_hander, IRQ_TRIGER_RISING, NULL, NULL);

  后来问了我导师,他说这个函数里的参数不能直接传硬件中断号,得从设备树获取,获取时核心层函数做了映射将中断号数组中对应的索引作为此函数的参数。得此点拨,如醍醐灌顶,令我拨云见日茅塞顿开。

 

正解:

设备树中:

interrupt-parent = <&intc>;
interrupt = <0 57 1>;  //共享中断,57+32=89, 触发方式:上升沿。设备树中共享中断要减32,私有中断要减16  

  

驱动代码中:

void spi_controler_init(void)
{
    int id,version;
    writel(0, SSIENR);
    writel(10, BAUDR);
    writel(1, TXFTLR);
    writel(1, RXFTLR);
    writel(0x11, IMR);
    writel(0x4C7, CTRLR0);
    writel(0x02, CTRLR1);
    id = readl(IDR);
    version = readl(SSI_COMP_VERSION);
    printk("ID= %#x, version= %#x \n", id, version);
}
int irq;
static int rf9808_probe(struct platform_device *dev)
{
    struct device_node *node;
    node = of_find_compatible_node(NULL,NULL,"sysnopsys,spi-pl");
//	spi_base_addr = ioremap(SSI_BASE_ADDR, 0xff);
//	en_swich_addr = ioremap(0x4001001C, 4);
    spi_base_addr = of_iomap(node, 0);
    en_swich_addr = of_iomap(node, 1);
    irq = of_irq_get(node,0);
    printk("irq= %d \n", irq);
    misc_dev = kzalloc(sizeof(*misc_dev), GFP_KERNEL);
    misc_dev->fops = &miscdev_fops;
    misc_dev->name = "rf9808-test";
    //主设备号恒为10,自动分配次设备号
    misc_dev->minor = MISC_DYNAMIC_MINOR;
    //3.注册misc设备
    misc_register(misc_dev);
    if(request_irq(irq,spiint_irq_handler, 0,
        "rf9808-test" , misc_dev->this_device) )
    {
        printk(KERN_DEBUG "requst irq failled \n");
    }
    spi_controler_init();
    return 0;
}
static int rf9808_remove(struct platform_device *dev)
{
    iounmap(spi_base_addr);
    iounmap(en_swich_addr);
    free_irq(irq,misc_dev->this_device);
    misc_deregister(misc_dev);
    kfree(misc_dev);
    return 0;
}
struct of_device_id dts_table[] = {
    {.compatible = "sysnopsys,spi-pl"},
    {},
};
struct platform_driver spi_pl = {
    .probe = rf9808_probe,
    .remove = rf9808_remove,
    .driver = {
        .name = "rf9808_test_driver",
        .of_match_table = dts_table,
    },
};
static int __init test_rf9808_init(void)
{
    platform_driver_register(&spi_pl);
    return 0;
}
/**
 * nufront_cap_cleanup - Driver un-registration call
 */
static void __exit test_rf9808_cleanup(void)
{
    platform_driver_unregister(&spi_pl);
}
module_init(test_rf9808_init);
module_exit(test_rf9808_cleanup);
MODULE_AUTHOR("Nufront,Inc.");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:rf9808");

  

 

使用of_irq_get()函数从设备树中取到中断号,然后再request_irq()。

 

 

 

以上是关于linux中requst_irq函数参数中的中断号问题的主要内容,如果未能解决你的问题,请参考以下文章

求 Linux 内核中断 INT 80H 详细资料

5.2 Linux中断注册

Linux中断处理流程

Linux内核中断之获取中断号

Linux内核中断之获取中断号

Linux内核中的软中断tasklet和工作队列具体解释