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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [mips/] [lasat/] [interrupt.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Carsten Langgaard, carstenl@mips.com
3
 * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
4
 *
5
 * ########################################################################
6
 *
7
 *  This program is free software; you can distribute it and/or modify it
8
 *  under the terms of the GNU General Public License (Version 2) as
9
 *  published by the Free Software Foundation.
10
 *
11
 *  This program is distributed in the hope it will be useful, but WITHOUT
12
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 *  for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License along
17
 *  with this program; if not, write to the Free Software Foundation, Inc.,
18
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19
 *
20
 * ########################################################################
21
 *
22
 * Routines for generic manipulation of the interrupts found on the
23
 * Lasat boards.
24
 *
25
 */
26
#include <linux/config.h>
27
#include <linux/init.h>
28
#include <linux/sched.h>
29
#include <linux/slab.h>
30
#include <linux/interrupt.h>
31
#include <linux/kernel_stat.h>
32
 
33
#include <asm/bootinfo.h>
34
#include <asm/irq.h>
35
#include <asm/lasat/lasatint.h>
36
#include <asm/gdb-stub.h>
37
 
38
static volatile int *lasat_int_status = NULL;
39
static volatile int *lasat_int_mask = NULL;
40
static volatile int lasat_int_mask_shift;
41
 
42
extern asmlinkage void mipsIRQ(void);
43
 
44
#if 0
45
#define DEBUG_INT(x...) printk(x)
46
#else
47
#define DEBUG_INT(x...)
48
#endif
49
 
50
void disable_lasat_irq(unsigned int irq_nr)
51
{
52
        unsigned long flags;
53
        DEBUG_INT("disable_lasat_irq: %d", irq_nr);
54
 
55
        local_irq_save(flags);
56
        *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
57
        local_irq_restore(flags);
58
}
59
 
60
void enable_lasat_irq(unsigned int irq_nr)
61
{
62
        unsigned long flags;
63
        DEBUG_INT("enable_lasat_irq: %d", irq_nr);
64
 
65
        local_irq_save(flags);
66
        *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
67
        local_irq_restore(flags);
68
}
69
 
70
static unsigned int startup_lasat_irq(unsigned int irq)
71
{
72
        enable_lasat_irq(irq);
73
        return 0; /* never anything pending */
74
}
75
 
76
#define shutdown_lasat_irq      disable_lasat_irq
77
 
78
#define mask_and_ack_lasat_irq disable_lasat_irq
79
 
80
static void end_lasat_irq(unsigned int irq)
81
{
82
        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
83
                enable_lasat_irq(irq);
84
}
85
 
86
static struct hw_interrupt_type lasat_irq_type = {
87
        "Lasat",
88
        startup_lasat_irq,
89
        shutdown_lasat_irq,
90
        enable_lasat_irq,
91
        disable_lasat_irq,
92
        mask_and_ack_lasat_irq,
93
        end_lasat_irq,
94
        NULL
95
};
96
 
97
static inline int ls1bit32(unsigned int x)
98
{
99
        int b = 31, s;
100
 
101
        s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
102
        s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
103
        s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
104
        s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
105
        s =  1; if (x <<  1 == 0) s = 0; b -= s;
106
 
107
        return b;
108
}
109
 
110
static unsigned long (* get_int_status)(void);
111
 
112
static unsigned long get_int_status_100(void)
113
{
114
        return (*lasat_int_status & *lasat_int_mask);
115
}
116
 
117
static unsigned long get_int_status_200(void)
118
{
119
        unsigned long int_status;
120
 
121
        int_status = *lasat_int_status;
122
        int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff;
123
        return int_status;
124
}
125
 
126
void lasat_hw0_irqdispatch(struct pt_regs *regs)
127
{
128
        struct irqaction *action;
129
        unsigned long int_status;
130
        int irq, cpu = smp_processor_id();
131
 
132
        int_status = get_int_status();
133
 
134
        /* if int_status == 0, then the interrupt has already been cleared */
135
        if (int_status == 0)
136
                return;
137
 
138
        irq = ls1bit32(int_status);
139
        action = irq_desc[irq].action;
140
 
141
        DEBUG_INT("lasat_hw0_irqdispatch: irq=%d\n", irq);
142
 
143
        /* if action == NULL, then we don't have a handler for the irq */
144
        if (action == NULL) {
145
                printk("No handler for hw0 irq: %i\n", irq);
146
                atomic_inc(&irq_err_count);
147
                return;
148
        }
149
 
150
        irq_enter(cpu, irq);
151
        kstat.irqs[0][irq]++;
152
        action->handler(irq, action->dev_id, regs);
153
        irq_exit(cpu, irq);
154
 
155
        return;
156
}
157
 
158
void __init init_IRQ(void)
159
{
160
        int i;
161
 
162
        init_generic_irq();
163
 
164
        switch (mips_machtype) {
165
        case MACH_LASAT_100:
166
                lasat_int_status = (void *)LASAT_INT_STATUS_REG_100;
167
                lasat_int_mask = (void *)LASAT_INT_MASK_REG_100;
168
                lasat_int_mask_shift = LASATINT_MASK_SHIFT_100;
169
                get_int_status = get_int_status_100;
170
                *lasat_int_mask = 0;
171
                break;
172
        case MACH_LASAT_200:
173
                lasat_int_status = (void *)LASAT_INT_STATUS_REG_200;
174
                lasat_int_mask = (void *)LASAT_INT_MASK_REG_200;
175
                lasat_int_mask_shift = LASATINT_MASK_SHIFT_200;
176
                get_int_status = get_int_status_200;
177
                *lasat_int_mask &= 0xffff;
178
                break;
179
        default:
180
                panic("init_IRQ: mips_machtype incorrect");
181
        }
182
 
183
        /* Now safe to set the exception vector. */
184
        set_except_vector(0, mipsIRQ);
185
 
186
        for (i = 0; i <= LASATINT_END; i++) {
187
                irq_desc[i].status      = IRQ_DISABLED;
188
                irq_desc[i].action      = 0;
189
                irq_desc[i].depth       = 1;
190
                irq_desc[i].handler     = &lasat_irq_type;
191
        }
192
}

powered by: WebSVN 2.1.0

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