OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [auto_irq.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* auto_irq.c: Auto-configure IRQ lines for linux. */
2
/*
3
    Written 1994 by Donald Becker.
4
 
5
    The author may be reached as becker@CESDIS.gsfc.nasa.gov, 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 (becker@cesdis.gsfc.nasa.gov)";
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
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.