Re: gpio-omap: Edge interrupts stall

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Mar 22, 2017 at 10:17:14AM -0700, Tony Lindgren wrote:
> Another good code review catch by Grygorii! :)
> 
> Can you guys please add a comment there to the code when posting the
> proper patch? Something like:
> 
> /*
>  * Edge GPIOs are already cleared during handling, clearing
>  * them here again will cause lost interrupts.
>  */

Just a though, as we are acking edge irq in demux handler
handle_simple_irq should do the job as well.

> And also add a proper Fixes tag so this gets propagated to the
> stable kernels. It really seems we've had this for a long time.

Well, it makes things better, but it is not good enough, yet...
Bellow is a little test code - I'm feeding gpio159 from signal
generator and expecting to see nearly the same on gpio161.
Now, if you connect speaker to output gpio, you do not even
need a scope and you can easily debug with your ears.

	ladis

    _       ,/'
   (_).  ,/'
   __  ::
  (__)'  `\.
            `\.

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/irq.h>

struct gpio_test_dev {
	int gpio_in;
	int gpio_out;
};

static struct gpio_test_dev dev;

static irqreturn_t gpio_irq(int irq, void *dev_id)
{
	struct gpio_test_dev *gpio_dev = dev_id;
	int val;

	val = gpio_get_value(gpio_dev->gpio_in);
	if (val < 0)
		goto err_get_value;

	gpio_set_value(gpio_dev->gpio_out, val);

err_get_value:
	return IRQ_HANDLED;
}

static int __init gpio_test_init(void)
{
	int rc;

	dev.gpio_in = 159;
	dev.gpio_out = 161;

	rc = gpio_request(dev.gpio_in, "gpio-in");
	if (rc < 0)
		goto err;
	rc  = gpio_direction_input(dev.gpio_in);
	if (rc < 0)
		goto err_free_input;

	rc = gpio_request(dev.gpio_out, "gpio-out");
	if (rc < 0)
		goto err_free_input;
	rc  = gpio_direction_output(dev.gpio_out, 0);
	if (rc < 0)
		goto err_free_output;

	rc = request_irq(gpio_to_irq(dev.gpio_in), gpio_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"gpio-irq", &dev);
	if (rc < 0)
		goto err_free_output;

	return 0;

err_free_output:
	gpio_free(dev.gpio_out);
err_free_input:
	gpio_free(dev.gpio_in);
err:
	return rc;
}

static void __exit gpio_test_exit(void)
{
	free_irq(gpio_to_irq(dev.gpio_in), &dev);
	gpio_free(dev.gpio_in);
	gpio_free(dev.gpio_out);
}

module_init(gpio_test_init);
module_exit(gpio_test_exit);

MODULE_DESCRIPTION("GPIO interrupt test driver");
MODULE_LICENSE("GPL v2");
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux