]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.2.14/genirq-fix-long-term-regression-in-genirq-irq_set_irq_type-handling.patch
Linux 5.0.18
[thirdparty/kernel/stable-queue.git] / releases / 3.2.14 / genirq-fix-long-term-regression-in-genirq-irq_set_irq_type-handling.patch
CommitLineData
f232e200
GKH
1From a09b659cd68c10ec6a30cb91ebd2c327fcd5bfe5 Mon Sep 17 00:00:00 2001
2From: Russell King <linux@arm.linux.org.uk>
3Date: Mon, 5 Mar 2012 15:07:25 -0800
4Subject: genirq: Fix long-term regression in genirq irq_set_irq_type() handling
5
6From: Russell King <linux@arm.linux.org.uk>
7
8commit a09b659cd68c10ec6a30cb91ebd2c327fcd5bfe5 upstream.
9
10In 2008, commit 0c5d1eb77a8be ("genirq: record trigger type") modified the
11way set_irq_type() handles the 'no trigger' condition. However, this has
12an adverse effect on PCMCIA support on Intel StrongARM and probably PXA
13platforms.
14
15PCMCIA has several status signals on the socket which can trigger
16interrupts; some of these status signals depend on the card's mode
17(whether it is configured in memory or IO mode). For example, cards have
18a 'Ready/IRQ' signal: in memory mode, this provides an indication to
19PCMCIA that the card has finished its power up initialization. In IO
20mode, it provides the device interrupt signal. Other status signals
21switch between on-board battery status and loud speaker output.
22
23In classical PCMCIA implementations, where you have a specific socket
24controller, the controller provides a method to mask interrupts from the
25socket, and importantly ignore any state transitions on the pins which
26correspond with interrupts once masked. This masking prevents unwanted
27events caused by the removal and application of socket power being
28forwarded.
29
30However, on platforms where there is no socket controller, the PCMCIA
31status and interrupt signals are routed to standard edge-triggered GPIOs.
32These GPIOs can be configured to interrupt on rising edge, falling edge,
33or never. This is where the problems start.
34
35Edge triggered interrupts are required to record events while disabled via
36the usual methods of {free,request,disable,enable}_irq() to prevent
37problems with dropped interrupts (eg, the 8390 driver uses disable_irq()
38to defer the delivery of interrupts). As a result, these interfaces can
39not be used to implement the desired behaviour.
40
41The side effect of this is that if the 'Ready/IRQ' GPIO is disabled via
42disable_irq() on suspend, and enabled via enable_irq() after resume, we
43will record the state transitions caused by powering events as valid
44interrupts, and foward them to the card driver, which may attempt to
45access a card which is not powered up.
46
47This leads delays resume while drivers spin in their interrupt handlers,
48and complaints from drivers before they realize what's happened.
49
50Moreover, in the case of the 'Ready/IRQ' signal, this is requested and
51freed by the card driver itself; the PCMCIA core has no idea whether the
52interrupt is requested, and, therefore, whether a call to disable_irq()
53would be valid. (We tried this around 2.4.17 / 2.5.1 kernel era, and
54ended up throwing it out because of this problem.)
55
56Therefore, it was decided back in around 2002 to disable the edge
57triggering instead, resulting in all state transitions on the GPIO being
58ignored. That's what we actually need the hardware to do.
59
60The commit above changes this behaviour; it explicitly prevents the 'no
61trigger' state being selected.
62
63The reason that request_irq() does not accept the 'no trigger' state is
64for compatibility with existing drivers which do not provide their desired
65triggering configuration. The set_irq_type() function is 'new' and not
66used by non-trigger aware drivers.
67
68Therefore, revert this change, and restore previously working platforms
69back to their former state.
70
71Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
72Cc: linux@arm.linux.org.uk
73Cc: Ingo Molnar <mingo@elte.hu>
74Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
75Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
76Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
77
78---
79 kernel/irq/chip.c | 3 +--
80 1 file changed, 1 insertion(+), 2 deletions(-)
81
82--- a/kernel/irq/chip.c
83+++ b/kernel/irq/chip.c
84@@ -61,8 +61,7 @@ int irq_set_irq_type(unsigned int irq, u
85 return -EINVAL;
86
87 type &= IRQ_TYPE_SENSE_MASK;
88- if (type != IRQ_TYPE_NONE)
89- ret = __irq_set_trigger(desc, irq, type);
90+ ret = __irq_set_trigger(desc, irq, type);
91 irq_put_desc_busunlock(desc, flags);
92 return ret;
93 }