GPIO Linux 框架是否支持在 GPIO 和 IRQ 之间切换模式

问题描述 投票:0回答:2

我查了GPIO的sysfs,只支持配置方向(in、out)、active_level、edge。

我没有看到它支持在 GPIO 和中断之间更改模式。有你认识的吗?或者有什么建议吗

示例: 某些 GPIO 可以支持 GPIO 或 IRQ。所以我想通过 sysfs 在 Linux 下更改它的模式。

提前致谢。

linux-device-driver embedded-linux interrupt gpio
2个回答
1
投票

GPIO 控制器(以及驱动程序)将提供该支持(如果有)。在这种情况下,GPIO 控制器被注册为中断控制器。有很多例子,比如 gpio-intel-mid.c 你有:

    retval = gpiochip_irqchip_add(&priv->chip,
                                  &intel_mid_irqchip,
                                  irq_base,
                                  handle_simple_irq,
                                  IRQ_TYPE_NONE);
    if (retval) {
            dev_err(&pdev->dev,
                    "could not connect irqchip to gpiochip\n");
            return retval;
    }

0
投票

按照惯例,GPIO 驱动程序(GPIO 芯片)也提供中断。因此,这个组合驱动程序同时利用两个子系统:gpioirq。 通常 GPIO 控制器也将充当辅助(子)中断控制器:

按照惯例,GPIO 驱动程序(GPIO 芯片)也提供中断,通常从父中断控制器级联

GPIO 驱动程序最重要的两个结构是

struct gpio_irq_chip
内的
struct gpio_chip
。在将
gpio_irq_chip
结构添加到内核之前,将 struct
gpio_chip
填充到 struct
gpio_chip
中。

设置助手的首选方法是在添加 gpio_chip 之前将 struct gpio_irq_chip 填充到 struct gpio_chip 中。如果这样做,gpiolib 将在设置其余 GPIO 功能的同时设置附加的 irq_chip。以下是使用 gpio_irq_chip 的链式级联中断处理程序的典型示例

gpio_irq_chip
内部,您可以定义用于确认、混合和取消屏蔽 GPIO 中断的回调。

/* Typical state container */
struct my_gpio {
    struct gpio_chip gc;
};

static void my_gpio_mask_irq(struct irq_data *d)
{
    struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    irq_hw_number_t hwirq = irqd_to_hwirq(d);

    /*
     * Perform any necessary action to mask the interrupt,
     * and then call into the core code to synchronise the
     * state.
     */

    gpiochip_disable_irq(gc, hwirq);
}

static void my_gpio_unmask_irq(struct irq_data *d)
{
    struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    irq_hw_number_t hwirq = irqd_to_hwirq(d);

    gpiochip_enable_irq(gc, hwirq);

    /*
     * Perform any necessary action to unmask the interrupt,
     * after having called into the core code to synchronise
     * the state.
     */
}

/*
 * Statically populate the irqchip. Note that it is made const
 * (further indicated by the IRQCHIP_IMMUTABLE flag), and that
 * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra
 * callbacks to the structure.
 */
static const struct irq_chip my_gpio_irq_chip = {
    .name             = "my_gpio_irq",
    .irq_ack          = my_gpio_ack_irq,
    .irq_mask         = my_gpio_mask_irq,
    .irq_unmask       = my_gpio_unmask_irq,
    .irq_set_type     = my_gpio_set_irq_type,
    .flags            = IRQCHIP_IMMUTABLE,
    /* Provide the gpio resource callbacks */
    GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

int irq; /* from platform etc */
struct my_gpio *g;
struct gpio_irq_chip *girq;

/* Get a pointer to the gpio_irq_chip */
girq = &g->gc.irq;
gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip);
girq->parent_handler = ftgpio_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
                             GFP_KERNEL);
if (!girq->parents)
    return -ENOMEM;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
girq->parents[0] = irq;

return devm_gpiochip_add_data(dev, &g->gc, g);
© www.soinside.com 2019 - 2024. All rights reserved.