Linux kernel Linux操作系统中的中断管理 上下文

Linux kernel Linux操作系统中的中断管理 上下文,linux-kernel,linux-device-driver,interrupt,platform,device-tree,Linux Kernel,Linux Device Driver,Interrupt,Platform,Device Tree,我有一个设备树,其中一个节点是: gpio@41210000 { #gpio-cells = <0x2>; #interrupt-cells = <0x2>; compatible = "xlnx,xps-gpio-1.00.a,generic-uio,BTandSW"; gpio-controller; interrupt-controller; interrupt-

我有一个设备树,其中一个节点是:

    gpio@41210000 {
        #gpio-cells = <0x2>;
        #interrupt-cells = <0x2>;
        compatible = "xlnx,xps-gpio-1.00.a,generic-uio,BTandSW";
        gpio-controller;
        interrupt-controller;
        interrupt-parent = <0x4>;
        //interrupt-parent =<&gic>;
        interrupts = <0x0 0x1d 0x4>;
        reg = <0x41210000 0x10000>;
        xlnx,all-inputs = <0x1>;
        xlnx,all-inputs-2 = <0x1>;
        xlnx,all-outputs = <0x0>;
        xlnx,all-outputs-2 = <0x0>;
        xlnx,dout-default = <0x0>;
        xlnx,dout-default-2 = <0x0>;
        xlnx,gpio-width = <0x4>;
        xlnx,gpio2-width = <0x2>;
        xlnx,interrupt-present = <0x1>;
        xlnx,is-dual = <0x1>;
        xlnx,tri-default = <0xffffffff>;
        xlnx,tri-default-2 = <0xffffffff>;
    };
结果是:

root@linaro-developer:~# cat /proc/interrupts
           CPU0       CPU1
 16:          0          0     GIC-0  27 Edge      gt
 17:          0          0     GIC-0  43 Level     ttc_clockevent
 18:       1588       1064     GIC-0  29 Edge      twd
 21:         43          0     GIC-0  39 Level     f8007100.adc
 24:          0          0     GIC-0  35 Level     f800c000.ocmc
 25:        506          0     GIC-0  59 Level     xuartps
 26:          0          0     GIC-0  51 Level     e000d000.spi
 27:          0          0     GIC-0  54 Level     eth5
 28:       4444          0     GIC-0  56 Level     mmc0
 29:          0          0     GIC-0  45 Level     f8003000.dmac
 30:          0          0     GIC-0  46 Level     f8003000.dmac
 31:          0          0     GIC-0  47 Level     f8003000.dmac
 32:          0          0     GIC-0  48 Level     f8003000.dmac
 33:          0          0     GIC-0  49 Level     f8003000.dmac
 34:          0          0     GIC-0  72 Level     f8003000.dmac
 35:          0          0     GIC-0  73 Level     f8003000.dmac
 36:          0          0     GIC-0  74 Level     f8003000.dmac
 37:          0          0     GIC-0  75 Level     f8003000.dmac
 38:          0          0     GIC-0  40 Level     f8007000.devcfg
 45:          0          0     GIC-0  41 Edge      f8005000.watchdog
IPI1:          0          0  Timer broadcast interrupts
IPI2:       1731       2206  Rescheduling interrupts
IPI3:         29         36  Function call interrupts
IPI4:          0          0  CPU stop interrupts
IPI5:          0          0  IRQ work interrupts
IPI6:          0          0  completion interrupts
Err:          0
问题
  • 一旦内核运行,它是否应该自动识别并更新文件
    /proc/interrupt
    中的数据

  • 但是,我用这种方式编写了一个
    .probe
    函数:

     static int SWITCH_of_probe(struct platform_device *pdev)
    {
        int ret=0;
        struct irq_data data_tmp;
        SWITCH_01_devices->temp_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!(SWITCH_01_devices->temp_res)) {
            dev_err(&pdev->dev, "TRY could not get IO memory\n");
            return -ENXIO;
        }
    
     PDEBUG("resource : regs.start=%#x,regs.end=%#x\n",SWITCH_01_devices->temp_res->start,SWITCH_01_devices->temp_res->end);
    
     //SWITCH_01_devices->irq_line = platform_get_irq(pdev, 0);
     SWITCH_01_devices->irq_line = irq_of_parse_and_map(pdev->dev.of_node, 0);
       if (SWITCH_01_devices->irq_line < 0) {
           dev_err(&pdev->dev, "could not get IRQ\n");
         printk(KERN_ALERT "could not get IRQ\n");
           return SWITCH_01_devices->irq_line;
       }
    
     PDEBUG(" resource VIRTUAL IRQ NUMBER : irq=%#x\n",SWITCH_01_devices->irq_line);
     ret = request_irq((SWITCH_01_devices->irq_line), SWITCH_01_interrupt, IRQF_SHARED  , DRIVER_NAME, NULL);
     if (ret) {
        printk(KERN_ALERT "NEW SWITCH_01: can't get assigned irq, ret= %d\n", SWITCH_01_devices->irq_line, ret);
        SWITCH_01_devices->irq_line = -1;
    }
    
    
     SWITCH_01_devices->mem_region_requested = request_mem_region((SWITCH_01_devices->temp_res->start),resource_size(SWITCH_01_devices->temp_res),"SWITCH_01");
     if(SWITCH_01_devices->mem_region_requested == NULL){
         printk(KERN_WARNING "[LEO] SWITCH: FaiSWITCH request_mem_region(res.start,resource_size(&(SWITCH_01_devices->res)),...);\n");
     }
     else
         PDEBUG(" [+] request_mem_region\n");
    
     return 0; /* Success */
     }
    
    我做错了什么?为什么我不能执行正确的请求\u irq

    注意:设备树的
    中断=
    字段和检测到的irq\U编号不同。正如所指出的,我改变了
    platform\u get\u irq(pdev,0)带有
    irq\u的\u解析和\u映射(pdev->dev.of\u节点,0)但结果是相同的

    一旦内核运行,它应该自动识别并 是否更新文件/proc/interrupt中的数据

    是,一旦中断被注册,它将更新

    [ 1249.777189] SWITCH_01: loading out-of-tree module taints kernel.
    [ 1249.777787] [LEO] SWITCH_01: dinamic allocation of major number
    [ 1249.777801] [LEO]  cdev initialized
    [ 1249.777988] [LEO] resource : regs.start=0x41210000,regs.end=0x4121ffff
    [ 1249.777994] [LEO]  resource : irq=0x2e
    [ 1249.778000] NEW SWITCH_01: can't get assigned irq, ret= -22
    [ 1249.782531] [LEO]  [+] request_mem_region
    
    我做错了什么?为什么我不能执行正确的请求\u irq


    共享中断(
    IRQF_shared
    )必须传递dev_id(在
    request_irq()
    中传递NULL),如果
    NULL
    ,则返回
    -EINVAL
    ,因此确保传递非NULL有效dev_id

    确保这是问题之一,我将按照您的建议解决它。我将在尝试修复该错误后立即更新该问题
    [ 1249.777189] SWITCH_01: loading out-of-tree module taints kernel.
    [ 1249.777787] [LEO] SWITCH_01: dinamic allocation of major number
    [ 1249.777801] [LEO]  cdev initialized
    [ 1249.777988] [LEO] resource : regs.start=0x41210000,regs.end=0x4121ffff
    [ 1249.777994] [LEO]  resource : irq=0x2e
    [ 1249.778000] NEW SWITCH_01: can't get assigned irq, ret= -22
    [ 1249.782531] [LEO]  [+] request_mem_region
    
    [ 1249.777189] SWITCH_01: loading out-of-tree module taints kernel.
    [ 1249.777787] [LEO] SWITCH_01: dinamic allocation of major number
    [ 1249.777801] [LEO]  cdev initialized
    [ 1249.777988] [LEO] resource : regs.start=0x41210000,regs.end=0x4121ffff
    [ 1249.777994] [LEO]  resource : irq=0x2e
    [ 1249.778000] NEW SWITCH_01: can't get assigned irq, ret= -22
    [ 1249.782531] [LEO]  [+] request_mem_region