我查了GPIO的sysfs,只支持配置方向(in、out)、active_level、edge。
我没有看到它支持在 GPIO 和中断之间更改模式。有你认识的吗?或者有什么建议吗
示例: 某些 GPIO 可以支持 GPIO 或 IRQ。所以我想通过 sysfs 在 Linux 下更改它的模式。
提前致谢。
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;
}
按照惯例,GPIO 驱动程序(GPIO 芯片)也提供中断。因此,这个组合驱动程序同时利用两个子系统:gpio和irq。 通常 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);