kernelinterruptgpioirq

How to provide interrupt generating GPIOs from a kernel module


I've written a (working) kernel module which uses returns a struct gpio_chip instance to specify how reads and writes (using the module-provided GPIOs) should be handled.

static struct gpio_chip template_chip = {
        .label                  = "my_module",
        .owner                  = THIS_MODULE,
        .get_direction          = my_module_gpio_get_direction,
        .direction_input        = my_module_gpio_direction_in,
        .get                    = my_module_gpio_get,
        .direction_output       = my_module_gpio_direction_out,
        .set                    = my_module_gpio_set,
        .to_irq                 = my_module_gpio_to_irq,
        .can_sleep              = true,
};

static int my_module_gpio_probe(struct platform_device *pdev)
{
        struct my_module *my_module = dev_get_drvdata(pdev->dev.parent);
        struct my_module_platform_data *pdata = dev_get_platdata(my_module->dev);
        struct my_module_gpio_data *my_module_gpio;
        int ret;

        printk(KERN_INFO "my_module_gpio_probe\n");

        my_module_gpio = devm_kzalloc(&pdev->dev, sizeof(*my_module_gpio), GFP_KERNEL);
        if (my_module_gpio == NULL)
                return -ENOMEM;

        my_module_gpio->my_module = my_module;
        my_module_gpio->gpio_chip = template_chip;
        my_module_gpio->gpio_chip.ngpio = NUM_GPIOS;
        my_module_gpio->gpio_chip.parent = &pdev->dev;
        ...

I now want my (software generated) GPIOs to be able to produce an interrupt when my module changes the GPIO values.

I want to support both the old /sys/class/gpio interface and the new chardev interface.

While googling, I've found lots of examples of how to consume interrupts in a kernel module.

What do I need to do to produce interrupts for my module's GPIOs?


Solution

  • In order to test GPIO library inside the kernel the gpio-sim module has been created which emulates what regular GPIO chip can do, including interrupt generation.

    The code responsible for that is located in the gpio_sim_apply_pull(). Don't look at the function name, because it just applies the full state of the artificial line.

    Note, that in the older kernels the gpio-mockup driver is present for the similar purposes.