Merge branch 'linus' into x86/pat
[linux-2.6] / kernel / irq / autoprobe.c
1 /*
2  * linux/kernel/irq/autoprobe.c
3  *
4  * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
5  *
6  * This file contains the interrupt probing code and driver APIs.
7  */
8
9 #include <linux/irq.h>
10 #include <linux/module.h>
11 #include <linux/interrupt.h>
12 #include <linux/delay.h>
13
14 #include "internals.h"
15
16 /*
17  * Autodetection depends on the fact that any interrupt that
18  * comes in on to an unassigned handler will get stuck with
19  * "IRQ_WAITING" cleared and the interrupt disabled.
20  */
21 static DEFINE_MUTEX(probing_active);
22
23 /**
24  *      probe_irq_on    - begin an interrupt autodetect
25  *
26  *      Commence probing for an interrupt. The interrupts are scanned
27  *      and a mask of potential interrupt lines is returned.
28  *
29  */
30 unsigned long probe_irq_on(void)
31 {
32         struct irq_desc *desc;
33         unsigned long mask;
34         unsigned int i;
35
36         mutex_lock(&probing_active);
37         /*
38          * something may have generated an irq long ago and we want to
39          * flush such a longstanding irq before considering it as spurious.
40          */
41         for (i = NR_IRQS-1; i > 0; i--) {
42                 desc = irq_desc + i;
43
44                 spin_lock_irq(&desc->lock);
45                 if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
46                         /*
47                          * An old-style architecture might still have
48                          * the handle_bad_irq handler there:
49                          */
50                         compat_irq_chip_set_default_handler(desc);
51
52                         /*
53                          * Some chips need to know about probing in
54                          * progress:
55                          */
56                         if (desc->chip->set_type)
57                                 desc->chip->set_type(i, IRQ_TYPE_PROBE);
58                         desc->chip->startup(i);
59                 }
60                 spin_unlock_irq(&desc->lock);
61         }
62
63         /* Wait for longstanding interrupts to trigger. */
64         msleep(20);
65
66         /*
67          * enable any unassigned irqs
68          * (we must startup again here because if a longstanding irq
69          * happened in the previous stage, it may have masked itself)
70          */
71         for (i = NR_IRQS-1; i > 0; i--) {
72                 desc = irq_desc + i;
73
74                 spin_lock_irq(&desc->lock);
75                 if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
76                         desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
77                         if (desc->chip->startup(i))
78                                 desc->status |= IRQ_PENDING;
79                 }
80                 spin_unlock_irq(&desc->lock);
81         }
82
83         /*
84          * Wait for spurious interrupts to trigger
85          */
86         msleep(100);
87
88         /*
89          * Now filter out any obviously spurious interrupts
90          */
91         mask = 0;
92         for (i = 0; i < NR_IRQS; i++) {
93                 unsigned int status;
94
95                 desc = irq_desc + i;
96                 spin_lock_irq(&desc->lock);
97                 status = desc->status;
98
99                 if (status & IRQ_AUTODETECT) {
100                         /* It triggered already - consider it spurious. */
101                         if (!(status & IRQ_WAITING)) {
102                                 desc->status = status & ~IRQ_AUTODETECT;
103                                 desc->chip->shutdown(i);
104                         } else
105                                 if (i < 32)
106                                         mask |= 1 << i;
107                 }
108                 spin_unlock_irq(&desc->lock);
109         }
110
111         return mask;
112 }
113 EXPORT_SYMBOL(probe_irq_on);
114
115 /**
116  *      probe_irq_mask - scan a bitmap of interrupt lines
117  *      @val:   mask of interrupts to consider
118  *
119  *      Scan the interrupt lines and return a bitmap of active
120  *      autodetect interrupts. The interrupt probe logic state
121  *      is then returned to its previous value.
122  *
123  *      Note: we need to scan all the irq's even though we will
124  *      only return autodetect irq numbers - just so that we reset
125  *      them all to a known state.
126  */
127 unsigned int probe_irq_mask(unsigned long val)
128 {
129         unsigned int mask;
130         int i;
131
132         mask = 0;
133         for (i = 0; i < NR_IRQS; i++) {
134                 struct irq_desc *desc = irq_desc + i;
135                 unsigned int status;
136
137                 spin_lock_irq(&desc->lock);
138                 status = desc->status;
139
140                 if (status & IRQ_AUTODETECT) {
141                         if (i < 16 && !(status & IRQ_WAITING))
142                                 mask |= 1 << i;
143
144                         desc->status = status & ~IRQ_AUTODETECT;
145                         desc->chip->shutdown(i);
146                 }
147                 spin_unlock_irq(&desc->lock);
148         }
149         mutex_unlock(&probing_active);
150
151         return mask & val;
152 }
153 EXPORT_SYMBOL(probe_irq_mask);
154
155 /**
156  *      probe_irq_off   - end an interrupt autodetect
157  *      @val: mask of potential interrupts (unused)
158  *
159  *      Scans the unused interrupt lines and returns the line which
160  *      appears to have triggered the interrupt. If no interrupt was
161  *      found then zero is returned. If more than one interrupt is
162  *      found then minus the first candidate is returned to indicate
163  *      their is doubt.
164  *
165  *      The interrupt probe logic state is returned to its previous
166  *      value.
167  *
168  *      BUGS: When used in a module (which arguably shouldn't happen)
169  *      nothing prevents two IRQ probe callers from overlapping. The
170  *      results of this are non-optimal.
171  */
172 int probe_irq_off(unsigned long val)
173 {
174         int i, irq_found = 0, nr_irqs = 0;
175
176         for (i = 0; i < NR_IRQS; i++) {
177                 struct irq_desc *desc = irq_desc + i;
178                 unsigned int status;
179
180                 spin_lock_irq(&desc->lock);
181                 status = desc->status;
182
183                 if (status & IRQ_AUTODETECT) {
184                         if (!(status & IRQ_WAITING)) {
185                                 if (!nr_irqs)
186                                         irq_found = i;
187                                 nr_irqs++;
188                         }
189                         desc->status = status & ~IRQ_AUTODETECT;
190                         desc->chip->shutdown(i);
191                 }
192                 spin_unlock_irq(&desc->lock);
193         }
194         mutex_unlock(&probing_active);
195
196         if (nr_irqs > 1)
197                 irq_found = -irq_found;
198
199         return irq_found;
200 }
201 EXPORT_SYMBOL(probe_irq_off);
202