* kernel/irq: __setup_irq/__free_irq disable-depth asymmetry?
@ 2010-01-11 8:36 Shmulik Ladkani
2010-01-12 7:41 ` [PATCH] kernel/irq: Reset IRQ desc->depth to 1 when __free_irq disables the line Shmulik Ladkani
0 siblings, 1 reply; 2+ messages in thread
From: Shmulik Ladkani @ 2010-01-11 8:36 UTC (permalink / raw)
To: linux-kernel; +Cc: mingo, yinghai, travis, tglx, peterz
Hi,
For discussion simplicity, lets assume our IRQ is not IRQF_SHARED, also
IRQ_NOAUTOEN is not set.
Normally, when the system is initialized, the initial value of
irq_desc[i].depth is 1, representing disable-depth of 1, as the line is
indeed initially disabeled.
When __setup_irq is called (as a result of request_irq call), the line gets
enabled via desc->chip->startup(irq), and desc->depth is set to 0
(meaning: there's no disable-depth).
When __free_irq is called (assuming last handler unregistering), the line
gets masked by desc->chip->shutdown(irq), however the desc->depth is not
modified.
In that case, desc->depth is still 0 ("no disable-depth") but the line is
actually disabled.
Now suppose someone calls disable_irq() and then enable_irq().
The overall result will be the line getting enabled by the latter call,
although there's no registered ISR.
(disable_irq increments depth to 1, enabled_irq decrements it to 0 and
thus calls desc->chip->enable).
Yes, I agree, calling disable_irq/enable_irq when there's no registered ISR
is bizzare... however bizzare things might happen to you too ;)
What bothers me is that the overall result is not identical when running
the following sequence: system initlialization, disable_irq, enable_irq
(without any __setup_irq/__free_irq calls).
In that case, the overall result is that the line is kept masked.
(upon initialization depth is 1, disable_irq increments it to 2, enable_irq
decrements it to back 1. no desc->chip->xxx calls whatsoever).
The cause for this behaviour is the assymetrical treatment to the 'depth' field
in __free_irq; it should have reverted what was done in __setup_irq.
So, I suggest resetting desc->depth to 1 within __free_irq (at the same place
desc->chip->shutdown is called).
Your thoughts appreciated.
--
Shmulik Ladkani
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH] kernel/irq: Reset IRQ desc->depth to 1 when __free_irq disables the line
2010-01-11 8:36 kernel/irq: __setup_irq/__free_irq disable-depth asymmetry? Shmulik Ladkani
@ 2010-01-12 7:41 ` Shmulik Ladkani
0 siblings, 0 replies; 2+ messages in thread
From: Shmulik Ladkani @ 2010-01-12 7:41 UTC (permalink / raw)
To: linux-kernel; +Cc: mingo, tglx, damm, peterz, ddaney
Reset irq_desc's depth field to 1, indicating IRQ line is disabled, when
__free_irq disables/shuts-down the line (i.e. upon unregistration of
last interrupt handler).
Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
---
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index eb6078c..642a98c 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -877,6 +877,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
/* If this was the last handler, shut down the IRQ line: */
if (!desc->action) {
+ desc->depth = 1;
desc->status |= IRQ_DISABLED;
if (desc->chip->shutdown)
desc->chip->shutdown(irq);
--
Shmulik Ladkani
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-01-12 7:42 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-11 8:36 kernel/irq: __setup_irq/__free_irq disable-depth asymmetry? Shmulik Ladkani
2010-01-12 7:41 ` [PATCH] kernel/irq: Reset IRQ desc->depth to 1 when __free_irq disables the line Shmulik Ladkani
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox