All of lore.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Russell King <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: hpa@zytor.com, gnurou@gmail.com, rmk+kernel@arm.linux.org.uk,
	tglx@linutronix.de, jason@lakedaemon.net,
	linus.walleij@linaro.org, thierry.reding@gmail.com,
	ulli.kroll@googlemail.com, lee.jones@linaro.org,
	linux-kernel@vger.kernel.org, mingo@kernel.org
Subject: [tip:irq/core] irq: Add irq_set_chained_handler_and_data()
Date: Thu, 18 Jun 2015 05:06:30 -0700	[thread overview]
Message-ID: <tip-3b0f95be143bea1aa47beb20134ef82e4e4068dc@git.kernel.org> (raw)
In-Reply-To: <E1Z4yzs-0002Rw-4B@rmk-PC.arm.linux.org.uk>

Commit-ID:  3b0f95be143bea1aa47beb20134ef82e4e4068dc
Gitweb:     http://git.kernel.org/tip/3b0f95be143bea1aa47beb20134ef82e4e4068dc
Author:     Russell King <rmk+kernel@arm.linux.org.uk>
AuthorDate: Tue, 16 Jun 2015 23:06:20 +0100
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 18 Jun 2015 14:03:08 +0200

irq: Add irq_set_chained_handler_and_data()

Driver authors seem to get the ordering of irq_set_chained_handler()
and irq_set_handler_data() wrong - ordering the former before the
latter.  This opens a race window where, if there is an interrupt
pending, the handler will be called between these two calls,
potentially resulting in an oops.

Provide a single interface to set both of these together, especially
as that's commonly what is required.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Hans Ulli Kroll <ulli.kroll@googlemail.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/E1Z4yzs-0002Rw-4B@rmk-PC.arm.linux.org.uk
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/irq.h |  9 +++++++++
 kernel/irq/chip.c   | 45 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index de3213d..42861d2 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -525,6 +525,15 @@ irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle)
 	__irq_set_handler(irq, handle, 1, NULL);
 }
 
+/*
+ * Set a highlevel chained flow handler and its data for a given IRQ.
+ * (a chained handler is automatically enabled and set to
+ *  IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
+ */
+void
+irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
+				 void *data);
+
 void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
 
 static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 330fc79..27f4332 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -719,15 +719,9 @@ void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc)
 }
 
 void
-__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
-		  const char *name)
+__irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
+		     int is_chained, const char *name)
 {
-	unsigned long flags;
-	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
-
-	if (!desc)
-		return;
-
 	if (!handle) {
 		handle = handle_bad_irq;
 	} else {
@@ -749,13 +743,13 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 			 * right away.
 			 */
 			if (WARN_ON(is_chained))
-				goto out;
+				return;
 			/* Try the parent */
 			irq_data = irq_data->parent_data;
 		}
 #endif
 		if (WARN_ON(!irq_data || irq_data->chip == &no_irq_chip))
-			goto out;
+			return;
 	}
 
 	/* Uninstall? */
@@ -774,12 +768,41 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 		irq_settings_set_nothread(desc);
 		irq_startup(desc, true);
 	}
-out:
+}
+
+void
+__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
+		  const char *name)
+{
+	unsigned long flags;
+	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
+
+	if (!desc)
+		return;
+
+	__irq_do_set_handler(desc, handle, is_chained, name);
 	irq_put_desc_busunlock(desc, flags);
 }
 EXPORT_SYMBOL_GPL(__irq_set_handler);
 
 void
+irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
+				 void *data)
+{
+	unsigned long flags;
+	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
+
+	if (!desc)
+		return;
+
+	__irq_do_set_handler(desc, handle, 1, NULL);
+	desc->irq_data.handler_data = data;
+
+	irq_put_desc_busunlock(desc, flags);
+}
+EXPORT_SYMBOL_GPL(irq_set_chained_handler_and_data);
+
+void
 irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
 			      irq_flow_handler_t handle, const char *name)
 {

      parent reply	other threads:[~2015-06-18 12:08 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-16 22:06 [PATCH 1/9] irq: add irq_set_chained_handler_and_data() Russell King
2015-06-16 22:06 ` Russell King
2015-06-16 22:29 ` [PATCH] GPU: ipu: fix lockup caused by pending chained interrupts Russell King
2015-06-16 22:29   ` Russell King
     [not found]   ` <E1Z4zMT-0004Y7-KJ-eh5Bv4kxaXIANfyc6IWni62ZND6+EDdj@public.gmane.org>
2015-06-19 14:36     ` Philipp Zabel
2015-06-19 14:36       ` Philipp Zabel
2015-06-17 14:10 ` [PATCH 1/9] irq: add irq_set_chained_handler_and_data() Thomas Gleixner
2015-06-17 14:10   ` Thomas Gleixner
2015-06-17 19:38   ` Russell King - ARM Linux
2015-06-17 19:38     ` Russell King - ARM Linux
2015-06-18 12:06 ` tip-bot for Russell King [this message]

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=tip-3b0f95be143bea1aa47beb20134ef82e4e4068dc@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=gnurou@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jason@lakedaemon.net \
    --cc=lee.jones@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=rmk+kernel@arm.linux.org.uk \
    --cc=tglx@linutronix.de \
    --cc=thierry.reding@gmail.com \
    --cc=ulli.kroll@googlemail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.