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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [sparc/] [kernel/] [sun4c_irq.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1624 jcastillo
/*  sun4c_irq.c
2
 *  arch/sparc/kernel/sun4c_irq.c:
3
 *
4
 *  djhr: Hacked out of irq.c into a CPU dependent version.
5
 *
6
 *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
7
 *  Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
8
 *  Copyright (C) 1995 Pete A. Zaitcev (zaitcev@ipmce.su)
9
 *  Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
10
 */
11
 
12
#include <linux/ptrace.h>
13
#include <linux/errno.h>
14
#include <linux/linkage.h>
15
#include <linux/kernel_stat.h>
16
#include <linux/signal.h>
17
#include <linux/sched.h>
18
#include <linux/interrupt.h>
19
#include <linux/malloc.h>
20
 
21
#include <asm/ptrace.h>
22
#include <asm/processor.h>
23
#include <asm/system.h>
24
#include <asm/psr.h>
25
#include <asm/vaddrs.h>
26
#include <asm/timer.h>
27
#include <asm/openprom.h>
28
#include <asm/oplib.h>
29
#include <asm/traps.h>
30
#include <asm/irq.h>
31
#include <asm/io.h>
32
 
33
/* Pointer to the interrupt enable byte
34
 *
35
 * Dave Redman (djhr@tadpole.co.uk)
36
 * What you may not be aware of is that entry.S requires this variable.
37
 *
38
 *  --- linux_trap_nmi_sun4c --
39
 *
40
 * so don't go making it static, like I tried. sigh.
41
 */
42
unsigned char *interrupt_enable = 0;
43
 
44
static void sun4c_disable_irq(unsigned int irq_nr)
45
{
46
        unsigned long flags;
47
        unsigned char current_mask, new_mask;
48
 
49
        save_flags(flags); cli();
50
        irq_nr &= NR_IRQS;
51
        current_mask = *interrupt_enable;
52
        switch(irq_nr) {
53
        case 1:
54
                new_mask = ((current_mask) & (~(SUN4C_INT_E1)));
55
                break;
56
        case 8:
57
                new_mask = ((current_mask) & (~(SUN4C_INT_E8)));
58
                break;
59
        case 10:
60
                new_mask = ((current_mask) & (~(SUN4C_INT_E10)));
61
                break;
62
        case 14:
63
                new_mask = ((current_mask) & (~(SUN4C_INT_E14)));
64
                break;
65
        default:
66
                restore_flags(flags);
67
                return;
68
        }
69
        *interrupt_enable = new_mask;
70
        restore_flags(flags);
71
}
72
 
73
static void sun4c_enable_irq(unsigned int irq_nr)
74
{
75
        unsigned long flags;
76
        unsigned char current_mask, new_mask;
77
 
78
        save_flags(flags); cli();
79
        irq_nr &= NR_IRQS;
80
        current_mask = *interrupt_enable;
81
        switch(irq_nr) {
82
        case 1:
83
                new_mask = ((current_mask) | SUN4C_INT_E1);
84
                break;
85
        case 8:
86
                new_mask = ((current_mask) | SUN4C_INT_E8);
87
                break;
88
        case 10:
89
                new_mask = ((current_mask) | SUN4C_INT_E10);
90
                break;
91
        case 14:
92
                new_mask = ((current_mask) | SUN4C_INT_E14);
93
                break;
94
        default:
95
                restore_flags(flags);
96
                return;
97
        }
98
        *interrupt_enable = new_mask;
99
        restore_flags(flags);
100
}
101
 
102
#define TIMER_IRQ       10    /* Also at level 14, but we ignore that one. */
103
#define PROFILE_IRQ     14    /* Level14 ticker.. used by OBP for polling */
104
 
105
volatile struct sun4c_timer_info *sun4c_timers;
106
 
107
static void sun4c_clear_clock_irq(void)
108
{
109
        volatile unsigned int clear_intr;
110
        clear_intr = sun4c_timers->timer_limit10;
111
}
112
 
113
static void sun4c_clear_profile_irq(void )
114
{
115
        /* Errm.. not sure how to do this.. */
116
}
117
 
118
static void sun4c_load_profile_irq(unsigned int limit)
119
{
120
        /* Errm.. not sure how to do this.. */
121
}
122
 
123
static void sun4c_init_timers(void (*counter_fn)(int, void *, struct pt_regs *))
124
{
125
        int irq;
126
 
127
        /* Map the Timer chip, this is implemented in hardware inside
128
         * the cache chip on the sun4c.
129
         */
130
        sun4c_timers = sparc_alloc_io ((void *) SUN4C_TIMER_PHYSADDR, 0,
131
                                       sizeof(struct sun4c_timer_info),
132
                                       "timer", 0x0, 0x0);
133
 
134
        /* Have the level 10 timer tick at 100HZ.  We don't touch the
135
         * level 14 timer limit since we are letting the prom handle
136
         * them until we have a real console driver so L1-A works.
137
         */
138
        sun4c_timers->timer_limit10 = (((1000000/HZ) + 1) << 10);
139
 
140
        irq = request_irq(TIMER_IRQ,
141
                          counter_fn,
142
                          (SA_INTERRUPT | SA_STATIC_ALLOC),
143
                          "timer", NULL);
144
        if (irq) {
145
                prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ);
146
                prom_halt();
147
        }
148
 
149
        claim_ticker14(NULL, PROFILE_IRQ, 0);
150
}
151
 
152
static void sun4c_nop(void)
153
{
154
}
155
 
156
void sun4c_init_IRQ(void)
157
{
158
        struct linux_prom_registers int_regs[2];
159
        int ie_node;
160
 
161
        ie_node = prom_searchsiblings (prom_getchild(prom_root_node),
162
                                       "interrupt-enable");
163
        if(ie_node == 0)
164
                panic("Cannot find /interrupt-enable node");
165
 
166
        /* Depending on the "address" property is bad news... */
167
        prom_getproperty(ie_node, "reg", (char *) int_regs, sizeof(int_regs));
168
        interrupt_enable = (char *) sparc_alloc_io(int_regs[0].phys_addr, 0,
169
                                                   int_regs[0].reg_size,
170
                                                   "sun4c_interrupts",
171
                                                   int_regs[0].which_io, 0x0);
172
        enable_irq = sun4c_enable_irq;
173
        disable_irq = sun4c_disable_irq;
174
        clear_clock_irq = sun4c_clear_clock_irq;
175
        clear_profile_irq = sun4c_clear_profile_irq;
176
        load_profile_irq = sun4c_load_profile_irq;
177
        init_timers = sun4c_init_timers;
178
#ifdef __SMP__
179
        set_cpu_int = sun4c_nop;
180
        clear_cpu_int = sun4c_nop;
181
        set_irq_udt = sun4c_nop;
182
#endif
183
        *interrupt_enable = (SUN4C_INT_ENABLE);
184
        sti();
185
}

powered by: WebSVN 2.1.0

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