* 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 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.