public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: David Brownell <david-b@pacbell.net>
To: Linux Kernel list <linux-kernel@vger.kernel.org>,
	tglx@linutronix.de, mingo@redhat.com
Cc: Andrew Victor <andrew@sanpeople.com>,
	Alessandro Zummo <alessandro.zummo@towertech.it>
Subject: [patch 2.6.18-rc1] genirq: {en,dis}able_irq_wake() need refcounting too
Date: Sun, 9 Jul 2006 14:58:51 -0700	[thread overview]
Message-ID: <200607091458.52298.david-b@pacbell.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 365 bytes --]

It's not just "normal" mode operation that needs refcounting for the
{en,dis}able_irq() calls ... "wakeup" mode calls need it too, for the
very same reasons.

This patch adds that refcounting.  I expect that some ARM drivers will
be triggering the new warning, but this call isn't yet widely used.
(Which is probably why the bug has lingered this long...)

- Dave


[-- Attachment #2: irqwake.patch --]
[-- Type: text/x-diff, Size: 3805 bytes --]

IRQs need refcounting and a state flag to track whether the the IRQ should
be enabled or disabled as a "normal IRQ" source after a series of calls to
disable_irq() and enable_irq().  For shared IRQs, the IRQ must be enabled
so long as at least one driver needs it active.

Likewise, IRQs need the same support to track whether the IRQ should be
enabled or disabled as a "wakeup event" source after a series of calls to
enable_irq_wake() and disable_irq_wake().  For shared IRQs, the IRQ must
be wakeup-enabled so long as at least one driver needs it.

But right now they don't have that refcounting ... which means sharing
wakeup-capable IRQs can't work correctly in some configurations.  This
patch adds the refcount and flag mechanisms to set_irq_wake(), and a
minimal description of what an irq wake mechanism is.

Drivers relying on the older (broken) "toggle" semantics will trigger a
warning; that'll be a handful of drivers on ARM systems.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>


Index: at91/include/linux/irq.h
===================================================================
--- at91.orig/include/linux/irq.h	2006-07-09 13:46:34.000000000 -0700
+++ at91/include/linux/irq.h	2006-07-09 13:57:35.000000000 -0700
@@ -58,6 +58,7 @@
 #define IRQ_NOREQUEST		0x04000000	/* IRQ cannot be requested */
 #define IRQ_NOAUTOEN		0x08000000	/* IRQ will not be enabled on request irq */
 #define IRQ_DELAYED_DISABLE	0x10000000	/* IRQ disable (masking) happens delayed. */
+#define IRQ_WAKEUP		0x20000000	/* IRQ triggers system wakeup */
 
 struct proc_dir_entry;
 
@@ -124,6 +125,7 @@ struct irq_chip {
  * @action:		the irq action chain
  * @status:		status information
  * @depth:		disable-depth, for nested irq_disable() calls
+ * @wake_depth:		enable depth, for multiple set_irq_wake() callers
  * @irq_count:		stats field to detect stalled irqs
  * @irqs_unhandled:	stats field for spurious unhandled interrupts
  * @lock:		locking for SMP
@@ -147,6 +149,7 @@ struct irq_desc {
 	unsigned int		status;		/* IRQ status */
 
 	unsigned int		depth;		/* nested irq disables */
+	unsigned int		wake_depth;	/* nested wake enables */
 	unsigned int		irq_count;	/* For detecting broken IRQs */
 	unsigned int		irqs_unhandled;
 	spinlock_t		lock;
Index: at91/kernel/irq/manage.c
===================================================================
--- at91.orig/kernel/irq/manage.c	2006-07-09 13:46:34.000000000 -0700
+++ at91/kernel/irq/manage.c	2006-07-09 13:57:35.000000000 -0700
@@ -137,16 +137,40 @@ EXPORT_SYMBOL(enable_irq);
  *	@irq:	interrupt to control
  *	@on:	enable/disable power management wakeup
  *
- *	Enable/disable power management wakeup mode
+ *	Enable/disable power management wakeup mode, which is
+ *	disabled by default.  Enables and disables must match,
+ *	just as they match for non-wakeup mode support.
+ *
+ *	Wakeup mode lets this IRQ wake the system from sleep
+ *	states like "suspend to RAM".
  */
 int set_irq_wake(unsigned int irq, unsigned int on)
 {
 	struct irq_desc *desc = irq_desc + irq;
 	unsigned long flags;
 	int ret = -ENXIO;
+	int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake;
 
+	/* wakeup-capable irqs can be shared between drivers that
+	 * don't need to have the same sleep mode behaviors.
+	 */
 	spin_lock_irqsave(&desc->lock, flags);
-	if (desc->chip->set_wake)
+	if (on) {
+		if (desc->wake_depth++ == 0)
+			desc->status |= IRQ_WAKEUP;
+		else
+			set_wake = NULL;
+	} else {
+		if (desc->wake_depth == 0) {
+			printk(KERN_WARNING "Unbalanced IRQ %d "
+					"wake disable\n", irq);
+			WARN_ON(1);
+		} else if (--desc->wake_depth == 0)
+			desc->status &= ~IRQ_WAKEUP;
+		else
+			set_wake = NULL;
+	}
+	if (set_wake)
 		ret = desc->chip->set_wake(irq, on);
 	spin_unlock_irqrestore(&desc->lock, flags);
 	return ret;

             reply	other threads:[~2006-07-09 21:58 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-09 21:58 David Brownell [this message]
2006-07-10  8:58 ` [patch 2.6.18-rc1] genirq: {en,dis}able_irq_wake() need refcounting too Ingo Molnar
2006-07-10  9:13   ` Russell King
2006-07-10  9:12     ` Ingo Molnar
2006-07-10  9:19     ` Russell King
2006-07-10  9:16       ` Ingo Molnar
2006-07-10  9:32   ` Thomas Gleixner
2006-07-15  1:31   ` David Brownell

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=200607091458.52298.david-b@pacbell.net \
    --to=david-b@pacbell.net \
    --cc=alessandro.zummo@towertech.it \
    --cc=andrew@sanpeople.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    /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