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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [m68k/] [kernel/] [ints.c] - Blame information for rev 1777

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

Line No. Rev Author Line
1 1623 jcastillo
/*
2
 * ints.c -- 680x0 Linux general interrupt handling code
3
 *
4
 * This file is subject to the terms and conditions of the GNU General Public
5
 * License.  See the file COPYING in the main directory of this archive
6
 * for more details.
7
 *
8
 * 07/03/96: Timer initialization, and thus mach_sched_init(),
9
 *           removed from request_irq() and moved to init_time().
10
 *           We should therefore consider renaming our add_isr() and
11
 *           remove_isr() to request_irq() and free_irq()
12
 *           respectively, so they are compliant with the other
13
 *           architectures.                                     /Jes
14
 */
15
 
16
#include <linux/types.h>
17
#include <linux/sched.h>
18
#include <linux/kernel_stat.h>
19
#include <linux/errno.h>
20
 
21
#include <asm/system.h>
22
#include <asm/irq.h>
23
#include <asm/traps.h>
24
#include <asm/page.h>
25
#include <asm/machdep.h>
26
 
27
/* list is accessed 0-6 for IRQs 1-7 */
28
static isr_node_t *isr_list[7];
29
 
30
/* The number of spurious interrupts */
31
volatile unsigned long num_spurious;
32
/*
33
unsigned long interrupt_stack[PAGE_SIZE/sizeof(long)];
34
*/
35
 
36
/*
37
 * void init_IRQ(void)
38
 *
39
 * Parameters:  None
40
 *
41
 * Returns:     Nothing
42
 *
43
 * This function should be called during kernel startup to initialize
44
 * the IRQ handling routines.
45
 */
46
 
47
void init_IRQ(void)
48
{
49
    /* Setup interrupt stack pointer */
50
  /*
51
    asm ("movec %0,%/isp"
52
         : : "r" (interrupt_stack + sizeof (interrupt_stack) / sizeof (long)));
53
         */
54
    mach_init_INTS ();
55
}
56
 
57
void insert_isr (isr_node_t **listp, isr_node_t *node)
58
{
59
    unsigned long spl;
60
    isr_node_t *cur;
61
 
62
    save_flags(spl);
63
    cli();
64
 
65
    cur = *listp;
66
 
67
    while (cur && cur->pri <= node->pri)
68
    {
69
        listp = &cur->next;
70
        cur = cur->next;
71
    }
72
 
73
    node->next = cur;
74
    *listp = node;
75
 
76
    restore_flags(spl);
77
}
78
 
79
void delete_isr (isr_node_t **listp, isrfunc isr, void *data)
80
{
81
    unsigned long flags;
82
    isr_node_t *np;
83
 
84
    save_flags(flags);
85
    cli();
86
    for (np = *listp; np; listp = &np->next, np = *listp) {
87
        if (np->isr == isr && np->data == data) {
88
            *listp = np->next;
89
            /* Mark it as free. */
90
            np->isr = NULL;
91
            restore_flags(flags);
92
            return;
93
        }
94
    }
95
    restore_flags(flags);
96
    printk ("delete_isr: isr %p not found on list!\n", isr);
97
}
98
 
99
#define NUM_ISR_NODES 100
100
static isr_node_t nodes[NUM_ISR_NODES];
101
 
102
isr_node_t *new_isr_node(void)
103
{
104
    isr_node_t *np;
105
 
106
    for (np = nodes; np < &nodes[NUM_ISR_NODES]; np++)
107
        if (np->isr == NULL)
108
            return np;
109
 
110
    printk ("new_isr_node: out of nodes");
111
    return NULL;
112
}
113
 
114
int add_isr (unsigned long source, isrfunc isr, int pri, void *data,
115
             char *name)
116
{
117
    isr_node_t *p;
118
 
119
    if (source & IRQ_MACHSPEC)
120
    {
121
        return mach_add_isr (source, isr, pri, data, name);
122
    }
123
 
124
    if (source < IRQ1 || source > IRQ7)
125
        panic ("add_isr: Incorrect IRQ source %ld from %s\n", source, name);
126
 
127
    p = new_isr_node();
128
    if (p == NULL)
129
        return 0;
130
    p->isr = isr;
131
    p->pri = pri;
132
    p->data = data;
133
    p->name = name;
134
    p->next = NULL;
135
 
136
    insert_isr (&isr_list[source-1], p);
137
 
138
    return 1;
139
}
140
 
141
int remove_isr (unsigned long source, isrfunc isr, void *data)
142
{
143
    if (source & IRQ_MACHSPEC)
144
        return mach_remove_isr (source, isr, data);
145
 
146
    if (source < IRQ1 || source > IRQ7) {
147
        printk ("remove_isr: Incorrect IRQ source %ld\n", source);
148
        return 0;
149
    }
150
 
151
    delete_isr (&isr_list[source - 1], isr, data);
152
    return 1;
153
}
154
 
155
void call_isr_list(int irq, isr_node_t *p, struct pt_regs *fp)
156
{
157
    while (p) {
158
        p->isr (irq, fp, p->data);
159
        p = p->next;
160
    }
161
}
162
 
163
asmlinkage void process_int(int vec, struct pt_regs *regs)
164
{
165
        int level;
166
 
167
        if (vec >= VECOFF(VEC_INT1) && vec <= VECOFF(VEC_INT7))
168
                level = (vec - VECOFF(VEC_SPUR)) >> 2;
169
        else {
170
                if (mach_process_int)
171
                        mach_process_int(vec, regs);
172
                else
173
                        panic("Can't process interrupt vector 0x%03x\n", vec);
174
                return;
175
        }
176
 
177
        kstat.interrupts[level]++;
178
        call_isr_list (level, isr_list[level-1], regs);
179
}
180
 
181
int request_irq(unsigned int irq,
182
                void (*handler)(int, void *, struct pt_regs *),
183
                unsigned long flags, const char * devname, void *dev_id)
184
{
185
        return -EINVAL;
186
}
187
 
188
void free_irq(unsigned int irq, void *dev_id)
189
{
190
}
191
 
192
/*
193
 * Do we need these probe functions on the m68k?
194
 */
195
unsigned long probe_irq_on (void)
196
{
197
  return 0;
198
}
199
 
200
int probe_irq_off (unsigned long irqs)
201
{
202
  return 0;
203
}
204
 
205
void enable_irq(unsigned int irq_nr)
206
{
207
        if ((irq_nr & IRQ_MACHSPEC) && mach_enable_irq)
208
                mach_enable_irq(irq_nr);
209
}
210
 
211
void disable_irq(unsigned int irq_nr)
212
{
213
        if ((irq_nr & IRQ_MACHSPEC) && mach_disable_irq)
214
                mach_disable_irq(irq_nr);
215
}
216
 
217
int get_irq_list(char *buf)
218
{
219
    int i, len = 0;
220
    isr_node_t *p;
221
 
222
    /* autovector interrupts */
223
    for (i = IRQ1; i <= IRQ7; ++i) {
224
        if (!isr_list[i-1])
225
            continue;
226
        len += sprintf(buf+len, "auto %2d: %8d ", i, kstat.interrupts[i]);
227
        for (p = isr_list[i-1]; p; p = p->next) {
228
            len += sprintf(buf+len, "%s\n", p->name);
229
            if (p->next)
230
                len += sprintf(buf+len, "                  ");
231
        }
232
    }
233
 
234
    len = mach_get_irq_list(buf, len);
235
    return len;
236
}

powered by: WebSVN 2.1.0

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