summaryrefslogtreecommitdiffstats
path: root/drivers/net/auto_irq.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1994-11-28 11:59:19 +0000
committer <ralf@linux-mips.org>1994-11-28 11:59:19 +0000
commit1513ff9b7899ab588401c89db0e99903dbf5f886 (patch)
treef69cc81a940a502ea23d664c3ffb2d215a479667 /drivers/net/auto_irq.c
Import of Linus's Linux 1.1.68
Diffstat (limited to 'drivers/net/auto_irq.c')
-rw-r--r--drivers/net/auto_irq.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/drivers/net/auto_irq.c b/drivers/net/auto_irq.c
new file mode 100644
index 000000000..0bab58cb1
--- /dev/null
+++ b/drivers/net/auto_irq.c
@@ -0,0 +1,125 @@
+/* auto_irq.c: Auto-configure IRQ lines for linux. */
+/*
+ Written 1994 by Donald Becker.
+
+ The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
+ Center of Excellence in Space Data and Information Sciences
+ Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
+
+ This code is a general-purpose IRQ line detector for devices with
+ jumpered IRQ lines. If you can make the device raise an IRQ (and
+ that IRQ line isn't already being used), these routines will tell
+ you what IRQ line it's using -- perfect for those oh-so-cool boot-time
+ device probes!
+
+ To use this, first call autoirq_setup(timeout). TIMEOUT is how many
+ 'jiffies' (1/100 sec.) to detect other devices that have active IRQ lines,
+ and can usually be zero at boot. 'autoirq_setup()' returns the bit
+ vector of nominally-available IRQ lines (lines may be physically in-use,
+ but not yet registered to a device).
+ Next, set up your device to trigger an interrupt.
+ Finally call autoirq_report(TIMEOUT) to find out which IRQ line was
+ most recently active. The TIMEOUT should usually be zero, but may
+ be set to the number of jiffies to wait for a slow device to raise an IRQ.
+
+ The idea of using the setup timeout to filter out bogus IRQs came from
+ the serial driver.
+*/
+
+
+#ifdef version
+static char *version=
+"auto_irq.c:v1.11 Donald Becker (becker@cesdis.gsfc.nasa.gov)";
+#endif
+
+/*#include <linux/config.h>*/
+/*#include <linux/kernel.h>*/
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/netdevice.h>
+/*#include <asm/system.h>*/
+
+struct device *irq2dev_map[16] = {0, 0, /* ... zeroed */};
+
+int irqs_busy = 0x2147; /* The set of fixed IRQs (keyboard, timer, etc) */
+int irqs_used = 0x0001; /* The set of fixed IRQs sometimes enabled. */
+int irqs_reserved = 0x0000; /* An advisory "reserved" table. */
+int irqs_shared = 0x0000; /* IRQ lines "shared" among conforming cards.*/
+
+static volatile int irq_number; /* The latest irq number we actually found. */
+static volatile int irq_bitmap; /* The irqs we actually found. */
+static int irq_handled; /* The irq lines we have a handler on. */
+
+static void autoirq_probe(int irq)
+{
+ irq_number = irq;
+ set_bit(irq, (void *)&irq_bitmap); /* irq_bitmap |= 1 << irq; */
+ disable_irq(irq);
+ return;
+}
+
+int autoirq_setup(int waittime)
+{
+ int i, mask;
+ int timeout = jiffies + waittime;
+ int boguscount = (waittime*loops_per_sec) / 100;
+
+ irq_handled = 0;
+ for (i = 0; i < 16; i++) {
+ if (test_bit(i, &irqs_busy) == 0
+ && request_irq(i, autoirq_probe, SA_INTERRUPT, "irq probe") == 0)
+ set_bit(i, (void *)&irq_handled); /* irq_handled |= 1 << i;*/
+ }
+ /* Update our USED lists. */
+ irqs_used |= ~irq_handled;
+ irq_number = 0;
+ irq_bitmap = 0;
+
+ /* Hang out at least <waittime> jiffies waiting for bogus IRQ hits. */
+ while (timeout > jiffies && --boguscount > 0)
+ ;
+
+ for (i = 0, mask = 0x01; i < 16; i++, mask <<= 1) {
+ if (irq_bitmap & irq_handled & mask) {
+ irq_handled &= ~mask;
+#ifdef notdef
+ printk(" Spurious interrupt on IRQ %d\n", i);
+#endif
+ free_irq(i);
+ }
+ }
+ return irq_handled;
+}
+
+int autoirq_report(int waittime)
+{
+ int i;
+ int timeout = jiffies+waittime;
+ int boguscount = (waittime*loops_per_sec) / 100;
+
+ /* Hang out at least <waittime> jiffies waiting for the IRQ. */
+
+ while (timeout > jiffies && --boguscount > 0)
+ if (irq_number)
+ break;
+
+ /* Retract the irq handlers that we installed. */
+ for (i = 0; i < 16; i++) {
+ if (test_bit(i, (void *)&irq_handled))
+ free_irq(i);
+ }
+ return irq_number;
+}
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c auto_irq.c"
+ * version-control: t
+ * kept-new-versions: 5
+ * c-indent-level: 4
+ * tab-width: 4
+ * End:
+ */