【问题标题】:Getting Linux IRQ number from hardware IRQ number从硬件 IRQ 号获取 Linux IRQ 号
【发布时间】:2019-01-09 06:27:55
【问题描述】:

我有一个 GPIO 外设,在设备树中定义如下:

gpio0: gpio@2300000 
{
    compatible = "fsl,qoriq-gpio";
    reg = <0x0 0x2300000 0x0 0x10000>;
    interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
    gpio-controller;
    #gpio-cells = <2>;
    interrupt-controller;
    #interrupt-cells = <2>;
};

我想为此编写一个中断处理程序(作为内核模块)。但是这个 IRQ 号 (66) 是一个硬件号,我需要一个虚拟的 Linux IRQ 号才能将它传递给request_irq

我怎样才能得到这个数字?只有一个中断控制器(GIC)。

有没有办法在不编写平台设备驱动程序的情况下做到这一点(因为系统中可能已经有一个在工作,我想我无法注册另一个)。

【问题讨论】:

  • 你想在这里达到什么目的?您是在尝试将 GPIO 转换为中断还是什么?
  • 作者问如何从hw irq获取linux virtual irq
  • 是的,我基本上是在 GPIO 引脚更改状态时尝试注册(请求)一个中断处理程序。

标签: linux linux-kernel driver linux-device-driver device


【解决方案1】:

根据您的评论,您希望将 GPIO 注册为中断。 您发布的设备树节点是中断控制器节点,它不会与我们手头的任务有关。

要将 gpio 注册为中断,您首先需要找到一个可以配置为中断的 GPIO(在大多数现代处理器中,所有 GPIO 都支持它),然后您必须确保它没有被其他设备使用通过多路复用它(如果它被 SPI 或 UART 等使用,如果您不使用该实体,则可以从设备树中禁用它们)。

现在您有了一个可以使用的 GPIO 引脚。在内核上找到该引脚对应的 GPIO 编号(这取决于您的处理器及其载板的架构)。

当你拥有它时,你可以编写一个简单的模块来导出你的 GPIO 并将其用作中断。

下面是来自http://derekmolloy.ie的sn-p

gpio_request(gpioButton, "sysfs");       // Set up the gpioButton
gpio_direction_input(gpioButton);        // Set the button GPIO to be an input
gpio_set_debounce(gpioButton, 200);      // Debounce the button with a delay of 200ms
gpio_export(gpioButton, false);          // Causes gpio115 to appear in /sys/class/gpio
                  // the bool argument prevents the direction from being changed
// Perform a quick test to see that the button is working as expected on LKM load
printk(KERN_INFO "GPIO_TEST: The button state is currently: %d\n", gpio_get_value(gpioButton));

// GPIO numbers and IRQ numbers are not the same! This function performs the mapping for us
irqNumber = gpio_to_irq(gpioButton);
printk(KERN_INFO "GPIO_TEST: The button is mapped to IRQ: %d\n", irqNumber);

// This next call requests an interrupt line
result = request_irq(irqNumber,             // The interrupt number requested
                    (irq_handler_t) ebbgpio_irq_handler, // The pointer to the handler function below
                    IRQF_TRIGGER_RISING,   // Interrupt on rising edge (button press, not release)
                    "ebb_gpio_handler",    // Used in /proc/interrupts to identify the owner
                    NULL);                 // The *dev_id for shared interrupt lines, NULL is okay

Link 到完整的代码。

【讨论】:

  • 太棒了!我不知道这种方法。我认为它使我免于编写自己的平台驱动程序或修改现有的驱动程序...注意如何查找 GPIO 编号:您 cd /sys/class/gpio 然后列出内容。例如,我有一个目录gpiochip480,进入它。然后在里面,cat base 给了我 480 号 - 端口的开头。所以我必须传递给gpio_request 的 GPIO 编号是 502,因为我在 SoC 上的 GPIO 引脚名称是 GPIO1_22(第一个端口的第 22 个引脚),而 480 + 22 是 502。
  • 在gpio类下,你会找到多个gpiochipxxx(同样取决于平台),在那个目录下你会找到该芯片控制的gpio数量和起始号(通常与gpiochipxxx相同,xxx将是起始编号)。当您导出该 gpio 例如引脚号 xxx+1 时,它将由该芯片控制。现在您必须找出哪些芯片支持gpio上的中断。数据表和原理图是您的朋友。
  • 是的,是的,我就是这么做的。我添加了这条评论以帮助其他可能阅读这篇文章的人,了解如何在 Linux 中找到您的 GPIO 引脚号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
相关资源
最近更新 更多