diff options
Diffstat (limited to 'arch/mips/sibyte')
-rw-r--r-- | arch/mips/sibyte/Kconfig | 161 | ||||
-rw-r--r-- | arch/mips/sibyte/bcm1480/Makefile | 5 | ||||
-rw-r--r-- | arch/mips/sibyte/bcm1480/irq.c | 476 | ||||
-rw-r--r-- | arch/mips/sibyte/bcm1480/irq_handler.S | 165 | ||||
-rw-r--r-- | arch/mips/sibyte/bcm1480/setup.c | 136 | ||||
-rw-r--r-- | arch/mips/sibyte/bcm1480/smp.c | 110 | ||||
-rw-r--r-- | arch/mips/sibyte/bcm1480/time.c | 138 | ||||
-rw-r--r-- | arch/mips/sibyte/cfe/smp.c | 14 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/bcm1250_tbprof.c | 154 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/bus_watcher.c | 2 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/irq.c | 121 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/setup.c | 4 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/smp.c | 18 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/time.c | 44 | ||||
-rw-r--r-- | arch/mips/sibyte/swarm/rtc_m41t81.c | 47 | ||||
-rw-r--r-- | arch/mips/sibyte/swarm/rtc_xicor1241.c | 42 | ||||
-rw-r--r-- | arch/mips/sibyte/swarm/setup.c | 41 | ||||
-rw-r--r-- | arch/mips/sibyte/swarm/time.c | 44 |
18 files changed, 1477 insertions, 245 deletions
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig new file mode 100644 index 000000000000..de46f62ac462 --- /dev/null +++ b/arch/mips/sibyte/Kconfig | |||
@@ -0,0 +1,161 @@ | |||
1 | config SIBYTE_SB1250 | ||
2 | bool | ||
3 | select HW_HAS_PCI | ||
4 | select SIBYTE_HAS_LDT | ||
5 | select SIBYTE_SB1xxx_SOC | ||
6 | |||
7 | config SIBYTE_BCM1120 | ||
8 | bool | ||
9 | select SIBYTE_BCM112X | ||
10 | select SIBYTE_SB1xxx_SOC | ||
11 | |||
12 | config SIBYTE_BCM1125 | ||
13 | bool | ||
14 | select HW_HAS_PCI | ||
15 | select SIBYTE_BCM112X | ||
16 | select SIBYTE_SB1xxx_SOC | ||
17 | |||
18 | config SIBYTE_BCM1125H | ||
19 | bool | ||
20 | select HW_HAS_PCI | ||
21 | select SIBYTE_BCM112X | ||
22 | select SIBYTE_HAS_LDT | ||
23 | select SIBYTE_SB1xxx_SOC | ||
24 | |||
25 | config SIBYTE_BCM112X | ||
26 | bool | ||
27 | select SIBYTE_SB1xxx_SOC | ||
28 | |||
29 | config SIBYTE_BCM1x80 | ||
30 | bool | ||
31 | select HW_HAS_PCI | ||
32 | select SIBYTE_SB1xxx_SOC | ||
33 | |||
34 | config SIBYTE_BCM1x55 | ||
35 | bool | ||
36 | select HW_HAS_PCI | ||
37 | select SIBYTE_SB1xxx_SOC | ||
38 | |||
39 | config SIBYTE_SB1xxx_SOC | ||
40 | bool | ||
41 | depends on EXPERIMENTAL | ||
42 | select DMA_COHERENT | ||
43 | select SIBYTE_CFE | ||
44 | select SWAP_IO_SPACE | ||
45 | select SYS_SUPPORTS_32BIT_KERNEL | ||
46 | select SYS_SUPPORTS_64BIT_KERNEL | ||
47 | |||
48 | choice | ||
49 | prompt "SiByte SOC Stepping" | ||
50 | depends on SIBYTE_SB1xxx_SOC | ||
51 | |||
52 | config CPU_SB1_PASS_1 | ||
53 | bool "1250 Pass1" | ||
54 | depends on SIBYTE_SB1250 | ||
55 | select CPU_HAS_PREFETCH | ||
56 | |||
57 | config CPU_SB1_PASS_2_1250 | ||
58 | bool "1250 An" | ||
59 | depends on SIBYTE_SB1250 | ||
60 | select CPU_SB1_PASS_2 | ||
61 | help | ||
62 | Also called BCM1250 Pass 2 | ||
63 | |||
64 | config CPU_SB1_PASS_2_2 | ||
65 | bool "1250 Bn" | ||
66 | depends on SIBYTE_SB1250 | ||
67 | select CPU_HAS_PREFETCH | ||
68 | help | ||
69 | Also called BCM1250 Pass 2.2 | ||
70 | |||
71 | config CPU_SB1_PASS_4 | ||
72 | bool "1250 Cn" | ||
73 | depends on SIBYTE_SB1250 | ||
74 | select CPU_HAS_PREFETCH | ||
75 | help | ||
76 | Also called BCM1250 Pass 3 | ||
77 | |||
78 | config CPU_SB1_PASS_2_112x | ||
79 | bool "112x Hybrid" | ||
80 | depends on SIBYTE_BCM112X | ||
81 | select CPU_SB1_PASS_2 | ||
82 | |||
83 | config CPU_SB1_PASS_3 | ||
84 | bool "112x An" | ||
85 | depends on SIBYTE_BCM112X | ||
86 | select CPU_HAS_PREFETCH | ||
87 | |||
88 | endchoice | ||
89 | |||
90 | config CPU_SB1_PASS_2 | ||
91 | bool | ||
92 | |||
93 | config SIBYTE_HAS_LDT | ||
94 | bool | ||
95 | depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H) | ||
96 | default y | ||
97 | |||
98 | config SIMULATION | ||
99 | bool "Running under simulation" | ||
100 | depends on SIBYTE_SB1xxx_SOC | ||
101 | help | ||
102 | Build a kernel suitable for running under the GDB simulator. | ||
103 | Primarily adjusts the kernel's notion of time. | ||
104 | |||
105 | config CONFIG_SB1_CEX_ALWAYS_FATAL | ||
106 | bool "All cache exceptions considered fatal (no recovery attempted)" | ||
107 | depends on SIBYTE_SB1xxx_SOC | ||
108 | |||
109 | config CONFIG_SB1_CERR_STALL | ||
110 | bool "Stall (rather than panic) on fatal cache error" | ||
111 | depends on SIBYTE_SB1xxx_SOC | ||
112 | |||
113 | config SIBYTE_CFE | ||
114 | bool "Booting from CFE" | ||
115 | depends on SIBYTE_SB1xxx_SOC | ||
116 | help | ||
117 | Make use of the CFE API for enumerating available memory, | ||
118 | controlling secondary CPUs, and possibly console output. | ||
119 | |||
120 | config SIBYTE_CFE_CONSOLE | ||
121 | bool "Use firmware console" | ||
122 | depends on SIBYTE_CFE | ||
123 | help | ||
124 | Use the CFE API's console write routines during boot. Other console | ||
125 | options (VT console, sb1250 duart console, etc.) should not be | ||
126 | configured. | ||
127 | |||
128 | config SIBYTE_STANDALONE | ||
129 | bool | ||
130 | depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE | ||
131 | default y | ||
132 | |||
133 | config SIBYTE_STANDALONE_RAM_SIZE | ||
134 | int "Memory size (in megabytes)" | ||
135 | depends on SIBYTE_STANDALONE | ||
136 | default "32" | ||
137 | |||
138 | config SIBYTE_BUS_WATCHER | ||
139 | bool "Support for Bus Watcher statistics" | ||
140 | depends on SIBYTE_SB1xxx_SOC | ||
141 | help | ||
142 | Handle and keep statistics on the bus error interrupts (COR_ECC, | ||
143 | BAD_ECC, IO_BUS). | ||
144 | |||
145 | config SIBYTE_BW_TRACE | ||
146 | bool "Capture bus trace before bus error" | ||
147 | depends on SIBYTE_BUS_WATCHER | ||
148 | help | ||
149 | Run a continuous bus trace, dumping the raw data as soon as | ||
150 | a ZBbus error is detected. Cannot work if ZBbus profiling | ||
151 | is turned on, and also will interfere with JTAG-based trace | ||
152 | buffer activity. Raw buffer data is dumped to console, and | ||
153 | must be processed off-line. | ||
154 | |||
155 | config SIBYTE_SB1250_PROF | ||
156 | bool "Support for SB1/SOC profiling - SB1/SCD perf counters" | ||
157 | depends on SIBYTE_SB1xxx_SOC | ||
158 | |||
159 | config SIBYTE_TBPROF | ||
160 | bool "Support for ZBbus profiling" | ||
161 | depends on SIBYTE_SB1xxx_SOC | ||
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile new file mode 100644 index 000000000000..538d5a51ae94 --- /dev/null +++ b/arch/mips/sibyte/bcm1480/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-y := setup.o irq.o irq_handler.o time.o | ||
2 | |||
3 | obj-$(CONFIG_SMP) += smp.o | ||
4 | |||
5 | EXTRA_AFLAGS := $(CFLAGS) | ||
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c new file mode 100644 index 000000000000..b2a1ba5d23df --- /dev/null +++ b/arch/mips/sibyte/bcm1480/irq.c | |||
@@ -0,0 +1,476 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | #include <linux/config.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/linkage.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/kernel_stat.h> | ||
27 | |||
28 | #include <asm/errno.h> | ||
29 | #include <asm/signal.h> | ||
30 | #include <asm/system.h> | ||
31 | #include <asm/ptrace.h> | ||
32 | #include <asm/io.h> | ||
33 | |||
34 | #include <asm/sibyte/bcm1480_regs.h> | ||
35 | #include <asm/sibyte/bcm1480_int.h> | ||
36 | #include <asm/sibyte/bcm1480_scd.h> | ||
37 | |||
38 | #include <asm/sibyte/sb1250_uart.h> | ||
39 | #include <asm/sibyte/sb1250.h> | ||
40 | |||
41 | /* | ||
42 | * These are the routines that handle all the low level interrupt stuff. | ||
43 | * Actions handled here are: initialization of the interrupt map, requesting of | ||
44 | * interrupt lines by handlers, dispatching if interrupts to handlers, probing | ||
45 | * for interrupt lines | ||
46 | */ | ||
47 | |||
48 | |||
49 | #define shutdown_bcm1480_irq disable_bcm1480_irq | ||
50 | static void end_bcm1480_irq(unsigned int irq); | ||
51 | static void enable_bcm1480_irq(unsigned int irq); | ||
52 | static void disable_bcm1480_irq(unsigned int irq); | ||
53 | static unsigned int startup_bcm1480_irq(unsigned int irq); | ||
54 | static void ack_bcm1480_irq(unsigned int irq); | ||
55 | #ifdef CONFIG_SMP | ||
56 | static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask); | ||
57 | #endif | ||
58 | |||
59 | #ifdef CONFIG_PCI | ||
60 | extern unsigned long ht_eoi_space; | ||
61 | #endif | ||
62 | |||
63 | #ifdef CONFIG_KGDB | ||
64 | #include <asm/gdb-stub.h> | ||
65 | extern void breakpoint(void); | ||
66 | static int kgdb_irq; | ||
67 | #ifdef CONFIG_GDB_CONSOLE | ||
68 | extern void register_gdb_console(void); | ||
69 | #endif | ||
70 | |||
71 | /* kgdb is on when configured. Pass "nokgdb" kernel arg to turn it off */ | ||
72 | static int kgdb_flag = 1; | ||
73 | static int __init nokgdb(char *str) | ||
74 | { | ||
75 | kgdb_flag = 0; | ||
76 | return 1; | ||
77 | } | ||
78 | __setup("nokgdb", nokgdb); | ||
79 | |||
80 | /* Default to UART1 */ | ||
81 | int kgdb_port = 1; | ||
82 | #ifdef CONFIG_SIBYTE_SB1250_DUART | ||
83 | extern char sb1250_duart_present[]; | ||
84 | #endif | ||
85 | #endif | ||
86 | |||
87 | static struct hw_interrupt_type bcm1480_irq_type = { | ||
88 | .typename = "BCM1480-IMR", | ||
89 | .startup = startup_bcm1480_irq, | ||
90 | .shutdown = shutdown_bcm1480_irq, | ||
91 | .enable = enable_bcm1480_irq, | ||
92 | .disable = disable_bcm1480_irq, | ||
93 | .ack = ack_bcm1480_irq, | ||
94 | .end = end_bcm1480_irq, | ||
95 | #ifdef CONFIG_SMP | ||
96 | .set_affinity = bcm1480_set_affinity | ||
97 | #endif | ||
98 | }; | ||
99 | |||
100 | /* Store the CPU id (not the logical number) */ | ||
101 | int bcm1480_irq_owner[BCM1480_NR_IRQS]; | ||
102 | |||
103 | DEFINE_SPINLOCK(bcm1480_imr_lock); | ||
104 | |||
105 | void bcm1480_mask_irq(int cpu, int irq) | ||
106 | { | ||
107 | unsigned long flags; | ||
108 | u64 cur_ints,hl_spacing; | ||
109 | |||
110 | spin_lock_irqsave(&bcm1480_imr_lock, flags); | ||
111 | hl_spacing = 0; | ||
112 | if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) { | ||
113 | hl_spacing = BCM1480_IMR_HL_SPACING; | ||
114 | irq -= BCM1480_NR_IRQS_HALF; | ||
115 | } | ||
116 | cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing)); | ||
117 | cur_ints |= (((u64) 1) << irq); | ||
118 | ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing)); | ||
119 | spin_unlock_irqrestore(&bcm1480_imr_lock, flags); | ||
120 | } | ||
121 | |||
122 | void bcm1480_unmask_irq(int cpu, int irq) | ||
123 | { | ||
124 | unsigned long flags; | ||
125 | u64 cur_ints,hl_spacing; | ||
126 | |||
127 | spin_lock_irqsave(&bcm1480_imr_lock, flags); | ||
128 | hl_spacing = 0; | ||
129 | if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) { | ||
130 | hl_spacing = BCM1480_IMR_HL_SPACING; | ||
131 | irq -= BCM1480_NR_IRQS_HALF; | ||
132 | } | ||
133 | cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing)); | ||
134 | cur_ints &= ~(((u64) 1) << irq); | ||
135 | ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing)); | ||
136 | spin_unlock_irqrestore(&bcm1480_imr_lock, flags); | ||
137 | } | ||
138 | |||
139 | #ifdef CONFIG_SMP | ||
140 | static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask) | ||
141 | { | ||
142 | int i = 0, old_cpu, cpu, int_on; | ||
143 | u64 cur_ints; | ||
144 | irq_desc_t *desc = irq_desc + irq; | ||
145 | unsigned long flags; | ||
146 | unsigned int irq_dirty; | ||
147 | |||
148 | i = first_cpu(mask); | ||
149 | if (next_cpu(i, mask) <= NR_CPUS) { | ||
150 | printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq); | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | /* Convert logical CPU to physical CPU */ | ||
155 | cpu = cpu_logical_map(i); | ||
156 | |||
157 | /* Protect against other affinity changers and IMR manipulation */ | ||
158 | spin_lock_irqsave(&desc->lock, flags); | ||
159 | spin_lock(&bcm1480_imr_lock); | ||
160 | |||
161 | /* Swizzle each CPU's IMR (but leave the IP selection alone) */ | ||
162 | old_cpu = bcm1480_irq_owner[irq]; | ||
163 | irq_dirty = irq; | ||
164 | if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) { | ||
165 | irq_dirty -= BCM1480_NR_IRQS_HALF; | ||
166 | } | ||
167 | |||
168 | int k; | ||
169 | for (k=0; k<2; k++) { /* Loop through high and low interrupt mask register */ | ||
170 | cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING))); | ||
171 | int_on = !(cur_ints & (((u64) 1) << irq_dirty)); | ||
172 | if (int_on) { | ||
173 | /* If it was on, mask it */ | ||
174 | cur_ints |= (((u64) 1) << irq_dirty); | ||
175 | ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING))); | ||
176 | } | ||
177 | bcm1480_irq_owner[irq] = cpu; | ||
178 | if (int_on) { | ||
179 | /* unmask for the new CPU */ | ||
180 | cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING))); | ||
181 | cur_ints &= ~(((u64) 1) << irq_dirty); | ||
182 | ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING))); | ||
183 | } | ||
184 | } | ||
185 | spin_unlock(&bcm1480_imr_lock); | ||
186 | spin_unlock_irqrestore(&desc->lock, flags); | ||
187 | } | ||
188 | #endif | ||
189 | |||
190 | |||
191 | /* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */ | ||
192 | extern void bcm1480_irq_handler(void); | ||
193 | |||
194 | /*****************************************************************************/ | ||
195 | |||
196 | static unsigned int startup_bcm1480_irq(unsigned int irq) | ||
197 | { | ||
198 | bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); | ||
199 | |||
200 | return 0; /* never anything pending */ | ||
201 | } | ||
202 | |||
203 | |||
204 | static void disable_bcm1480_irq(unsigned int irq) | ||
205 | { | ||
206 | bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); | ||
207 | } | ||
208 | |||
209 | static void enable_bcm1480_irq(unsigned int irq) | ||
210 | { | ||
211 | bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); | ||
212 | } | ||
213 | |||
214 | |||
215 | static void ack_bcm1480_irq(unsigned int irq) | ||
216 | { | ||
217 | u64 pending; | ||
218 | unsigned int irq_dirty; | ||
219 | |||
220 | /* | ||
221 | * If the interrupt was an HT interrupt, now is the time to | ||
222 | * clear it. NOTE: we assume the HT bridge was set up to | ||
223 | * deliver the interrupts to all CPUs (which makes affinity | ||
224 | * changing easier for us) | ||
225 | */ | ||
226 | irq_dirty = irq; | ||
227 | if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) { | ||
228 | irq_dirty -= BCM1480_NR_IRQS_HALF; | ||
229 | } | ||
230 | int k; | ||
231 | for (k=0; k<2; k++) { /* Loop through high and low LDT interrupts */ | ||
232 | pending = __raw_readq(IOADDR(A_BCM1480_IMR_REGISTER(bcm1480_irq_owner[irq], | ||
233 | R_BCM1480_IMR_LDT_INTERRUPT_H + (k*BCM1480_IMR_HL_SPACING)))); | ||
234 | pending &= ((u64)1 << (irq_dirty)); | ||
235 | if (pending) { | ||
236 | #ifdef CONFIG_SMP | ||
237 | int i; | ||
238 | for (i=0; i<NR_CPUS; i++) { | ||
239 | /* | ||
240 | * Clear for all CPUs so an affinity switch | ||
241 | * doesn't find an old status | ||
242 | */ | ||
243 | __raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(cpu_logical_map(i), | ||
244 | R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING)))); | ||
245 | } | ||
246 | #else | ||
247 | __raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING)))); | ||
248 | #endif | ||
249 | |||
250 | /* | ||
251 | * Generate EOI. For Pass 1 parts, EOI is a nop. For | ||
252 | * Pass 2, the LDT world may be edge-triggered, but | ||
253 | * this EOI shouldn't hurt. If they are | ||
254 | * level-sensitive, the EOI is required. | ||
255 | */ | ||
256 | #ifdef CONFIG_PCI | ||
257 | if (ht_eoi_space) | ||
258 | *(uint32_t *)(ht_eoi_space+(irq<<16)+(7<<2)) = 0; | ||
259 | #endif | ||
260 | } | ||
261 | } | ||
262 | bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); | ||
263 | } | ||
264 | |||
265 | |||
266 | static void end_bcm1480_irq(unsigned int irq) | ||
267 | { | ||
268 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { | ||
269 | bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | |||
274 | void __init init_bcm1480_irqs(void) | ||
275 | { | ||
276 | int i; | ||
277 | |||
278 | for (i = 0; i < NR_IRQS; i++) { | ||
279 | irq_desc[i].status = IRQ_DISABLED; | ||
280 | irq_desc[i].action = 0; | ||
281 | irq_desc[i].depth = 1; | ||
282 | if (i < BCM1480_NR_IRQS) { | ||
283 | irq_desc[i].handler = &bcm1480_irq_type; | ||
284 | bcm1480_irq_owner[i] = 0; | ||
285 | } else { | ||
286 | irq_desc[i].handler = &no_irq_type; | ||
287 | } | ||
288 | } | ||
289 | } | ||
290 | |||
291 | |||
292 | static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id, | ||
293 | struct pt_regs *regs) | ||
294 | { | ||
295 | return IRQ_NONE; | ||
296 | } | ||
297 | |||
298 | static struct irqaction bcm1480_dummy_action = { | ||
299 | .handler = bcm1480_dummy_handler, | ||
300 | .flags = 0, | ||
301 | .mask = CPU_MASK_NONE, | ||
302 | .name = "bcm1480-private", | ||
303 | .next = NULL, | ||
304 | .dev_id = 0 | ||
305 | }; | ||
306 | |||
307 | int bcm1480_steal_irq(int irq) | ||
308 | { | ||
309 | irq_desc_t *desc = irq_desc + irq; | ||
310 | unsigned long flags; | ||
311 | int retval = 0; | ||
312 | |||
313 | if (irq >= BCM1480_NR_IRQS) | ||
314 | return -EINVAL; | ||
315 | |||
316 | spin_lock_irqsave(&desc->lock,flags); | ||
317 | /* Don't allow sharing at all for these */ | ||
318 | if (desc->action != NULL) | ||
319 | retval = -EBUSY; | ||
320 | else { | ||
321 | desc->action = &bcm1480_dummy_action; | ||
322 | desc->depth = 0; | ||
323 | } | ||
324 | spin_unlock_irqrestore(&desc->lock,flags); | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * init_IRQ is called early in the boot sequence from init/main.c. It | ||
330 | * is responsible for setting up the interrupt mapper and installing the | ||
331 | * handler that will be responsible for dispatching interrupts to the | ||
332 | * "right" place. | ||
333 | */ | ||
334 | /* | ||
335 | * For now, map all interrupts to IP[2]. We could save | ||
336 | * some cycles by parceling out system interrupts to different | ||
337 | * IP lines, but keep it simple for bringup. We'll also direct | ||
338 | * all interrupts to a single CPU; we should probably route | ||
339 | * PCI and LDT to one cpu and everything else to the other | ||
340 | * to balance the load a bit. | ||
341 | * | ||
342 | * On the second cpu, everything is set to IP5, which is | ||
343 | * ignored, EXCEPT the mailbox interrupt. That one is | ||
344 | * set to IP[2] so it is handled. This is needed so we | ||
345 | * can do cross-cpu function calls, as requred by SMP | ||
346 | */ | ||
347 | |||
348 | #define IMR_IP2_VAL K_BCM1480_INT_MAP_I0 | ||
349 | #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 | ||
350 | #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 | ||
351 | #define IMR_IP5_VAL K_BCM1480_INT_MAP_I3 | ||
352 | #define IMR_IP6_VAL K_BCM1480_INT_MAP_I4 | ||
353 | |||
354 | void __init arch_init_irq(void) | ||
355 | { | ||
356 | |||
357 | unsigned int i, cpu; | ||
358 | u64 tmp; | ||
359 | unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | | ||
360 | STATUSF_IP1 | STATUSF_IP0; | ||
361 | |||
362 | /* Default everything to IP2 */ | ||
363 | /* Start with _high registers which has no bit 0 interrupt source */ | ||
364 | for (i = 1; i < BCM1480_NR_IRQS_HALF; i++) { /* was I0 */ | ||
365 | for (cpu = 0; cpu < 4; cpu++) { | ||
366 | __raw_writeq(IMR_IP2_VAL, | ||
367 | IOADDR(A_BCM1480_IMR_REGISTER(cpu, | ||
368 | R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (i << 3))); | ||
369 | } | ||
370 | } | ||
371 | |||
372 | /* Now do _low registers */ | ||
373 | for (i = 0; i < BCM1480_NR_IRQS_HALF; i++) { | ||
374 | for (cpu = 0; cpu < 4; cpu++) { | ||
375 | __raw_writeq(IMR_IP2_VAL, | ||
376 | IOADDR(A_BCM1480_IMR_REGISTER(cpu, | ||
377 | R_BCM1480_IMR_INTERRUPT_MAP_BASE_L) + (i << 3))); | ||
378 | } | ||
379 | } | ||
380 | |||
381 | init_bcm1480_irqs(); | ||
382 | |||
383 | /* | ||
384 | * Map the high 16 bits of mailbox_0 registers to IP[3], for | ||
385 | * inter-cpu messages | ||
386 | */ | ||
387 | /* Was I1 */ | ||
388 | for (cpu = 0; cpu < 4; cpu++) { | ||
389 | __raw_writeq(IMR_IP3_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + | ||
390 | (K_BCM1480_INT_MBOX_0_0 << 3))); | ||
391 | } | ||
392 | |||
393 | |||
394 | /* Clear the mailboxes. The firmware may leave them dirty */ | ||
395 | for (cpu = 0; cpu < 4; cpu++) { | ||
396 | __raw_writeq(0xffffffffffffffffULL, | ||
397 | IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_0_CLR_CPU))); | ||
398 | __raw_writeq(0xffffffffffffffffULL, | ||
399 | IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_1_CLR_CPU))); | ||
400 | } | ||
401 | |||
402 | |||
403 | /* Mask everything except the high 16 bit of mailbox_0 registers for all cpus */ | ||
404 | tmp = ~((u64) 0) ^ ( (((u64) 1) << K_BCM1480_INT_MBOX_0_0)); | ||
405 | for (cpu = 0; cpu < 4; cpu++) { | ||
406 | __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_H))); | ||
407 | } | ||
408 | tmp = ~((u64) 0); | ||
409 | for (cpu = 0; cpu < 4; cpu++) { | ||
410 | __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L))); | ||
411 | } | ||
412 | |||
413 | bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0); | ||
414 | |||
415 | /* | ||
416 | * Note that the timer interrupts are also mapped, but this is | ||
417 | * done in bcm1480_time_init(). Also, the profiling driver | ||
418 | * does its own management of IP7. | ||
419 | */ | ||
420 | |||
421 | #ifdef CONFIG_KGDB | ||
422 | imask |= STATUSF_IP6; | ||
423 | #endif | ||
424 | /* Enable necessary IPs, disable the rest */ | ||
425 | change_c0_status(ST0_IM, imask); | ||
426 | set_except_vector(0, bcm1480_irq_handler); | ||
427 | |||
428 | #ifdef CONFIG_KGDB | ||
429 | if (kgdb_flag) { | ||
430 | kgdb_irq = K_BCM1480_INT_UART_0 + kgdb_port; | ||
431 | |||
432 | #ifdef CONFIG_SIBYTE_SB1250_DUART | ||
433 | sb1250_duart_present[kgdb_port] = 0; | ||
434 | #endif | ||
435 | /* Setup uart 1 settings, mapper */ | ||
436 | /* QQQ FIXME */ | ||
437 | __raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port)); | ||
438 | |||
439 | bcm1480_steal_irq(kgdb_irq); | ||
440 | __raw_writeq(IMR_IP6_VAL, | ||
441 | IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + | ||
442 | (kgdb_irq<<3)); | ||
443 | bcm1480_unmask_irq(0, kgdb_irq); | ||
444 | |||
445 | #ifdef CONFIG_GDB_CONSOLE | ||
446 | register_gdb_console(); | ||
447 | #endif | ||
448 | prom_printf("Waiting for GDB on UART port %d\n", kgdb_port); | ||
449 | set_debug_traps(); | ||
450 | breakpoint(); | ||
451 | } | ||
452 | #endif | ||
453 | } | ||
454 | |||
455 | #ifdef CONFIG_KGDB | ||
456 | |||
457 | #include <linux/delay.h> | ||
458 | |||
459 | #define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) | ||
460 | #define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) | ||
461 | |||
462 | void bcm1480_kgdb_interrupt(struct pt_regs *regs) | ||
463 | { | ||
464 | /* | ||
465 | * Clear break-change status (allow some time for the remote | ||
466 | * host to stop the break, since we would see another | ||
467 | * interrupt on the end-of-break too) | ||
468 | */ | ||
469 | kstat.irqs[smp_processor_id()][kgdb_irq]++; | ||
470 | mdelay(500); | ||
471 | duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT | | ||
472 | M_DUART_RX_EN | M_DUART_TX_EN); | ||
473 | set_async_breakpoint(®s->cp0_epc); | ||
474 | } | ||
475 | |||
476 | #endif /* CONFIG_KGDB */ | ||
diff --git a/arch/mips/sibyte/bcm1480/irq_handler.S b/arch/mips/sibyte/bcm1480/irq_handler.S new file mode 100644 index 000000000000..408db88d050f --- /dev/null +++ b/arch/mips/sibyte/bcm1480/irq_handler.S | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * bcm1480_irq_handler() is the routine that is actually called when an | ||
21 | * interrupt occurs. It is installed as the exception vector handler in | ||
22 | * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c | ||
23 | * | ||
24 | * In the handle we figure out which interrupts need handling, and use that | ||
25 | * to call the dispatcher, which will take care of actually calling | ||
26 | * registered handlers | ||
27 | * | ||
28 | * Note that we take care of all raised interrupts in one go at the handler. | ||
29 | * This is more BSDish than the Indy code, and also, IMHO, more sane. | ||
30 | */ | ||
31 | #include <linux/config.h> | ||
32 | |||
33 | #include <asm/addrspace.h> | ||
34 | #include <asm/asm.h> | ||
35 | #include <asm/mipsregs.h> | ||
36 | #include <asm/regdef.h> | ||
37 | #include <asm/stackframe.h> | ||
38 | #include <asm/sibyte/sb1250_defs.h> | ||
39 | #include <asm/sibyte/bcm1480_regs.h> | ||
40 | #include <asm/sibyte/bcm1480_int.h> | ||
41 | |||
42 | /* | ||
43 | * What a pain. We have to be really careful saving the upper 32 bits of any | ||
44 | * register across function calls if we don't want them trashed--since were | ||
45 | * running in -o32, the calling routing never saves the full 64 bits of a | ||
46 | * register across a function call. Being the interrupt handler, we're | ||
47 | * guaranteed that interrupts are disabled during this code so we don't have | ||
48 | * to worry about random interrupts blasting the high 32 bits. | ||
49 | */ | ||
50 | |||
51 | .text | ||
52 | .set push | ||
53 | .set noreorder | ||
54 | .set noat | ||
55 | .set mips64 | ||
56 | #.set mips4 | ||
57 | .align 5 | ||
58 | NESTED(bcm1480_irq_handler, PT_SIZE, sp) | ||
59 | SAVE_ALL | ||
60 | CLI | ||
61 | |||
62 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
63 | /* Set compare to count to silence count/compare timer interrupts */ | ||
64 | mfc0 t1, CP0_COUNT | ||
65 | mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */ | ||
66 | #endif | ||
67 | /* Read cause */ | ||
68 | mfc0 s0, CP0_CAUSE | ||
69 | |||
70 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
71 | /* Cpu performance counter interrupt is routed to IP[7] */ | ||
72 | andi t1, s0, CAUSEF_IP7 | ||
73 | beqz t1, 0f | ||
74 | srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */ | ||
75 | and t1, t1, 0x4 /* mask to get just BD bit */ | ||
76 | #ifdef CONFIG_MIPS64 | ||
77 | dmfc0 a0, CP0_EPC | ||
78 | daddu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ | ||
79 | #else | ||
80 | mfc0 a0, CP0_EPC | ||
81 | addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ | ||
82 | #endif | ||
83 | jal sbprof_cpu_intr | ||
84 | nop | ||
85 | j ret_from_irq | ||
86 | nop | ||
87 | 0: | ||
88 | #endif | ||
89 | |||
90 | /* Timer interrupt is routed to IP[4] */ | ||
91 | andi t1, s0, CAUSEF_IP4 | ||
92 | beqz t1, 1f | ||
93 | nop | ||
94 | jal bcm1480_timer_interrupt | ||
95 | move a0, sp /* Pass the registers along */ | ||
96 | j ret_from_irq | ||
97 | nop /* delay slot */ | ||
98 | 1: | ||
99 | |||
100 | #ifdef CONFIG_SMP | ||
101 | /* Mailbox interrupt is routed to IP[3] */ | ||
102 | andi t1, s0, CAUSEF_IP3 | ||
103 | beqz t1, 2f | ||
104 | nop | ||
105 | jal bcm1480_mailbox_interrupt | ||
106 | move a0, sp | ||
107 | j ret_from_irq | ||
108 | nop /* delay slot */ | ||
109 | 2: | ||
110 | #endif | ||
111 | |||
112 | #ifdef CONFIG_KGDB | ||
113 | /* KGDB (uart 1) interrupt is routed to IP[6] */ | ||
114 | andi t1, s0, CAUSEF_IP6 | ||
115 | beqz t1, 3f | ||
116 | nop /* delay slot */ | ||
117 | jal bcm1480_kgdb_interrupt | ||
118 | move a0, sp | ||
119 | j ret_from_irq | ||
120 | nop /* delay slot */ | ||
121 | 3: | ||
122 | #endif | ||
123 | |||
124 | and t1, s0, CAUSEF_IP2 | ||
125 | beqz t1, 9f | ||
126 | nop | ||
127 | |||
128 | /* | ||
129 | * Default...we've hit an IP[2] interrupt, which means we've got | ||
130 | * to check the 1480 interrupt registers to figure out what to do | ||
131 | * Need to detect which CPU we're on, now that smp_affinity is | ||
132 | * supported. | ||
133 | */ | ||
134 | PTR_LA v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE | ||
135 | #ifdef CONFIG_SMP | ||
136 | lw t1, TI_CPU($28) | ||
137 | sll t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT | ||
138 | addu v0, v0, t1 | ||
139 | #endif | ||
140 | |||
141 | /* Read IP[2] status (get both high and low halves of status) */ | ||
142 | ld s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0) | ||
143 | ld s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0) | ||
144 | |||
145 | move s2, zero /* intr number */ | ||
146 | li s3, 64 | ||
147 | |||
148 | beqz s0, 9f /* No interrupts. Return. */ | ||
149 | move a1, sp | ||
150 | |||
151 | xori s4, s0, 1 /* if s0 (_H) == 1, it's a low intr, so... */ | ||
152 | movz s2, s3, s4 /* start the intr number at 64, and */ | ||
153 | movz s0, s1, s4 /* look at the low status value. */ | ||
154 | |||
155 | dclz s1, s0 /* Find the next interrupt. */ | ||
156 | dsubu a0, zero, s1 | ||
157 | daddiu a0, a0, 63 | ||
158 | jal do_IRQ | ||
159 | daddu a0, a0, s2 | ||
160 | |||
161 | 9: j ret_from_irq | ||
162 | nop | ||
163 | |||
164 | .set pop | ||
165 | END(bcm1480_irq_handler) | ||
diff --git a/arch/mips/sibyte/bcm1480/setup.c b/arch/mips/sibyte/bcm1480/setup.c new file mode 100644 index 000000000000..d90a0b87874c --- /dev/null +++ b/arch/mips/sibyte/bcm1480/setup.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | #include <linux/config.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/reboot.h> | ||
21 | #include <linux/string.h> | ||
22 | |||
23 | #include <asm/bootinfo.h> | ||
24 | #include <asm/mipsregs.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/sibyte/sb1250.h> | ||
27 | |||
28 | #include <asm/sibyte/bcm1480_regs.h> | ||
29 | #include <asm/sibyte/bcm1480_scd.h> | ||
30 | #include <asm/sibyte/sb1250_scd.h> | ||
31 | |||
32 | unsigned int sb1_pass; | ||
33 | unsigned int soc_pass; | ||
34 | unsigned int soc_type; | ||
35 | unsigned int periph_rev; | ||
36 | unsigned int zbbus_mhz; | ||
37 | |||
38 | static unsigned int part_type; | ||
39 | |||
40 | static char *soc_str; | ||
41 | static char *pass_str; | ||
42 | |||
43 | static inline int setup_bcm1x80_bcm1x55(void); | ||
44 | |||
45 | /* Setup code likely to be common to all SiByte platforms */ | ||
46 | |||
47 | static inline int sys_rev_decode(void) | ||
48 | { | ||
49 | int ret = 0; | ||
50 | |||
51 | switch (soc_type) { | ||
52 | case K_SYS_SOC_TYPE_BCM1x80: | ||
53 | if (part_type == K_SYS_PART_BCM1480) | ||
54 | soc_str = "BCM1480"; | ||
55 | else if (part_type == K_SYS_PART_BCM1280) | ||
56 | soc_str = "BCM1280"; | ||
57 | else | ||
58 | soc_str = "BCM1x80"; | ||
59 | ret = setup_bcm1x80_bcm1x55(); | ||
60 | break; | ||
61 | |||
62 | case K_SYS_SOC_TYPE_BCM1x55: | ||
63 | if (part_type == K_SYS_PART_BCM1455) | ||
64 | soc_str = "BCM1455"; | ||
65 | else if (part_type == K_SYS_PART_BCM1255) | ||
66 | soc_str = "BCM1255"; | ||
67 | else | ||
68 | soc_str = "BCM1x55"; | ||
69 | ret = setup_bcm1x80_bcm1x55(); | ||
70 | break; | ||
71 | |||
72 | default: | ||
73 | prom_printf("Unknown part type %x\n", part_type); | ||
74 | ret = 1; | ||
75 | break; | ||
76 | } | ||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static inline int setup_bcm1x80_bcm1x55(void) | ||
81 | { | ||
82 | int ret = 0; | ||
83 | |||
84 | switch (soc_pass) { | ||
85 | case K_SYS_REVISION_BCM1480_S0: | ||
86 | periph_rev = 1; | ||
87 | pass_str = "S0 (pass1)"; | ||
88 | break; | ||
89 | case K_SYS_REVISION_BCM1480_A1: | ||
90 | periph_rev = 1; | ||
91 | pass_str = "A1 (pass1)"; | ||
92 | break; | ||
93 | case K_SYS_REVISION_BCM1480_A2: | ||
94 | periph_rev = 1; | ||
95 | pass_str = "A2 (pass1)"; | ||
96 | break; | ||
97 | case K_SYS_REVISION_BCM1480_A3: | ||
98 | periph_rev = 1; | ||
99 | pass_str = "A3 (pass1)"; | ||
100 | break; | ||
101 | case K_SYS_REVISION_BCM1480_B0: | ||
102 | periph_rev = 1; | ||
103 | pass_str = "B0 (pass2)"; | ||
104 | break; | ||
105 | default: | ||
106 | prom_printf("Unknown %s rev %x\n", soc_str, soc_pass); | ||
107 | periph_rev = 1; | ||
108 | pass_str = "Unknown Revision"; | ||
109 | break; | ||
110 | } | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | void bcm1480_setup(void) | ||
115 | { | ||
116 | uint64_t sys_rev; | ||
117 | int plldiv; | ||
118 | |||
119 | sb1_pass = read_c0_prid() & 0xff; | ||
120 | sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION)); | ||
121 | soc_type = SYS_SOC_TYPE(sys_rev); | ||
122 | part_type = G_SYS_PART(sys_rev); | ||
123 | soc_pass = G_SYS_REVISION(sys_rev); | ||
124 | |||
125 | if (sys_rev_decode()) { | ||
126 | prom_printf("Restart after failure to identify SiByte chip\n"); | ||
127 | machine_restart(NULL); | ||
128 | } | ||
129 | |||
130 | plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG))); | ||
131 | zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25); | ||
132 | |||
133 | prom_printf("Broadcom SiByte %s %s @ %d MHz (SB-1A rev %d)\n", | ||
134 | soc_str, pass_str, zbbus_mhz * 2, sb1_pass); | ||
135 | prom_printf("Board type: %s\n", get_system_type()); | ||
136 | } | ||
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c new file mode 100644 index 000000000000..584a4b33faac --- /dev/null +++ b/arch/mips/sibyte/bcm1480/smp.c | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2001,2002,2004 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/init.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/smp.h> | ||
22 | #include <linux/kernel_stat.h> | ||
23 | |||
24 | #include <asm/mmu_context.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/sibyte/sb1250.h> | ||
27 | #include <asm/sibyte/bcm1480_regs.h> | ||
28 | #include <asm/sibyte/bcm1480_int.h> | ||
29 | |||
30 | extern void smp_call_function_interrupt(void); | ||
31 | |||
32 | /* | ||
33 | * These are routines for dealing with the bcm1480 smp capabilities | ||
34 | * independent of board/firmware | ||
35 | */ | ||
36 | |||
37 | static void *mailbox_0_set_regs[] = { | ||
38 | IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), | ||
39 | IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), | ||
40 | IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), | ||
41 | IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), | ||
42 | }; | ||
43 | |||
44 | static void *mailbox_0_clear_regs[] = { | ||
45 | IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), | ||
46 | IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), | ||
47 | IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), | ||
48 | IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), | ||
49 | }; | ||
50 | |||
51 | static void *mailbox_0_regs[] = { | ||
52 | IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), | ||
53 | IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), | ||
54 | IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), | ||
55 | IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), | ||
56 | }; | ||
57 | |||
58 | /* | ||
59 | * SMP init and finish on secondary CPUs | ||
60 | */ | ||
61 | void bcm1480_smp_init(void) | ||
62 | { | ||
63 | unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | | ||
64 | STATUSF_IP1 | STATUSF_IP0; | ||
65 | |||
66 | /* Set interrupt mask, but don't enable */ | ||
67 | change_c0_status(ST0_IM, imask); | ||
68 | } | ||
69 | |||
70 | void bcm1480_smp_finish(void) | ||
71 | { | ||
72 | extern void bcm1480_time_init(void); | ||
73 | bcm1480_time_init(); | ||
74 | local_irq_enable(); | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * These are routines for dealing with the sb1250 smp capabilities | ||
79 | * independent of board/firmware | ||
80 | */ | ||
81 | |||
82 | /* | ||
83 | * Simple enough; everything is set up, so just poke the appropriate mailbox | ||
84 | * register, and we should be set | ||
85 | */ | ||
86 | void core_send_ipi(int cpu, unsigned int action) | ||
87 | { | ||
88 | __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]); | ||
89 | } | ||
90 | |||
91 | void bcm1480_mailbox_interrupt(struct pt_regs *regs) | ||
92 | { | ||
93 | int cpu = smp_processor_id(); | ||
94 | unsigned int action; | ||
95 | |||
96 | kstat_this_cpu.irqs[K_BCM1480_INT_MBOX_0_0]++; | ||
97 | /* Load the mailbox register to figure out what we're supposed to do */ | ||
98 | action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff; | ||
99 | |||
100 | /* Clear the mailbox to clear the interrupt */ | ||
101 | __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]); | ||
102 | |||
103 | /* | ||
104 | * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the | ||
105 | * interrupt will do the reschedule for us | ||
106 | */ | ||
107 | |||
108 | if (action & SMP_CALL_FUNCTION) | ||
109 | smp_call_function_interrupt(); | ||
110 | } | ||
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c new file mode 100644 index 000000000000..e545752695a1 --- /dev/null +++ b/arch/mips/sibyte/bcm1480/time.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000,2001,2004 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * These are routines to set up and handle interrupts from the | ||
21 | * bcm1480 general purpose timer 0. We're using the timer as a | ||
22 | * system clock, so we set it up to run at 100 Hz. On every | ||
23 | * interrupt, we update our idea of what the time of day is, | ||
24 | * then call do_timer() in the architecture-independent kernel | ||
25 | * code to do general bookkeeping (e.g. update jiffies, run | ||
26 | * bottom halves, etc.) | ||
27 | */ | ||
28 | #include <linux/config.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/sched.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/kernel_stat.h> | ||
33 | |||
34 | #include <asm/irq.h> | ||
35 | #include <asm/ptrace.h> | ||
36 | #include <asm/addrspace.h> | ||
37 | #include <asm/time.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | #include <asm/sibyte/bcm1480_regs.h> | ||
41 | #include <asm/sibyte/sb1250_regs.h> | ||
42 | #include <asm/sibyte/bcm1480_int.h> | ||
43 | #include <asm/sibyte/bcm1480_scd.h> | ||
44 | |||
45 | #include <asm/sibyte/sb1250.h> | ||
46 | |||
47 | |||
48 | #define IMR_IP2_VAL K_BCM1480_INT_MAP_I0 | ||
49 | #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 | ||
50 | #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 | ||
51 | |||
52 | extern int bcm1480_steal_irq(int irq); | ||
53 | |||
54 | void bcm1480_time_init(void) | ||
55 | { | ||
56 | int cpu = smp_processor_id(); | ||
57 | int irq = K_BCM1480_INT_TIMER_0+cpu; | ||
58 | |||
59 | /* Only have 4 general purpose timers */ | ||
60 | if (cpu > 3) { | ||
61 | BUG(); | ||
62 | } | ||
63 | |||
64 | if (!cpu) { | ||
65 | /* Use our own gettimeoffset() routine */ | ||
66 | do_gettimeoffset = bcm1480_gettimeoffset; | ||
67 | } | ||
68 | |||
69 | bcm1480_mask_irq(cpu, irq); | ||
70 | |||
71 | /* Map the timer interrupt to ip[4] of this cpu */ | ||
72 | __raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) | ||
73 | + (irq<<3))); | ||
74 | |||
75 | /* the general purpose timer ticks at 1 Mhz independent of the rest of the system */ | ||
76 | /* Disable the timer and set up the count */ | ||
77 | __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | ||
78 | __raw_writeq( | ||
79 | #ifndef CONFIG_SIMULATION | ||
80 | 1000000/HZ | ||
81 | #else | ||
82 | 50000/HZ | ||
83 | #endif | ||
84 | , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); | ||
85 | |||
86 | /* Set the timer running */ | ||
87 | __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, | ||
88 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | ||
89 | |||
90 | bcm1480_unmask_irq(cpu, irq); | ||
91 | bcm1480_steal_irq(irq); | ||
92 | /* | ||
93 | * This interrupt is "special" in that it doesn't use the request_irq | ||
94 | * way to hook the irq line. The timer interrupt is initialized early | ||
95 | * enough to make this a major pain, and it's also firing enough to | ||
96 | * warrant a bit of special case code. bcm1480_timer_interrupt is | ||
97 | * called directly from irq_handler.S when IP[4] is set during an | ||
98 | * interrupt | ||
99 | */ | ||
100 | } | ||
101 | |||
102 | #include <asm/sibyte/sb1250.h> | ||
103 | |||
104 | void bcm1480_timer_interrupt(struct pt_regs *regs) | ||
105 | { | ||
106 | int cpu = smp_processor_id(); | ||
107 | int irq = K_BCM1480_INT_TIMER_0+cpu; | ||
108 | |||
109 | /* Reset the timer */ | ||
110 | __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, | ||
111 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | ||
112 | |||
113 | /* | ||
114 | * CPU 0 handles the global timer interrupt job | ||
115 | */ | ||
116 | if (cpu == 0) { | ||
117 | ll_timer_interrupt(irq, regs); | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * every CPU should do profiling and process accouting | ||
122 | */ | ||
123 | ll_local_timer_interrupt(irq, regs); | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * We use our own do_gettimeoffset() instead of the generic one, | ||
128 | * because the generic one does not work for SMP case. | ||
129 | * In addition, since we use general timer 0 for system time, | ||
130 | * we can get accurate intra-jiffy offset without calibration. | ||
131 | */ | ||
132 | unsigned long bcm1480_gettimeoffset(void) | ||
133 | { | ||
134 | unsigned long count = | ||
135 | __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); | ||
136 | |||
137 | return 1000000/HZ - count; | ||
138 | } | ||
diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c index e44ce1a9eea9..e8485124b8fc 100644 --- a/arch/mips/sibyte/cfe/smp.c +++ b/arch/mips/sibyte/cfe/smp.c | |||
@@ -70,8 +70,15 @@ void prom_boot_secondary(int cpu, struct task_struct *idle) | |||
70 | */ | 70 | */ |
71 | void prom_init_secondary(void) | 71 | void prom_init_secondary(void) |
72 | { | 72 | { |
73 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) | ||
74 | extern void bcm1480_smp_init(void); | ||
75 | bcm1480_smp_init(); | ||
76 | #elif defined(CONFIG_SIBYTE_SB1250) | ||
73 | extern void sb1250_smp_init(void); | 77 | extern void sb1250_smp_init(void); |
74 | sb1250_smp_init(); | 78 | sb1250_smp_init(); |
79 | #else | ||
80 | #error invalid SMP configuration | ||
81 | #endif | ||
75 | } | 82 | } |
76 | 83 | ||
77 | /* | 84 | /* |
@@ -80,8 +87,15 @@ void prom_init_secondary(void) | |||
80 | */ | 87 | */ |
81 | void prom_smp_finish(void) | 88 | void prom_smp_finish(void) |
82 | { | 89 | { |
90 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) | ||
91 | extern void bcm1480_smp_finish(void); | ||
92 | bcm1480_smp_finish(); | ||
93 | #elif defined(CONFIG_SIBYTE_SB1250) | ||
83 | extern void sb1250_smp_finish(void); | 94 | extern void sb1250_smp_finish(void); |
84 | sb1250_smp_finish(); | 95 | sb1250_smp_finish(); |
96 | #else | ||
97 | #error invalid SMP configuration | ||
98 | #endif | ||
85 | } | 99 | } |
86 | 100 | ||
87 | /* | 101 | /* |
diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c index 7f813ae9eaff..992e0d8dbb67 100644 --- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c +++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/reboot.h> | 30 | #include <linux/reboot.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/wait.h> | ||
31 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
32 | #include <asm/io.h> | 34 | #include <asm/io.h> |
33 | #include <asm/sibyte/sb1250.h> | 35 | #include <asm/sibyte/sb1250.h> |
@@ -64,24 +66,25 @@ static void arm_tb(void) | |||
64 | u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL; | 66 | u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL; |
65 | /* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to | 67 | /* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to |
66 | trigger start of trace. XXX vary sampling period */ | 68 | trigger start of trace. XXX vary sampling period */ |
67 | bus_writeq(0, IOADDR(A_SCD_PERF_CNT_1)); | 69 | __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1)); |
68 | scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG)); | 70 | scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); |
69 | /* Unfortunately, in Pass 2 we must clear all counters to knock down | 71 | /* Unfortunately, in Pass 2 we must clear all counters to knock down |
70 | a previous interrupt request. This means that bus profiling | 72 | a previous interrupt request. This means that bus profiling |
71 | requires ALL of the SCD perf counters. */ | 73 | requires ALL of the SCD perf counters. */ |
72 | bus_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is | 74 | __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | |
73 | M_SPC_CFG_ENABLE | // enable counting | 75 | // keep counters 0,2,3 as is |
74 | M_SPC_CFG_CLEAR | // clear all counters | 76 | M_SPC_CFG_ENABLE | // enable counting |
75 | V_SPC_CFG_SRC1(1), // counter 1 counts cycles | 77 | M_SPC_CFG_CLEAR | // clear all counters |
76 | IOADDR(A_SCD_PERF_CNT_CFG)); | 78 | V_SPC_CFG_SRC1(1), // counter 1 counts cycles |
77 | bus_writeq(next, IOADDR(A_SCD_PERF_CNT_1)); | 79 | IOADDR(A_SCD_PERF_CNT_CFG)); |
80 | __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1)); | ||
78 | /* Reset the trace buffer */ | 81 | /* Reset the trace buffer */ |
79 | bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); | 82 | __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); |
80 | #if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) | 83 | #if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) |
81 | /* XXXKW may want to expose control to the data-collector */ | 84 | /* XXXKW may want to expose control to the data-collector */ |
82 | tb_options |= M_SCD_TRACE_CFG_FORCECNT; | 85 | tb_options |= M_SCD_TRACE_CFG_FORCECNT; |
83 | #endif | 86 | #endif |
84 | bus_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG)); | 87 | __raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG)); |
85 | sbp.tb_armed = 1; | 88 | sbp.tb_armed = 1; |
86 | } | 89 | } |
87 | 90 | ||
@@ -93,23 +96,30 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
93 | /* XXX should use XKPHYS to make writes bypass L2 */ | 96 | /* XXX should use XKPHYS to make writes bypass L2 */ |
94 | u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; | 97 | u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; |
95 | /* Read out trace */ | 98 | /* Read out trace */ |
96 | bus_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG)); | 99 | __raw_writeq(M_SCD_TRACE_CFG_START_READ, |
100 | IOADDR(A_SCD_TRACE_CFG)); | ||
97 | __asm__ __volatile__ ("sync" : : : "memory"); | 101 | __asm__ __volatile__ ("sync" : : : "memory"); |
98 | /* Loop runs backwards because bundles are read out in reverse order */ | 102 | /* Loop runs backwards because bundles are read out in reverse order */ |
99 | for (i = 256 * 6; i > 0; i -= 6) { | 103 | for (i = 256 * 6; i > 0; i -= 6) { |
100 | // Subscripts decrease to put bundle in the order | 104 | // Subscripts decrease to put bundle in the order |
101 | // t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi | 105 | // t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi |
102 | p[i-1] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi | 106 | p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); |
103 | p[i-2] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo | 107 | // read t2 hi |
104 | p[i-3] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi | 108 | p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); |
105 | p[i-4] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo | 109 | // read t2 lo |
106 | p[i-5] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi | 110 | p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); |
107 | p[i-6] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo | 111 | // read t1 hi |
112 | p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); | ||
113 | // read t1 lo | ||
114 | p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); | ||
115 | // read t0 hi | ||
116 | p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); | ||
117 | // read t0 lo | ||
108 | } | 118 | } |
109 | if (!sbp.tb_enable) { | 119 | if (!sbp.tb_enable) { |
110 | DBG(printk(DEVNAME ": tb_intr shutdown\n")); | 120 | DBG(printk(DEVNAME ": tb_intr shutdown\n")); |
111 | bus_writeq(M_SCD_TRACE_CFG_RESET, | 121 | __raw_writeq(M_SCD_TRACE_CFG_RESET, |
112 | IOADDR(A_SCD_TRACE_CFG)); | 122 | IOADDR(A_SCD_TRACE_CFG)); |
113 | sbp.tb_armed = 0; | 123 | sbp.tb_armed = 0; |
114 | wake_up(&sbp.tb_sync); | 124 | wake_up(&sbp.tb_sync); |
115 | } else { | 125 | } else { |
@@ -118,7 +128,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
118 | } else { | 128 | } else { |
119 | /* No more trace buffer samples */ | 129 | /* No more trace buffer samples */ |
120 | DBG(printk(DEVNAME ": tb_intr full\n")); | 130 | DBG(printk(DEVNAME ": tb_intr full\n")); |
121 | bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); | 131 | __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); |
122 | sbp.tb_armed = 0; | 132 | sbp.tb_armed = 0; |
123 | if (!sbp.tb_enable) { | 133 | if (!sbp.tb_enable) { |
124 | wake_up(&sbp.tb_sync); | 134 | wake_up(&sbp.tb_sync); |
@@ -152,13 +162,11 @@ int sbprof_zbprof_start(struct file *filp) | |||
152 | return -EBUSY; | 162 | return -EBUSY; |
153 | } | 163 | } |
154 | /* Make sure there isn't a perf-cnt interrupt waiting */ | 164 | /* Make sure there isn't a perf-cnt interrupt waiting */ |
155 | scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG)); | 165 | scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); |
156 | /* Disable and clear counters, override SRC_1 */ | 166 | /* Disable and clear counters, override SRC_1 */ |
157 | bus_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) | | 167 | __raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) | |
158 | M_SPC_CFG_ENABLE | | 168 | M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1), |
159 | M_SPC_CFG_CLEAR | | 169 | IOADDR(A_SCD_PERF_CNT_CFG)); |
160 | V_SPC_CFG_SRC1(1), | ||
161 | IOADDR(A_SCD_PERF_CNT_CFG)); | ||
162 | 170 | ||
163 | /* We grab this interrupt to prevent others from trying to use | 171 | /* We grab this interrupt to prevent others from trying to use |
164 | it, even though we don't want to service the interrupts | 172 | it, even though we don't want to service the interrupts |
@@ -172,55 +180,55 @@ int sbprof_zbprof_start(struct file *filp) | |||
172 | /* I need the core to mask these, but the interrupt mapper to | 180 | /* I need the core to mask these, but the interrupt mapper to |
173 | pass them through. I am exploiting my knowledge that | 181 | pass them through. I am exploiting my knowledge that |
174 | cp0_status masks out IP[5]. krw */ | 182 | cp0_status masks out IP[5]. krw */ |
175 | bus_writeq(K_INT_MAP_I3, | 183 | __raw_writeq(K_INT_MAP_I3, |
176 | IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + | 184 | IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + |
177 | (K_INT_PERF_CNT << 3))); | 185 | (K_INT_PERF_CNT << 3))); |
178 | 186 | ||
179 | /* Initialize address traps */ | 187 | /* Initialize address traps */ |
180 | bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_0)); | 188 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0)); |
181 | bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_1)); | 189 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1)); |
182 | bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_2)); | 190 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2)); |
183 | bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_3)); | 191 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3)); |
184 | 192 | ||
185 | bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0)); | 193 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0)); |
186 | bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1)); | 194 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1)); |
187 | bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2)); | 195 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2)); |
188 | bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3)); | 196 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3)); |
189 | 197 | ||
190 | bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0)); | 198 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0)); |
191 | bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1)); | 199 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1)); |
192 | bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2)); | 200 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2)); |
193 | bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3)); | 201 | __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3)); |
194 | 202 | ||
195 | /* Initialize Trace Event 0-7 */ | 203 | /* Initialize Trace Event 0-7 */ |
196 | // when interrupt | 204 | // when interrupt |
197 | bus_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0)); | 205 | __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0)); |
198 | bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1)); | 206 | __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1)); |
199 | bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2)); | 207 | __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2)); |
200 | bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3)); | 208 | __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3)); |
201 | bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4)); | 209 | __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4)); |
202 | bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5)); | 210 | __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5)); |
203 | bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6)); | 211 | __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6)); |
204 | bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7)); | 212 | __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7)); |
205 | 213 | ||
206 | /* Initialize Trace Sequence 0-7 */ | 214 | /* Initialize Trace Sequence 0-7 */ |
207 | // Start on event 0 (interrupt) | 215 | // Start on event 0 (interrupt) |
208 | bus_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff, | 216 | __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff, |
209 | IOADDR(A_SCD_TRACE_SEQUENCE_0)); | 217 | IOADDR(A_SCD_TRACE_SEQUENCE_0)); |
210 | // dsamp when d used | asamp when a used | 218 | // dsamp when d used | asamp when a used |
211 | bus_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE | | 219 | __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE | |
212 | K_SCD_TRSEQ_TRIGGER_ALL, | 220 | K_SCD_TRSEQ_TRIGGER_ALL, |
213 | IOADDR(A_SCD_TRACE_SEQUENCE_1)); | 221 | IOADDR(A_SCD_TRACE_SEQUENCE_1)); |
214 | bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2)); | 222 | __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2)); |
215 | bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3)); | 223 | __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3)); |
216 | bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4)); | 224 | __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4)); |
217 | bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5)); | 225 | __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5)); |
218 | bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6)); | 226 | __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6)); |
219 | bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7)); | 227 | __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7)); |
220 | 228 | ||
221 | /* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */ | 229 | /* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */ |
222 | bus_writeq((1ULL << K_INT_PERF_CNT), | 230 | __raw_writeq(1ULL << K_INT_PERF_CNT, |
223 | IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE))); | 231 | IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE))); |
224 | 232 | ||
225 | arm_tb(); | 233 | arm_tb(); |
226 | 234 | ||
@@ -231,6 +239,7 @@ int sbprof_zbprof_start(struct file *filp) | |||
231 | 239 | ||
232 | int sbprof_zbprof_stop(void) | 240 | int sbprof_zbprof_stop(void) |
233 | { | 241 | { |
242 | DEFINE_WAIT(wait); | ||
234 | DBG(printk(DEVNAME ": stopping\n")); | 243 | DBG(printk(DEVNAME ": stopping\n")); |
235 | 244 | ||
236 | if (sbp.tb_enable) { | 245 | if (sbp.tb_enable) { |
@@ -240,7 +249,9 @@ int sbprof_zbprof_stop(void) | |||
240 | this sleep happens. */ | 249 | this sleep happens. */ |
241 | if (sbp.tb_armed) { | 250 | if (sbp.tb_armed) { |
242 | DBG(printk(DEVNAME ": wait for disarm\n")); | 251 | DBG(printk(DEVNAME ": wait for disarm\n")); |
243 | interruptible_sleep_on(&sbp.tb_sync); | 252 | prepare_to_wait(&sbp.tb_sync, &wait, TASK_INTERRUPTIBLE); |
253 | schedule(); | ||
254 | finish_wait(&sbp.tb_sync, &wait); | ||
244 | DBG(printk(DEVNAME ": disarm complete\n")); | 255 | DBG(printk(DEVNAME ": disarm complete\n")); |
245 | } | 256 | } |
246 | free_irq(K_INT_TRACE_FREEZE, &sbp); | 257 | free_irq(K_INT_TRACE_FREEZE, &sbp); |
@@ -333,13 +344,13 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf, | |||
333 | return count; | 344 | return count; |
334 | } | 345 | } |
335 | 346 | ||
336 | static int sbprof_tb_ioctl(struct inode *inode, | 347 | static long sbprof_tb_ioctl(struct file *filp, |
337 | struct file *filp, | 348 | unsigned int command, |
338 | unsigned int command, | 349 | unsigned long arg) |
339 | unsigned long arg) | ||
340 | { | 350 | { |
341 | int error = 0; | 351 | int error = 0; |
342 | 352 | ||
353 | lock_kernel(); | ||
343 | switch (command) { | 354 | switch (command) { |
344 | case SBPROF_ZBSTART: | 355 | case SBPROF_ZBSTART: |
345 | error = sbprof_zbprof_start(filp); | 356 | error = sbprof_zbprof_start(filp); |
@@ -348,13 +359,17 @@ static int sbprof_tb_ioctl(struct inode *inode, | |||
348 | error = sbprof_zbprof_stop(); | 359 | error = sbprof_zbprof_stop(); |
349 | break; | 360 | break; |
350 | case SBPROF_ZBWAITFULL: | 361 | case SBPROF_ZBWAITFULL: |
351 | interruptible_sleep_on(&sbp.tb_read); | 362 | DEFINE_WAIT(wait); |
363 | prepare_to_wait(&sbp.tb_read, &wait, TASK_INTERRUPTIBLE); | ||
364 | schedule(); | ||
365 | finish_wait(&sbp.tb_read, &wait); | ||
352 | /* XXXKW check if interrupted? */ | 366 | /* XXXKW check if interrupted? */ |
353 | return put_user(TB_FULL, (int *) arg); | 367 | return put_user(TB_FULL, (int *) arg); |
354 | default: | 368 | default: |
355 | error = -EINVAL; | 369 | error = -EINVAL; |
356 | break; | 370 | break; |
357 | } | 371 | } |
372 | unlock_kernel(); | ||
358 | 373 | ||
359 | return error; | 374 | return error; |
360 | } | 375 | } |
@@ -364,7 +379,8 @@ static struct file_operations sbprof_tb_fops = { | |||
364 | .open = sbprof_tb_open, | 379 | .open = sbprof_tb_open, |
365 | .release = sbprof_tb_release, | 380 | .release = sbprof_tb_release, |
366 | .read = sbprof_tb_read, | 381 | .read = sbprof_tb_read, |
367 | .ioctl = sbprof_tb_ioctl, | 382 | .unlocked_ioctl = sbprof_tb_ioctl, |
383 | .compat_ioctl = sbprof_tb_ioctl, | ||
368 | .mmap = NULL, | 384 | .mmap = NULL, |
369 | }; | 385 | }; |
370 | 386 | ||
diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c index 1a97e3127aeb..482dee054e68 100644 --- a/arch/mips/sibyte/sb1250/bus_watcher.c +++ b/arch/mips/sibyte/sb1250/bus_watcher.c | |||
@@ -189,7 +189,7 @@ static irqreturn_t sibyte_bw_int(int irq, void *data, struct pt_regs *regs) | |||
189 | 189 | ||
190 | for (i=0; i<256*6; i++) | 190 | for (i=0; i<256*6; i++) |
191 | printk("%016llx\n", | 191 | printk("%016llx\n", |
192 | (unsigned long long)bus_readq(IOADDR(A_SCD_TRACE_READ))); | 192 | (long long)__raw_readq(IOADDR(A_SCD_TRACE_READ))); |
193 | 193 | ||
194 | csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); | 194 | csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); |
195 | csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG)); | 195 | csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG)); |
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index 2725b263cced..589537bfcc3d 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c | |||
@@ -53,7 +53,7 @@ static void disable_sb1250_irq(unsigned int irq); | |||
53 | static unsigned int startup_sb1250_irq(unsigned int irq); | 53 | static unsigned int startup_sb1250_irq(unsigned int irq); |
54 | static void ack_sb1250_irq(unsigned int irq); | 54 | static void ack_sb1250_irq(unsigned int irq); |
55 | #ifdef CONFIG_SMP | 55 | #ifdef CONFIG_SMP |
56 | static void sb1250_set_affinity(unsigned int irq, unsigned long mask); | 56 | static void sb1250_set_affinity(unsigned int irq, cpumask_t mask); |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #ifdef CONFIG_SIBYTE_HAS_LDT | 59 | #ifdef CONFIG_SIBYTE_HAS_LDT |
@@ -71,17 +71,15 @@ extern char sb1250_duart_present[]; | |||
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | static struct hw_interrupt_type sb1250_irq_type = { | 73 | static struct hw_interrupt_type sb1250_irq_type = { |
74 | "SB1250-IMR", | 74 | .typename = "SB1250-IMR", |
75 | startup_sb1250_irq, | 75 | .startup = startup_sb1250_irq, |
76 | shutdown_sb1250_irq, | 76 | .shutdown = shutdown_sb1250_irq, |
77 | enable_sb1250_irq, | 77 | .enable = enable_sb1250_irq, |
78 | disable_sb1250_irq, | 78 | .disable = disable_sb1250_irq, |
79 | ack_sb1250_irq, | 79 | .ack = ack_sb1250_irq, |
80 | end_sb1250_irq, | 80 | .end = end_sb1250_irq, |
81 | #ifdef CONFIG_SMP | 81 | #ifdef CONFIG_SMP |
82 | sb1250_set_affinity | 82 | .set_affinity = sb1250_set_affinity |
83 | #else | ||
84 | NULL | ||
85 | #endif | 83 | #endif |
86 | }; | 84 | }; |
87 | 85 | ||
@@ -96,11 +94,11 @@ void sb1250_mask_irq(int cpu, int irq) | |||
96 | u64 cur_ints; | 94 | u64 cur_ints; |
97 | 95 | ||
98 | spin_lock_irqsave(&sb1250_imr_lock, flags); | 96 | spin_lock_irqsave(&sb1250_imr_lock, flags); |
99 | cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) + | 97 | cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + |
100 | R_IMR_INTERRUPT_MASK)); | 98 | R_IMR_INTERRUPT_MASK)); |
101 | cur_ints |= (((u64) 1) << irq); | 99 | cur_ints |= (((u64) 1) << irq); |
102 | __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + | 100 | ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + |
103 | R_IMR_INTERRUPT_MASK)); | 101 | R_IMR_INTERRUPT_MASK)); |
104 | spin_unlock_irqrestore(&sb1250_imr_lock, flags); | 102 | spin_unlock_irqrestore(&sb1250_imr_lock, flags); |
105 | } | 103 | } |
106 | 104 | ||
@@ -110,32 +108,25 @@ void sb1250_unmask_irq(int cpu, int irq) | |||
110 | u64 cur_ints; | 108 | u64 cur_ints; |
111 | 109 | ||
112 | spin_lock_irqsave(&sb1250_imr_lock, flags); | 110 | spin_lock_irqsave(&sb1250_imr_lock, flags); |
113 | cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) + | 111 | cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + |
114 | R_IMR_INTERRUPT_MASK)); | 112 | R_IMR_INTERRUPT_MASK)); |
115 | cur_ints &= ~(((u64) 1) << irq); | 113 | cur_ints &= ~(((u64) 1) << irq); |
116 | __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + | 114 | ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + |
117 | R_IMR_INTERRUPT_MASK)); | 115 | R_IMR_INTERRUPT_MASK)); |
118 | spin_unlock_irqrestore(&sb1250_imr_lock, flags); | 116 | spin_unlock_irqrestore(&sb1250_imr_lock, flags); |
119 | } | 117 | } |
120 | 118 | ||
121 | #ifdef CONFIG_SMP | 119 | #ifdef CONFIG_SMP |
122 | static void sb1250_set_affinity(unsigned int irq, unsigned long mask) | 120 | static void sb1250_set_affinity(unsigned int irq, cpumask_t mask) |
123 | { | 121 | { |
124 | int i = 0, old_cpu, cpu, int_on; | 122 | int i = 0, old_cpu, cpu, int_on; |
125 | u64 cur_ints; | 123 | u64 cur_ints; |
126 | irq_desc_t *desc = irq_desc + irq; | 124 | irq_desc_t *desc = irq_desc + irq; |
127 | unsigned long flags; | 125 | unsigned long flags; |
128 | 126 | ||
129 | while (mask) { | 127 | i = first_cpu(mask); |
130 | if (mask & 1) { | ||
131 | mask >>= 1; | ||
132 | break; | ||
133 | } | ||
134 | mask >>= 1; | ||
135 | i++; | ||
136 | } | ||
137 | 128 | ||
138 | if (mask) { | 129 | if (cpus_weight(mask) > 1) { |
139 | printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq); | 130 | printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq); |
140 | return; | 131 | return; |
141 | } | 132 | } |
@@ -149,23 +140,23 @@ static void sb1250_set_affinity(unsigned int irq, unsigned long mask) | |||
149 | 140 | ||
150 | /* Swizzle each CPU's IMR (but leave the IP selection alone) */ | 141 | /* Swizzle each CPU's IMR (but leave the IP selection alone) */ |
151 | old_cpu = sb1250_irq_owner[irq]; | 142 | old_cpu = sb1250_irq_owner[irq]; |
152 | cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(old_cpu) + | 143 | cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(old_cpu) + |
153 | R_IMR_INTERRUPT_MASK)); | 144 | R_IMR_INTERRUPT_MASK)); |
154 | int_on = !(cur_ints & (((u64) 1) << irq)); | 145 | int_on = !(cur_ints & (((u64) 1) << irq)); |
155 | if (int_on) { | 146 | if (int_on) { |
156 | /* If it was on, mask it */ | 147 | /* If it was on, mask it */ |
157 | cur_ints |= (((u64) 1) << irq); | 148 | cur_ints |= (((u64) 1) << irq); |
158 | __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) + | 149 | ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) + |
159 | R_IMR_INTERRUPT_MASK)); | 150 | R_IMR_INTERRUPT_MASK)); |
160 | } | 151 | } |
161 | sb1250_irq_owner[irq] = cpu; | 152 | sb1250_irq_owner[irq] = cpu; |
162 | if (int_on) { | 153 | if (int_on) { |
163 | /* unmask for the new CPU */ | 154 | /* unmask for the new CPU */ |
164 | cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) + | 155 | cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + |
165 | R_IMR_INTERRUPT_MASK)); | 156 | R_IMR_INTERRUPT_MASK)); |
166 | cur_ints &= ~(((u64) 1) << irq); | 157 | cur_ints &= ~(((u64) 1) << irq); |
167 | __bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + | 158 | ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + |
168 | R_IMR_INTERRUPT_MASK)); | 159 | R_IMR_INTERRUPT_MASK)); |
169 | } | 160 | } |
170 | spin_unlock(&sb1250_imr_lock); | 161 | spin_unlock(&sb1250_imr_lock); |
171 | spin_unlock_irqrestore(&desc->lock, flags); | 162 | spin_unlock_irqrestore(&desc->lock, flags); |
@@ -208,8 +199,8 @@ static void ack_sb1250_irq(unsigned int irq) | |||
208 | * deliver the interrupts to all CPUs (which makes affinity | 199 | * deliver the interrupts to all CPUs (which makes affinity |
209 | * changing easier for us) | 200 | * changing easier for us) |
210 | */ | 201 | */ |
211 | pending = bus_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq], | 202 | pending = __raw_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq], |
212 | R_IMR_LDT_INTERRUPT))); | 203 | R_IMR_LDT_INTERRUPT))); |
213 | pending &= ((u64)1 << (irq)); | 204 | pending &= ((u64)1 << (irq)); |
214 | if (pending) { | 205 | if (pending) { |
215 | int i; | 206 | int i; |
@@ -224,8 +215,8 @@ static void ack_sb1250_irq(unsigned int irq) | |||
224 | * Clear for all CPUs so an affinity switch | 215 | * Clear for all CPUs so an affinity switch |
225 | * doesn't find an old status | 216 | * doesn't find an old status |
226 | */ | 217 | */ |
227 | bus_writeq(pending, | 218 | __raw_writeq(pending, |
228 | IOADDR(A_IMR_REGISTER(cpu, | 219 | IOADDR(A_IMR_REGISTER(cpu, |
229 | R_IMR_LDT_INTERRUPT_CLR))); | 220 | R_IMR_LDT_INTERRUPT_CLR))); |
230 | } | 221 | } |
231 | 222 | ||
@@ -340,12 +331,14 @@ void __init arch_init_irq(void) | |||
340 | 331 | ||
341 | /* Default everything to IP2 */ | 332 | /* Default everything to IP2 */ |
342 | for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */ | 333 | for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */ |
343 | bus_writeq(IMR_IP2_VAL, | 334 | __raw_writeq(IMR_IP2_VAL, |
344 | IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + | 335 | IOADDR(A_IMR_REGISTER(0, |
345 | (i << 3))); | 336 | R_IMR_INTERRUPT_MAP_BASE) + |
346 | bus_writeq(IMR_IP2_VAL, | 337 | (i << 3))); |
347 | IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) + | 338 | __raw_writeq(IMR_IP2_VAL, |
348 | (i << 3))); | 339 | IOADDR(A_IMR_REGISTER(1, |
340 | R_IMR_INTERRUPT_MAP_BASE) + | ||
341 | (i << 3))); | ||
349 | } | 342 | } |
350 | 343 | ||
351 | init_sb1250_irqs(); | 344 | init_sb1250_irqs(); |
@@ -355,23 +348,23 @@ void __init arch_init_irq(void) | |||
355 | * inter-cpu messages | 348 | * inter-cpu messages |
356 | */ | 349 | */ |
357 | /* Was I1 */ | 350 | /* Was I1 */ |
358 | bus_writeq(IMR_IP3_VAL, | 351 | __raw_writeq(IMR_IP3_VAL, |
359 | IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + | 352 | IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + |
360 | (K_INT_MBOX_0 << 3))); | 353 | (K_INT_MBOX_0 << 3))); |
361 | bus_writeq(IMR_IP3_VAL, | 354 | __raw_writeq(IMR_IP3_VAL, |
362 | IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) + | 355 | IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) + |
363 | (K_INT_MBOX_0 << 3))); | 356 | (K_INT_MBOX_0 << 3))); |
364 | 357 | ||
365 | /* Clear the mailboxes. The firmware may leave them dirty */ | 358 | /* Clear the mailboxes. The firmware may leave them dirty */ |
366 | bus_writeq(0xffffffffffffffffULL, | 359 | __raw_writeq(0xffffffffffffffffULL, |
367 | IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU))); | 360 | IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU))); |
368 | bus_writeq(0xffffffffffffffffULL, | 361 | __raw_writeq(0xffffffffffffffffULL, |
369 | IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU))); | 362 | IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU))); |
370 | 363 | ||
371 | /* Mask everything except the mailbox registers for both cpus */ | 364 | /* Mask everything except the mailbox registers for both cpus */ |
372 | tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0); | 365 | tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0); |
373 | bus_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK))); | 366 | __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK))); |
374 | bus_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK))); | 367 | __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK))); |
375 | 368 | ||
376 | sb1250_steal_irq(K_INT_MBOX_0); | 369 | sb1250_steal_irq(K_INT_MBOX_0); |
377 | 370 | ||
@@ -396,12 +389,14 @@ void __init arch_init_irq(void) | |||
396 | sb1250_duart_present[kgdb_port] = 0; | 389 | sb1250_duart_present[kgdb_port] = 0; |
397 | #endif | 390 | #endif |
398 | /* Setup uart 1 settings, mapper */ | 391 | /* Setup uart 1 settings, mapper */ |
399 | bus_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port))); | 392 | __raw_writeq(M_DUART_IMR_BRK, |
393 | IOADDR(A_DUART_IMRREG(kgdb_port))); | ||
400 | 394 | ||
401 | sb1250_steal_irq(kgdb_irq); | 395 | sb1250_steal_irq(kgdb_irq); |
402 | bus_writeq(IMR_IP6_VAL, | 396 | __raw_writeq(IMR_IP6_VAL, |
403 | IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + | 397 | IOADDR(A_IMR_REGISTER(0, |
404 | (kgdb_irq<<3))); | 398 | R_IMR_INTERRUPT_MAP_BASE) + |
399 | (kgdb_irq << 3))); | ||
405 | sb1250_unmask_irq(0, kgdb_irq); | 400 | sb1250_unmask_irq(0, kgdb_irq); |
406 | } | 401 | } |
407 | #endif | 402 | #endif |
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index f8c605be96c7..df2e266c700c 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c | |||
@@ -153,7 +153,7 @@ void sb1250_setup(void) | |||
153 | int bad_config = 0; | 153 | int bad_config = 0; |
154 | 154 | ||
155 | sb1_pass = read_c0_prid() & 0xff; | 155 | sb1_pass = read_c0_prid() & 0xff; |
156 | sys_rev = bus_readq(IOADDR(A_SCD_SYSTEM_REVISION)); | 156 | sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION)); |
157 | soc_type = SYS_SOC_TYPE(sys_rev); | 157 | soc_type = SYS_SOC_TYPE(sys_rev); |
158 | soc_pass = G_SYS_REVISION(sys_rev); | 158 | soc_pass = G_SYS_REVISION(sys_rev); |
159 | 159 | ||
@@ -162,7 +162,7 @@ void sb1250_setup(void) | |||
162 | machine_restart(NULL); | 162 | machine_restart(NULL); |
163 | } | 163 | } |
164 | 164 | ||
165 | plldiv = G_SYS_PLL_DIV(bus_readq(IOADDR(A_SCD_SYSTEM_CFG))); | 165 | plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG))); |
166 | zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25); | 166 | zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25); |
167 | 167 | ||
168 | prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n", | 168 | prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n", |
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c index be91b3990952..f859db02d3c9 100644 --- a/arch/mips/sibyte/sb1250/smp.c +++ b/arch/mips/sibyte/sb1250/smp.c | |||
@@ -29,18 +29,18 @@ | |||
29 | #include <asm/sibyte/sb1250_int.h> | 29 | #include <asm/sibyte/sb1250_int.h> |
30 | 30 | ||
31 | static void *mailbox_set_regs[] = { | 31 | static void *mailbox_set_regs[] = { |
32 | (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU), | 32 | IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU), |
33 | (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU) | 33 | IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU) |
34 | }; | 34 | }; |
35 | 35 | ||
36 | static void *mailbox_clear_regs[] = { | 36 | static void *mailbox_clear_regs[] = { |
37 | (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU), | 37 | IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU), |
38 | (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU) | 38 | IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU) |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static void *mailbox_regs[] = { | 41 | static void *mailbox_regs[] = { |
42 | (void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU), | 42 | IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU), |
43 | (void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU) | 43 | IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU) |
44 | }; | 44 | }; |
45 | 45 | ||
46 | /* | 46 | /* |
@@ -73,7 +73,7 @@ void sb1250_smp_finish(void) | |||
73 | */ | 73 | */ |
74 | void core_send_ipi(int cpu, unsigned int action) | 74 | void core_send_ipi(int cpu, unsigned int action) |
75 | { | 75 | { |
76 | bus_writeq((((u64)action) << 48), mailbox_set_regs[cpu]); | 76 | __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]); |
77 | } | 77 | } |
78 | 78 | ||
79 | void sb1250_mailbox_interrupt(struct pt_regs *regs) | 79 | void sb1250_mailbox_interrupt(struct pt_regs *regs) |
@@ -83,10 +83,10 @@ void sb1250_mailbox_interrupt(struct pt_regs *regs) | |||
83 | 83 | ||
84 | kstat_this_cpu.irqs[K_INT_MBOX_0]++; | 84 | kstat_this_cpu.irqs[K_INT_MBOX_0]++; |
85 | /* Load the mailbox register to figure out what we're supposed to do */ | 85 | /* Load the mailbox register to figure out what we're supposed to do */ |
86 | action = (__bus_readq(mailbox_regs[cpu]) >> 48) & 0xffff; | 86 | action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff; |
87 | 87 | ||
88 | /* Clear the mailbox to clear the interrupt */ | 88 | /* Clear the mailbox to clear the interrupt */ |
89 | __bus_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]); | 89 | ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]); |
90 | 90 | ||
91 | /* | 91 | /* |
92 | * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the | 92 | * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the |
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 8b4c848c907b..511c89d65f38 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c | |||
@@ -67,24 +67,24 @@ void sb1250_time_init(void) | |||
67 | sb1250_mask_irq(cpu, irq); | 67 | sb1250_mask_irq(cpu, irq); |
68 | 68 | ||
69 | /* Map the timer interrupt to ip[4] of this cpu */ | 69 | /* Map the timer interrupt to ip[4] of this cpu */ |
70 | bus_writeq(IMR_IP4_VAL, | 70 | __raw_writeq(IMR_IP4_VAL, |
71 | IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) + | 71 | IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) + |
72 | (irq << 3))); | 72 | (irq << 3))); |
73 | 73 | ||
74 | /* the general purpose timer ticks at 1 Mhz independent if the rest of the system */ | 74 | /* the general purpose timer ticks at 1 Mhz independent if the rest of the system */ |
75 | /* Disable the timer and set up the count */ | 75 | /* Disable the timer and set up the count */ |
76 | bus_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | 76 | __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); |
77 | #ifdef CONFIG_SIMULATION | 77 | #ifdef CONFIG_SIMULATION |
78 | bus_writeq(50000 / HZ, | 78 | __raw_writeq(50000 / HZ, |
79 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); | 79 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); |
80 | #else | 80 | #else |
81 | bus_writeq(1000000/HZ, | 81 | __raw_writeq(1000000 / HZ, |
82 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); | 82 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | /* Set the timer running */ | 85 | /* Set the timer running */ |
86 | bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, | 86 | __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, |
87 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | 87 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); |
88 | 88 | ||
89 | sb1250_unmask_irq(cpu, irq); | 89 | sb1250_unmask_irq(cpu, irq); |
90 | sb1250_steal_irq(irq); | 90 | sb1250_steal_irq(irq); |
@@ -100,25 +100,25 @@ void sb1250_time_init(void) | |||
100 | 100 | ||
101 | void sb1250_timer_interrupt(struct pt_regs *regs) | 101 | void sb1250_timer_interrupt(struct pt_regs *regs) |
102 | { | 102 | { |
103 | extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs); | ||
104 | int cpu = smp_processor_id(); | 103 | int cpu = smp_processor_id(); |
105 | int irq = K_INT_TIMER_0 + cpu; | 104 | int irq = K_INT_TIMER_0 + cpu; |
106 | 105 | ||
107 | /* Reset the timer */ | 106 | /* Reset the timer */ |
108 | __bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, | 107 | ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, |
109 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | 108 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); |
110 | 109 | ||
111 | /* | ||
112 | * CPU 0 handles the global timer interrupt job | ||
113 | */ | ||
114 | if (cpu == 0) { | 110 | if (cpu == 0) { |
111 | /* | ||
112 | * CPU 0 handles the global timer interrupt job | ||
113 | */ | ||
115 | ll_timer_interrupt(irq, regs); | 114 | ll_timer_interrupt(irq, regs); |
116 | } | 115 | } |
117 | 116 | else { | |
118 | /* | 117 | /* |
119 | * every CPU should do profiling and process accouting | 118 | * other CPUs should just do profiling and process accounting |
120 | */ | 119 | */ |
121 | ll_local_timer_interrupt(irq, regs); | 120 | ll_local_timer_interrupt(irq, regs); |
121 | } | ||
122 | } | 122 | } |
123 | 123 | ||
124 | /* | 124 | /* |
@@ -130,7 +130,7 @@ void sb1250_timer_interrupt(struct pt_regs *regs) | |||
130 | unsigned long sb1250_gettimeoffset(void) | 130 | unsigned long sb1250_gettimeoffset(void) |
131 | { | 131 | { |
132 | unsigned long count = | 132 | unsigned long count = |
133 | bus_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); | 133 | __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); |
134 | 134 | ||
135 | return 1000000/HZ - count; | 135 | return 1000000/HZ - count; |
136 | } | 136 | } |
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c index a686bb716ec6..5b4fc26c1b36 100644 --- a/arch/mips/sibyte/swarm/rtc_m41t81.c +++ b/arch/mips/sibyte/swarm/rtc_m41t81.c | |||
@@ -82,59 +82,60 @@ | |||
82 | #define M41T81REG_SQW 0x13 /* square wave register */ | 82 | #define M41T81REG_SQW 0x13 /* square wave register */ |
83 | 83 | ||
84 | #define M41T81_CCR_ADDRESS 0x68 | 84 | #define M41T81_CCR_ADDRESS 0x68 |
85 | #define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg)))) | 85 | |
86 | #define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg)) | ||
86 | 87 | ||
87 | static int m41t81_read(uint8_t addr) | 88 | static int m41t81_read(uint8_t addr) |
88 | { | 89 | { |
89 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 90 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
90 | ; | 91 | ; |
91 | 92 | ||
92 | bus_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD)); | 93 | __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD)); |
93 | bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE), | 94 | __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE, |
94 | SMB_CSR(R_SMB_START)); | 95 | SMB_CSR(R_SMB_START)); |
95 | 96 | ||
96 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 97 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
97 | ; | 98 | ; |
98 | 99 | ||
99 | bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), | 100 | __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, |
100 | SMB_CSR(R_SMB_START)); | 101 | SMB_CSR(R_SMB_START)); |
101 | 102 | ||
102 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 103 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
103 | ; | 104 | ; |
104 | 105 | ||
105 | if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { | 106 | if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { |
106 | /* Clear error bit by writing a 1 */ | 107 | /* Clear error bit by writing a 1 */ |
107 | bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); | 108 | __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); |
108 | return -1; | 109 | return -1; |
109 | } | 110 | } |
110 | 111 | ||
111 | return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff); | 112 | return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); |
112 | } | 113 | } |
113 | 114 | ||
114 | static int m41t81_write(uint8_t addr, int b) | 115 | static int m41t81_write(uint8_t addr, int b) |
115 | { | 116 | { |
116 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 117 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
117 | ; | 118 | ; |
118 | 119 | ||
119 | bus_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD)); | 120 | __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD)); |
120 | bus_writeq((b & 0xff), SMB_CSR(R_SMB_DATA)); | 121 | __raw_writeq(b & 0xff, SMB_CSR(R_SMB_DATA)); |
121 | bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, | 122 | __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, |
122 | SMB_CSR(R_SMB_START)); | 123 | SMB_CSR(R_SMB_START)); |
123 | 124 | ||
124 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 125 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
125 | ; | 126 | ; |
126 | 127 | ||
127 | if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { | 128 | if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { |
128 | /* Clear error bit by writing a 1 */ | 129 | /* Clear error bit by writing a 1 */ |
129 | bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); | 130 | __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); |
130 | return -1; | 131 | return -1; |
131 | } | 132 | } |
132 | 133 | ||
133 | /* read the same byte again to make sure it is written */ | 134 | /* read the same byte again to make sure it is written */ |
134 | bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, | 135 | __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, |
135 | SMB_CSR(R_SMB_START)); | 136 | SMB_CSR(R_SMB_START)); |
136 | 137 | ||
137 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 138 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
138 | ; | 139 | ; |
139 | 140 | ||
140 | return 0; | 141 | return 0; |
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c index 981d21f16e64..d9ff9323f24e 100644 --- a/arch/mips/sibyte/swarm/rtc_xicor1241.c +++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c | |||
@@ -57,52 +57,52 @@ | |||
57 | 57 | ||
58 | #define X1241_CCR_ADDRESS 0x6F | 58 | #define X1241_CCR_ADDRESS 0x6F |
59 | 59 | ||
60 | #define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg)))) | 60 | #define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg)) |
61 | 61 | ||
62 | static int xicor_read(uint8_t addr) | 62 | static int xicor_read(uint8_t addr) |
63 | { | 63 | { |
64 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 64 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
65 | ; | 65 | ; |
66 | 66 | ||
67 | bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD)); | 67 | __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD)); |
68 | bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA)); | 68 | __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA)); |
69 | bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), | 69 | __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, |
70 | SMB_CSR(R_SMB_START)); | 70 | SMB_CSR(R_SMB_START)); |
71 | 71 | ||
72 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 72 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
73 | ; | 73 | ; |
74 | 74 | ||
75 | bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), | 75 | __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, |
76 | SMB_CSR(R_SMB_START)); | 76 | SMB_CSR(R_SMB_START)); |
77 | 77 | ||
78 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 78 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
79 | ; | 79 | ; |
80 | 80 | ||
81 | if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { | 81 | if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { |
82 | /* Clear error bit by writing a 1 */ | 82 | /* Clear error bit by writing a 1 */ |
83 | bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); | 83 | __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); |
84 | return -1; | 84 | return -1; |
85 | } | 85 | } |
86 | 86 | ||
87 | return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff); | 87 | return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); |
88 | } | 88 | } |
89 | 89 | ||
90 | static int xicor_write(uint8_t addr, int b) | 90 | static int xicor_write(uint8_t addr, int b) |
91 | { | 91 | { |
92 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 92 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
93 | ; | 93 | ; |
94 | 94 | ||
95 | bus_writeq(addr, SMB_CSR(R_SMB_CMD)); | 95 | __raw_writeq(addr, SMB_CSR(R_SMB_CMD)); |
96 | bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA)); | 96 | __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA)); |
97 | bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE, | 97 | __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE, |
98 | SMB_CSR(R_SMB_START)); | 98 | SMB_CSR(R_SMB_START)); |
99 | 99 | ||
100 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 100 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
101 | ; | 101 | ; |
102 | 102 | ||
103 | if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { | 103 | if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { |
104 | /* Clear error bit by writing a 1 */ | 104 | /* Clear error bit by writing a 1 */ |
105 | bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); | 105 | __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); |
106 | return -1; | 106 | return -1; |
107 | } else { | 107 | } else { |
108 | return 0; | 108 | return 0; |
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index 4daeaa413def..b614ca0ddb69 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation | 2 | * Copyright (C) 2000, 2001, 2002, 2003, 2004 Broadcom Corporation |
3 | * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) | 3 | * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -39,11 +39,23 @@ | |||
39 | #include <asm/time.h> | 39 | #include <asm/time.h> |
40 | #include <asm/traps.h> | 40 | #include <asm/traps.h> |
41 | #include <asm/sibyte/sb1250.h> | 41 | #include <asm/sibyte/sb1250.h> |
42 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) | ||
43 | #include <asm/sibyte/bcm1480_regs.h> | ||
44 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) | ||
42 | #include <asm/sibyte/sb1250_regs.h> | 45 | #include <asm/sibyte/sb1250_regs.h> |
46 | #else | ||
47 | #error invalid SiByte board configuation | ||
48 | #endif | ||
43 | #include <asm/sibyte/sb1250_genbus.h> | 49 | #include <asm/sibyte/sb1250_genbus.h> |
44 | #include <asm/sibyte/board.h> | 50 | #include <asm/sibyte/board.h> |
45 | 51 | ||
52 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) | ||
53 | extern void bcm1480_setup(void); | ||
54 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) | ||
46 | extern void sb1250_setup(void); | 55 | extern void sb1250_setup(void); |
56 | #else | ||
57 | #error invalid SiByte board configuation | ||
58 | #endif | ||
47 | 59 | ||
48 | extern int xicor_probe(void); | 60 | extern int xicor_probe(void); |
49 | extern int xicor_set_time(unsigned long); | 61 | extern int xicor_set_time(unsigned long); |
@@ -66,27 +78,34 @@ void __init swarm_timer_setup(struct irqaction *irq) | |||
66 | */ | 78 | */ |
67 | 79 | ||
68 | /* We only need to setup the generic timer */ | 80 | /* We only need to setup the generic timer */ |
69 | sb1250_time_init(); | 81 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) |
82 | bcm1480_time_init(); | ||
83 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) | ||
84 | sb1250_time_init(); | ||
85 | #else | ||
86 | #error invalid SiByte board configuation | ||
87 | #endif | ||
70 | } | 88 | } |
71 | 89 | ||
72 | int swarm_be_handler(struct pt_regs *regs, int is_fixup) | 90 | int swarm_be_handler(struct pt_regs *regs, int is_fixup) |
73 | { | 91 | { |
74 | if (!is_fixup && (regs->cp0_cause & 4)) { | 92 | if (!is_fixup && (regs->cp0_cause & 4)) { |
75 | /* Data bus error - print PA */ | 93 | /* Data bus error - print PA */ |
76 | #ifdef CONFIG_64BIT | 94 | printk("DBE physical address: %010Lx\n", |
77 | printk("DBE physical address: %010lx\n", | ||
78 | __read_64bit_c0_register($26, 1)); | 95 | __read_64bit_c0_register($26, 1)); |
79 | #else | ||
80 | printk("DBE physical address: %010llx\n", | ||
81 | __read_64bit_c0_split($26, 1)); | ||
82 | #endif | ||
83 | } | 96 | } |
84 | return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); | 97 | return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); |
85 | } | 98 | } |
86 | 99 | ||
87 | static int __init swarm_setup(void) | 100 | void __init plat_setup(void) |
88 | { | 101 | { |
102 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) | ||
103 | bcm1480_setup(); | ||
104 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) | ||
89 | sb1250_setup(); | 105 | sb1250_setup(); |
106 | #else | ||
107 | #error invalid SiByte board configuation | ||
108 | #endif | ||
90 | 109 | ||
91 | panic_timeout = 5; /* For debug. */ | 110 | panic_timeout = 5; /* For debug. */ |
92 | 111 | ||
@@ -133,12 +152,8 @@ static int __init swarm_setup(void) | |||
133 | }; | 152 | }; |
134 | /* XXXKW for CFE, get lines/cols from environment */ | 153 | /* XXXKW for CFE, get lines/cols from environment */ |
135 | #endif | 154 | #endif |
136 | |||
137 | return 0; | ||
138 | } | 155 | } |
139 | 156 | ||
140 | early_initcall(swarm_setup); | ||
141 | |||
142 | #ifdef LEDS_PHYS | 157 | #ifdef LEDS_PHYS |
143 | 158 | ||
144 | #ifdef CONFIG_SIBYTE_CARMEL | 159 | #ifdef CONFIG_SIBYTE_CARMEL |
diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c index c1f1a9defeeb..97c73c793c35 100644 --- a/arch/mips/sibyte/swarm/time.c +++ b/arch/mips/sibyte/swarm/time.c | |||
@@ -79,48 +79,48 @@ static unsigned int usec_bias = 0; | |||
79 | 79 | ||
80 | static int xicor_read(uint8_t addr) | 80 | static int xicor_read(uint8_t addr) |
81 | { | 81 | { |
82 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 82 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
83 | ; | 83 | ; |
84 | 84 | ||
85 | bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD)); | 85 | __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD)); |
86 | bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA)); | 86 | __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA)); |
87 | bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), | 87 | __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, |
88 | SMB_CSR(R_SMB_START)); | 88 | SMB_CSR(R_SMB_START)); |
89 | 89 | ||
90 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 90 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
91 | ; | 91 | ; |
92 | 92 | ||
93 | bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), | 93 | __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, |
94 | SMB_CSR(R_SMB_START)); | 94 | SMB_CSR(R_SMB_START)); |
95 | 95 | ||
96 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 96 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
97 | ; | 97 | ; |
98 | 98 | ||
99 | if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { | 99 | if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { |
100 | /* Clear error bit by writing a 1 */ | 100 | /* Clear error bit by writing a 1 */ |
101 | bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); | 101 | __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); |
102 | return -1; | 102 | return -1; |
103 | } | 103 | } |
104 | 104 | ||
105 | return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff); | 105 | return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); |
106 | } | 106 | } |
107 | 107 | ||
108 | static int xicor_write(uint8_t addr, int b) | 108 | static int xicor_write(uint8_t addr, int b) |
109 | { | 109 | { |
110 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 110 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
111 | ; | 111 | ; |
112 | 112 | ||
113 | bus_writeq(addr, SMB_CSR(R_SMB_CMD)); | 113 | __raw_writeq(addr, SMB_CSR(R_SMB_CMD)); |
114 | bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA)); | 114 | __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA)); |
115 | bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE, | 115 | __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE, |
116 | SMB_CSR(R_SMB_START)); | 116 | SMB_CSR(R_SMB_START)); |
117 | 117 | ||
118 | while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) | 118 | while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) |
119 | ; | 119 | ; |
120 | 120 | ||
121 | if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { | 121 | if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { |
122 | /* Clear error bit by writing a 1 */ | 122 | /* Clear error bit by writing a 1 */ |
123 | bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); | 123 | __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); |
124 | return -1; | 124 | return -1; |
125 | } else { | 125 | } else { |
126 | return 0; | 126 | return 0; |
@@ -228,8 +228,8 @@ void __init swarm_time_init(void) | |||
228 | /* Establish communication with the Xicor 1241 RTC */ | 228 | /* Establish communication with the Xicor 1241 RTC */ |
229 | /* XXXKW how do I share the SMBus with the I2C subsystem? */ | 229 | /* XXXKW how do I share the SMBus with the I2C subsystem? */ |
230 | 230 | ||
231 | bus_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ)); | 231 | __raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ)); |
232 | bus_writeq(0, SMB_CSR(R_SMB_CONTROL)); | 232 | __raw_writeq(0, SMB_CSR(R_SMB_CONTROL)); |
233 | 233 | ||
234 | if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) { | 234 | if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) { |
235 | printk("x1241: couldn't detect on SWARM SMBus 1\n"); | 235 | printk("x1241: couldn't detect on SWARM SMBus 1\n"); |