linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Grygorii Strashko <grygorii.strashko@ti.com>
To: Linus Walleij <linus.walleij@linaro.org>,
	Alexandre Courbot <gnurou@gmail.com>
Cc: Sekhar Nori <nsekhar@ti.com>,
	linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
	Grygorii Strashko <grygorii.strashko@ti.com>,
	Geert Uytterhoeven <geert+renesas@glider.be>
Subject: [PATCH v2] gpio: pcf857x: handle only enabled irqs
Date: Thu, 11 Jun 2015 00:01:09 +0300	[thread overview]
Message-ID: <1433970069-30235-1-git-send-email-grygorii.strashko@ti.com> (raw)

Now pcf857x_irq() IRQ's dispatcher will try to run nested
IRQ handlers for each GPIO pin which state has changed.
Such IRQs are, actually, spurious and nested IRQ handlers
have to be called only for IRQs wich were enabled by users.
This is not critical issue - just  /proc/interrupts
will display counters for unused IRQS:
399:          4          0   pcf857x   0 Edge
428:          1          0   pcf857x  13 Edge
430:          1          0   pcf857x  15 Edge

Hence, fix it by adding irq_enabled field in struct pcf857x to track
enabled GPIO IRQs and corresponding callbacks in pcf857x_irq_chip.

Similar functionality was presented in pcf857x driver, commit
21fd3cd1874a ('gpio: pcf857x: call the gpio user handler iff...')

and then it was removed by commit
 a39294bdf4b0 ('gpio: pcf857x: Switch to use gpiolib irqchip...')

Cc: Geert Uytterhoeven <geert+renesas@glider.be>

Fixes: a39294bdf4b0 ('gpio: pcf857x: Switch to use gpiolib irqchip helpers')
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---

No functional changes.
It's just rebased on top of "devel" branch
git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git

 drivers/gpio/gpio-pcf857x.c | 46 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
index 83db0e1..404f3c6 100644
--- a/drivers/gpio/gpio-pcf857x.c
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -92,6 +92,7 @@ struct pcf857x {
 	unsigned		out;		/* software latch */
 	unsigned		status;		/* current status */
 	unsigned int		irq_parent;
+	unsigned		irq_enabled;	/* enabled irqs */
 
 	int (*write)(struct i2c_client *client, unsigned data);
 	int (*read)(struct i2c_client *client);
@@ -195,7 +196,7 @@ static irqreturn_t pcf857x_irq(int irq, void *data)
 	 * interrupt source, just to avoid bad irqs
 	 */
 
-	change = (gpio->status ^ status);
+	change = (gpio->status ^ status) & gpio->irq_enabled;
 	for_each_set_bit(i, &change, gpio->chip.ngpio)
 		handle_nested_irq(irq_find_mapping(gpio->chip.irqdomain, i));
 	gpio->status = status;
@@ -210,14 +211,10 @@ static irqreturn_t pcf857x_irq(int irq, void *data)
  */
 static void noop(struct irq_data *data) { }
 
-static unsigned int noop_ret(struct irq_data *data)
-{
-	return 0;
-}
-
 static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on)
 {
 	struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
+
 	int error = 0;
 
 	if (gpio->irq_parent) {
@@ -229,20 +226,47 @@ static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on)
 			gpio->irq_parent = 0;
 		}
 	}
-
 	return error;
 }
 
+static void pcf857x_irq_enable(struct irq_data *data)
+{
+	struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
+
+	gpio->irq_enabled |= (1 << data->hwirq);
+}
+
+static void pcf857x_irq_disable(struct irq_data *data)
+{
+	struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
+
+	gpio->irq_enabled &= ~(1 << data->hwirq);
+}
+
+static void pcf857x_irq_bus_lock(struct irq_data *data)
+{
+	struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&gpio->lock);
+}
+
+static void pcf857x_irq_bus_sync_unlock(struct irq_data *data)
+{
+	struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
+
+	mutex_unlock(&gpio->lock);
+}
+
 static struct irq_chip pcf857x_irq_chip = {
 	.name		= "pcf857x",
-	.irq_startup	= noop_ret,
-	.irq_shutdown	= noop,
-	.irq_enable	= noop,
-	.irq_disable	= noop,
+	.irq_enable	= pcf857x_irq_enable,
+	.irq_disable	= pcf857x_irq_disable,
 	.irq_ack	= noop,
 	.irq_mask	= noop,
 	.irq_unmask	= noop,
 	.irq_set_wake	= pcf857x_irq_set_wake,
+	.irq_bus_lock		= pcf857x_irq_bus_lock,
+	.irq_bus_sync_unlock	= pcf857x_irq_bus_sync_unlock,
 };
 
 /*-------------------------------------------------------------------------*/
-- 
1.9.1


             reply	other threads:[~2015-06-10 21:01 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-10 21:01 Grygorii Strashko [this message]
2015-06-16  8:58 ` [PATCH v2] gpio: pcf857x: handle only enabled irqs Linus Walleij
2015-06-16  9:06   ` Geert Uytterhoeven
2015-06-16 10:52     ` Grygorii Strashko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1433970069-30235-1-git-send-email-grygorii.strashko@ti.com \
    --to=grygorii.strashko@ti.com \
    --cc=geert+renesas@glider.be \
    --cc=gnurou@gmail.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nsekhar@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).