diff options
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/entry.S | 20 | ||||
-rw-r--r-- | arch/sparc/kernel/head_32.S | 7 | ||||
-rw-r--r-- | arch/sparc/kernel/irq_32.c | 5 | ||||
-rw-r--r-- | arch/sparc/kernel/kernel.h | 3 | ||||
-rw-r--r-- | arch/sparc/kernel/process_32.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4c_irq.c | 269 |
7 files changed, 11 insertions, 297 deletions
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index cb85458f89d2..bfb93c37313c 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
@@ -28,7 +28,7 @@ obj-y += traps_$(BITS).o | |||
28 | 28 | ||
29 | # IRQ | 29 | # IRQ |
30 | obj-y += irq_$(BITS).o | 30 | obj-y += irq_$(BITS).o |
31 | obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o | 31 | obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4d_irq.o |
32 | 32 | ||
33 | obj-y += process_$(BITS).o | 33 | obj-y += process_$(BITS).o |
34 | obj-y += signal_$(BITS).o | 34 | obj-y += signal_$(BITS).o |
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index f445e98463e6..e0e0b8109225 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -317,8 +317,8 @@ maybe_smp4m_msg_out: | |||
317 | RESTORE_ALL | 317 | RESTORE_ALL |
318 | 318 | ||
319 | .align 4 | 319 | .align 4 |
320 | .globl linux_trap_ipi15_sun4m | 320 | .globl linux_trap_ipi15 |
321 | linux_trap_ipi15_sun4m: | 321 | linux_trap_ipi15: |
322 | SAVE_ALL | 322 | SAVE_ALL |
323 | sethi %hi(0x80000000), %o2 | 323 | sethi %hi(0x80000000), %o2 |
324 | GET_PROCESSOR4M_ID(o0) | 324 | GET_PROCESSOR4M_ID(o0) |
@@ -760,20 +760,12 @@ setcc_trap_handler: | |||
760 | jmp %l2 ! advance over trap instruction | 760 | jmp %l2 ! advance over trap instruction |
761 | rett %l2 + 0x4 ! like this... | 761 | rett %l2 + 0x4 ! like this... |
762 | 762 | ||
763 | #ifndef CONFIG_SMP | ||
763 | .align 4 | 764 | .align 4 |
764 | .globl linux_trap_nmi_sun4c | 765 | .globl linux_trap_ipi15 |
765 | linux_trap_nmi_sun4c: | 766 | linux_trap_ipi15: |
766 | SAVE_ALL | 767 | SAVE_ALL |
767 | 768 | ||
768 | /* Ugh, we need to clear the IRQ line. This is now | ||
769 | * a very sun4c specific trap handler... | ||
770 | */ | ||
771 | sethi %hi(interrupt_enable), %l5 | ||
772 | ld [%l5 + %lo(interrupt_enable)], %l5 | ||
773 | ldub [%l5], %l6 | ||
774 | andn %l6, INTS_ENAB, %l6 | ||
775 | stb %l6, [%l5] | ||
776 | |||
777 | /* Now it is safe to re-enable traps without recursion. */ | 769 | /* Now it is safe to re-enable traps without recursion. */ |
778 | or %l0, PSR_PIL, %l0 | 770 | or %l0, PSR_PIL, %l0 |
779 | wr %l0, PSR_ET, %psr | 771 | wr %l0, PSR_ET, %psr |
@@ -797,6 +789,8 @@ linux_trap_nmi_sun4c: | |||
797 | 789 | ||
798 | RESTORE_ALL | 790 | RESTORE_ALL |
799 | 791 | ||
792 | #endif /* CONFIG_SMP */ | ||
793 | |||
800 | .align 4 | 794 | .align 4 |
801 | .globl invalid_segment_patch1_ff | 795 | .globl invalid_segment_patch1_ff |
802 | .globl invalid_segment_patch2_ff | 796 | .globl invalid_segment_patch2_ff |
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 587785759838..054a49f3044c 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S | |||
@@ -111,11 +111,8 @@ t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */ | |||
111 | t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */ | 111 | t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */ |
112 | t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */ | 112 | t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */ |
113 | .globl t_nmi | 113 | .globl t_nmi |
114 | #ifndef CONFIG_SMP | 114 | t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15) |
115 | t_nmi: NMI_TRAP /* Level 15 (NMI) */ | 115 | |
116 | #else | ||
117 | t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) | ||
118 | #endif | ||
119 | t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */ | 116 | t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */ |
120 | t_iacce:BAD_TRAP(0x21) /* Instr Access Error */ | 117 | t_iacce:BAD_TRAP(0x21) /* Instr Access Error */ |
121 | t_bad22:BAD_TRAP(0x22) BAD_TRAP(0x23) | 118 | t_bad22:BAD_TRAP(0x22) BAD_TRAP(0x23) |
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index 4a2b8018ac97..998d90cb5439 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c | |||
@@ -346,11 +346,6 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
346 | void __init init_IRQ(void) | 346 | void __init init_IRQ(void) |
347 | { | 347 | { |
348 | switch (sparc_cpu_model) { | 348 | switch (sparc_cpu_model) { |
349 | case sun4c: | ||
350 | case sun4: | ||
351 | sun4c_init_IRQ(); | ||
352 | break; | ||
353 | |||
354 | case sun4m: | 349 | case sun4m: |
355 | pcic_probe(); | 350 | pcic_probe(); |
356 | if (pcic_present()) | 351 | if (pcic_present()) |
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 8abbad38e34e..8278df5d4ce7 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h | |||
@@ -43,9 +43,6 @@ extern spinlock_t irq_action_lock; | |||
43 | extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs); | 43 | extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs); |
44 | extern void init_IRQ(void); | 44 | extern void init_IRQ(void); |
45 | 45 | ||
46 | /* sun4c_irq.c */ | ||
47 | extern void sun4c_init_IRQ(void); | ||
48 | |||
49 | /* sun4m_irq.c */ | 46 | /* sun4m_irq.c */ |
50 | extern void sun4m_init_IRQ(void); | 47 | extern void sun4m_init_IRQ(void); |
51 | extern void sun4m_unmask_profile_irq(void); | 48 | extern void sun4m_unmask_profile_irq(void); |
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index efa07542e85f..de81e21cbf68 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c | |||
@@ -100,7 +100,7 @@ void cpu_idle(void) | |||
100 | printk("kernel faults / second = %ld\n", fps); | 100 | printk("kernel faults / second = %ld\n", fps); |
101 | #endif | 101 | #endif |
102 | if (fps >= SUN4C_FAULT_HIGH) { | 102 | if (fps >= SUN4C_FAULT_HIGH) { |
103 | sun4c_grow_kernel_ring(); | 103 | /*sun4c_grow_kernel_ring();*/ |
104 | } | 104 | } |
105 | } | 105 | } |
106 | local_irq_enable(); | 106 | local_irq_enable(); |
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c deleted file mode 100644 index 39c64211b1b6..000000000000 --- a/arch/sparc/kernel/sun4c_irq.c +++ /dev/null | |||
@@ -1,269 +0,0 @@ | |||
1 | /* | ||
2 | * sun4c irq support | ||
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@yahoo.com) | ||
9 | * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | |||
14 | #include <asm/oplib.h> | ||
15 | #include <asm/timer.h> | ||
16 | #include <asm/irq.h> | ||
17 | #include <asm/io.h> | ||
18 | |||
19 | #include "irq.h" | ||
20 | |||
21 | /* Sun4c interrupts are typically laid out as follows: | ||
22 | * | ||
23 | * 1 - Software interrupt, SBUS level 1 | ||
24 | * 2 - SBUS level 2 | ||
25 | * 3 - ESP SCSI, SBUS level 3 | ||
26 | * 4 - Software interrupt | ||
27 | * 5 - Lance ethernet, SBUS level 4 | ||
28 | * 6 - Software interrupt | ||
29 | * 7 - Graphics card, SBUS level 5 | ||
30 | * 8 - SBUS level 6 | ||
31 | * 9 - SBUS level 7 | ||
32 | * 10 - Counter timer | ||
33 | * 11 - Floppy | ||
34 | * 12 - Zilog uart | ||
35 | * 13 - CS4231 audio | ||
36 | * 14 - Profiling timer | ||
37 | * 15 - NMI | ||
38 | * | ||
39 | * The interrupt enable bits in the interrupt mask register are | ||
40 | * really only used to enable/disable the timer interrupts, and | ||
41 | * for signalling software interrupts. There is also a master | ||
42 | * interrupt enable bit in this register. | ||
43 | * | ||
44 | * Interrupts are enabled by setting the SUN4C_INT_* bits, they | ||
45 | * are disabled by clearing those bits. | ||
46 | */ | ||
47 | |||
48 | /* | ||
49 | * Bit field defines for the interrupt registers on various | ||
50 | * Sparc machines. | ||
51 | */ | ||
52 | |||
53 | /* The sun4c interrupt register. */ | ||
54 | #define SUN4C_INT_ENABLE 0x01 /* Allow interrupts. */ | ||
55 | #define SUN4C_INT_E14 0x80 /* Enable level 14 IRQ. */ | ||
56 | #define SUN4C_INT_E10 0x20 /* Enable level 10 IRQ. */ | ||
57 | #define SUN4C_INT_E8 0x10 /* Enable level 8 IRQ. */ | ||
58 | #define SUN4C_INT_E6 0x08 /* Enable level 6 IRQ. */ | ||
59 | #define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */ | ||
60 | #define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */ | ||
61 | |||
62 | /* | ||
63 | * Pointer to the interrupt enable byte | ||
64 | * Used by entry.S | ||
65 | */ | ||
66 | unsigned char __iomem *interrupt_enable; | ||
67 | |||
68 | static void sun4c_mask_irq(struct irq_data *data) | ||
69 | { | ||
70 | unsigned long mask = (unsigned long)data->chip_data; | ||
71 | |||
72 | if (mask) { | ||
73 | unsigned long flags; | ||
74 | |||
75 | local_irq_save(flags); | ||
76 | mask = sbus_readb(interrupt_enable) & ~mask; | ||
77 | sbus_writeb(mask, interrupt_enable); | ||
78 | local_irq_restore(flags); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static void sun4c_unmask_irq(struct irq_data *data) | ||
83 | { | ||
84 | unsigned long mask = (unsigned long)data->chip_data; | ||
85 | |||
86 | if (mask) { | ||
87 | unsigned long flags; | ||
88 | |||
89 | local_irq_save(flags); | ||
90 | mask = sbus_readb(interrupt_enable) | mask; | ||
91 | sbus_writeb(mask, interrupt_enable); | ||
92 | local_irq_restore(flags); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | static unsigned int sun4c_startup_irq(struct irq_data *data) | ||
97 | { | ||
98 | irq_link(data->irq); | ||
99 | sun4c_unmask_irq(data); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static void sun4c_shutdown_irq(struct irq_data *data) | ||
105 | { | ||
106 | sun4c_mask_irq(data); | ||
107 | irq_unlink(data->irq); | ||
108 | } | ||
109 | |||
110 | static struct irq_chip sun4c_irq = { | ||
111 | .name = "sun4c", | ||
112 | .irq_startup = sun4c_startup_irq, | ||
113 | .irq_shutdown = sun4c_shutdown_irq, | ||
114 | .irq_mask = sun4c_mask_irq, | ||
115 | .irq_unmask = sun4c_unmask_irq, | ||
116 | }; | ||
117 | |||
118 | static unsigned int sun4c_build_device_irq(struct platform_device *op, | ||
119 | unsigned int real_irq) | ||
120 | { | ||
121 | unsigned int irq; | ||
122 | |||
123 | if (real_irq >= 16) { | ||
124 | prom_printf("Bogus sun4c IRQ %u\n", real_irq); | ||
125 | prom_halt(); | ||
126 | } | ||
127 | |||
128 | irq = irq_alloc(real_irq, real_irq); | ||
129 | if (irq) { | ||
130 | unsigned long mask = 0UL; | ||
131 | |||
132 | switch (real_irq) { | ||
133 | case 1: | ||
134 | mask = SUN4C_INT_E1; | ||
135 | break; | ||
136 | case 8: | ||
137 | mask = SUN4C_INT_E8; | ||
138 | break; | ||
139 | case 10: | ||
140 | mask = SUN4C_INT_E10; | ||
141 | break; | ||
142 | case 14: | ||
143 | mask = SUN4C_INT_E14; | ||
144 | break; | ||
145 | default: | ||
146 | /* All the rest are either always enabled, | ||
147 | * or are for signalling software interrupts. | ||
148 | */ | ||
149 | break; | ||
150 | } | ||
151 | irq_set_chip_and_handler_name(irq, &sun4c_irq, | ||
152 | handle_level_irq, "level"); | ||
153 | irq_set_chip_data(irq, (void *)mask); | ||
154 | } | ||
155 | return irq; | ||
156 | } | ||
157 | |||
158 | struct sun4c_timer_info { | ||
159 | u32 l10_count; | ||
160 | u32 l10_limit; | ||
161 | u32 l14_count; | ||
162 | u32 l14_limit; | ||
163 | }; | ||
164 | |||
165 | static struct sun4c_timer_info __iomem *sun4c_timers; | ||
166 | |||
167 | static void sun4c_clear_clock_irq(void) | ||
168 | { | ||
169 | sbus_readl(&sun4c_timers->l10_limit); | ||
170 | } | ||
171 | |||
172 | static void sun4c_load_profile_irq(int cpu, unsigned int limit) | ||
173 | { | ||
174 | /* Errm.. not sure how to do this.. */ | ||
175 | } | ||
176 | |||
177 | static void __init sun4c_init_timers(void) | ||
178 | { | ||
179 | const struct linux_prom_irqs *prom_irqs; | ||
180 | struct device_node *dp; | ||
181 | unsigned int irq; | ||
182 | const u32 *addr; | ||
183 | int err; | ||
184 | |||
185 | dp = of_find_node_by_name(NULL, "counter-timer"); | ||
186 | if (!dp) { | ||
187 | prom_printf("sun4c_init_timers: Unable to find counter-timer\n"); | ||
188 | prom_halt(); | ||
189 | } | ||
190 | |||
191 | addr = of_get_property(dp, "address", NULL); | ||
192 | if (!addr) { | ||
193 | prom_printf("sun4c_init_timers: No address property\n"); | ||
194 | prom_halt(); | ||
195 | } | ||
196 | |||
197 | sun4c_timers = (void __iomem *) (unsigned long) addr[0]; | ||
198 | |||
199 | prom_irqs = of_get_property(dp, "intr", NULL); | ||
200 | of_node_put(dp); | ||
201 | if (!prom_irqs) { | ||
202 | prom_printf("sun4c_init_timers: No intr property\n"); | ||
203 | prom_halt(); | ||
204 | } | ||
205 | |||
206 | /* Have the level 10 timer tick at 100HZ. We don't touch the | ||
207 | * level 14 timer limit since we are letting the prom handle | ||
208 | * them until we have a real console driver so L1-A works. | ||
209 | */ | ||
210 | sparc_config.cs_period = SBUS_CLOCK_RATE / HZ; | ||
211 | sparc_config.features |= | ||
212 | FEAT_L10_CLOCKSOURCE | FEAT_L10_CLOCKEVENT; | ||
213 | sbus_writel(timer_value(sparc_config.cs_period), | ||
214 | &sun4c_timers->l10_limit); | ||
215 | |||
216 | master_l10_counter = &sun4c_timers->l10_count; | ||
217 | |||
218 | irq = sun4c_build_device_irq(NULL, prom_irqs[0].pri); | ||
219 | err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); | ||
220 | if (err) { | ||
221 | prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err); | ||
222 | prom_halt(); | ||
223 | } | ||
224 | |||
225 | /* disable timer interrupt */ | ||
226 | sun4c_mask_irq(irq_get_irq_data(irq)); | ||
227 | } | ||
228 | |||
229 | #ifdef CONFIG_SMP | ||
230 | static void sun4c_nop(void) | ||
231 | { | ||
232 | } | ||
233 | #endif | ||
234 | |||
235 | void __init sun4c_init_IRQ(void) | ||
236 | { | ||
237 | struct device_node *dp; | ||
238 | const u32 *addr; | ||
239 | |||
240 | dp = of_find_node_by_name(NULL, "interrupt-enable"); | ||
241 | if (!dp) { | ||
242 | prom_printf("sun4c_init_IRQ: Unable to find interrupt-enable\n"); | ||
243 | prom_halt(); | ||
244 | } | ||
245 | |||
246 | addr = of_get_property(dp, "address", NULL); | ||
247 | of_node_put(dp); | ||
248 | if (!addr) { | ||
249 | prom_printf("sun4c_init_IRQ: No address property\n"); | ||
250 | prom_halt(); | ||
251 | } | ||
252 | |||
253 | interrupt_enable = (void __iomem *) (unsigned long) addr[0]; | ||
254 | |||
255 | BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM); | ||
256 | BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP); | ||
257 | |||
258 | sparc_config.init_timers = sun4c_init_timers; | ||
259 | sparc_config.build_device_irq = sun4c_build_device_irq; | ||
260 | sparc_config.clock_rate = SBUS_CLOCK_RATE; | ||
261 | |||
262 | #ifdef CONFIG_SMP | ||
263 | BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); | ||
264 | BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); | ||
265 | BTFIXUPSET_CALL(set_irq_udt, sun4c_nop, BTFIXUPCALL_NOP); | ||
266 | #endif | ||
267 | sbus_writeb(SUN4C_INT_ENABLE, interrupt_enable); | ||
268 | /* Cannot enable interrupts until OBP ticker is disabled. */ | ||
269 | } | ||