Hi,
It is possible to write a GPIO interrupt handle code in user space?
for example: when the GPIO change state, execute a function in user space without using while loop to check the GPIO pin status.
Thanks & Regards
Keldy
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
It is possible to write a GPIO interrupt handle code in user space?
for example: when the GPIO change state, execute a function in user space without using while loop to check the GPIO pin status.
Thanks & Regards
Keldy
Interrupt handling was added to the GPIO sysfs interface around 2.6.32. I think. Check you kernel source in Documentation/gpio.txt to see if your version supports interrupt handling and for general info on how to use the GPIO sysfs interface.
The interrupt handling used poll(). Strictly speaking, it does not use a callback mode. You will have to setup a thread, block on poil(), call your function when unblocked. Poll might sound like a loop but it shouldn't be. It is supposed to be waiting for a real interrupt.
Note that userspace interrupt handling appears to be for human interface as it cannot really handle quickly changing signals, ie faster than 10ms. Some people on this forum have tried with limited success.
You can use Real Time signals for this purpose.
Generate a signal from kernel space and wait for that signal at usespace.
Regards,
Krunal
I am assuming you want to write your own kernel driver. The GPIO driver is a kernel code with a user space interface on top of that. The user space code is in gpiolib.c. The kernel code is platform dependent and tends to be all over the place. The kernel GPIO code does not handle interrupts directly. The generic IRQ driver is used. A lot of drivers use gpio interrupts. Search for gpio_to_irq() call with a subsequent request_any_context_irq() or request_irq() call.
Thanks for your response.
Correct, I am looking forward to create a kernel driver exposing an interrupt capability which originally comes from FPGA connected to one of CPU GPIO pins (irq-capable).
Found something in some example in 2.6.37 in linux/arch/arm/mach-omap1/fpga.c
gpio_request(13, "FPGA irq");
gpio_direction_input(13);
set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
and then implement the cb, of course ... can I just use request_irq on 13?
Do I need to define something else, saw that there is reference to static struct irq_chip, not sure if this is also a part of story.?
Also not sure about the OMAP1510_INT_FPGA number that is passed to set_irq_chained_handler, how should it be defined?
Yakir
Sorry I can't help you. My experience has been usually with request_irq(). Quite likely the set_irq_*() functions probably do that same things. You could try using gpio_to_irq(13) for OMAP1510_INT_FPGA. That's all I got.
Thanks, Norman. Cheers!
Anyway, maybe someone can have a look (??), still have a problem of hanging due to request_irq() call in the driver, during its insmod.
Well, I think it hangs because of the interrupt not being defined "correctly" on the board. I don't have the real interrupt connected yet but I still expect it to be seen after its defined. My definitions of the board file were guided another example from OMAP2, initiating irq for smsc911x:
#define GPIO_FPGA_INTR 78
#define FPGA_START_ADDRESS 0x1000000
static struct resource am3517_fpga_mmx_resources[] = {
[0] = {
.start = FPGA_START_ADDRESS,
.end = FPGA_START_ADDRESS + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = OMAP_GPIO_IRQ(GPIO_FPGA_INTR),
.end = OMAP_GPIO_IRQ(GPIO_FPGA_INTR),
.flags = (IORESOURCE_IRQ | IRQF_TRIGGER_LOW | IRQF_SHARED),
},
};
static struct platform_device am3517_fpga_mmx_device = {
.name = "fpga_mmx",
.id = -1,
.num_resources = ARRAY_SIZE(am3517_fpga_mmx_resources),
.resource = &am3517_fpga_mmx_resources[0],
};
Well, there is no 0x1000000 on my system yet but the GPIO for the [1] is there.
At the evm_init() I call for:
/* FPGA Dev Test */
omap_mux_init_gpio(GPIO_FPGA_INTR, OMAP_PIN_INPUT_PULLUP);
r = gpio_request(GPIO_FPGA_INTR, "fpga_mmx_irq");
if (r < 0)
{
printk("failed to request GPIO # %d\n", GPIO_FPGA_INTR);
return;
}
gpio_direction_input(GPIO_FPGA_INTR);
gpio_export(GPIO_FPGA_INTR, 1);
set_irq_type(gpio_to_irq(GPIO_FPGA_INTR), IRQ_TYPE_LEVEL_LOW);
platform_device_register(&am3517_fpga_mmx_device);
On the driver side I am loading the fpga driver first which is a platform driver calling -> platform_driver_register(&fpga_driver); with same name "fpga_mmx"
But even that is not enough for the GPIO pin to be defined as interrupt, looking on this bank in debugfs I got that:
GPIOs 64-95, gpio:
gpio-65 (tsc2004-irq ) in hi irq-225 edge-falling
gpio-78 (fpga_mmx_irq ) in lo
Am I missing something?