|
|
1.1 root 1: /* auto_irq.c: Auto-configure IRQ lines for linux. */
2: /*
3: Written 1994 by Donald Becker.
4:
5: The author may be reached as [email protected], or C/O
6: Center of Excellence in Space Data and Information Sciences
7: Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
8:
9: This code is a general-purpose IRQ line detector for devices with
10: jumpered IRQ lines. If you can make the device raise an IRQ (and
11: that IRQ line isn't already being used), these routines will tell
12: you what IRQ line it's using -- perfect for those oh-so-cool boot-time
13: device probes!
14:
15: To use this, first call autoirq_setup(timeout). TIMEOUT is how many
16: 'jiffies' (1/100 sec.) to detect other devices that have active IRQ lines,
17: and can usually be zero at boot. 'autoirq_setup()' returns the bit
18: vector of nominally-available IRQ lines (lines may be physically in-use,
19: but not yet registered to a device).
20: Next, set up your device to trigger an interrupt.
21: Finally call autoirq_report(TIMEOUT) to find out which IRQ line was
22: most recently active. The TIMEOUT should usually be zero, but may
23: be set to the number of jiffies to wait for a slow device to raise an IRQ.
24:
25: The idea of using the setup timeout to filter out bogus IRQs came from
26: the serial driver.
27: */
28:
29:
30: #ifdef version
31: static const char *version=
32: "auto_irq.c:v1.11 Donald Becker ([email protected])";
33: #endif
34:
35: #include <linux/sched.h>
36: #include <linux/delay.h>
37: #include <asm/bitops.h>
38: #include <asm/io.h>
39: #include <asm/irq.h>
40: #include <linux/netdevice.h>
41:
42: struct device *irq2dev_map[NR_IRQS] = {0, 0, /* ... zeroed */};
43:
44: unsigned long irqs_busy = 0x2147; /* The set of fixed IRQs (keyboard, timer, etc) */
45: unsigned long irqs_used = 0x0001; /* The set of fixed IRQs sometimes enabled. */
46: unsigned long irqs_reserved = 0x0000; /* An advisory "reserved" table. */
47: unsigned long irqs_shared = 0x0000; /* IRQ lines "shared" among conforming cards.*/
48:
49: static volatile unsigned long irq_bitmap; /* The irqs we actually found. */
50: static unsigned long irq_handled; /* The irq lines we have a handler on. */
51: static volatile int irq_number; /* The latest irq number we actually found. */
52:
53: static void autoirq_probe(int irq, void *dev_id, struct pt_regs * regs)
54: {
55: irq_number = irq;
56: set_bit(irq, (void *)&irq_bitmap); /* irq_bitmap |= 1 << irq; */
57: /* This code used to disable the irq. However, the interrupt stub
58: * would then re-enable the interrupt with (potentially) disastrous
59: * consequences
60: */
61: free_irq(irq, dev_id);
62: return;
63: }
64:
65: int autoirq_setup(int waittime)
66: {
67: int i;
68: unsigned long timeout = jiffies + waittime;
69: unsigned long boguscount = (waittime*loops_per_sec) / 100;
70:
71: irq_handled = 0;
72: irq_bitmap = 0;
73:
74: for (i = 0; i < 16; i++) {
75: if (test_bit(i, &irqs_busy) == 0
76: && request_irq(i, autoirq_probe, SA_INTERRUPT, "irq probe", NULL) == 0)
77: set_bit(i, (void *)&irq_handled); /* irq_handled |= 1 << i;*/
78: }
79: /* Update our USED lists. */
80: irqs_used |= ~irq_handled;
81:
82: /* Hang out at least <waittime> jiffies waiting for bogus IRQ hits. */
83: while (timeout > jiffies && --boguscount > 0)
84: ;
85:
86: irq_handled &= ~irq_bitmap;
87:
88: irq_number = 0; /* We are interested in new interrupts from now on */
89:
90: return irq_handled;
91: }
92:
93: int autoirq_report(int waittime)
94: {
95: int i;
96: unsigned long timeout = jiffies+waittime;
97: unsigned long boguscount = (waittime*loops_per_sec) / 100;
98:
99: /* Hang out at least <waittime> jiffies waiting for the IRQ. */
100:
101: while (timeout > jiffies && --boguscount > 0)
102: if (irq_number)
103: break;
104:
105: irq_handled &= ~irq_bitmap; /* This eliminates the already reset handlers */
106:
107: /* Retract the irq handlers that we installed. */
108: for (i = 0; i < 16; i++) {
109: if (test_bit(i, (void *)&irq_handled))
110: free_irq(i, NULL);
111: }
112: return irq_number;
113: }
114:
115: /*
116: * Local variables:
117: * compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c auto_irq.c"
118: * version-control: t
119: * kept-new-versions: 5
120: * c-indent-level: 4
121: * tab-width: 4
122: * End:
123: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.