1 diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
2 index c5d351786416..78bf5825044c 100644
3 --- a/arch/mips/include/asm/irq.h
4 +++ b/arch/mips/include/asm/irq.h
5 @@ -60,9 +60,11 @@ extern void do_IRQ(unsigned int irq);
6 extern void arch_init_irq(void);
7 extern void spurious_interrupt(void);
9 -extern int allocate_irqno(void);
10 -extern void alloc_legacy_irqno(void);
11 -extern void free_irqno(unsigned int irq);
12 +#if defined(CONFIG_SGI_IP27)
13 +extern int ip27_alloc_irq_num(void);
14 +extern void ip27_assign_irq_num(int irq);
15 +extern void ip27_free_irq_num(int irq);
19 * Before R2 the timer and performance counter interrupts were both fixed to
20 diff --git a/arch/mips/include/asm/mach-ip27/mangle-port.h b/arch/mips/include/asm/mach-ip27/mangle-port.h
21 index f6e4912ea062..5184c947718d 100644
22 --- a/arch/mips/include/asm/mach-ip27/mangle-port.h
23 +++ b/arch/mips/include/asm/mach-ip27/mangle-port.h
25 #ifndef __ASM_MACH_IP27_MANGLE_PORT_H
26 #define __ASM_MACH_IP27_MANGLE_PORT_H
28 -#define __swizzle_addr_b(port) (port)
29 +#define __swizzle_addr_b(port) ((port) ^ 3)
30 #define __swizzle_addr_w(port) ((port) ^ 2)
31 #define __swizzle_addr_l(port) (port)
32 #define __swizzle_addr_q(port) (port)
34 # define ioswabl(a, x) (x)
35 # define __mem_ioswabl(a, x) cpu_to_le32(x)
36 # define ioswabq(a, x) (x)
37 -# define __mem_ioswabq(a, x) cpu_to_le32(x)
38 +# define __mem_ioswabq(a, x) cpu_to_le64(x)
40 #endif /* __ASM_MACH_IP27_MANGLE_PORT_H */
41 diff --git a/arch/mips/include/asm/mach-ip27/mmzone.h b/arch/mips/include/asm/mach-ip27/mmzone.h
42 index 2ed3094dee07..f7006e185f79 100644
43 --- a/arch/mips/include/asm/mach-ip27/mmzone.h
44 +++ b/arch/mips/include/asm/mach-ip27/mmzone.h
46 /* SPDX-License-Identifier: GPL-2.0 */
48 #ifndef _ASM_MACH_MMZONE_H
49 #define _ASM_MACH_MMZONE_H
52 #include <asm/sn/arch.h>
53 #include <asm/sn/hub.h>
55 -#define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr))
57 -#define LEVELS_PER_SLICE 128
58 +#define pa_to_nid(addr) sn_nasid_to_cnodeid[NASID_GET(addr)]
61 - unsigned long irq_enable_mask[2];
62 - int level_to_irq[LEVELS_PER_SLICE];
64 +#define BITS_PER_HUB 128
67 kern_vars_t kern_vars;
68 DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
70 unsigned long slice_map;
71 - unsigned long irq_alloc_mask[2];
72 - struct slice_data slice[2];
73 + unsigned long irq_alloc_map[2];
74 + s8 irq_owner[BITS_PER_HUB];
75 + s8 irq_to_bit[BITS_PER_HUB];
76 + s8 bit_to_irq[BITS_PER_HUB];
77 + raw_spinlock_t lock;
81 + * struct ip27_percpu_data - percpu data for each CPU in an IP27 system.
82 + * @id: ID of the CPU
84 + * @codeid: compact node id.
85 + * @slice: 0 for CPU A or 1 for CPU B
86 + * @irq_mask: array of two unsigned longs to hold the INT_PEND mask.
87 + * @irq_owner: boolean array to mark if a CPU owns an IRQ.
88 + * @hub_data: struct hub_data pointer for the HUB chip the CPU is attached to.
90 +struct ip27_percpu_data {
95 + unsigned long irq_mask[2];
96 + struct hub_data *hub;
99 +/* XXX: This probably belongs in a dedicated cpu.h header. */
100 +#define IP27_CPU_SLICE(_s) \
101 + (!(_s) ? 'A' : 'B')
104 struct pglist_data pglist;
106 diff --git a/arch/mips/include/asm/mach-ip27/pcibr.h b/arch/mips/include/asm/mach-ip27/pcibr.h
107 index 6664843c30f9..193856bc4ba6 100644
108 --- a/arch/mips/include/asm/mach-ip27/pcibr.h
109 +++ b/arch/mips/include/asm/mach-ip27/pcibr.h
111 * Used by ip27-bridge.c and ip27-irq.c.
113 #define PCIBR_MAX_BUS_X_DEV (PCIBR_MAX_NUM_PCIBUS * PCIBR_MAX_DEV_PCIBUS)
114 -extern struct bridge_controller *irq_to_bridge[PCIBR_MAX_BUS_X_DEV];
115 -extern u32 irq_to_slot[PCIBR_MAX_BUS_X_DEV];
117 -/* XXX: Temporary until IP27 "mega update". */
118 -extern int request_bridge_irq(struct bridge_controller *bc);
119 +extern struct bridge_controller *ip27_irq_to_bridge[PCIBR_MAX_BUS_X_DEV];
120 +extern u32 ip27_irq_to_slot[PCIBR_MAX_BUS_X_DEV];
122 #endif /* __ASM_MACH_IP27_PCIBR_H */
124 diff --git a/arch/mips/include/asm/mach-ip27/spaces.h b/arch/mips/include/asm/mach-ip27/spaces.h
125 index 24d5e31bcfa6..66421e9a6aa6 100644
126 --- a/arch/mips/include/asm/mach-ip27/spaces.h
127 +++ b/arch/mips/include/asm/mach-ip27/spaces.h
129 #ifndef _ASM_MACH_IP27_SPACES_H
130 #define _ASM_MACH_IP27_SPACES_H
132 +#include <linux/const.h>
135 * IP27 uses the R10000's uncached attribute feature. Attribute 3 selects
136 * uncached memory addressing. Hide the definitions on 32-bit compilation
137 * of the compat-vdso code.
140 -#define HSPEC_BASE 0x9000000000000000
141 -#define IO_BASE 0x9200000000000000
142 -#define MSPEC_BASE 0x9400000000000000
143 -#define UNCAC_BASE 0x9600000000000000
144 -#define CAC_BASE 0xa800000000000000
145 +#define HSPEC_BASE _AC(0x9000000000000000, UL)
146 +#define IO_BASE _AC(0x9200000000000000, UL)
147 +#define MSPEC_BASE _AC(0x9400000000000000, UL)
148 +#define UNCAC_BASE _AC(0x9600000000000000, UL)
149 +#define CAC_BASE _AC(0xa800000000000000, UL)
152 #define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK))
153 diff --git a/arch/mips/include/asm/mach-ip27/sysinfo.h b/arch/mips/include/asm/mach-ip27/sysinfo.h
155 index 000000000000..83270d0e625b
157 +++ b/arch/mips/include/asm/mach-ip27/sysinfo.h
160 + * IP27/Origin/Onyx2 misc system defines that don't fit into other headers.
162 + * Copyright (C) 2016 Joshua Kinard <kumba@gentoo.org>
164 + * This file is subject to the terms and conditions of the GNU General Public
165 + * License. See the file "COPYING" in the main directory of this archive
166 + * for more details.
168 +#ifndef __ASM_MACH_IP27_SYSINFO_H
169 +#define __ASM_MACH_IP27_SYSINFO_H
171 +/* Hardcoded IP27 xtalk widget IDs. */
172 +#define IP27_WIDGET_XBOW _AC(0x0, UL) /* XBow is always 0 */
173 +#define IP27_WIDGET_HUB _AC(0xa, UL) /* HUB is always 0xa */
174 +#define IP27_WIDGET_PCI_CAGE _AC(0xc, UL) /* PCI Cage is always 12 */
175 +#define IP27_WIDGET_PCI_BASE _AC(0xf, UL) /* IO6[-G] is always 15 */
177 +/* On the IO6 BRIDGE, at least one slot is hardwired for special functions */
178 +#define IP27_IO6_2ND_IOC3 3
179 +/* XXX: Could there be more? What's slot #4 do? */
181 +#endif /* __ASM_MACH_IP27_SYSINFO_H */
182 diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h
183 index 42ea1313626c..d9052fd5210f 100644
184 --- a/arch/mips/include/asm/mach-ip27/topology.h
185 +++ b/arch/mips/include/asm/mach-ip27/topology.h
187 /* SPDX-License-Identifier: GPL-2.0 */
189 #ifndef _ASM_MACH_TOPOLOGY_H
190 -#define _ASM_MACH_TOPOLOGY_H 1
191 +#define _ASM_MACH_TOPOLOGY_H
193 #include <asm/sn/hub.h>
194 #include <asm/sn/types.h>
195 #include <asm/mmzone.h>
197 -struct cpuinfo_ip27 {
198 -// cpuid_t p_cpuid; /* PROM assigned cpuid */
199 - cnodeid_t p_nodeid; /* my node ID in compact-id-space */
200 - nasid_t p_nasid; /* my node ID in numa-as-id-space */
201 - unsigned char p_slice; /* Physical position on node board */
203 - unsigned long loops_per_sec;
204 - unsigned long ipi_count;
205 - unsigned long irq_attempt[NR_IRQS];
206 - unsigned long smp_local_irq_count;
207 - unsigned long prof_multiplier;
208 - unsigned long prof_counter;
212 -extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
214 -#define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid)
215 +DECLARE_PER_CPU(struct ip27_percpu_data, ip27_cpu);
217 +#define cpu_to_node(cpu) (per_cpu(ip27_cpu, cpu).cnodeid)
218 #define cpumask_of_node(node) ((node) == -1 ? \
220 - &hub_data(node)->h_cpus)
221 + cpu_all_mask : &hub_data(node)->h_cpus)
223 extern int pcibus_to_node(struct pci_bus *);
225 diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h
226 index f891a44169a0..1e1507711b2a 100644
227 --- a/arch/mips/include/asm/pci/bridge.h
228 +++ b/arch/mips/include/asm/pci/bridge.h
229 @@ -823,7 +823,8 @@ struct bridge_widget {
232 * XXX: Convert below struct into bitfield macros. Or do away with
233 - * entirely. Unused in Linux, but useful documentation.
234 + * entirely. It's good documentation, but otherwise, is not
235 + * used anywhere in the kernel.
238 * Field formats for Error Command Word and Auxiliary Error Command Word
239 @@ -994,7 +995,6 @@ struct bridge_controller {
244 int (*alloc_irq)(struct pci_dev *);
247 diff --git a/arch/mips/include/asm/sn/addrs.h b/arch/mips/include/asm/sn/addrs.h
248 index 66814f8ba8e8..ac118518c617 100644
249 --- a/arch/mips/include/asm/sn/addrs.h
250 +++ b/arch/mips/include/asm/sn/addrs.h
252 #define UALIAS_FLIP_BASE UALIAS_BASE
253 #define UALIAS_FLIP_SIZE 0x20000
254 #define UALIAS_FLIP_BIT 0x10000
255 -#define UALIAS_FLIP_ADDR(_x) (cputoslice(smp_processor_id()) ? \
256 +#define UALIAS_FLIP_ADDR(_x) (per_cpu(ip27_cpu, smp_processor_id()).slice) ? \
257 (_x) ^ UALIAS_FLIP_BIT : (_x))
259 #define LBOOT_BASE (HSPEC_BASE + 0x10000000)
260 diff --git a/arch/mips/include/asm/sn/agent.h b/arch/mips/include/asm/sn/agent.h
261 index e33d09293019..c7ad95e3c1f6 100644
262 --- a/arch/mips/include/asm/sn/agent.h
263 +++ b/arch/mips/include/asm/sn/agent.h
267 #if defined(CONFIG_SGI_IP27)
268 -#define HUB_NIC_ADDR(_cpuid) \
269 - REMOTE_HUB_ADDR(COMPACT_TO_NASID_NODEID(cpu_to_node(_cpuid)), \
270 +#define HUB_NIC_ADDR(_cpuid) \
271 + REMOTE_HUB_ADDR(sn_cnodeid_to_nasid[sn_cpuid_to_cnodeid[(_cpuid)]], \
275 diff --git a/arch/mips/include/asm/sn/arch.h b/arch/mips/include/asm/sn/arch.h
276 index 471e6870d876..9b9bc31a0d9a 100644
277 --- a/arch/mips/include/asm/sn/arch.h
278 +++ b/arch/mips/include/asm/sn/arch.h
280 #define _ASM_SN_ARCH_H
282 #include <linux/types.h>
283 +#include <linux/percpu.h>
285 #include <asm/sn/types.h>
286 #ifdef CONFIG_SGI_IP27
287 #include <asm/sn/sn0/arch.h>
290 typedef u64 hubreg_t;
292 -#define cputonasid(cpu) (sn_cpu_info[(cpu)].p_nasid)
293 -#define cputoslice(cpu) (sn_cpu_info[(cpu)].p_slice)
294 #define makespnum(_nasid, _slice) \
295 (((_nasid) << CPUS_PER_NODE_SHFT) | (_slice))
297 @@ -30,35 +30,24 @@ typedef u64 hubreg_t;
298 #define INVALID_MODULE (moduleid_t)-1
299 #define INVALID_PARTID (partid_t)-1
301 -extern nasid_t get_nasid(void);
302 -extern cnodeid_t get_cpu_cnode(cpuid_t);
303 -extern int get_cpu_slice(cpuid_t);
304 +extern nasid_t ip27_get_nasid(void);
305 +extern int get_cpu_slice(cpuid_t) __init;
308 - * NO ONE should access these arrays directly. The only reason we refer to
309 - * them here is to avoid the procedure call that would be required in the
310 - * macros below. (Really want private data members here :-)
312 -extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
313 -extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
314 +#define NASID_TO_REGION(nnode) \
315 + ((nnode) >> (is_fine_dirmode() ? \
316 + NASID_TO_FINEREG_SHFT : NASID_TO_COARSEREG_SHFT))
319 - * These macros are used by various parts of the kernel to convert
320 - * between the three different kinds of node numbering. At least some
321 - * of them may change to procedure calls in the future, but the macros
322 - * will continue to work. Don't use the arrays above directly.
325 -#define NASID_TO_REGION(nnode) \
327 - (is_fine_dirmode() ? NASID_TO_FINEREG_SHFT : NASID_TO_COARSEREG_SHFT))
328 +/* Compact node ID to nasid mappings as per-cpu data */
329 +DECLARE_PER_CPU(cnodeid_t, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
330 +#define sn_cnodeid_to_nasid this_cpu_ptr(&__sn_cnodeid_to_nasid[0])
332 -extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
333 -extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
334 -extern cnodeid_t cpuid_to_compact_node[MAXCPUS];
335 +/* NUMA-node-as-ID to compact node ID mappings as per-cpu data */
336 +DECLARE_PER_CPU(nasid_t, __sn_nasid_to_cnodeid[MAX_NASIDS]);
337 +#define sn_nasid_to_cnodeid this_cpu_ptr(&__sn_nasid_to_cnodeid[0])
339 -#define NASID_TO_COMPACT_NODEID(nnode) (nasid_to_compact_node[nnode])
340 -#define COMPACT_TO_NASID_NODEID(cnode) (compact_to_nasid_node[cnode])
341 -#define CPUID_TO_COMPACT_NODEID(cpu) (cpuid_to_compact_node[(cpu)])
342 +/* CPUID to compact node ID mappings as per-cpu data */
343 +DECLARE_PER_CPU(cnodeid_t, __sn_cpuid_to_cnodeid[MAXCPUS]);
344 +#define sn_cpuid_to_cnodeid this_cpu_ptr(&__sn_cpuid_to_cnodeid[0])
346 #endif /* _ASM_SN_ARCH_H */
347 diff --git a/arch/mips/include/asm/sn/fru.h b/arch/mips/include/asm/sn/fru.h
348 index bbb83257c8e2..b92901ef2051 100644
349 --- a/arch/mips/include/asm/sn/fru.h
350 +++ b/arch/mips/include/asm/sn/fru.h
352 #define MAX_DIMMS 8 /* max # of dimm banks */
353 #define MAX_PCIDEV 8 /* max # of pci devices on a pci bus */
355 -typedef unsigned char confidence_t;
357 typedef struct kf_mem_s {
358 - confidence_t km_confidence; /* confidence level that the memory is bad
359 + u8 km_confidence; /* confidence level that the memory is bad
360 * is this necessary ?
362 - confidence_t km_dimm[MAX_DIMMS];
363 + u8 km_dimm[MAX_DIMMS];
364 /* confidence level that dimm[i] is bad
365 *I think this is the right number
367 @@ -28,16 +26,16 @@ typedef struct kf_mem_s {
370 typedef struct kf_cpu_s {
371 - confidence_t kc_confidence; /* confidence level that cpu is bad */
372 - confidence_t kc_icache; /* confidence level that instr. cache is bad */
373 - confidence_t kc_dcache; /* confidence level that data cache is bad */
374 - confidence_t kc_scache; /* confidence level that sec. cache is bad */
375 - confidence_t kc_sysbus; /* confidence level that sysad/cmd/state bus is bad */
376 + u8 kc_confidence; /* confidence level that cpu is bad */
377 + u8 kc_icache; /* confidence level that instr. cache is bad */
378 + u8 kc_dcache; /* confidence level that data cache is bad */
379 + u8 kc_scache; /* confidence level that sec. cache is bad */
380 + u8 kc_sysbus; /* confidence level that sysad/cmd/state bus is bad */
383 typedef struct kf_pci_bus_s {
384 - confidence_t kpb_belief; /* confidence level that the pci bus is bad */
385 - confidence_t kpb_pcidev_belief[MAX_PCIDEV];
386 + u8 kpb_belief; /* confidence level that the pci bus is bad */
387 + u8 kpb_pcidev_belief[MAX_PCIDEV];
388 /* confidence level that the pci dev is bad */
391 diff --git a/arch/mips/include/asm/sn/gda.h b/arch/mips/include/asm/sn/gda.h
392 index 85fa1b5f639d..852d48c43041 100644
393 --- a/arch/mips/include/asm/sn/gda.h
394 +++ b/arch/mips/include/asm/sn/gda.h
395 @@ -65,7 +65,7 @@ typedef struct gda {
399 -#define GDA ((gda_t*) GDA_ADDR(get_nasid()))
400 +#define GDA ((gda_t*) GDA_ADDR(ip27_get_nasid()))
402 #endif /* !__ASSEMBLY__ */
404 diff --git a/arch/mips/include/asm/sn/hub.h b/arch/mips/include/asm/sn/hub.h
405 index 9e6d76f8d12a..646cc1806c0e 100644
406 --- a/arch/mips/include/asm/sn/hub.h
407 +++ b/arch/mips/include/asm/sn/hub.h
409 #include <asm/xtalk/xtalk.h>
412 -extern unsigned long hub_pio_map(cnodeid_t cnode, s8 widget,
413 - unsigned long xtalk_addr, size_t size);
414 -extern void hub_pio_init(cnodeid_t cnode);
417 + * XXX: Requires porting from 2.4 arch/ia64/sn/io/io.c the various HUB
418 + * PIO/DMA mapping stuff and setting up generic Xtalk bus support.
420 +extern u64 ip27_hub_pio_map(cnodeid_t cnode, s8 widget,
421 + unsigned long xtalk_addr, size_t size);
423 +extern void __init ip27_hub_pio_init(cnodeid_t cnode);
425 #endif /* __ASM_SN_HUB_H */
426 diff --git a/arch/mips/include/asm/sn/klconfig.h b/arch/mips/include/asm/sn/klconfig.h
427 index 467c313d5767..9290691c64f2 100644
428 --- a/arch/mips/include/asm/sn/klconfig.h
429 +++ b/arch/mips/include/asm/sn/klconfig.h
431 #ifndef _ASM_SN_KLCONFIG_H
432 #define _ASM_SN_KLCONFIG_H
435 - * The KLCONFIG structures store info about the various BOARDs found
436 - * during Hardware Discovery. In addition, it stores info about the
437 - * components found on the BOARDs.
442 - * Certain assembly language routines (notably xxxxx.s) in the IP27PROM
443 - * will depend on the format of the data structures in this file. In
444 - * most cases, rearranging the fields can seriously break things.
445 - * Adding fields in the beginning or middle can also break things.
446 - * Add fields if necessary, to the end of a struct in such a way
447 - * that offsets of existing fields do not change.
450 #include <linux/types.h>
451 #include <asm/sn/types.h>
453 #if defined(CONFIG_SGI_IP27)
455 #include <asm/sn/sn0/addrs.h>
456 -//#include <sys/SN/router.h>
457 -// XXX Stolen from <sys/SN/router.h>:
458 -#define MAX_ROUTER_PORTS (6) /* Max. number of ports on a router */
459 #include <asm/sn/fru.h>
460 -//#include <sys/graph.h>
461 -//#include <sys/xtalk/xbow.h>
463 -#elif defined(CONFIG_SGI_IP35)
465 -#include <asm/sn/sn1/addrs.h>
466 -#include <sys/sn/router.h>
467 -#include <sys/graph.h>
468 -#include <asm/xtalk/xbow.h>
469 +/* CONFIG_SGI_IP35 bits will go here in the future. */
470 +#endif /* CONFIG_SGI_IP27 */
472 -#endif /* !CONFIG_SGI_IP27 && !CONFIG_SGI_IP35 */
474 -#if defined(CONFIG_SGI_IP27) || defined(CONFIG_SGI_IP35)
475 +#if defined(CONFIG_SGI_IP27) /* || defined(CONFIG_SGI_IP35) */
476 #include <asm/sn/agent.h>
477 #include <asm/fw/arc/types.h>
478 #include <asm/fw/arc/hinv.h>
479 -#if defined(CONFIG_SGI_IP35)
480 -// The hack file has to be before vector and after sn0_fru....
481 -#include <asm/hack.h>
482 -#include <asm/sn/vector.h>
483 -#include <asm/xtalk/xtalk.h>
484 -#endif /* CONFIG_SGI_IP35 */
485 -#endif /* CONFIG_SGI_IP27 || CONFIG_SGI_IP35 */
489 -#define KLCFGINFO_MAGIC 0xbeedbabe
490 +/* CONFIG_SGI_IP35 bits will go here in the future. */
491 +#endif /* CONFIG_SGI_IP27 */
493 -typedef s32 klconf_off_t;
496 - * Some IMPORTANT OFFSETS. These are the offsets on all NODES.
498 -#define MAX_MODULE_ID 255
499 -#define SIZE_PAD 4096 /* 4k padding for structures */
501 - * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets,
502 - * 2 Midplanes assuming no pci card cages
504 -#define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 2)
506 -/* XXX if each node is guaranteed to have some memory */
508 -#define MAX_PCI_DEVS 8
510 -/* lboard_t->brd_flags fields */
511 -/* All bits in this field are currently used. Try the pad fields if
512 - you need more flag bits */
514 -#define ENABLE_BOARD 0x01
515 -#define FAILED_BOARD 0x02
516 -#define DUPLICATE_BOARD 0x04 /* Boards like midplanes/routers which
517 - are discovered twice. Use one of them */
518 -#define VISITED_BOARD 0x08 /* Used for compact hub numbering. */
519 -#define LOCAL_MASTER_IO6 0x10 /* master io6 for that node */
520 -#define GLOBAL_MASTER_IO6 0x20
521 -#define THIRD_NIC_PRESENT 0x40 /* for future use */
522 -#define SECOND_NIC_PRESENT 0x80 /* addons like MIO are present */
524 -/* klinfo->flags fields */
526 -#define KLINFO_ENABLE 0x01 /* This component is enabled */
527 -#define KLINFO_FAILED 0x02 /* This component failed */
528 -#define KLINFO_DEVICE 0x04 /* This component is a device */
529 -#define KLINFO_VISITED 0x08 /* This component has been visited */
530 -#define KLINFO_CONTROLLER 0x10 /* This component is a device controller */
531 -#define KLINFO_INSTALL 0x20 /* Install a driver */
532 -#define KLINFO_HEADLESS 0x40 /* Headless (or hubless) component */
533 -#define IS_CONSOLE_IOC3(i) ((((klinfo_t *)i)->flags) & KLINFO_INSTALL)
535 -#define GB2 0x80000000
537 -#define MAX_RSV_PTRS 32
539 -/* Structures to manage various data storage areas */
540 -/* The numbers must be contiguous since the array index i
541 - is used in the code to allocate various areas.
544 -#define BOARD_STRUCT 0
545 -#define COMPONENT_STRUCT 1
546 -#define ERRINFO_STRUCT 2
547 -#define KLMALLOC_TYPE_MAX (ERRINFO_STRUCT + 1)
548 -#define DEVICE_STRUCT 3
551 -typedef struct console_s {
552 - unsigned long uart_base;
553 - unsigned long config_base;
554 - unsigned long memory_base;
564 -typedef struct klc_malloc_hdr {
565 - klconf_off_t km_base;
566 - klconf_off_t km_limit;
567 - klconf_off_t km_current;
570 -/* Functions/macros needed to use this structure */
572 -typedef struct kl_config_hdr {
573 - u64 ch_magic; /* set this to KLCFGINFO_MAGIC */
574 - u32 ch_version; /* structure version number */
575 - klconf_off_t ch_malloc_hdr_off; /* offset of ch_malloc_hdr */
576 - klconf_off_t ch_cons_off; /* offset of ch_cons */
577 - klconf_off_t ch_board_info; /* the link list of boards */
578 - console_t ch_cons_info; /* address info of the console */
579 - klc_malloc_hdr_t ch_malloc_hdr[KLMALLOC_TYPE_MAX];
580 - confidence_t ch_sw_belief; /* confidence that software is bad*/
581 - confidence_t ch_sn0net_belief; /* confidence that sn0net is bad */
585 -#define KL_CONFIG_HDR(_nasid) ((kl_config_hdr_t *)(KLCONFIG_ADDR(_nasid)))
586 -#define KL_CONFIG_INFO_OFFSET(_nasid) \
587 - (KL_CONFIG_HDR(_nasid)->ch_board_info)
588 -#define KL_CONFIG_INFO_SET_OFFSET(_nasid, _off) \
589 - (KL_CONFIG_HDR(_nasid)->ch_board_info = (_off))
591 -#define KL_CONFIG_INFO(_nasid) \
592 - (lboard_t *)((KL_CONFIG_HDR(_nasid)->ch_board_info) ? \
593 - NODE_OFFSET_TO_K1((_nasid), KL_CONFIG_HDR(_nasid)->ch_board_info) : \
595 -#define KL_CONFIG_MAGIC(_nasid) (KL_CONFIG_HDR(_nasid)->ch_magic)
597 -#define KL_CONFIG_CHECK_MAGIC(_nasid) \
598 - (KL_CONFIG_HDR(_nasid)->ch_magic == KLCFGINFO_MAGIC)
600 -#define KL_CONFIG_HDR_INIT_MAGIC(_nasid) \
601 - (KL_CONFIG_HDR(_nasid)->ch_magic = KLCFGINFO_MAGIC)
603 -/* --- New Macros for the changed kl_config_hdr_t structure --- */
605 -#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\
606 - ((unsigned long)_k + (_k->ch_malloc_hdr_off)))
608 -#define KL_CONFIG_CH_MALLOC_HDR(_n) PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n))
610 -#define PTR_CH_CONS_INFO(_k) ((console_t *)\
611 - ((unsigned long)_k + (_k->ch_cons_off)))
613 -#define KL_CONFIG_CH_CONS_INFO(_n) PTR_CH_CONS_INFO(KL_CONFIG_HDR(_n))
615 -/* ------------------------------------------------------------- */
617 -#define KL_CONFIG_INFO_START(_nasid) \
618 - (klconf_off_t)(KLCONFIG_OFFSET(_nasid) + sizeof(kl_config_hdr_t))
620 -#define KL_CONFIG_BOARD_NASID(_brd) ((_brd)->brd_nasid)
621 -#define KL_CONFIG_BOARD_SET_NEXT(_brd, _off) ((_brd)->brd_next = (_off))
623 -#define KL_CONFIG_DUPLICATE_BOARD(_brd) ((_brd)->brd_flags & DUPLICATE_BOARD)
625 -#define XBOW_PORT_TYPE_HUB(_xbowp, _link) \
626 - ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_HUB)
627 -#define XBOW_PORT_TYPE_IO(_xbowp, _link) \
628 - ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_IO)
630 -#define XBOW_PORT_IS_ENABLED(_xbowp, _link) \
631 - ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_ENABLE)
632 -#define XBOW_PORT_NASID(_xbowp, _link) \
633 - ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_nasid)
635 -#define XBOW_PORT_IO 0x1
636 -#define XBOW_PORT_HUB 0x2
637 -#define XBOW_PORT_ENABLE 0x4
639 -#define SN0_PORT_FENCE_SHFT 0
640 -#define SN0_PORT_FENCE_MASK (1 << SN0_PORT_FENCE_SHFT)
643 + * The KLCONFIG structures store info about the various BOARDs found
644 + * during Hardware Discovery. In addition, it stores info about the
645 + * components found on the BOARDs.
647 * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD
648 * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to
649 * the LOCAL/current NODE. REMOTE means it is attached to a different
650 @@ -240,31 +58,31 @@ typedef struct kl_config_hdr {
651 * the local base address and ignoring all rboard values.
656 - +------------+ +------------+ +------------+ +------------+
657 - | lboard | +-->| lboard | +-->| rboard | +-->| lboard |
658 - +------------+ | +------------+ | +------------+ | +------------+
659 - | board info | | | board info | | |errinfo,bptr| | | board info |
660 - +------------+ | +------------+ | +------------+ | +------------+
661 - | offset |--+ | offset |--+ | offset |--+ |offset=NULL |
662 - +------------+ +------------+ +------------+ +------------+
667 - +------------+ +--------------------------------+
668 - | compt 1 |------>| type, rev, diaginfo, size ... | (CPU)
669 - +------------+ +--------------------------------+
671 - +------------+ | +--------------------------------+
672 - | ... | +--->| type, rev, diaginfo, size ... | (MEM_BANK)
673 - +------------+ +--------------------------------+
675 - +------------+ | +--------------------------------+
676 - +--->|r/l brd errinfo,compt err flags |
677 - +--------------------------------+
681 + * +------------+ +------------+ +------------+ +------------+
682 + * | lboard | +-->| lboard | +-->| rboard | +-->| lboard |
683 + * +------------+ | +------------+ | +------------+ | +------------+
684 + * | board info | | | board info | | |errinfo,bptr| | | board info |
685 + * +------------+ | +------------+ | +------------+ | +------------+
686 + * | offset |--+ | offset |--+ | offset |--+ |offset=NULL |
687 + * +------------+ +------------+ +------------+ +------------+
692 + * +------------+ +--------------------------------+
693 + * | comp 1 |------>| type, rev, diaginfo, size ... | (CPU)
694 + * +------------+ +--------------------------------+
696 + * +------------+ | +--------------------------------+
697 + * | ... | +--->| type, rev, diaginfo, size ... | (MEM_BANK)
698 + * +------------+ +--------------------------------+
700 + * +------------+ | +--------------------------------+
701 + * +--->|r/l brd errinfo,compt err flags |
702 + * +--------------------------------+
705 * Each BOARD consists of COMPONENTs and the BOARD structure has
706 * pointers (offsets) to its COMPONENT structure.
707 @@ -292,11 +110,12 @@ typedef struct kl_config_hdr {
708 * using the rboard errinfo pointer.
710 * In order to get useful information from this Data organization, a set of
711 - * interface routines are provided (TBD). The important thing to remember while
712 - * manipulating the structures, is that, the NODE number information should
713 - * be used. If the NODE is non-zero (remote) then each offset should
714 - * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR.
715 - * This includes offsets for BOARDS, COMPONENTS and ERRORINFO.
716 + * interface routines are provided (TBD). The important thing to remember
717 + * while manipulating the structures, is that, the NODE number information
718 + * should be used. If the NODE is non-zero (remote) then each offset should
719 + * be added to the REMOTE_BASE_ADDR else it should be added to the
720 + * LOCAL_BASE_ADDR. This includes offsets for BOARDS, COMPONENTS and
723 * Note that these structures do not provide much info about connectivity.
724 * That info will be part of HWGRAPH, which is an extension of the cfg_t
725 @@ -304,595 +123,1099 @@ typedef struct kl_config_hdr {
726 * the IO part of the Network(TBD).
728 * The data structures below define the above concepts.
730 + * XXX: Missing definition for struct klc_rboard!
734 - * Values for CPU types
735 + * XXX: Linux note: The below warning is apparently a relic from IRIX.
738 + * Certain assembly language routines (notably xxxxx.s) in the IP27PROM
739 + * will depend on the format of the data structures in this file. In
740 + * most cases, rearranging the fields can seriously break things.
741 + * Adding fields in the beginning or middle can also break things.
742 + * Add fields if necessary, to the end of a struct in such a way
743 + * that offsets of existing fields do not change.
745 -#define KL_CPU_R4000 0x1 /* Standard R4000 */
746 -#define KL_CPU_TFP 0x2 /* TFP processor */
747 -#define KL_CPU_R10000 0x3 /* R10000 (T5) */
748 -#define KL_CPU_NONE (-1) /* no cpu present in slot */
751 +/* XXX: Linux note: The below defines aren't used anywhere. Keep? */
752 +#define MAX_MODULE_ID 255
753 +#define SIZE_PAD 4096 /* 4k padding for structures */
754 +#define GB2 0x80000000
755 +#define MAX_RSV_PTRS 32
756 +#define SN0_PORT_FENCE_SHFT 0
757 +#define SN0_PORT_FENCE_MASK (1 << SN0_PORT_FENCE_SHFT)
760 - * IP27 BOARD classes
761 + * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets,
762 + * 2 Midplanes assuming no pci card cages
764 +#define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 2)
766 -#define KLCLASS_MASK 0xf0
767 -#define KLCLASS_NONE 0x00
768 -#define KLCLASS_NODE 0x10 /* CPU, Memory and HUB board */
769 -#define KLCLASS_CPU KLCLASS_NODE
770 -#define KLCLASS_IO 0x20 /* BaseIO, 4 ch SCSI, ethernet, FDDI
771 - and the non-graphics widget boards */
772 -#define KLCLASS_ROUTER 0x30 /* Router board */
773 -#define KLCLASS_MIDPLANE 0x40 /* We need to treat this as a board
774 - so that we can record error info */
775 -#define KLCLASS_GFX 0x50 /* graphics boards */
776 +/* ----------------------------------------------------------------------- */
777 +/* struct klc_* casting wrappers - Add more as needed */
779 -#define KLCLASS_PSEUDO_GFX 0x60 /* HDTV type cards that use a gfx
780 - * hw ifc to xtalk and are not gfx
781 - * class for sw purposes */
783 + * Common parameter conventions for macros:
784 + * _b: BOARD or MEMBANK
786 + * _i: struct klc_info passed by value
787 + * _k: Refers to either K0 or K1 MIPS memory area
794 -#define KLCLASS_MAX 7 /* Bump this if a new CLASS is added */
795 -#define KLTYPE_MAX 10 /* Bump this if a new CLASS is added */
796 +#define KLCF_CAST(_t) (struct klc_##_t *)
797 +#define KLCF_CAST_CONS(_t) (KLCF_CAST(cons)(_t)) /* klc_cons */
798 +#define KLCF_CAST_MALLOC(_t) (KLCF_CAST(malloc)(_t)) /* klc_malloc */
799 +#define KLCF_CAST_HEADER(_t) (KLCF_CAST(header)(_t)) /* klc_header */
800 +#define KLCF_CAST_INFO(_t) (KLCF_CAST(info)(_t)) /* klc_info */
801 +#define KLCF_CAST_LBOARD(_t) (KLCF_CAST(lboard)(_t)) /* klc_lboard */
802 +#define KLCF_CAST_ROUTER(_t) (KLCF_CAST(router)(_t)) /* klc_router */
803 +#define KLCF_CAST_CPU(_t) (KLCF_CAST(cpu)(_t)) /* klc_cpu */
804 +#define KLCF_CAST_HUB(_t) (KLCF_CAST(hub)(_t)) /* klc_hub */
805 +#define KLCF_CAST_MEMBANK(_t) (KLCF_CAST(membank)(_t)) /* klc_membank */
806 +#define KLCF_CAST_MOD_SN(_t) (KLCF_CAST(mod_sn)(_t)) /* klc_mod_sn */
807 +#define KLCF_CAST_XBOW(_t) (KLCF_CAST(xbow)(_t)) /* klc_xbow */
809 -#define KLCLASS_UNKNOWN 0xf0
811 -#define KLCLASS(_x) ((_x) & KLCLASS_MASK)
812 +/* ----------------------------------------------------------------------- */
813 +/* struct klc_cons, struct klc_malloc, and struct klc_header */
819 -#define KLTYPE_MASK 0x0f
820 -#define KLTYPE_NONE 0x00
821 -#define KLTYPE_EMPTY 0x00
823 -#define KLTYPE_WEIRDCPU (KLCLASS_CPU | 0x0)
824 -#define KLTYPE_IP27 (KLCLASS_CPU | 0x1) /* 2 CPUs(R10K) per board */
826 -#define KLTYPE_WEIRDIO (KLCLASS_IO | 0x0)
827 -#define KLTYPE_BASEIO (KLCLASS_IO | 0x1) /* IOC3, SuperIO, Bridge, SCSI */
828 -#define KLTYPE_IO6 KLTYPE_BASEIO /* Additional name */
829 -#define KLTYPE_4CHSCSI (KLCLASS_IO | 0x2)
830 -#define KLTYPE_MSCSI KLTYPE_4CHSCSI /* Additional name */
831 -#define KLTYPE_ETHERNET (KLCLASS_IO | 0x3)
832 -#define KLTYPE_MENET KLTYPE_ETHERNET /* Additional name */
833 -#define KLTYPE_FDDI (KLCLASS_IO | 0x4)
834 -#define KLTYPE_UNUSED (KLCLASS_IO | 0x5) /* XXX UNUSED */
835 -#define KLTYPE_HAROLD (KLCLASS_IO | 0x6) /* PCI SHOE BOX */
836 -#define KLTYPE_PCI KLTYPE_HAROLD
837 -#define KLTYPE_VME (KLCLASS_IO | 0x7) /* Any 3rd party VME card */
838 -#define KLTYPE_MIO (KLCLASS_IO | 0x8)
839 -#define KLTYPE_FC (KLCLASS_IO | 0x9)
840 -#define KLTYPE_LINC (KLCLASS_IO | 0xA)
841 -#define KLTYPE_TPU (KLCLASS_IO | 0xB) /* Tensor Processing Unit */
842 -#define KLTYPE_GSN_A (KLCLASS_IO | 0xC) /* Main GSN board */
843 -#define KLTYPE_GSN_B (KLCLASS_IO | 0xD) /* Auxiliary GSN board */
845 -#define KLTYPE_GFX (KLCLASS_GFX | 0x0) /* unknown graphics type */
846 -#define KLTYPE_GFX_KONA (KLCLASS_GFX | 0x1) /* KONA graphics on IP27 */
847 -#define KLTYPE_GFX_MGRA (KLCLASS_GFX | 0x3) /* MGRAS graphics on IP27 */
849 -#define KLTYPE_WEIRDROUTER (KLCLASS_ROUTER | 0x0)
850 -#define KLTYPE_ROUTER (KLCLASS_ROUTER | 0x1)
851 -#define KLTYPE_ROUTER2 KLTYPE_ROUTER /* Obsolete! */
852 -#define KLTYPE_NULL_ROUTER (KLCLASS_ROUTER | 0x2)
853 -#define KLTYPE_META_ROUTER (KLCLASS_ROUTER | 0x3)
855 -#define KLTYPE_WEIRDMIDPLANE (KLCLASS_MIDPLANE | 0x0)
856 -#define KLTYPE_MIDPLANE8 (KLCLASS_MIDPLANE | 0x1) /* 8 slot backplane */
857 -#define KLTYPE_MIDPLANE KLTYPE_MIDPLANE8
858 -#define KLTYPE_PBRICK_XBOW (KLCLASS_MIDPLANE | 0x2)
860 -#define KLTYPE_IOBRICK (KLCLASS_IOBRICK | 0x0)
861 -#define KLTYPE_IBRICK (KLCLASS_IOBRICK | 0x1)
862 -#define KLTYPE_PBRICK (KLCLASS_IOBRICK | 0x2)
863 -#define KLTYPE_XBRICK (KLCLASS_IOBRICK | 0x3)
864 + * The numbers must be contiguous since the array index i is used in the code
865 + * to allocate the various areas.
867 +#define BOARD_STRUCT 0
868 +#define COMPONENT_STRUCT 1
869 +#define ERRINFO_STRUCT 2
870 +#define KLMALLOC_TYPE_MAX (ERRINFO_STRUCT + 1)
871 +#define DEVICE_STRUCT 3
873 -#define KLTYPE_PBRICK_BRIDGE KLTYPE_PBRICK
875 + * struct klc_cons - KLCONFIG main console
876 + * @uart_base: base addr of UART
877 + * @config_base: base addr of UART config
878 + * @memory_base: base addr of UART mem
880 + * @flag: UART flags
882 + * @nasid: NASID of node
885 + * @baseio_nic: BaseIO Number
888 + unsigned long uart_base;
889 + unsigned long config_base;
890 + unsigned long memory_base;
901 + * struct klc_malloc - KLCONFIG main console
912 +/* KLCONFIG Header */
913 +#define KLCONFIG_MAGIC 0xbeedbabe
916 + * struct klc_header - KLCONFIG main console
917 + * @magic: set to KLCONFIG_MAGIC
918 + * @version: STRUCTURE VERSION
919 + * @malloc_hdr_off: offset to klc_malloc
920 + * @cons_off: offset to klc_cons
921 + * @board_info: beginning of linked list of boards
922 + * @cons_info: console info as struct klc_cons
924 + * @sw_belief: confidence that software is bad
925 + * @sn0net_belief: confidence that sn0net is bad
930 + s32 malloc_hdr_off;
933 + struct klc_cons cons_info;
934 + struct klc_malloc malloc_hdr[KLMALLOC_TYPE_MAX];
939 +/* Gets a pointer to the start of the KLCONFIG data area. */
940 +#define KL_CONFIG_HDR(_n) (KLCF_CAST_HEADER(KLCONFIG_ADDR(_n)))
942 +/* Gets a pointer to the start of the linked list of boards. */
943 +#define KL_CONFIG_BRD_INFO_OFF(_n) \
944 + (KL_CONFIG_HDR(_n)->board_info)
946 +/* Get the KLCONFIG magic value. */
947 +#define KL_CONFIG_MAGIC(_n) (KL_CONFIG_HDR(_n)->magic)
949 +/* Check the KLCONFIG magic value against KLCFGINFO_MAGIC. */
950 +#define KL_CONFIG_CHECK_MAGIC(_n) \
951 + (KL_CONFIG_MAGIC(_n) == KLCFGINFO_MAGIC)
953 +/* Initialize the KLCONFIG magic value. */
954 +#define KL_CONFIG_HDR_INIT_MAGIC(_n) \
955 + (KL_CONFIG_MAGIC(_n) = KLCFGINFO_MAGIC)
957 +/* Pointer macro to struct klc_header->cons_info */
958 +#define PTR_CONS_INFO(_k) \
959 + (KLCF_CAST_CONS((unsigned long)_k + (_k->cons_off)))
961 +/* Returns struct klc_cons from struct klc_header->cons_info */
962 +#define KL_CONFIG_CONS_INFO(_n) \
963 + PTR_CONS_INFO(KL_CONFIG_HDR(_n))
965 +/* Pointer macro to struct klc_header->malloc_hdr_off */
966 +#define PTR_MALLOC_HDR(_k) \
967 + (KLCF_CAST_MALLOC((unsigned long)_k + (_k->malloc_hdr_off)))
969 +/* Returns struct klc_malloc from struct klc_header->malloc_hdr_off */
970 +#define KL_CONFIG_MALLOC_HDR(_n) \
971 + PTR_MALLOC_HDR(KL_CONFIG_HDR(_n))
973 +/* Points at the first struct klc_info area (?) */
974 +#define KL_CONFIG_INFO_START(_n) \
975 + (s32)(KLCONFIG_OFFSET(_n) + sizeof(struct klc_header))
978 +/* ----------------------------------------------------------------------- */
979 +/* struct klc_info */
982 + * struct klc_info - stores common info about a component
983 + * @struct_type: type of this structure
984 + * @struct_version: ver of this structure
985 + * @flags: enabled/disabled state, etc
986 + * @revision: component revision
987 + * @diag_val: diagnostic value
988 + * @diag_parm: diagnostic param
989 + * @inventory: prev inventory status
990 + * @nic: must be aligned properly
991 + * @physid: physical id of component
992 + * @virtid: virtual id as seen by system
993 + * @widid: widget id (if applicable)
994 + * @nasid: node number (from parent)
996 + * @arcs_compt: ptr to the ARCS struct for ease
997 + * @errinfo: component specific errors
1002 + u8 struct_version;
1014 + COMPONENT *arcs_compt;
1019 +/* struct klc_info->flags definitions */
1020 +#define KLINFO_ENABLE 0x01 /* Component is enabled */
1021 +#define KLINFO_FAILED 0x02 /* Component failed */
1022 +#define KLINFO_DEVICE 0x04 /* Component is a device */
1023 +#define KLINFO_VISITED 0x08 /* Component has been visited */
1024 +#define KLINFO_CONTROLLER 0x10 /* Component is a device controller */
1025 +#define KLINFO_INSTALL 0x20 /* Install a driver */
1026 +#define KLINFO_HEADLESS 0x40 /* Headless (or hubless) component */
1028 -/* The value of type should be more than 8 so that hinv prints
1029 - * out the board name from the NIC string. For values less than
1030 - * 8 the name of the board needs to be hard coded in a few places.
1031 - * When bringup started nic names had not standardized and so we
1032 - * had to hard code. (For people interested in history.)
1033 +#define IS_CONSOLE_IOC3(_i) ((KLCF_CAST_INFO(_i)->flags) & KLINFO_INSTALL)
1035 +/* Wrapper to get the NUMA-as-node-ID from a board */
1036 +#define KLCF_BOARD_NASID(_b) ((_b)->nasid)
1038 +/* Wrapper to get the next board in the linked list */
1039 +#define KLCF_BOARD_NEXT(_b) ((_b)->next)
1041 +/* Wrapper to check the board flags for a duplicate board */
1042 +#define KL_CONFIG_DUPLICATE_BOARD(_b) \
1043 + ((_b)->flags & DUPLICATE_BOARD)
1045 +/* Test whether a board is local or remote */
1046 +#define KLCF_REMOTE(_b) (((_b)->struct_type & KLBOARD_LOCAL) ? 0 : 1)
1048 +/* Test if a board is enabled - pass by value, not reference */
1049 +#define KLCF_INFO_ENABLED(_i) ((_i).flags & KLINFO_ENABLE)
1051 +/* ----------------------------------------------------------------------- */
1052 +/* struct klc_lboard */
1054 +#define MAX_COMPONENTS 24 /* Max components per board */
1055 +#define KLBOARD_LOCAL 0x1 /* Board is local to node */
1056 +#define KLBOARD_REMOTE 0x2 /* Board is on another node */
1059 + * struct klc_info - stores info about a local BOARD
1060 + * @next: next BOARD
1061 + * @struct_type: type of struct, local or remote
1062 + * @type: board type + class
1063 + * @struct_ver: structure version
1064 + * @rev: board revision
1065 + * @prom_ver: board prom version, if any
1066 + * @flags: board flags
1067 + * @slot: board slot num
1068 + * @debug_switch: debug switches
1069 + * @module: module to which board belongs
1070 + * @partition: partition number
1071 + * @diag_val: diag value
1072 + * @diag_parm: diag param
1073 + * @inventory: inventory history
1074 + * @num_components: num of components
1075 + * @nic: Number-in-a-Can (NIC)
1076 + * @nasid: NUMA-node-AS-ID
1077 + * @components: board components
1078 + * @err_info: board's error information
1079 + * @parent: logical parent for this board
1080 + * @graph_link: vertex handle for external components
1081 + * @confidence: belief that board is bad
1082 + * @owner: who owns this board
1083 + * @nic_flags: to handle 8 more NICs
1084 + * @name: static string for board name
1086 -#define KLTYPE_XTHD (KLCLASS_PSEUDO_GFX | 0x9)
1087 +struct klc_lboard {
1097 + moduleid_t module;
1098 + partid_t partition;
1102 + u8 num_components;
1105 + s32 components[MAX_COMPONENTS];
1107 + struct klc_lboard *parent;
1115 -#define KLTYPE_UNKNOWN (KLCLASS_UNKNOWN | 0xf)
1117 + * struct klc_lboard->flags fields
1119 + * All bits in this field are currently used. Try the __padX fields if
1120 + * additional flag bits are needed
1122 +#define ENABLE_BOARD 0x01
1123 +#define FAILED_BOARD 0x02
1124 +#define DUPLICATE_BOARD 0x04 /* Boards like midplanes/routers which
1125 + are discovered twice. Use only 1 */
1126 +#define VISITED_BOARD 0x08 /* Used for compact hub numbering. */
1127 +#define LOCAL_MASTER_IO6 0x10 /* Master IO6 for that node */
1128 +#define GLOBAL_MASTER_IO6 0x20 /* Global IO6 for all nodes */
1129 +#define THIRD_NIC_PRESENT 0x40 /* For the future (?) */
1130 +#define SECOND_NIC_PRESENT 0x80 /* Add-ons like MIO are present */
1132 +/* These are the indices of various components within a lboard structure */
1133 +#define IP27_CPU0_INDEX 0
1134 +#define IP27_CPU1_INDEX 1
1135 +#define IP27_HUB_INDEX 2
1136 +#define IP27_MEM_INDEX 3
1137 +#define BASEIO_BRIDGE_INDEX 0
1138 +#define BASEIO_IOC3_INDEX 1
1139 +#define BASEIO_SCSI0_INDEX 2
1140 +#define BASEIO_SCSI1_INDEX 3
1141 +#define MIDPLANE_XBOW_INDEX 0
1142 +#define ROUTER_COMPONENT_INDEX 0
1143 +#define CH4SCSI_BRIDGE_INDEX 0
1145 +/* Gets the board info from the specified node. */
1146 +#define KL_CONFIG_INFO(_n) \
1147 + (KLCF_CAST_LBOARD(KL_CONFIG_BRD_INFO_OFF(_n) ? \
1148 + NODE_OFFSET_TO_K1((_n), KL_CONFIG_BRD_INFO_OFF(_n)) : 0))
1150 +/* Get board information */
1151 +#define KLCF_SLOT(_b) ((_b)->slot)
1152 +#define KLCF_CLASS(_b) KLCLASS((_b)->type)
1153 +#define KLCF_TYPE(_b) KLTYPE((_b)->type)
1154 +#define KLCF_NUM_COMPS(_b) ((_b)->num_components) /* # of components */
1155 +#define KLCF_MODULE_ID(_b) ((_b)->module) /* Module ID */
1158 +/* ----------------------------------------------------------------------- */
1159 +/* Various BOARD definition values */
1161 +/* Values for CPU types */
1162 +#define KL_CPU_R4000 0x1 /* Standard R4000 */
1163 +#define KL_CPU_TFP 0x2 /* R8000 (TFP) */
1164 +#define KL_CPU_R10000 0x3 /* R10000 (T5) */
1165 +#define KL_CPU_NONE (-1) /* No cpu present in slot */
1167 +/* IP27 BOARD Classes */
1168 +#define KLCLASS_MASK 0xf0
1169 +#define KLCLASS_UNKNOWN 0xf0 /* XXX: Same as KLCLASS_MASK */
1170 +#define KLCLASS_NONE 0x00
1171 +#define KLCLASS_NODE 0x10 /* CPU/Mem/HUB nodeboard */
1172 +#define KLCLASS_CPU KLCLASS_NODE
1173 +#define KLCLASS_IO 0x20 /* BaseIO, 4ch SCSI, Eth, FDDI,
1174 + * & the non-graphics widget
1177 +#define KLCLASS_ROUTER 0x30 /* Router board */
1178 +#define KLCLASS_MIDPLANE 0x40 /* We need to treat this as a
1179 + * board so that we can record
1182 +#define KLCLASS_GFX 0x50 /* Gfx boards (kona, mgras) */
1183 +#define KLCLASS_PSEUDO_GFX 0x60 /* HDTV type cards that use a
1184 + * gfx hw interface to xtalk
1185 + * and are not gfx class for
1186 + * software purposes.
1188 +/* Bump both of these if a new CLASS is added */
1189 +#define KLCLASS_MAX 7
1190 +#define KLTYPE_MAX 10
1192 +/* Given struct klc_lboard->type, returns the BOARD's class */
1193 +#define KLCLASS(_x) ((_x) & KLCLASS_MASK)
1196 +/* IP27 BOARD Types */
1197 +#define KLTYPE_MASK 0x0f
1198 +#define KLTYPE_NONE 0x00
1199 +#define KLTYPE_EMPTY 0x00
1200 +#define KLTYPE_UNKNOWN (KLCLASS_UNKNOWN | 0xf)
1202 +#define KLTYPE_WEIRDCPU (KLCLASS_CPU | 0x0) /* Unknown CPU */
1203 +#define KLTYPE_IP27 (KLCLASS_CPU | 0x1) /* 2 CPUs/nodeboard */
1205 +#define KLTYPE_WEIRDIO (KLCLASS_IO | 0x0)
1206 +#define KLTYPE_BASEIO (KLCLASS_IO | 0x1) /* IOC3/BRIDGE/SCSI */
1207 +#define KLTYPE_IO6 KLTYPE_BASEIO
1208 +#define KLTYPE_4CHSCSI (KLCLASS_IO | 0x2) /* Quad SCSI Xtalk */
1209 +#define KLTYPE_MSCSI KLTYPE_4CHSCSI
1210 +#define KLTYPE_MENET (KLCLASS_IO | 0x3) /* IOC3 Ethernet */
1211 +#define KLTYPE_ETHERNET KLTYPE_MENET
1212 +#define KLTYPE_FDDI (KLCLASS_IO | 0x4) /* FDDI Xtalk */
1213 +#define KLTYPE_UNUSED (KLCLASS_IO | 0x5) /* XXX: Unused */
1214 +#define KLTYPE_PCIBOX (KLCLASS_IO | 0x6) /* PCI Shoebox */
1215 +#define KLTYPE_HAROLD KLTYPE_PCIBOX
1216 +#define KLTYPE_VME (KLCLASS_IO | 0x7) /* VME cards */
1217 +#define KLTYPE_MIO (KLCLASS_IO | 0x8) /* XXX: Unknown */
1218 +#define KLTYPE_FC (KLCLASS_IO | 0x9) /* FibreChannel */
1219 +#define KLTYPE_LINC (KLCLASS_IO | 0xa) /* LINC (HIPPI/ATM) */
1220 +#define KLTYPE_TPU (KLCLASS_IO | 0xb) /* Tensor Processor */
1221 +#define KLTYPE_GSN_A (KLCLASS_IO | 0xc) /* Main GSN board */
1222 +#define KLTYPE_GSN_B (KLCLASS_IO | 0xd) /* Aux GSN board */
1224 +#define KLTYPE_GFX (KLCLASS_GFX | 0x0) /* Unknown Gfx type */
1225 +#define KLTYPE_GFX_KONA (KLCLASS_GFX | 0x1) /* InfiniteReality */
1226 +#define KLTYPE_GFX_MGRA (KLCLASS_GFX | 0x3) /* MGRAS/Impact Gfx */
1227 +#define KLTYPE_HDTV (KLCLASS_PSEUDO_GFX | 0x9) /* HDTV board */
1229 +#define KLTYPE_WEIRDROUTER (KLCLASS_ROUTER | 0x0) /* Unknown router */
1230 +#define KLTYPE_ROUTER (KLCLASS_ROUTER | 0x1) /* Std router */
1231 +#define KLTYPE_NULL_ROUTER (KLCLASS_ROUTER | 0x2) /* Null Router */
1232 +#define KLTYPE_META_ROUTER (KLCLASS_ROUTER | 0x3) /* Metarouter */
1234 +#define KLTYPE_WEIRDMIDPLANE (KLCLASS_MIDPLANE | 0x0)/* Unknown Midplane */
1235 +#define KLTYPE_MIDPLANE (KLCLASS_MIDPLANE | 0x1)/* 8 slot backplane */
1236 +#define KLTYPE_PBRICK_XBOW (KLCLASS_MIDPLANE | 0x2)/* IP35 P-BRICK Xbow */
1238 +#define KLTYPE_IOBRICK (KLCLASS_IOBRICK | 0x0) /* IP35 Basic I/O */
1239 +#define KLTYPE_IBRICK (KLCLASS_IOBRICK | 0x1)
1240 +#define KLTYPE_PBRICK (KLCLASS_IOBRICK | 0x2) /* IP35 PCI */
1241 +#define KLTYPE_XBRICK (KLCLASS_IOBRICK | 0x3) /* IP35 XIO */
1242 +#define KLTYPE_PBRICK_BRIDGE KLTYPE_PBRICK
1244 -#define KLTYPE(_x) ((_x) & KLTYPE_MASK)
1245 -#define IS_MIO_PRESENT(l) ((l->brd_type == KLTYPE_BASEIO) && \
1246 - (l->brd_flags & SECOND_NIC_PRESENT))
1247 -#define IS_MIO_IOC3(l, n) (IS_MIO_PRESENT(l) && (n > 2))
1248 +/* Given struct klc_lboard->type, returns the BOARD's type */
1249 +#define KLTYPE(_t) ((_t) & KLTYPE_MASK)
1252 - * board structures
1255 -#define MAX_COMPTS_PER_BRD 24
1257 -#define LOCAL_BOARD 1
1258 -#define REMOTE_BOARD 2
1260 -#define LBOARD_STRUCT_VERSION 2
1262 -typedef struct lboard_s {
1263 - klconf_off_t brd_next; /* Next BOARD */
1264 - unsigned char struct_type; /* type of structure, local or remote */
1265 - unsigned char brd_type; /* type+class */
1266 - unsigned char brd_sversion; /* version of this structure */
1267 - unsigned char brd_brevision; /* board revision */
1268 - unsigned char brd_promver; /* board prom version, if any */
1269 - unsigned char brd_flags; /* Enabled, Disabled etc */
1270 - unsigned char brd_slot; /* slot number */
1271 - unsigned short brd_debugsw; /* Debug switches */
1272 - moduleid_t brd_module; /* module to which it belongs */
1273 - partid_t brd_partition; /* Partition number */
1274 - unsigned short brd_diagval; /* diagnostic value */
1275 - unsigned short brd_diagparm; /* diagnostic parameter */
1276 - unsigned char brd_inventory; /* inventory history */
1277 - unsigned char brd_numcompts; /* Number of components */
1278 - nic_t brd_nic; /* Number in CAN */
1279 - nasid_t brd_nasid; /* passed parameter */
1280 - klconf_off_t brd_compts[MAX_COMPTS_PER_BRD]; /* pointers to COMPONENTS */
1281 - klconf_off_t brd_errinfo; /* Board's error information */
1282 - struct lboard_s *brd_parent; /* Logical parent for this brd */
1283 - vertex_hdl_t brd_graph_link; /* vertex hdl to connect extern compts */
1284 - confidence_t brd_confidence; /* confidence that the board is bad */
1285 - nasid_t brd_owner; /* who owns this board */
1286 - unsigned char brd_nic_flags; /* To handle 8 more NICs */
1287 - char brd_name[32];
1289 + * Linux note: The below is apocryphal information. No idea where it belongs.
1291 + * The value of type should be more than 8 so that hinv prints out the board
1292 + * name from the NIC string. For values less than 8 the name of the board
1293 + * needs to be hard coded in a few places. When bringup started NIC names
1294 + * had not been standardized and so we had to hard code. (For people
1295 + * interested in history.)
1299 +/* ----------------------------------------------------------------------- */
1300 +/* Various Component definitions */
1303 - * Make sure we pass back the calias space address for local boards.
1304 - * klconfig board traversal and error structure extraction defines.
1305 + * Following are the currently identified components:
1306 + * - CPU, HUB, MEM_BANK,
1307 + * - XBOW (consists of 16 WIDGETs, each of which can be HUB/GFX/BRIDGE),
1308 + * - BRIDGE, IOC3, SuperIO, SCSI, FDDI,
1312 +#define KLSTRUCT_UNKNOWN 0
1313 +#define KLSTRUCT_CPU 1
1314 +#define KLSTRUCT_HUB 2
1315 +#define KLSTRUCT_MEMBNK 3
1316 +#define KLSTRUCT_XBOW 4
1317 +#define KLSTRUCT_BRI 5
1318 +#define KLSTRUCT_IOC3 6
1319 +#define KLSTRUCT_PCI 7
1320 +#define KLSTRUCT_VME 8
1321 +#define KLSTRUCT_ROU 9
1322 +#define KLSTRUCT_GFX 10
1323 +#define KLSTRUCT_SCSI 11
1324 +#define KLSTRUCT_FDDI 12
1325 +#define KLSTRUCT_MIO 13
1326 +#define KLSTRUCT_DISK 14
1327 +#define KLSTRUCT_TAPE 15
1328 +#define KLSTRUCT_CDROM 16
1329 +#define KLSTRUCT_HUB_UART 17
1330 +#define KLSTRUCT_IOC3ENET 18
1331 +#define KLSTRUCT_IOC3UART 19
1332 +#define KLSTRUCT_UNUSED 20 /* XXX: UNUSED */
1333 +#define KLSTRUCT_IOC3PCKM 21
1334 +#define KLSTRUCT_RAD 22
1335 +#define KLSTRUCT_HUB_TTY 23
1336 +#define KLSTRUCT_IOC3_TTY 24
1338 -#define BOARD_SLOT(_brd) ((_brd)->brd_slot)
1340 + * Linux note: The below likely refers to something IRIX-specific.
1342 + * Early access IO proms are compatible only with KLSTRUCT values up to 24.
1344 +#define KLSTRUCT_FIBERCHANNEL 25
1345 +#define KLSTRUCT_MOD_SERIAL_NUM 26
1346 +#define KLSTRUCT_IOC3MS 27
1347 +#define KLSTRUCT_TPU 28
1348 +#define KLSTRUCT_GSN_A 29
1349 +#define KLSTRUCT_GSN_B 30
1350 +#define KLSTRUCT_HDTV 31
1352 -#define KLCF_CLASS(_brd) KLCLASS((_brd)->brd_type)
1353 -#define KLCF_TYPE(_brd) KLTYPE((_brd)->brd_type)
1354 -#define KLCF_REMOTE(_brd) (((_brd)->struct_type & LOCAL_BOARD) ? 0 : 1)
1355 -#define KLCF_NUM_COMPS(_brd) ((_brd)->brd_numcompts)
1356 -#define KLCF_MODULE_ID(_brd) ((_brd)->brd_module)
1358 -#define KLCF_NEXT(_brd) \
1359 - ((_brd)->brd_next ? \
1360 - (lboard_t *)(NODE_OFFSET_TO_K1(NASID_GET(_brd), (_brd)->brd_next)):\
1362 -#define KLCF_COMP(_brd, _ndx) \
1363 - (klinfo_t *)(NODE_OFFSET_TO_K1(NASID_GET(_brd), \
1364 - (_brd)->brd_compts[(_ndx)]))
1365 +/* ----------------------------------------------------------------------- */
1366 +/* Component struct definitions */
1368 -#define KLCF_COMP_ERROR(_brd, _comp) \
1369 - (NODE_OFFSET_TO_K1(NASID_GET(_brd), (_comp)->errinfo))
1371 + * Linux note: The below applies to struct klc_port.
1373 + * The port info in ip27_cfg area translates to a struct klc_lboard in the
1374 + * KLCONFIG area. But since KLCONFIG does not use pointers, struct klc_lboard
1375 + * is stored in terms of a nasid and a offset from start of KLCONFIG area on
1379 -#define KLCF_COMP_TYPE(_comp) ((_comp)->struct_type)
1380 -#define KLCF_BRIDGE_W_ID(_comp) ((_comp)->physid) /* Widget ID */
1382 + * struct klc_port - stores info about a port on HUB or XBOW
1383 + * @nasid: NUMA-node-AS-ID
1384 + * @flag: port flags
1385 + * @offset: port offset
1395 + * struct klc_cpu - stores info about a CPU
1396 + * @kl_info: common info
1397 + * @prid: processor PRID value
1398 + * @fpirr: FPU IRR value
1399 + * @speed: speed in MHZ
1400 + * @scache_sz: L2 size in MB
1401 + * @scache_spd: L2 speed in MHz
1404 + struct klc_info kl_info;
1414 + * struct klc_hub - stores info about a HUB chip on a nodeboard
1415 + * @kl_info: common info
1416 + * @flags: PCFG_HUB_xxx flags
1417 + * @port: XBOW port that HUB is connected to
1419 + * @mfg_nic: mfgr NIC string
1420 + * @speed: speed of HUB in HZ
1423 + struct klc_info kl_info;
1425 + struct klc_port port;
1433 + * struct klc_hub_uart - stores info about a UART chip attached to a HUB
1434 + * @kl_info: common info
1435 + * @flags: PCFG_HUB_xxx flags
1438 +struct klc_hub_uart {
1439 + struct klc_info kl_info;
1446 + * struct klc_membank - stores info about a memory bank
1447 + * @kl_info: common info
1448 + * @mem_sz: total memory in MB
1449 + * @dimm_select: bank to physaddr mapping
1450 + * @bank_sz: memory bank sizes
1451 + * @attr: bank attributes
1453 +struct klc_membank {
1454 + struct klc_info kl_info;
1457 + s16 bank_sz[MD_MEM_BANKS];
1461 +/* Get the size of a memory bank. */
1462 +#define KLCF_MEMBANK_SIZE(_i, _b) \
1463 + ((_i)->bank_sz[(_b)])
1465 +/* Check if a memory bank has premium DIMMs (directory memory). */
1466 +#define MEMBANK_PREM 1
1467 +#define KLCONFIG_MEMBANK_PREM(_i, _b) \
1468 + ((_i)->attr & (MEMBANK_PREM << (_b)))
1471 +#define MAX_SERIAL_NUM_SIZE 10
1473 + * struct klc_mod_sn - stores info about a module serial
1474 + * @kl_info: common info
1475 + * @sn: union sn: read S/N as either string or integer
1476 + * @str: read S/N as str
1477 + * @num: read S/N as integer
1479 +struct klc_mod_sn {
1480 + struct klc_info kl_info;
1482 + s8 str[MAX_SERIAL_NUM_SIZE];
1488 + * Hard coded values are necessary since we cannot treat the serial number
1489 + * as a component without losing compatibility between PROM versions.
1491 +#define GET_COMP_SERIAL(_c) \
1492 + (KLCF_CAST_MOD_SN(KLCF_COMP(_c, _c->num_components)))
1496 - * Generic info structure. This stores common info about a
1500 -typedef struct klinfo_s { /* Generic info */
1501 - unsigned char struct_type; /* type of this structure */
1502 - unsigned char struct_version; /* version of this structure */
1503 - unsigned char flags; /* Enabled, disabled etc */
1504 - unsigned char revision; /* component revision */
1505 - unsigned short diagval; /* result of diagnostics */
1506 - unsigned short diagparm; /* diagnostic parameter */
1507 - unsigned char inventory; /* previous inventory status */
1508 - nic_t nic; /* MUst be aligned properly */
1509 - unsigned char physid; /* physical id of component */
1510 - unsigned int virtid; /* virtual id as seen by system */
1511 - unsigned char widid; /* Widget id - if applicable */
1512 - nasid_t nasid; /* node number - from parent */
1513 - char pad1; /* pad out structure. */
1514 - char pad2; /* pad out structure. */
1515 - COMPONENT *arcs_compt; /* ptr to the arcs struct for ease*/
1516 - klconf_off_t errinfo; /* component specific errors */
1517 - unsigned short pad3; /* pci fields have moved over to */
1518 - unsigned short pad4; /* klbri_t */
1521 -#define KLCONFIG_INFO_ENABLED(_i) ((_i)->flags & KLINFO_ENABLE)
1523 - * Component structures.
1524 - * Following are the currently identified components:
1525 - * CPU, HUB, MEM_BANK,
1526 - * XBOW(consists of 16 WIDGETs, each of which can be HUB or GRAPHICS or BRIDGE)
1527 - * BRIDGE, IOC3, SuperIO, SCSI, FDDI
1531 -#define KLSTRUCT_UNKNOWN 0
1532 -#define KLSTRUCT_CPU 1
1533 -#define KLSTRUCT_HUB 2
1534 -#define KLSTRUCT_MEMBNK 3
1535 -#define KLSTRUCT_XBOW 4
1536 -#define KLSTRUCT_BRI 5
1537 -#define KLSTRUCT_IOC3 6
1538 -#define KLSTRUCT_PCI 7
1539 -#define KLSTRUCT_VME 8
1540 -#define KLSTRUCT_ROU 9
1541 -#define KLSTRUCT_GFX 10
1542 -#define KLSTRUCT_SCSI 11
1543 -#define KLSTRUCT_FDDI 12
1544 -#define KLSTRUCT_MIO 13
1545 -#define KLSTRUCT_DISK 14
1546 -#define KLSTRUCT_TAPE 15
1547 -#define KLSTRUCT_CDROM 16
1548 -#define KLSTRUCT_HUB_UART 17
1549 -#define KLSTRUCT_IOC3ENET 18
1550 -#define KLSTRUCT_IOC3UART 19
1551 -#define KLSTRUCT_UNUSED 20 /* XXX UNUSED */
1552 -#define KLSTRUCT_IOC3PCKM 21
1553 -#define KLSTRUCT_RAD 22
1554 -#define KLSTRUCT_HUB_TTY 23
1555 -#define KLSTRUCT_IOC3_TTY 24
1557 -/* Early Access IO proms are compatible
1558 - only with KLSTRUCT values up to 24. */
1560 -#define KLSTRUCT_FIBERCHANNEL 25
1561 -#define KLSTRUCT_MOD_SERIAL_NUM 26
1562 -#define KLSTRUCT_IOC3MS 27
1563 -#define KLSTRUCT_TPU 28
1564 -#define KLSTRUCT_GSN_A 29
1565 -#define KLSTRUCT_GSN_B 30
1566 -#define KLSTRUCT_XTHD 31
1567 +#define MAX_XBOW_LINKS 16
1568 +#define XBOW_PORT_IO 0x1
1569 +#define XBOW_PORT_HUB 0x2
1570 +#define XBOW_PORT_ENABLE 0x4
1573 - * These are the indices of various components within a lboard structure.
1575 + * struct klc_xbow - stores info about a XBOW chip
1576 + * @kl_info: common info
1577 + * @port_info: represents each XBOW port as struct klc_port
1578 + * @master_hub_link: holds numeric value of which XBOW port HUB is connected
1581 + struct klc_info kl_info;
1582 + struct klc_port port_info[MAX_XBOW_LINKS];
1583 + int master_hub_link;
1584 + /* type of brd connected + component struct ptr+flags */
1587 -#define IP27_CPU0_INDEX 0
1588 -#define IP27_CPU1_INDEX 1
1589 -#define IP27_HUB_INDEX 2
1590 -#define IP27_MEM_INDEX 3
1591 +/* Get struct klc_xbow->port_info[offset] */
1592 +#define XBOW_PORT_INFO(_x, _o) \
1593 + ((_x)->port_info[(_o) - BASE_XBOW_PORT])
1595 -#define BASEIO_BRIDGE_INDEX 0
1596 -#define BASEIO_IOC3_INDEX 1
1597 -#define BASEIO_SCSI1_INDEX 2
1598 -#define BASEIO_SCSI2_INDEX 3
1599 +/* Get struct klc_xbow->port_info[offset].flag */
1600 +#define XBOW_PORT_FLAG(_x, _o) \
1601 + XBOW_PORT_INFO(_x, _o).flag
1603 -#define MIDPLANE_XBOW_INDEX 0
1604 -#define ROUTER_COMPONENT_INDEX 0
1605 +/* Check if port flag indicates a HUB is attached */
1606 +#define XBOW_PORT_TYPE_HUB(_x, _o) \
1607 + (XBOW_PORT_FLAG(_x, _o) & XBOW_PORT_HUB)
1609 -#define CH4SCSI_BRIDGE_INDEX 0
1610 +/* Check if port flag indicates an I/O device is attached */
1611 +#define XBOW_PORT_TYPE_IO(_x, _o) \
1612 + (XBOW_PORT_FLAG(_x, _o) & XBOW_PORT_IO)
1614 -/* Info holders for various hardware components */
1615 +/* Check if port is enabled */
1616 +#define XBOW_PORT_IS_ENABLED(_x, _o) \
1617 + (XBOW_PORT_FLAG(_x, _o) & XBOW_PORT_ENABLE)
1619 -typedef u64 *pci_t;
1620 -typedef u64 *vmeb_t;
1621 -typedef u64 *vmed_t;
1622 -typedef u64 *fddi_t;
1623 -typedef u64 *scsi_t;
1624 -typedef u64 *mio_t;
1625 -typedef u64 *graphics_t;
1626 -typedef u64 *router_t;
1627 +/* Get port NASID */
1628 +#define XBOW_PORT_NASID(_x, _o) \
1629 + (XBOW_PORT_INFO(_x, _o).nasid)
1632 +#define MAX_PCI_DEVS 8
1634 + * struct klc_pdev - stores info about a PCI device
1635 + * @dev_id: 32-bits vendor/device ID
1636 + * @__pad: 32-bits padding
1644 + * struct klc_pcibr - stores info about a PCI [X]BRIDGE
1645 + * @kl_info: common info
1646 + * @io6prom_info: IO6prom connected to bridge
1647 + * @bustype: PCI/VME BUS bridge/GIO
1648 + * @specific: PCI Board config info
1649 + * @devices: PCI IDs
1650 + * @mfg_nic: BRIDGE MFG NIC
1653 + struct klc_info kl_info;
1657 + struct klc_pdev devices[MAX_PCI_DEVS];
1661 +#define MAX_IOC3_TTY 2
1663 + * struct klc_ioc3 - stores info about an IOC3 device
1664 + * @kl_info: common info
1665 + * @ssram: Info about SSRAM
1666 + * @nvram: Info about NVRAM
1667 + * @kl_sio_info: struct klc_info for SuperIO device
1668 + * @tty_off: offset to tty info (?)
1669 + * @kl_eth_info: struct klc_info for ethernet device
1670 + * @eth_off: offset to ethernet info (?)
1671 + * @kbd_off: offset to keyboard/mouse info (?)
1674 + struct klc_info kl_info;
1677 + struct klc_info kl_sio_info;
1679 + struct klc_info kl_eth_info;
1684 +/* Get the widget ID of a bridge component. */
1685 +#define KLCF_BRIDGE_W_ID(_c) ((_c)->physid)
1688 +#define MAX_VME_SLOTS 8
1690 + * struct klc_vme - stores info about a VME BRIDGE Ctlr
1691 + * @kl_info: common info
1692 + * @specific: VME-specific info
1693 + * @slots: VME slot/board info
1696 + struct klc_info kl_info;
1698 + s32 slots[MAX_VME_SLOTS];
1702 +#define MAX_ROUTER_PORTS 6 /* Max num of ports on a router */
1704 + * struct klc_router - stores info about a ROUTER that links nodes together
1705 + * @kl_info: common info
1706 + * @flags: PCFG_ROUTER_xxx flags
1707 + * @box_nic: NIC of the containing module
1708 + * @port: struct klc_port for each ROUTER port
1709 + * @mfg_nic: MFG NIC string
1710 + * @vector: vector from master node
1712 +struct klc_router {
1713 + struct klc_info kl_info;
1716 + struct klc_port port[MAX_ROUTER_PORTS + 1];
1722 - * The port info in ip27_cfg area translates to a lboart_t in the
1723 - * KLCONFIG area. But since KLCONFIG does not use pointers, lboart_t
1724 - * is stored in terms of a nasid and a offset from start of KLCONFIG
1725 - * area on that nasid.
1727 -typedef struct klport_s {
1728 - nasid_t port_nasid;
1729 - unsigned char port_flag;
1730 - klconf_off_t port_offset;
1733 -typedef struct klcpu_s { /* CPU */
1734 - klinfo_t cpu_info;
1735 - unsigned short cpu_prid; /* Processor PRID value */
1736 - unsigned short cpu_fpirr; /* FPU IRR value */
1737 - unsigned short cpu_speed; /* Speed in MHZ */
1738 - unsigned short cpu_scachesz; /* secondary cache size in MB */
1739 - unsigned short cpu_scachespeed;/* secondary cache speed in MHz */
1742 -#define CPU_STRUCT_VERSION 2
1744 -typedef struct klhub_s { /* HUB */
1745 - klinfo_t hub_info;
1746 - unsigned int hub_flags; /* PCFG_HUB_xxx flags */
1747 - klport_t hub_port; /* hub is connected to this */
1748 - nic_t hub_box_nic; /* nic of containing box */
1749 - klconf_off_t hub_mfg_nic; /* MFG NIC string */
1750 - u64 hub_speed; /* Speed of hub in HZ */
1753 -typedef struct klhub_uart_s { /* HUB */
1754 - klinfo_t hubuart_info;
1755 - unsigned int hubuart_flags; /* PCFG_HUB_xxx flags */
1756 - nic_t hubuart_box_nic; /* nic of containing box */
1759 -#define MEMORY_STRUCT_VERSION 2
1761 -typedef struct klmembnk_s { /* MEMORY BANK */
1762 - klinfo_t membnk_info;
1763 - short membnk_memsz; /* Total memory in megabytes */
1764 - short membnk_dimm_select; /* bank to physical addr mapping*/
1765 - short membnk_bnksz[MD_MEM_BANKS]; /* Memory bank sizes */
1766 - short membnk_attr;
1769 -#define KLCONFIG_MEMBNK_SIZE(_info, _bank) \
1770 - ((_info)->membnk_bnksz[(_bank)])
1773 -#define MEMBNK_PREMIUM 1
1774 -#define KLCONFIG_MEMBNK_PREMIUM(_info, _bank) \
1775 - ((_info)->membnk_attr & (MEMBNK_PREMIUM << (_bank)))
1777 -#define MAX_SERIAL_NUM_SIZE 10
1779 -typedef struct klmod_serial_num_s {
1780 - klinfo_t snum_info;
1782 - char snum_str[MAX_SERIAL_NUM_SIZE];
1783 - unsigned long long snum_int;
1785 -} klmod_serial_num_t;
1787 -/* Macros needed to access serial number structure in lboard_t.
1788 - Hard coded values are necessary since we cannot treat
1789 - serial number struct as a component without losing compatibility
1790 - between prom versions. */
1792 -#define GET_SNUM_COMP(_l) ((klmod_serial_num_t *)\
1793 - KLCF_COMP(_l, _l->brd_numcompts))
1795 -#define MAX_XBOW_LINKS 16
1797 -typedef struct klxbow_s { /* XBOW */
1798 - klinfo_t xbow_info ;
1799 - klport_t xbow_port_info[MAX_XBOW_LINKS] ; /* Module number */
1800 - int xbow_master_hub_link;
1801 - /* type of brd connected+component struct ptr+flags */
1804 -#define MAX_PCI_SLOTS 8
1806 -typedef struct klpci_device_s {
1807 - s32 pci_device_id; /* 32 bits of vendor/device ID. */
1808 - s32 pci_device_pad; /* 32 bits of padding. */
1811 -#define BRIDGE_STRUCT_VERSION 2
1813 -typedef struct klbri_s { /* BRIDGE */
1814 - klinfo_t bri_info ;
1815 - unsigned char bri_eprominfo ; /* IO6prom connected to bridge */
1816 - unsigned char bri_bustype ; /* PCI/VME BUS bridge/GIO */
1817 - pci_t pci_specific ; /* PCI Board config info */
1818 - klpci_device_t bri_devices[MAX_PCI_DEVS] ; /* PCI IDs */
1819 - klconf_off_t bri_mfg_nic ;
1822 -#define MAX_IOC3_TTY 2
1824 -typedef struct klioc3_s { /* IOC3 */
1825 - klinfo_t ioc3_info ;
1826 - unsigned char ioc3_ssram ; /* Info about ssram */
1827 - unsigned char ioc3_nvram ; /* Info about nvram */
1828 - klinfo_t ioc3_superio ; /* Info about superio */
1829 - klconf_off_t ioc3_tty_off ;
1830 - klinfo_t ioc3_enet ;
1831 - klconf_off_t ioc3_enet_off ;
1832 - klconf_off_t ioc3_kbd_off ;
1835 -#define MAX_VME_SLOTS 8
1837 -typedef struct klvmeb_s { /* VME BRIDGE - PCI CTLR */
1838 - klinfo_t vmeb_info ;
1839 - vmeb_t vmeb_specific ;
1840 - klconf_off_t vmeb_brdinfo[MAX_VME_SLOTS] ; /* VME Board config info */
1843 -typedef struct klvmed_s { /* VME DEVICE - VME BOARD */
1844 - klinfo_t vmed_info ;
1845 - vmed_t vmed_specific ;
1846 - klconf_off_t vmed_brdinfo[MAX_VME_SLOTS] ; /* VME Board config info */
1849 -#define ROUTER_VECTOR_VERS 2
1851 -/* XXX - Don't we need the number of ports here?!? */
1852 -typedef struct klrou_s { /* ROUTER */
1853 - klinfo_t rou_info ;
1854 - unsigned int rou_flags ; /* PCFG_ROUTER_xxx flags */
1855 - nic_t rou_box_nic ; /* nic of the containing module */
1856 - klport_t rou_port[MAX_ROUTER_PORTS + 1] ; /* array index 1 to 6 */
1857 - klconf_off_t rou_mfg_nic ; /* MFG NIC string */
1858 - u64 rou_vector; /* vector from master node */
1862 - * Graphics Controller/Device
1863 + * XXX: Linux note: The below is IRIX apocrypha.
1865 - * (IP27/IO6) Prom versions 6.13 (and 6.5.1 kernels) and earlier
1866 - * used a couple different structures to store graphics information.
1867 - * For compatibility reasons, the newer data structure preserves some
1868 - * of the layout so that fields that are used in the old versions remain
1869 - * in the same place (with the same info). Determination of what version
1870 - * of this structure we have is done by checking the cookie field.
1872 -#define KLGFX_COOKIE 0x0c0de000
1874 -typedef struct klgfx_s { /* GRAPHICS Device */
1875 - klinfo_t gfx_info;
1876 - klconf_off_t old_gndevs; /* for compatibility with older proms */
1877 - klconf_off_t old_gdoff0; /* for compatibility with older proms */
1878 - unsigned int cookie; /* for compatibility with older proms */
1879 - unsigned int moduleslot;
1880 - struct klgfx_s *gfx_next_pipe;
1881 - graphics_t gfx_specific;
1882 - klconf_off_t pad0; /* for compatibility with older proms */
1883 - klconf_off_t gfx_mfg_nic;
1886 -typedef struct klxthd_s {
1887 - klinfo_t xthd_info ;
1888 - klconf_off_t xthd_mfg_nic ; /* MFG NIC string */
1891 -typedef struct kltpu_s { /* TPU board */
1892 - klinfo_t tpu_info ;
1893 - klconf_off_t tpu_mfg_nic ; /* MFG NIC string */
1896 -typedef struct klgsn_s { /* GSN board */
1897 - klinfo_t gsn_info ;
1898 - klconf_off_t gsn_mfg_nic ; /* MFG NIC string */
1900 + * (IP27/IO6) Prom versions 6.13 (and 6.5.1 kernels) and earlier used a
1901 + * couple different structures to store graphics information.
1902 + * For compatibility reasons, the newer data structure preserves some of
1903 + * the layout so that fields that are used in the old versions remain in
1904 + * the same place (with the same info). Determination of what version of
1905 + * this structure we have is done by checking the cookie field.
1908 +#define KLGFX_COOKIE 0x0c0de000
1910 + * struct klc_gfx - stores info about a GRAPHICS device (Kona/Mgras)
1911 + * @kl_info: common info
1912 + * @old_gndevs: compatibility w/ older PROMs
1913 + * @old_gdoff0: compatibility w/ older PROMs
1914 + * @cookie: compatibility w/ older PROMs
1915 + * @module_slot: slot of the containing module
1916 + * @next_pipe: pointer to next gfx pipe
1917 + * @specific: pointer to gfx-specific info
1918 + * @__pad: padding (compat w/ older PROMs)
1919 + * @mfg_nic: MFG NIC string
1922 + struct klc_info kl_info;
1927 + struct klc_gfx *next_pipe;
1934 + * struct klc_hdtv - stores info about a pseudo-gfx device (HDTV board)
1935 + * @kl_info: common info
1936 + * @mfg_nic: MFG NIC string
1939 + struct klc_info kl_info;
1945 + * struct klc_tpu - stores info about a tensor processing unit (rare hw)
1946 + * @kl_info: common info
1947 + * @mfg_nic: MFG NIC string
1950 + struct klc_info kl_info;
1955 + * struct klc_gsn - stores info about a GSN board (?) (rare hw)
1956 + * @kl_info: common info
1957 + * @mfg_nic: MFG NIC string
1960 + struct klc_info kl_info;
1965 #define MAX_SCSI_DEVS 16
1967 + * struct klc_scsi - stores info about a SCSI controller
1968 + * @kl_info: common info
1969 + * @specific: pointer to SCSI-specific info
1970 + * @num_devs: number of attached devices
1971 + * @dev_info: per-device info
1974 + struct klc_info kl_info;
1977 + s32 dev_info[MAX_SCSI_DEVS];
1981 +#define MAX_FDDI_DEVS 10 /* XXX: Is this correct? */
1983 + * struct klc_fddi - stores info about an FDDI controller
1984 + * @kl_info: common info
1985 + * @specific: pointer to FDDI-specific info
1986 + * @dev_info: per-device info
1989 + struct klc_info kl_info;
1991 + s32 dev_info[MAX_FDDI_DEVS];
1995 - * NOTE: THis is the max sized kl* structure and is used in klmalloc.c
1996 - * to allocate space of type COMPONENT. Make sure that if the size of
1997 - * any other component struct becomes more than this, then redefine
1998 - * that as the size to be klmalloced.
2001 -typedef struct klscsi_s { /* SCSI Controller */
2002 - klinfo_t scsi_info ;
2003 - scsi_t scsi_specific ;
2004 - unsigned char scsi_numdevs ;
2005 - klconf_off_t scsi_devinfo[MAX_SCSI_DEVS] ;
2008 -typedef struct klscdev_s { /* SCSI device */
2009 - klinfo_t scdev_info ;
2010 - struct scsidisk_data *scdev_cfg ; /* driver fills up this */
2013 -typedef struct klttydev_s { /* TTY device */
2014 - klinfo_t ttydev_info ;
2015 - struct terminal_data *ttydev_cfg ; /* driver fills up this */
2018 -typedef struct klenetdev_s { /* ENET device */
2019 - klinfo_t enetdev_info ;
2020 - struct net_data *enetdev_cfg ; /* driver fills up this */
2023 -typedef struct klkbddev_s { /* KBD device */
2024 - klinfo_t kbddev_info ;
2025 - struct keyboard_data *kbddev_cfg ; /* driver fills up this */
2028 -typedef struct klmsdev_s { /* mouse device */
2029 - klinfo_t msdev_info ;
2033 -#define MAX_FDDI_DEVS 10 /* XXX Is this true */
2035 -typedef struct klfddi_s { /* FDDI */
2036 - klinfo_t fddi_info ;
2037 - fddi_t fddi_specific ;
2038 - klconf_off_t fddi_devinfo[MAX_FDDI_DEVS] ;
2041 -typedef struct klmio_s { /* MIO */
2042 - klinfo_t mio_info ;
2043 - mio_t mio_specific ;
2047 -typedef union klcomp_s {
2050 - klmembnk_t kc_mem;
2059 - klscdev_t kc_scsi_dev;
2062 - klmod_serial_num_t kc_snum ;
2065 -typedef union kldev_s { /* for device structure allocation */
2066 - klscdev_t kc_scsi_dev ;
2067 - klttydev_t kc_tty_dev ;
2068 - klenetdev_t kc_enet_dev ;
2069 - klkbddev_t kc_kbd_dev ;
2072 -/* Data structure interface routines. TBD */
2074 -/* Include launch info in this file itself? TBD */
2077 - * TBD - Can the ARCS and device driver related info also be included in the
2078 - * KLCONFIG area. On the IO4PROM, prom device driver info is part of cfgnode_t
2079 - * structure, viz private to the IO4prom.
2081 + * struct klc_mio - stores info about a MIO device (?)
2082 + * @kl_info: common info
2083 + * @specific: pointer to MIO-specific info
2086 + struct klc_info kl_info;
2090 +#define IS_MIO_PRESENT(_b) \
2091 + ((_b->type == KLTYPE_BASEIO) && \
2092 + (_b->flags & SECOND_NIC_PRESENT))
2094 +#define IS_MIO_IOC3(_b, _n) \
2095 + (IS_MIO_PRESENT(_b) && ((_n) > 2))
2099 + * struct klc_scdev - stores info about a SCSI device
2100 + * @kl_info: common info
2101 + * @dev_cfg: void pointer to driver-specific info
2104 + struct klc_info kl_info;
2109 + * struct klc_tty - stores info about a TTY device
2110 + * @kl_info: common info
2111 + * @dev_cfg: void pointer to driver-specific info
2114 + struct klc_info kl_info;
2119 + * struct klc_eth - stores info about an ethernet device
2120 + * @kl_info: common info
2121 + * @dev_cfg: void pointer to driver-specific info
2124 + struct klc_info kl_info;
2129 + * struct klc_kbd - stores info about a keyboard device
2130 + * @kl_info: common info
2131 + * @dev_cfg: void pointer to driver-specific info
2134 + struct klc_info kl_info;
2139 + * struct klc_mouse - stores info about a mouse device
2140 + * @kl_info: common info
2141 + * @dev_cfg: void pointer to driver-specific info
2144 + struct klc_info kl_info;
2150 + * union klc_components - union to access component data
2153 + * @membank: memory bank
2154 + * @xbow: XBOW ASIC
2155 + * @pcibr: PCI [X]BRIDGE
2156 + * @ioc3: IOC3 device
2157 + * @vmebr: VME BRIDGE
2158 + * @vdev: VME device
2159 + * @router: ROUTER board
2160 + * @gfx: GRAPHICS pipe
2161 + * @hdtv: pseudo-GFX device/HDTV
2162 + * @tpu: tensor processing unit
2163 + * @gsn: GSN device/board
2164 + * @scsi: SCSI controller
2165 + * @scdev: SCSI device
2166 + * @fddi: FDDI controller
2167 + * @mio: MIO device
2168 + * @serial_num: serial number
2170 +union klc_components {
2171 + struct klc_cpu cpu;
2172 + struct klc_hub hub;
2173 + struct klc_membank membank;
2174 + struct klc_xbow xbow;
2175 + struct klc_pcibr pcibr;
2176 + struct klc_ioc3 ioc3;
2177 + struct klc_vme vmebr;
2178 + struct klc_vme vdev;
2179 + struct klc_router router;
2180 + struct klc_gfx gfx;
2181 + struct klc_hdtv hdtv;
2182 + struct klc_tpu tpu;
2183 + struct klc_gsn gsn;
2184 + struct klc_scsi scsi;
2185 + struct klc_scdev scdev;
2186 + struct klc_fddi fddi;
2187 + struct klc_mio mio;
2188 + struct klc_mod_sn serial_num;
2192 + * union klc_components - union to access component data
2193 + * @scdev: SCSI device
2194 + * @tty: TTY device
2195 + * @eth: ethernet device
2199 +union klc_devices {
2200 + struct klc_scdev scdev;
2201 + struct klc_tty tty;
2202 + struct klc_eth eth;
2203 + struct klc_kbd kbd;
2204 + struct klc_mouse mouse;
2208 +/* ----------------------------------------------------------------------- */
2209 +/* Macros that assist in casting to various struct klc_* instances */
2211 +/* struct klc_* via KLCF_NODE_OFFSET_K(0|1) */
2212 +#define KLCF_NODE_OFFSET(_k, _b, _o) \
2213 + (NODE_OFFSET_TO_##_k(NASID_GET(_b), (_o)))
2215 +/* klc_info via K1 */
2216 +#define KLCF_INFO_K1(_b, _o) \
2217 + (KLCF_CAST_INFO(KLCF_NODE_OFFSET(K1, (_b), (_o))))
2219 +/* klc_lboard via K0 */
2220 +#define KLCF_LBOARD_K0(_b, _o) \
2221 + (KLCF_CAST_LBOARD(KLCF_NODE_OFFSET(K0, (_b), (_o))))
2223 +/* klc_lboard via K1 */
2224 +#define KLCF_LBOARD_K1(_b, _o) \
2225 + (KLCF_CAST_LBOARD(KLCF_NODE_OFFSET(K1, (_b), (_o))))
2227 +/* klc_router via K0 */
2228 +#define KLCF_ROUTER_K0(_b, _o) \
2229 + (KLCF_CAST_ROUTER(KLCF_NODE_OFFSET(K0, (_b), (_o))))
2231 +/* struct klc_lboard via KL_CONFIG_INFO() */
2232 +#define KLCF_LBOARD_INFO(_n) \
2233 + KLCF_CAST_LBOARD(KL_CONFIG_INFO(_n))
2235 +/* Get a pointer to the next board. */
2236 +#define KLCF_NEXT(_b) \
2238 + KLCF_LBOARD_K1((_b), (_b)->next) : NULL)
2240 +/* Get a pointer to a component on a board. */
2241 +#define KLCF_COMP(_b, _o) \
2242 + (KLCF_INFO_K1((_b), (_b)->components[(_o)]))
2244 +/* Get a pointer to a component's errinfo data. */
2245 +#define KLCF_COMP_ERROR(_b, _c) \
2246 + (KLCF_NODE_OFFSET(K1, (_b), (_c)->errinfo))
2248 +/* Get the component's structure type. */
2249 +#define KLCF_COMP_TYPE(_c) \
2250 + ((_c)->struct_type)
2253 +/* ----------------------------------------------------------------------- */
2254 +/* External function declarations */
2256 +extern struct klc_lboard *kl_find_lboard(struct klc_lboard *start, u8 type);
2257 +extern struct klc_info *kl_find_component(struct klc_lboard *brd,
2258 + struct klc_info *kli, u8 type);
2259 +extern struct klc_info *kl_find_1st_component(struct klc_lboard *brd, u8 type);
2260 +extern struct klc_cpu *nasid_slice_to_cpuinfo(nasid_t, int);
2261 +extern struct klc_lboard *kl_find_lboard_class(struct klc_lboard *start,
2265 +/* ----------------------------------------------------------------------- */
2266 +/* Virtual dipswitch values (starting from switch "7") */
2268 +#define VDS_NOGFX 0x8000 /* Don't enable gfx and autoboot */
2269 +#define VDS_NOMP 0x0100 /* Don't start slave processors */
2270 +#define VDS_MANUMODE 0x0080 /* Manufacturing mode */
2271 +#define VDS_NOARB 0x0040 /* No bootmaster arbitration */
2272 +#define VDS_PODMODE 0x0020 /* Go straight to POD mode */
2273 +#define VDS_NO_DIAGS 0x0010 /* Don't run any diags after BM arb */
2274 +#define VDS_DEFAULTS 0x0008 /* Use default environment values */
2275 +#define VDS_NOMEMCLEAR 0x0004 /* Don't run mem cfg code */
2276 +#define VDS_2ND_IO4 0x0002 /* Boot from the second IO4 */
2277 +#define VDS_DEBUG_PROM 0x0001 /* Print PROM debugging messages */
2280 +/* ----------------------------------------------------------------------- */
2283 +/* XXX: Data structure interface routines. TBD */
2285 +/* XXX: Include launch info in this file itself? TBD */
2288 - * TBD - Allocation issues.
2290 - * Do we need to Mark off sepatate heaps for lboard_t, rboard_t, component,
2291 - * errinfo and allocate from them, or have a single heap and allocate all
2292 - * structures from it. Debug is easier in the former method since we can
2293 - * dump all similar structs in one command, but there will be lots of holes,
2294 - * in memory and max limits are needed for number of structures.
2295 - * Another way to make it organized, is to have a union of all components
2296 - * and allocate a aligned chunk of memory greater than the biggest
2298 + * XXX: TBD: Can the ARCS and device driver related info also be included in
2299 + * the KLCONFIG area. On the IO4PROM, prom device driver info is part of
2300 + * cfgnode_t structure, viz private to the IO4prom.
2304 - lboard_t *lbinfo ;
2307 + * XXX: TBD: Allocation issues.
2308 + * Do we need to mark off separate heaps for struct klc_lboard,
2309 + * struct klc_rboard, struct klc_components, errinfo and allocate from
2310 + * them, or have a single heap and allocate all structures from it.
2311 + * Debug is easier in the former method since we can dump all similar
2312 + * structs in one command, but there will be lots of holes, in memory
2313 + * and max limits are needed for number of structures.
2314 + * Another way to make it organized, is to have a union of all components
2315 + * and allocate an aligned chunk of memory greater than the biggest
2319 +/* XXX: What is this? */
2321 + struct klc_lboard *lbinfo;
2324 +/* XXX: these probably belong elsewhere. */
2325 #define BRI_PER_XBOW 6
2326 #define PCI_PER_BRI 8
2327 #define DEV_PER_PCI 16
2330 -/* Virtual dipswitch values (starting from switch "7"): */
2332 -#define VDS_NOGFX 0x8000 /* Don't enable gfx and autoboot */
2333 -#define VDS_NOMP 0x100 /* Don't start slave processors */
2334 -#define VDS_MANUMODE 0x80 /* Manufacturing mode */
2335 -#define VDS_NOARB 0x40 /* No bootmaster arbitration */
2336 -#define VDS_PODMODE 0x20 /* Go straight to POD mode */
2337 -#define VDS_NO_DIAGS 0x10 /* Don't run any diags after BM arb */
2338 -#define VDS_DEFAULTS 0x08 /* Use default environment values */
2339 -#define VDS_NOMEMCLEAR 0x04 /* Don't run mem cfg code */
2340 -#define VDS_2ND_IO4 0x02 /* Boot from the second IO4 */
2341 -#define VDS_DEBUG_PROM 0x01 /* Print PROM debugging messages */
2343 -/* external declarations of Linux kernel functions. */
2345 -extern lboard_t *find_lboard(lboard_t *start, unsigned char type);
2346 -extern klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char type);
2347 -extern klinfo_t *find_first_component(lboard_t *brd, unsigned char type);
2348 -extern klcpu_t *nasid_slice_to_cpuinfo(nasid_t, int);
2349 -extern lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_class);
2352 -extern klcpu_t *sn_get_cpuinfo(cpuid_t cpu);
2354 #endif /* _ASM_SN_KLCONFIG_H */
2355 diff --git a/arch/mips/include/asm/sn/sn0/addrs.h b/arch/mips/include/asm/sn/sn0/addrs.h
2356 index 6b53070f400f..f13df84edfdd 100644
2357 --- a/arch/mips/include/asm/sn/sn0/addrs.h
2358 +++ b/arch/mips/include/asm/sn/sn0/addrs.h
2359 @@ -134,11 +134,6 @@
2361 #define CALIAS_BASE CAC_BASE
2365 -#define BRIDGE_REG_PTR(_base, _off) ((volatile bridgereg_t *) \
2366 - ((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
2368 #define SN0_WIDGET_BASE(_nasid, _wid) (NODE_SWIN_BASE((_nasid), (_wid)))
2370 /* Turn on sable logging for the processors whose bits are set. */
2371 diff --git a/arch/mips/include/asm/sn/sn0/arch.h b/arch/mips/include/asm/sn/sn0/arch.h
2372 index 425a67e6a947..840a44ac8b5f 100644
2373 --- a/arch/mips/include/asm/sn/sn0/arch.h
2374 +++ b/arch/mips/include/asm/sn/sn0/arch.h
2376 #ifndef _ASM_SN_SN0_ARCH_H
2377 #define _ASM_SN_SN0_ARCH_H
2380 -#ifndef SN0XXL /* 128 cpu SMP max */
2382 * This is the maximum number of nodes that can be part of a kernel.
2383 * Effectively, it's the maximum number of compact node ids (cnodeid_t).
2388 -#else /* SN0XXL system */
2390 -#define MAX_COMPACT_NODES 128
2391 -#define MAXCPUS 256
2393 -#endif /* SN0XXL */
2395 + * XXX: Historical Note regarding SN0XXL:
2397 + * There used to be an obscure #ifndef check for SN0XXL, which appears to
2398 + * have been a much larger IP27 setup that supported a maximum of 128 compact
2399 + * nodes and 256 CPUs. SN0XXL was never defined anywhere, though, so those
2400 + * defines never got used. In reality, complete SN0XXL systems are not likely
2401 + * to exist any longer, so I think it's safe to remove these definitions and
2402 + * leave this historical note behind.
2406 * This is the maximum number of NASIDS that can be present in a system.
2408 #endif /* CONFIG_SGI_SN_M_MODE */
2410 #define SLOT_SHIFT (27)
2411 -#define SLOT_MIN_MEM_SIZE (32*1024*1024)
2412 +#define SLOT_MIN_MEM_SIZE (32 * 1024 * 1024)
2414 #define CPUS_PER_NODE 2 /* CPUs on a single hub */
2415 #define CPUS_PER_NODE_SHFT 1 /* Bits to shift in the node number */
2416 diff --git a/arch/mips/include/asm/sn/sn0/hubmd.h b/arch/mips/include/asm/sn/sn0/hubmd.h
2417 index 305d002be182..d0e48ff5d99e 100644
2418 --- a/arch/mips/include/asm/sn/sn0/hubmd.h
2419 +++ b/arch/mips/include/asm/sn/sn0/hubmd.h
2421 (HUB_S(CPU_LED_ADDR(_nasid, _slice), (_val)))
2423 #define SET_MY_LEDS(_v) \
2424 - SET_CPU_LEDS(get_nasid(), get_slice(), (_v))
2425 + SET_CPU_LEDS(ip27_get_nasid(), get_slice(), (_v))
2428 * Operations on Memory/Directory DIMM control register
2429 diff --git a/arch/mips/include/asm/sn/sn_private.h b/arch/mips/include/asm/sn/sn_private.h
2430 index f09ba846c644..af21afe50e2d 100644
2431 --- a/arch/mips/include/asm/sn/sn_private.h
2432 +++ b/arch/mips/include/asm/sn/sn_private.h
2435 extern nasid_t master_nasid;
2437 -extern void cpu_node_probe(void);
2438 -extern cnodeid_t get_compact_nodeid(void);
2439 -extern void hub_rtc_init(cnodeid_t);
2440 -extern void cpu_time_init(void);
2441 -extern void per_cpu_init(void);
2442 -extern void install_cpu_nmi_handler(int slice);
2443 -extern void install_ipi(void);
2444 +extern void ip27_smp_cpu_node_probe(void);
2445 +extern void ip27_per_cpu_init(void);
2446 +extern void ip27_install_cpu_nmi_handler(int slice);
2447 +extern void ip27_install_ipi(void);
2448 extern void setup_replication_mask(void);
2449 extern void replicate_kernel_text(void);
2450 -extern unsigned long node_getfirstfree(cnodeid_t);
2451 +extern unsigned long node_get_first_free(cnodeid_t);
2453 #endif /* __ASM_SN_SN_PRIVATE_H */
2454 diff --git a/arch/mips/include/asm/sn/types.h b/arch/mips/include/asm/sn/types.h
2455 index 6d24d4e8b9ed..6a01f14f850b 100644
2456 --- a/arch/mips/include/asm/sn/types.h
2457 +++ b/arch/mips/include/asm/sn/types.h
2460 typedef unsigned long cpuid_t;
2461 typedef unsigned long cnodemask_t;
2462 -typedef signed short nasid_t; /* node id in numa-as-id space */
2463 -typedef signed short cnodeid_t; /* node id in compact-id space */
2464 -typedef signed char partid_t; /* partition ID type */
2465 -typedef signed short moduleid_t; /* user-visible module number type */
2466 -typedef signed short cmoduleid_t; /* kernel compact module id type */
2467 -typedef unsigned char clusterid_t; /* Clusterid of the cell */
2469 -typedef dev_t vertex_hdl_t; /* hardware graph vertex handle */
2470 +typedef s16 nasid_t; /* node id in numa-as-id space */
2471 +typedef s16 cnodeid_t; /* node id in compact-id space */
2472 +typedef s8 partid_t; /* partition ID type */
2473 +typedef s16 moduleid_t; /* user-visible module number type */
2475 #endif /* _ASM_SN_TYPES_H */
2476 diff --git a/arch/mips/include/asm/xtalk/xwidget.h b/arch/mips/include/asm/xtalk/xwidget.h
2477 index cb0bf300b437..9366bdaf8337 100644
2478 --- a/arch/mips/include/asm/xtalk/xwidget.h
2479 +++ b/arch/mips/include/asm/xtalk/xwidget.h
2480 @@ -196,6 +196,19 @@ static const struct widget_ident __initconst widget_idents[] = {
2484 +#if defined(CONFIG_SGI_IP27)
2485 + #include <asm/sn/sn0/hubio.h>
2486 + #include <asm/mach-ip27/sysinfo.h>
2489 + #define XTALK_XBOW IP27_WIDGET_XBOW
2490 + #define XTALK_HUB IP27_WIDGET_HUB
2491 + #define XTALK_PCIBR IP27_WIDGET_PCI_CAGE
2492 + #define XTALK_BRIDGE IP27_WIDGET_PCI_BASE
2493 + #define XTALK_LOW_DEV HUB_WIDGET_ID_MIN
2494 + #define XTALK_HIGH_DEV HUB_WIDGET_ID_MAX
2497 /* Common widget bits */
2498 #define XTALK_NODEV 0xffffffff
2500 diff --git a/arch/mips/pci/pci-bridge.c b/arch/mips/pci/pci-bridge.c
2501 index fa0089cdd69f..473a193814c3 100644
2502 --- a/arch/mips/pci/pci-bridge.c
2503 +++ b/arch/mips/pci/pci-bridge.c
2504 @@ -31,36 +31,119 @@
2506 #if defined(CONFIG_SGI_IP27)
2507 #include <asm/mach-ip27/pcibr.h>
2508 +#include <asm/mach-ip27/sysinfo.h>
2510 #error "Unknown CONFIG_SGI_IP??"
2513 /* Increments for each additional bridge. */
2514 -static int num_bridges;
2515 +static int num_bridges __initdata;
2518 -/* XXX: Temporary until the IP27 "mega update". */
2520 - * XXX: No kmalloc available when we do our crosstalk scan,
2521 - * we should try to move it later in the boot process.
2522 +/* RRB constants. */
2523 +#define BRIDGE_MAX_RRBS 8 /* 8 RRBs max/reg */
2524 +#define BRIDGE_PAIRS_PER_REG 4 /* 4 RRB pairs/reg */
2525 +#define BRIDGE_DEFAULT_RRB_VALUE 0x00000000
2528 + * bridge_alloc_rrbs - allocate specific read response buffer resources.
2529 + * @dev1: u32 num of RRBs to request for device #1.
2530 + * @dev2: ... for device #2.
2531 + * @dev3: ... for device #3.
2532 + * @dev4: ... for device #4.
2533 + * @virt1: bool to set whether virtual channel is enabled for device #1.
2534 + * @virt2: ... for device #2.
2535 + * @virt3: ... for device #3.
2536 + * @virt4: ... for device #4.
2538 + * returns a value to be assigned directly to a BRIDGE's even or odd
2539 + * "Read Response Buffer" register. Each register maps 4 sets of 4 bits
2540 + * for each RRB. The "even" register sets RRBs for slots 0, 2, 4, & 6 and
2541 + * the "odd" register sets RRBs for slots 1, 3, 5, & 7.
2543 + * This function was adapted from the original "pcibr_alloc_all_rrbs"
2544 + * function in arch/ia64/sn/io/sn1/pcibr.c in Linux-2.5.70.
2546 -static struct bridge_controller bridges[PCIBR_MAX_NUM_PCIBUS];
2548 +bridge_alloc_rrbs(u8 dev1, u8 dev2, u8 dev3, u8 dev4,
2549 + bool virt1, bool virt2, bool virt3, bool virt4)
2552 + u32 rrb_value = BRIDGE_DEFAULT_RRB_VALUE;
2553 + u32 rrbs[4], virt[4];
2557 + /* Copy the args to arrays for use in loops. */
2567 + /* Only 8 RRBs per register are available. */
2568 + if ((dev1 + dev2 + dev3 + dev4) > BRIDGE_MAX_RRBS)
2569 + return BRIDGE_DEFAULT_RRB_VALUE;
2571 + /* Walk through the RRBs */
2572 + for (i = 0; i < BRIDGE_PAIRS_PER_REG; i++) {
2574 + cur_rrb = (i | 0xc);
2575 + cur_rrb <<= (rrb_shift * 4);
2577 + rrb_value |= cur_rrb;
2580 + for (j = 0; j < rrbs[i]; j++) {
2581 + cur_rrb = (i | 0x8);
2582 + cur_rrb <<= (rrb_shift * 4);
2584 + rrb_value |= cur_rrb;
2592 + * bridge_probe_slot - protected memory access to a bridge slot.
2593 + * @bridge: const pointer to a BRIDGE structure.
2594 + * @slot: u32 number of specific slot to probe.
2596 + * returns 'true' if something is in the slot, else 'false'.
2598 +static inline bool __init
2599 +bridge_probe_slot(struct bridge_controller *bc, u32 slot)
2601 + volatile void *addr;
2604 + addr = &bc->bridge->pci_t0[slot].fields.common.dev_id;
2605 + get_dbe(results, (u32 __iomem *)addr);
2607 + return results ? true : false;
2611 * bridge_probe - probes a BRIDGE chip and configures it.
2612 - * @nasid: NUMA Address Space Identifier.
2613 * @widget_id: s8 value of this BRIDGE's xtalk widget ID.
2614 - * @masterwid: widget ID of HUB.
2615 + * @pdata: struct xwidget_platform_data passed by the xtalk probe.
2617 * Always returns '0'.
2620 -bridge_probe(nasid_t nasid, int widget_id, int masterwid)
2622 +bridge_probe(s8 widget_id, const struct xwidget_platform_data *pdata)
2625 u32 wid_ctrl; /* BRIDGE WAR */
2626 + nasid_t nasid = pdata->nasid;
2627 + s8 masterwid = pdata->masterwid;
2628 unsigned long offset = NODE_OFFSET(nasid);
2629 struct bridge_controller *bc;
2630 + bool slot_census[BRIDGE_MAX_DEVS];
2632 #ifdef CONFIG_SGI_IP27
2634 @@ -77,12 +160,12 @@ bridge_probe(nasid_t nasid, int widget_id, int masterwid)
2635 pci_set_flags(PCI_PROBE_ONLY);
2638 - /* XXX: Temporary until the IP27 "mega update". */
2639 - bc = &bridges[num_bridges];
2641 - ioport_resource.end = ~0UL;
2642 + /* Alloc & zero some memory for the bridge_controller. */
2643 + bc = kzalloc(sizeof(struct bridge_controller), GFP_KERNEL);
2645 /* Set bridge_controller parameters. */
2646 + bc->alloc_irq = pdata->bridge_pdata->alloc_irq;
2647 + bc->pc.pre_enable = pdata->bridge_pdata->pre_enable;
2648 bc->pc.pci_ops = &bridge_pci_ops;
2649 bc->pc.mem_resource = &bc->mem;
2650 bc->pc.mem_offset = offset;
2651 @@ -111,9 +194,6 @@ bridge_probe(nasid_t nasid, int widget_id, int masterwid)
2653 bc->baddr = ((u64)masterwid << PCI64_ATTR_TARG_SHFT);
2656 - bc->irq_cpu = smp_processor_id();
2658 /* Point to this bridge. */
2659 bc->bridge = (struct bridge_widget __iomem *)
2660 RAW_NODE_SWIN_BASE(nasid, widget_id);
2661 @@ -143,12 +223,6 @@ bridge_probe(nasid_t nasid, int widget_id, int masterwid)
2662 /* Configure BRIDGE widget control ... */
2663 wid_ctrl = bridge_read_reg(bc, b_wid_ctrl);
2666 - * IP27 & IP35 need I/O and Mem swapping enabled.
2667 - * IP30 needs it disabled.
2669 - wid_ctrl |= (BRIDGE_CTRL_IO_SWAP | BRIDGE_CTRL_MEM_SWAP);
2671 /* Set the BRIDGE PAGE_SIZE */
2672 #ifdef CONFIG_PAGE_SIZE_4KB
2673 wid_ctrl &= ~BRIDGE_CTRL_PAGE_SIZE;
2674 @@ -180,12 +254,22 @@ bridge_probe(nasid_t nasid, int widget_id, int masterwid)
2676 bridge_write_reg(reg, bc, b_device(slot));
2677 bc->pci_int[slot] = -1;
2679 + /* Take a census of each slot to see if something is there. */
2680 + slot_census[slot] = bridge_probe_slot(bc, slot);
2683 /* Configure direct-mapped DMA */
2684 reg = (masterwid << BRIDGE_DIRMAP_W_ID_SHFT);
2685 + if (pdata->bridge_pdata->add_512)
2686 + reg |= BRIDGE_DIRMAP_ADD512;
2687 bridge_write_reg(reg, bc, b_dir_map);
2689 + /* XXX: Assign RRBs for the BaseIO BRIDGE only (for now) */
2690 + if (bc->widget_id == pdata->bridge_pdata->baseio_widget_id &&
2691 + pdata->bridge_pdata->setup_baseio_rrbs)
2692 + pdata->bridge_pdata->setup_baseio_rrbs(bc, slot_census);
2695 * Route all PCI bridge interrupts to the appropriate ASIC responsible
2696 * for handling IRQs (HUB in IP27, HEART in IP30, BEDROCK in IP35).
2697 @@ -197,7 +281,8 @@ bridge_probe(nasid_t nasid, int widget_id, int masterwid)
2699 bridge_write_reg(((masterwid << WIDGET_TARGET_ID_SHFT) | 0x8000), bc,
2701 - bridge_write_reg(PCIBR_XIO_SEES_HUB, bc, b_wid_int_lower);
2702 + bridge_write_reg(pdata->bridge_pdata->xio_target_addr, bc,
2704 bridge_write_reg(BRIDGE_COSMIC_INT_DEV, bc, b_int_device);
2705 bridge_write_reg(0, bc, b_int_mode);
2706 reg = bridge_read_reg(bc, b_int_enable);
2707 @@ -251,26 +336,7 @@ pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
2709 pcibios_plat_dev_init(struct pci_dev *dev)
2711 - struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
2712 - struct pci_dev *rdev = bridge_root_dev(dev);
2713 - int slot = PCI_SLOT(rdev->devfn);
2716 - irq = bc->pci_int[slot];
2718 - irq = request_bridge_irq(bc);
2722 - bc->pci_int[slot] = irq;
2725 - irq_to_bridge[irq] = bc;
2726 - irq_to_slot[irq] = slot;
2731 + return bridge_alloc_irq(dev);
2735 @@ -303,22 +369,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_RAD1,
2736 bridge_disable_swapping_dma);
2739 -/* XXX: Temporarily defined here until the IP27 "mega update". */
2742 - * pcibus_to_node - fetch the nasid that the passed struct pci_bus lives on.
2743 - * @bus: struct pci_bus pointer for a given PCI bus.
2745 - * casts bus->sysdata to struct bridge_controller and returns the nasid
2746 - * member that references the specific node this PCI bus lives on.
2749 -pcibus_to_node(struct pci_bus *bus)
2751 +bridge_init(struct platform_device *pdev)
2753 - struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
2754 + struct xwidget_platform_data *pdata;
2756 + /* Get the platform data. */
2757 + pdata = (struct xwidget_platform_data *) pdev->dev.platform_data;
2762 + return bridge_probe(pdev->id, pdata);
2764 -EXPORT_SYMBOL(pcibus_to_node);
2765 -#endif /* CONFIG_NUMA */
2767 +static struct platform_driver __refdata
2769 + .probe = bridge_init,
2770 + /* BRIDGE cannot be dynamically removed. */
2775 +builtin_platform_driver(bridge_driver);
2776 diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile
2777 index 73502fda13ee..9dea47e015fd 100644
2778 --- a/arch/mips/sgi-ip27/Makefile
2779 +++ b/arch/mips/sgi-ip27/Makefile
2780 @@ -8,5 +8,6 @@ obj-y := ip27-berr.o ip27-irq.o ip27-irqno.o ip27-init.o ip27-klconfig.o \
2781 ip27-hubio.o ip27-xtalk.o
2783 obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o
2784 -obj-$(CONFIG_PCI) += ip27-irq-pci.o
2785 +obj-$(CONFIG_PCI) += ip27-irq-pci.o ip27-bridge.o
2786 obj-$(CONFIG_SMP) += ip27-smp.o
2787 +obj-$(CONFIG_RTC_DRV_M48T35) += ip27-rtc.o
2788 diff --git a/arch/mips/sgi-ip27/ip27-bridge.c b/arch/mips/sgi-ip27/ip27-bridge.c
2789 new file mode 100644
2790 index 000000000000..5b738fe8a5f6
2792 +++ b/arch/mips/sgi-ip27/ip27-bridge.c
2795 + * This file is subject to the terms and conditions of the GNU General Public
2796 + * License. See the file "COPYING" in the main directory of this archive
2797 + * for more details.
2799 + * ip27-bridge.c: BRIDGE platform device setup for IP27.
2801 + * Copyright (C) 2016 Joshua Kinard <kumba@gentoo.org>
2804 +#include <linux/export.h>
2805 +#include <linux/init.h>
2806 +#include <linux/platform_device.h>
2808 +#include <asm/addrspace.h>
2809 +#include <asm/pci/bridge.h>
2811 +#include <asm/mach-ip27/pcibr.h>
2812 +#include <asm/mach-ip27/sysinfo.h>
2814 +/* Defined in ip27-irq-pci.c. */
2815 +extern int ip27_request_irq(void);
2817 +/* Defined in arch/mips/pci/pci-bridge.c */
2818 +extern u32 bridge_alloc_rrbs(u8, u8, u8, u8, bool, bool, bool, bool);
2822 + * XXX: drivers/misc/ioc3.c metadriver needs to check device flags
2823 + * to see what devices are actually present on a given IOC3 chip.
2825 + * XXX: for now, use a static bool to determine if we're probing the
2826 + * first IOC3 card on either an IO6 or IO6-G card. If it's an IO6-G,
2827 + * then this bool will prevent the second IOC3 from trying to acquire
2830 +static bool ip27_io6_probed_2nd_ioc3_irq __initdata = false;
2834 + * pcibus_to_node - fetch the nasid that the passed struct pci_bus lives on.
2835 + * @bus: struct pci_bus pointer for a given PCI bus.
2837 + * casts bus->sysdata to struct bridge_controller and returns the nasid
2838 + * member that references the specific node this PCI bus lives on.
2841 +pcibus_to_node(struct pci_bus *bus)
2843 + struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
2847 +EXPORT_SYMBOL(pcibus_to_node);
2848 +#endif /* CONFIG_NUMA */
2852 + * ip27_setup_io6_rrbs - alloc the read response buffers on an IP27 IO6 card.
2853 + * @bridge: const pointer to a BRIDGE structure.
2854 + * @census: array of bools indicating if a slot is populated or not.
2856 + * RRB values and logic was adapted from the original (and unused) function
2857 + * "sn00_rrb_alloc", found in arch/ia64/sn/io/ml_iograph.c in Linux-2.5.70.
2859 + * There are two 32-bit registers for manipulating the RRB layout. The first
2860 + * register handles even-numbered slots (0, 2, 4, & 6) and the second register
2861 + * handles odd-numbered slots (1, 3, 5, & 7). RRB assignment involves
2862 + * frobbing four bits per RRB, for a total of 8 RRBs split between the four
2863 + * BRIDGE slots in each register. For each RRB, the four bits are in order:
2864 + * - Buffer Enable (1 bit)
2865 + * - Virtual Channel Enable (1 bit)
2866 + * - Device Number Assigned (upper two bits of device number)
2868 + * Slot assignment can differ slightly depending on if there is an IO6 board
2869 + * (Origin 200/2000) or IO6-G board (Onyx2) present. For an IO6:
2872 + * - Slot 2 (IOC3 Ethernet)
2873 + * - Slot 3 (IOC3 I/O)
2874 + * - Remaining slots are empty
2876 + * For an IO6-G, the same as above, plus:
2878 + * - Slot 7 (2nd IOC3, I/O only)
2880 + * Other configurations may be possible, but these have not been encountered
2883 + * IP27's RRB logic is:
2884 + * - 3+ RRBs for scsi0 (qla)
2885 + * - 2 RRBs for scsi1 (qla, external)
2886 + * - 2+ RRBs for IOC3 ethernet
2887 + * - 1 RRB for IOC3 I/O (kb/mouse, serial ports)
2889 + * This leads to the following RRB assignment logic:
2891 + * - If nothing in Slot 6 (0xc8889999):
2892 + * - Slot 0, 4 RRBs
2893 + * - Slot 2, 4 RRBs
2894 + * - Else (0xc8899bbb):
2895 + * - Slot 0, 3 RRBs
2896 + * - Slot 2, 2 RRBs
2897 + * - Slot 6, 3 RRBs
2900 + * - If nothing in Slot 5 or Slot 7 (0xc8889999):
2901 + * - Slot 1, 4 RRBs
2902 + * - Slot 3, 4 RRBs
2903 + * - Else if something in Slot 5 (0xc8899aaa) xor Slot 7 (0xc8899bbb):
2904 + * - Slot 1, 3 RRBs
2905 + * - Slot 3, 2 RRBs
2906 + * - Slot 5 or Slot 7, 3 RRBs (if not empty)
2907 + * - Else (0xc89aaabb):
2908 + * - Slot 1, 2 RRBs
2909 + * - Slot 3, 1 RRBs
2910 + * - Slot 5, 3 RRBs
2911 + * - Slot 7, 2 RRBs
2913 + * The RRB-assignment logic suggests something may be able to exist in
2914 + * Slot 5, but it is unknown at this time what device that might be on an
2915 + * IO6/IO6-G. Slot 4 should always be empty, but it is unknown if a system
2916 + * function may be wired through there or not, like Slot 6 on the IP30 BaseIO
2917 + * BRIDGE for its power button.
2920 +ip27_bridge_setup_io6_rrbs(struct bridge_controller *bc, const bool *census)
2926 + rrbs = bridge_alloc_rrbs(3, 2, 0, 3,
2927 + false, false, false, false);
2929 + rrbs = bridge_alloc_rrbs(4, 4, 0, 0,
2930 + false, false, false, false);
2931 + spin_lock(&bc->lock);
2932 + bridge_write_reg(rrbs, bc, b_dev_even_rrb);
2934 + spin_unlock(&bc->lock);
2937 + if (census[5] && census[7])
2938 + rrbs = bridge_alloc_rrbs(2, 1, 3, 2,
2939 + false, false, false, false);
2940 + else if (census[5] && !census[7])
2941 + rrbs = bridge_alloc_rrbs(3, 2, 3, 0,
2942 + false, false, false, false);
2943 + else if (!census[5] && census[7])
2944 + rrbs = bridge_alloc_rrbs(3, 2, 0, 3,
2945 + false, false, false, false);
2947 + rrbs = bridge_alloc_rrbs(4, 4, 0, 0,
2948 + false, false, false, false);
2949 + spin_lock(&bc->lock);
2950 + bridge_write_reg(rrbs, bc, b_dev_odd_rrb);
2952 + spin_unlock(&bc->lock);
2956 + * ip27_bridge_alloc_irq - platform-specific BRIDGE IRQ allocator.
2957 + * @dev: pointer to struct pci_dev for the specific PCI device.
2959 + * Returns the assigned IRQ or -1 if no IRQ was allocated.
2962 +ip27_bridge_alloc_irq(struct pci_dev *dev)
2964 + struct pci_dev *rdev = bridge_root_dev(dev);
2965 + struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
2966 + int slot = PCI_SLOT(rdev->devfn);
2969 + irq = bc->pci_int[slot];
2971 + irq = ip27_request_irq();
2975 + bc->pci_int[slot] = irq;
2976 + } else if ((bc->widget_id == IP27_WIDGET_PCI_BASE) &&
2977 + (dev->device == PCI_DEVICE_ID_SGI_IOC3)) {
2980 + * XXX: Onyx2 systems have an IO6-G, which has TWO IOC3
2981 + * chips on it. The first IOC3 is much like the Origin 2k's
2982 + * IO6, but the second IOC3 on an IO6-G only has 2x serial
2983 + * ports and kb/mouse ports, no ethernet. So, in that
2984 + * instance, PCI INTA will have already been allocated and
2985 + * and hopefully, those ports will all work. But the IOC3
2986 + * metadriver is a tad braindead and will still attempt to
2987 + * request a 2nd IRQ, which isn't needed on this 2nd IOC3
2990 + if (ip27_io6_probed_2nd_ioc3_irq) {
2996 + * XXX: IO6 IOC3 needs a second IRQ, which will also be
2997 + * hardwired to BRIDGE slot #3. But don't overwrite the
2998 + * dev->irq assignment, as the ethernet is primary.
3000 + irq = ip27_request_irq();
3001 + ip27_irq_to_bridge[irq] = bc;
3002 + ip27_irq_to_slot[irq] = IP27_IO6_2ND_IOC3;
3003 + ip27_io6_probed_2nd_ioc3_irq = true;
3007 + ip27_irq_to_bridge[irq] = bc;
3008 + ip27_irq_to_slot[irq] = slot;
3015 +struct bridge_platform_data
3016 +ip27_bridge_platform_data[] __initdata = {
3018 + .xio_target_addr = PCIBR_XIO_SEES_HUB,
3019 + .baseio_widget_id = IP27_WIDGET_PCI_BASE,
3020 + .iomem_swap = true,
3022 + .setup_baseio_rrbs = ip27_bridge_setup_io6_rrbs,
3023 + .alloc_irq = ip27_bridge_alloc_irq,
3024 + .pre_enable = NULL,
3027 diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c
3028 index 225a13ee52f4..cf28a85eb04d 100644
3029 --- a/arch/mips/sgi-ip27/ip27-console.c
3030 +++ b/arch/mips/sgi-ip27/ip27-console.c
3032 * Copyright (C) 2001, 2002 Ralf Baechle
3035 +#include <asm/delay.h>
3036 #include <asm/page.h>
3038 +#include <asm/sgi/ioc3.h>
3039 #include <asm/sn/addrs.h>
3040 -#include <asm/sn/sn0/hub.h>
3041 #include <asm/sn/klconfig.h>
3042 -#include <asm/sgi/ioc3.h>
3043 #include <asm/sn/sn_private.h>
3044 +#include <asm/sn/sn0/hub.h>
3046 #include <linux/serial.h>
3047 #include <linux/serial_core.h>
3049 #define IOC3_CLK (22000000 / 3)
3050 #define IOC3_FLAGS (0)
3052 -static inline struct ioc3_uartregs *console_uart(void)
3053 +static inline struct ioc3_uartregs *
3059 - nasid = (master_nasid == INVALID_NASID) ? get_nasid() : master_nasid;
3060 - ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(nasid)->memory_base;
3061 + nasid = ((master_nasid == INVALID_NASID) ? ip27_get_nasid() :
3063 + ioc3 = (struct ioc3 *)KL_CONFIG_CONS_INFO(nasid)->memory_base;
3065 return &ioc3->sregs.uarta;
3068 -void prom_putchar(char c)
3070 +prom_putchar(char c)
3072 struct ioc3_uartregs *uart = console_uart();
3074 - while ((uart->iu_lsr & 0x20) == 0);
3075 + while ((((u8 __iomem)uart->iu_lsr) & 0x20) == 0)
3080 diff --git a/arch/mips/sgi-ip27/ip27-hubio.c b/arch/mips/sgi-ip27/ip27-hubio.c
3081 index 36485dcf7af0..b04b0ed5affc 100644
3082 --- a/arch/mips/sgi-ip27/ip27-hubio.c
3083 +++ b/arch/mips/sgi-ip27/ip27-hubio.c
3085 #include <asm/sn/hub.h>
3088 -static int force_fire_and_forget = 1;
3089 +static int __initdata force_fire_and_forget = 1;
3093 + * XXX: Requires porting from 2.4 arch/ia64/sn/io/io.c the various HUB
3094 + * PIO/DMA mapping stuff and setting up generic Xtalk bus support.
3098 - * hub_pio_map - establish a HUB PIO mapping
3100 - * @hub: hub to perform PIO mapping on
3101 - * @widget: widget ID to perform PIO mapping for
3102 + * ip27_hub_pio_map - establish a HUB PIO mapping
3103 + * @hub: hub to perform PIO mapping on
3104 + * @widget: widget ID to perform PIO mapping for
3105 * @xtalk_addr: xtalk_address that needs to be mapped
3106 - * @size: size of the PIO mapping
3107 + * @size: size of the PIO mapping
3110 -unsigned long hub_pio_map(cnodeid_t cnode, s8 widget,
3111 - unsigned long xtalk_addr, size_t size)
3113 +ip27_hub_pio_map(cnodeid_t cnode, s8 widget,
3114 + unsigned long xtalk_addr, size_t size)
3116 - nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
3118 + nasid_t nasid = sn_cnodeid_to_nasid[cnode];
3121 /* use small-window mapping if possible */
3122 if ((xtalk_addr % SWIN_SIZE) + size <= SWIN_SIZE)
3123 - return NODE_SWIN_BASE(nasid, widget) + (xtalk_addr % SWIN_SIZE);
3124 + return (NODE_SWIN_BASE(nasid, widget) +
3125 + (xtalk_addr % SWIN_SIZE));
3127 if ((xtalk_addr % BWIN_SIZE) + size > BWIN_SIZE) {
3128 - printk(KERN_WARNING "PIO mapping at hub %d widget %d addr 0x%lx"
3129 - " too big (%ld)\n",
3130 - nasid, widget, xtalk_addr, size);
3131 + pr_warn("PIO mapping at hub %d, widget %d, addr 0x%lx too big (%ld)\n",
3132 + nasid, widget, xtalk_addr, size);
3136 - xtalk_addr &= ~(BWIN_SIZE-1);
3137 + xtalk_addr &= ~(BWIN_SIZE - 1);
3138 for (i = 0; i < HUB_NUM_BIG_WINDOW; i++) {
3139 if (test_and_set_bit(i, hub_data(cnode)->h_bigwin_used))
3141 @@ -63,25 +69,26 @@ unsigned long hub_pio_map(cnodeid_t cnode, s8 widget,
3142 * after we write it.
3144 IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr);
3145 - (void) HUB_L(IIO_ITTE_GET(nasid, i));
3146 + (void)HUB_L(IIO_ITTE_GET(nasid, i));
3148 - return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE);
3149 + return (NODE_BWIN_BASE(nasid, widget) +
3150 + (xtalk_addr % BWIN_SIZE));
3153 - printk(KERN_WARNING "unable to establish PIO mapping for at"
3154 - " hub %d widget %d addr 0x%lx\n",
3155 - nasid, widget, xtalk_addr);
3156 + pr_warn("IP27: Unable to establish PIO mapping for at hub %d, widget %d, addr 0x%lx\n",
3157 + nasid, widget, xtalk_addr);
3164 - * hub_setup_prb(nasid, prbnum, credits, conveyor)
3165 + * ip27_hub_setup_prb(nasid, prbnum, credits, conveyor)
3167 - * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise,
3168 - * put it into conveyor belt mode with the specified number of credits.
3169 + * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise,
3170 + * put it into conveyor belt mode with the specified number of credits.
3172 -static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
3174 +ip27_hub_setup_prb(nasid_t nasid, int prbnum, int credits)
3178 @@ -116,24 +123,24 @@ static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
3182 - * hub_set_piomode - set pio mode for a given hub
3184 - * @nasid: physical node ID for the hub in question
3185 + * ip27_hub_set_piomode - set pio mode for a given hub
3186 + * @nasid: physical node ID for the hub in question
3188 * Put the hub into either "PIO conveyor belt" mode or "fire-and-forget" mode.
3189 * To do this, we have to make absolutely sure that no PIOs are in progress
3190 * so we turn off access to all widgets for the duration of the function.
3192 - * XXX - This code should really check what kind of widget we're talking
3193 + * XXX: This code should really check what kind of widget we're talking
3194 * to. Bridges can only handle three requests, but XG will do more.
3195 * How many can crossbow handle to widget 0? We're assuming 1.
3197 - * XXX - There is a bug in the crossbow that link reset PIOs do not
3198 + * XXX: There is a bug in the crossbow that link reset PIOs do not
3199 * return write responses. The easiest solution to this problem is to
3200 * leave widget 0 (xbow) in fire-and-forget mode at all times. This
3201 * only affects pio's to xbow registers, which should be rare.
3203 -static void hub_set_piomode(nasid_t nasid)
3205 +ip27_hub_set_piomode(nasid_t nasid)
3209 @@ -148,12 +155,12 @@ static void hub_set_piomode(nasid_t nasid)
3211 * Assume a bridge here.
3213 - hub_setup_prb(nasid, 0, 3);
3214 + ip27_hub_setup_prb(nasid, 0, 3);
3217 * Assume a crossbow here.
3219 - hub_setup_prb(nasid, 0, 1);
3220 + ip27_hub_setup_prb(nasid, 0, 1);
3224 @@ -161,19 +168,19 @@ static void hub_set_piomode(nasid_t nasid)
3225 * when account assigning credits.
3227 for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++)
3228 - hub_setup_prb(nasid, i, 3);
3229 + ip27_hub_setup_prb(nasid, i, 3);
3231 REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
3235 - * hub_pio_init - PIO-related hub initialization
3237 - * @hub: hubinfo structure for our hub
3239 + * ip27_hub_pio_init - PIO-related hub initialization.
3240 + * @cnode: cnodeid_t value for the cnode to init.
3242 -void hub_pio_init(cnodeid_t cnode)
3244 +ip27_hub_pio_init(cnodeid_t cnode)
3246 - nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
3247 + nasid_t nasid = sn_cnodeid_to_nasid[cnode];
3250 /* initialize big window piomaps for this hub */
3251 @@ -181,5 +188,5 @@ void hub_pio_init(cnodeid_t cnode)
3252 for (i = 0; i < HUB_NUM_BIG_WINDOW; i++)
3253 IIO_ITTE_DISABLE(nasid, i);
3255 - hub_set_piomode(nasid);
3256 + ip27_hub_set_piomode(nasid);
3258 diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
3259 index 4a9c05c0b147..03a86f996c2b 100644
3260 --- a/arch/mips/sgi-ip27/ip27-init.c
3261 +++ b/arch/mips/sgi-ip27/ip27-init.c
3264 * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
3265 * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
3267 + * Functions/info/insight sourced from old IA64 code are:
3268 + * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
3269 + * Copyright (C) 2000 by Alan Mayer
3271 #include <linux/kernel.h>
3272 #include <linux/init.h>
3273 @@ -36,49 +40,149 @@
3274 #include <asm/sn/sn0/ip27.h>
3275 #include <asm/sn/mapped_kernel.h>
3277 -#define CPU_NONE (cpuid_t)-1
3279 -static DECLARE_BITMAP(hub_init_mask, MAX_COMPACT_NODES);
3280 +static DECLARE_BITMAP(hub_init_mask, MAX_COMPACT_NODES) __initdata;
3281 nasid_t master_nasid = INVALID_NASID;
3283 -cnodeid_t nasid_to_compact_node[MAX_NASIDS];
3284 -nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
3285 -cnodeid_t cpuid_to_compact_node[MAXCPUS];
3286 +DEFINE_PER_CPU(cnodeid_t, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
3287 +EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
3289 +DEFINE_PER_CPU(nasid_t, __sn_nasid_to_cnodeid[MAX_NASIDS]);
3290 +EXPORT_PER_CPU_SYMBOL(__sn_nasid_to_cnodeid);
3292 -EXPORT_SYMBOL(nasid_to_compact_node);
3293 +DEFINE_PER_CPU(cnodeid_t, __sn_cpuid_to_cnodeid[MAXCPUS]);
3294 +EXPORT_PER_CPU_SYMBOL(__sn_cpuid_to_cnodeid);
3296 -struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
3297 -EXPORT_SYMBOL_GPL(sn_cpu_info);
3298 +DEFINE_PER_CPU(struct ip27_percpu_data, ip27_cpu);
3299 +EXPORT_PER_CPU_SYMBOL(ip27_cpu);
3301 -extern void pcibr_setup(cnodeid_t);
3303 -extern void xtalk_probe_node(cnodeid_t nid);
3304 +/* ----------------------------------------------------------------------- */
3305 +/* IP27 Initialization routines. */
3307 -static void per_hub_init(cnodeid_t cnode)
3309 + * ip27_get_nasid() returns the physical node id number of the caller.
3312 +ip27_get_nasid(void)
3314 + return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK) >>
3315 + NSRI_NODEID_SHFT);
3319 + * ip27_hub_clock_init - enable/set the various clocks on a HUB.
3320 + * @cnode: compact nodeid of the current node.
3322 + * We only need to initialize the current node. If this is not the current
3323 + * node, then it is a cpuless (headless) node and timeouts will not happen
3327 +ip27_hub_clock_init(cnodeid_t cnode)
3329 + cnodeid_t this_cnode = sn_nasid_to_cnodeid[ip27_get_nasid()];
3331 + if (this_cnode == cnode) {
3332 + LOCAL_HUB_S(PI_RT_EN_A, 1);
3333 + LOCAL_HUB_S(PI_RT_EN_B, 1);
3334 + LOCAL_HUB_S(PI_PROF_EN_A, 0);
3335 + LOCAL_HUB_S(PI_PROF_EN_B, 0);
3336 + LOCAL_HUB_S(PI_RT_COUNT, 0);
3337 + LOCAL_HUB_S(PI_RT_PEND_A, 0);
3338 + LOCAL_HUB_S(PI_RT_PEND_B, 0);
3343 + * ip27_per_hub_init - initialize each HUB on a node.
3344 + * @cnode: compact nodeid of the current node.
3347 +ip27_per_hub_init(cnodeid_t cnode)
3349 - struct hub_data *hub = hub_data(cnode);
3350 - nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
3353 + nasid_t nasid = sn_cnodeid_to_nasid[cnode];
3354 + struct hub_data *hub = hub_data(cnode);
3355 +#ifdef CONFIG_REPLICATE_EXHANDLERS
3356 + cnodeid_t this_cnode = sn_nasid_to_cnodeid[ip27_get_nasid()];
3359 cpumask_set_cpu(smp_processor_id(), &hub->h_cpus);
3361 - if (test_and_set_bit(cnode, hub_init_mask))
3362 + if (test_and_set_bit(cnode, hub_init_mask)) {
3367 + * Clear the HUB IRQ allocation map and set all irq_to_bit/bit_to_irq
3368 + * mappings to -1. There's two INT_PEND registers, each 64-bits wide,
3369 + * for a total of 128 bits per HUB. HUB carries two INT_MASK regs
3372 + for (i = 0; i < BITS_PER_HUB; i++) {
3373 + hub->irq_to_bit[i] = -1;
3374 + hub->bit_to_irq[i] = -1;
3375 + __clear_bit(i, hub->irq_alloc_map);
3379 + * Some interrupts are reserved by hardware or by software convention.
3380 + * Mark these as reserved right away so they won't be accidentally
3383 + for (i = 0; i <= BASE_PCI_IRQ; i++) {
3384 + __set_bit(i, hub->irq_alloc_map);
3385 + LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
3388 + __set_bit(IP_PEND0_6_63, hub->irq_alloc_map);
3389 + LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
3391 + for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
3392 + __set_bit(i, hub->irq_alloc_map);
3393 + LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
3397 * Set CRB timeout at 5ms, (< PI timeout of 10ms)
3399 REMOTE_HUB_S(nasid, IIO_ICTP, 0x800);
3400 REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
3402 - hub_rtc_init(cnode);
3403 - xtalk_probe_node(cnode);
3405 + * The following source code comment provided this useful bit of info:
3407 + * Turn off UNCAC_UNCORR interrupt in the masks. Anyone interested
3408 + * in these errors will peek at the int pend register to see if its
3411 + * It was discovered in Linux-2.4.18/arch/ia64/sn/io/huberror.c in
3412 + * 'hub_error_init' in an #ifdef'ed section of code that was likely
3413 + * yanked from IRIX's SN0 code and was to be used for bring up of the
3414 + * early IA64 SN1 platform. The entire file was removed in
3415 + * Linux-2.4.19, though, with no clear reasoning why. Still, it might
3416 + * help in the updated IP27 code so that CPU's other than CPU0 can use
3417 + * get_dbe() to probe BRIDGE slots to see if the slot is populated or
3420 + * Modified to work for IP27/SN0, which only has a single PI, and thus
3421 + * we don't need to loop through any subnodes (that's IP35/SN1).
3423 + reg = LOCAL_HUB_L(PI_ERR_INT_MASK_A);
3424 + LOCAL_HUB_S(PI_ERR_INT_MASK_A, (reg & ~PI_ERR_UNCAC_UNCORR_A));
3425 + reg = LOCAL_HUB_L(PI_ERR_INT_MASK_B);
3426 + LOCAL_HUB_S(PI_ERR_INT_MASK_B, (reg & ~PI_ERR_UNCAC_UNCORR_B));
3428 + ip27_hub_clock_init(cnode);
3429 + ip27_hub_pio_init(cnode);
3431 #ifdef CONFIG_REPLICATE_EXHANDLERS
3433 * If this is not a headless node initialization,
3434 * copy over the caliased exception handlers.
3436 - if (get_compact_nodeid() == cnode) {
3437 + if (this_cnode == cnode) {
3438 extern char except_vec2_generic, except_vec3_generic;
3439 extern void build_tlb_refill_handler(void);
3441 @@ -90,92 +194,123 @@ static void per_hub_init(cnodeid_t cnode)
3442 __flush_cache_all();
3448 + * ip27_cpu_time_init - platform time initialization.
3451 +ip27_cpu_time_init(void)
3453 + struct klc_lboard *brd;
3454 + struct klc_cpu *cpu;
3456 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
3459 - * Some interrupts are reserved by hardware or by software convention.
3460 - * Mark these as reserved right away so they won't be used accidentally
3462 + * ARCS is fragile and its place in memory is typically obliterated
3463 + * right after the TLB is set up by the kernel, so we cannot use it
3464 + * to discover information about the hardware in the system.
3466 + * Fortunately, IP27 platforms have KLCONFIG available, which is a
3467 + * simple linked-list data structure set up by the PROM that contains
3468 + * a complete hardware inventory and it is always available.
3470 - for (i = 0; i <= BASE_PCI_IRQ; i++) {
3471 - __set_bit(i, hub->irq_alloc_mask);
3472 - LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
3474 + brd = kl_find_lboard(KLCF_LBOARD_INFO(ip27_get_nasid()), KLTYPE_IP27);
3476 + panic("IP27: Can't find board info for myself?");
3478 - __set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
3479 - LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
3480 + cpuid = (LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX);
3481 + cpu = KLCF_CAST_CPU(KLCF_COMP(brd, cpuid));
3483 + panic("IP27: No information about myself?");
3485 - for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
3486 - __set_bit(i, hub->irq_alloc_mask);
3487 - LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
3489 + mips_hpt_frequency = (read_c0_count() * 10);
3490 + pr_info("IP27: CPU %d%c (CPU%d): %d MHz CPU detected.\n",
3491 + (cpud->nasid + 1), IP27_CPU_SLICE(cpud->slice), cpud->id,
3494 + set_c0_status(STATUSF_IP4); /* SRB_TIMOCLK */
3497 -void per_cpu_init(void)
3499 +ip27_per_cpu_init(void)
3501 int cpu = smp_processor_id();
3502 int slice = LOCAL_HUB_L(PI_CPU_NUM);
3503 - cnodeid_t cnode = get_compact_nodeid();
3504 - struct hub_data *hub = hub_data(cnode);
3505 - struct slice_data *si = hub->slice + slice;
3506 + cnodeid_t this_cnode = sn_nasid_to_cnodeid[ip27_get_nasid()];
3507 + struct hub_data *hub = hub_data(this_cnode);
3508 + struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
3511 if (test_and_set_bit(slice, &hub->slice_map))
3514 + /* Disable all interrupts. */
3515 clear_c0_status(ST0_IM);
3517 - per_hub_init(cnode);
3518 + /* Populate the percpu struct for IP27 CPU data. */
3520 + cpud->nasid = ip27_get_nasid();
3521 + cpud->cnodeid = this_cnode;
3522 + cpud->slice = slice;
3524 - for (i = 0; i < LEVELS_PER_SLICE; i++)
3525 - si->level_to_irq[i] = -1;
3526 + /* Run necessary HUB init code if not already done. */
3527 + ip27_per_hub_init(this_cnode);
3530 - * We use this so we can find the local hub's data as fast as only
3533 - cpu_data[cpu].data = si;
3534 + /* Initialize the array tracking which CPU owns what IRQ number. */
3535 + for (i = 0; i < BITS_PER_HUB; i++) {
3536 + hub->irq_owner[i] = -1;
3537 + __clear_bit(i, cpud->irq_mask);
3543 + /* Copy CPU0's sn_cnodeid_to_nasid table to this cpu. */
3544 + memcpy(sn_cnodeid_to_nasid,
3545 + (&per_cpu(__sn_cnodeid_to_nasid, 0)),
3546 + sizeof(this_cpu_ptr(__sn_cnodeid_to_nasid)));
3548 + /* Copy CPU0's sn_nasid_to_cnodeid table to this cpu. */
3549 + memcpy(sn_nasid_to_cnodeid,
3550 + (&per_cpu(__sn_nasid_to_cnodeid, 0)),
3551 + sizeof(this_cpu_ptr(__sn_nasid_to_cnodeid)));
3553 + /* Copy CPU0's sn_cpuid_to_cnodeid table to this cpu. */
3554 + memcpy(sn_cpuid_to_cnodeid,
3555 + (&per_cpu(__sn_cpuid_to_cnodeid, 0)),
3556 + sizeof(this_cpu_ptr(__sn_cpuid_to_cnodeid)));
3559 - /* Install our NMI handler if symmon hasn't installed one. */
3560 - install_cpu_nmi_handler(cputoslice(cpu));
3561 + /* Done with ip27_percpu_data. */
3565 - set_c0_status(SRB_DEV0 | SRB_DEV1);
3567 + ip27_cpu_time_init();
3568 + ip27_install_ipi();
3571 - * get_nasid() returns the physical node id number of the caller.
3576 - return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
3577 - >> NSRI_NODEID_SHFT);
3579 + /* Install an NMI handler. */
3580 + ip27_install_cpu_nmi_handler(slice);
3583 - * Map the physical node id to a virtual node id (virtual node ids are contiguous).
3585 -cnodeid_t get_compact_nodeid(void)
3587 - return NASID_TO_COMPACT_NODEID(get_nasid());
3588 + set_c0_status(STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP6);
3591 -static inline void ioc3_eth_init(void)
3593 +ip27_ioc3_eth_init(void)
3598 - nid = get_nasid();
3599 - ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
3600 + nid = ip27_get_nasid();
3601 + ioc3 = (struct ioc3 *)KL_CONFIG_CONS_INFO(nid)->memory_base;
3606 extern void ip27_reboot_setup(void);
3607 +extern void ip27_be_init(void);
3609 -void __init plat_mem_setup(void)
3611 +plat_mem_setup(void)
3613 hubreg_t p, e, n_mode;
3615 @@ -185,27 +320,27 @@ void __init plat_mem_setup(void)
3617 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
3619 - nid = get_nasid();
3620 - printk("IP27: Running on node %d.\n", nid);
3621 + nid = ip27_get_nasid();
3622 + pr_info("IP27: Running on node %d.\n", nid);
3624 - p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
3625 - e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
3626 - printk("Node %d has %s primary CPU%s.\n", nid,
3628 - e ? ", CPU is running" : "");
3629 + p = (LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1);
3630 + e = (LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1);
3631 + pr_info("IP27: Node %d has %s primary CPU%s.\n", nid,
3633 + e ? ", CPU is running" : "");
3635 - p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
3636 - e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
3637 - printk("Node %d has %s secondary CPU%s.\n", nid,
3639 - e ? ", CPU is running" : "");
3640 + p = (LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1);
3641 + e = (LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1);
3642 + pr_info("IP27: Node %d has %s secondary CPU%s.\n", nid,
3644 + e ? ", CPU is running" : "");
3647 * Try to catch kernel missconfigurations and give user an
3648 * indication what option to select.
3650 n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
3651 - printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
3652 + pr_info("IP27: Machine is in %c mode.\n", n_mode ? 'N' : 'M');
3653 #ifdef CONFIG_SGI_SN_N_MODE
3655 panic("Kernel compiled for M mode.");
3656 @@ -214,8 +349,9 @@ void __init plat_mem_setup(void)
3657 panic("Kernel compiled for N mode.");
3662 + ip27_ioc3_eth_init();
3663 + ip27_per_cpu_init();
3666 set_io_port_base(IO_BASE);
3668 diff --git a/arch/mips/sgi-ip27/ip27-irq-pci.c b/arch/mips/sgi-ip27/ip27-irq-pci.c
3669 index cbd75c08a38a..0d51c346c7f4 100644
3670 --- a/arch/mips/sgi-ip27/ip27-irq-pci.c
3671 +++ b/arch/mips/sgi-ip27/ip27-irq-pci.c
3673 // SPDX-License-Identifier: GPL-2.0
3675 - * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
3676 + * This file is subject to the terms and conditions of the GNU General Public
3677 + * License. See the file "COPYING" in the main directory of this archive
3678 + * for more details.
3680 - * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
3681 - * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
3682 - * Copyright (C) 1999 - 2001 Kanoj Sarcar
3683 + * ip27-irq-pci.c: Highlevel interrupt handling for IP27 architecture.
3685 + * The original version of this file inspired the original IRQ logic for
3686 + * the IP30 platform in ip30-irq.c, but ideas from that were later refactored
3687 + * back into this file, which was then re-used to rewrite ip30-irq.c so the
3688 + * two look remarkably similar now. As such, the original code is:
3689 + * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
3690 + * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
3691 + * Copyright (C) 1999-2001 Kanoj Sarcar
3693 + * While snippets of code from ip30-irq.c are:
3694 + * Copyright (C) 2004-2007 Stanislaw Skowronek <skylark@unaligned.org>
3695 + * Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de>
3696 + * Copyright (C) 2007-2014, 2016 Joshua Kinard <kumba@gentoo.org>
3701 #include <linux/irq.h>
3702 #include <linux/errno.h>
3703 -#include <linux/signal.h>
3704 -#include <linux/sched.h>
3705 #include <linux/types.h>
3706 #include <linux/interrupt.h>
3707 -#include <linux/ioport.h>
3708 -#include <linux/timex.h>
3709 -#include <linux/smp.h>
3710 -#include <linux/random.h>
3711 -#include <linux/kernel.h>
3712 -#include <linux/kernel_stat.h>
3713 -#include <linux/delay.h>
3714 #include <linux/bitops.h>
3716 +#include <asm/barrier.h>
3717 #include <asm/bootinfo.h>
3719 #include <asm/mipsregs.h>
3721 -#include <asm/processor.h>
3722 #include <asm/pci/bridge.h>
3723 #include <asm/sn/addrs.h>
3724 #include <asm/sn/agent.h>
3725 #include <asm/sn/arch.h>
3726 #include <asm/sn/hub.h>
3727 #include <asm/sn/intr.h>
3728 +#include <asm/sn/sn_private.h>
3731 - * Linux has a controller-independent x86 interrupt architecture.
3732 - * every controller has a 'controller-template', that is used
3733 - * by the main code to do the right thing. Each driver-visible
3734 - * interrupt source is transparently wired to the appropriate
3735 - * controller. Thus drivers need not be aware of the
3736 - * interrupt-controller.
3738 - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
3739 - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
3740 - * (IO-APICs assumed to be messaging to Pentium local-APICs)
3742 - * the code is designed to be easily extended with new/different
3743 - * interrupt controllers, without having to do assembly magic.
3745 +#include <asm/mach-ip27/pcibr.h>
3747 -extern struct bridge_controller *irq_to_bridge[];
3748 -extern int irq_to_slot[];
3749 +#undef IP27_DEBUG_IRQ
3752 - * use these macros to get the encoded nasid and widget id
3753 - * from the irq value
3755 -#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)]
3756 -#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i]
3757 +/* Defined in ip27-init.c */
3758 +DECLARE_PER_CPU(struct ip27_percpu_data, ip27_cpu);
3760 -static inline int alloc_level(int cpu, int irq)
3762 - struct hub_data *hub = hub_data(cpu_to_node(cpu));
3763 - struct slice_data *si = cpu_data[cpu].data;
3765 +/* Defined in ip27-irq.c */
3766 +extern struct bridge_controller *ip27_irq_to_bridge[PCIBR_MAX_BUS_X_DEV];
3767 +extern u32 ip27_irq_to_slot[PCIBR_MAX_BUS_X_DEV];
3769 - level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
3770 - if (level >= LEVELS_PER_SLICE)
3771 - panic("Cpu %d flooded with devices", cpu);
3773 - __set_bit(level, hub->irq_alloc_mask);
3774 - si->level_to_irq[level] = irq;
3775 +/* ----------------------------------------------------------------------- */
3776 +/* HUB Interrupt Bit Ops */
3780 + * ip27_earmark_irq_bit - earmarks a free interrupt bit in the HUB to an irq.
3781 + * @hub: pointer to struct hub_data.
3782 + * @nasid: node ID.
3783 + * @irq: int value of irq to assign.
3785 + * This function finds the first free bit in HUB's irq_alloc_map and
3786 + * earmarks it for assignment to the requested IRQ number. It then returns
3787 + * the earmarked bit.
3789 + * Interrupt mapping on IP27 is not straight-forward. An IRQ number can be
3790 + * assigned to any CPU attached to a given HUB chip in any of the nodes of
3791 + * the machine. Although, so far, this mapping appears to limit interrupts
3792 + * from a device to the specific HUB that that device's corresponding XBOW
3793 + * chip is connected to. Meaning, we hope that if CPU 1A earmarks a free bit
3794 + * in its connected HUB chip, that CPU 2B won't be the CPU that attempts to
3795 + * claim ownership, because that CPU would be on a different HUB chip entirely.
3797 + * CPU ownership takes place in ip27_startup_hub_irq(), which is where the IRQ
3798 + * bring up happens.
3800 + * Note: Previously, a "bit" was known as a "level" in IRIX terminology. But
3801 + * this is Linux, not IRIX.
3804 +ip27_earmark_irq_bit(struct hub_data *hub, nasid_t nasid, int irq)
3807 +#ifdef IP27_DEBUG_IRQ
3808 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
3811 + bit = find_first_zero_bit(hub->irq_alloc_map, BITS_PER_HUB);
3812 + if (bit >= BITS_PER_HUB)
3813 + panic("IP27: HUB/n%d flooded with IRQ assignments!\n", nasid);
3815 + smp_mb__before_atomic();
3816 + set_bit(bit, hub->irq_alloc_map);
3817 + hub->irq_to_bit[irq] = bit;
3818 + hub->bit_to_irq[bit] = irq;
3819 + smp_mb__after_atomic();
3821 +#ifdef IP27_DEBUG_IRQ
3822 + pr_info("IP27: CPU %d%c (CPU%d): earmarking IRQ %d to HUB bit %d\n",
3823 + (cpud->nasid + 1), IP27_CPU_SLICE(cpud->slice), cpud->id,
3830 -static inline int find_level(cpuid_t *cpunum, int irq)
3832 + * ip27_update_hub_irq_mask - updates irq_mask on a specific HUB/CPU.
3833 + * @cpud: const pointer to the percpu ip27_percpu_data structure.
3836 +ip27_update_hub_irq_mask(const struct ip27_percpu_data __percpu *cpud)
3840 - for_each_online_cpu(cpu) {
3841 - struct slice_data *si = cpu_data[cpu].data;
3843 - for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
3844 - if (si->level_to_irq[i] == irq) {
3849 + if (!cpud->slice) {
3850 + REMOTE_HUB_S(cpud->nasid, PI_INT_MASK0_A, cpud->irq_mask[0]);
3851 + REMOTE_HUB_S(cpud->nasid, PI_INT_MASK1_A, cpud->irq_mask[1]);
3853 + REMOTE_HUB_S(cpud->nasid, PI_INT_MASK0_B, cpud->irq_mask[0]);
3854 + REMOTE_HUB_S(cpud->nasid, PI_INT_MASK1_B, cpud->irq_mask[1]);
3857 - panic("Could not identify cpu/level for irq %d", irq);
3860 -static int intr_connect_level(int cpu, int bit)
3862 + * ip27_set_hub_bit - sets a bit in irq_mask for a specific HUB/CPU.
3863 + * @bit: int value of the interrupt bit to set.
3866 +ip27_set_hub_bit(int bit)
3868 - nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
3869 - struct slice_data *si = cpu_data[cpu].data;
3871 - set_bit(bit, si->irq_enable_mask);
3873 - if (!cputoslice(cpu)) {
3874 - REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
3875 - REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
3877 - REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
3878 - REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
3880 + struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
3883 + set_bit(bit, cpud->irq_mask);
3884 + ip27_update_hub_irq_mask(cpud);
3887 -static int intr_disconnect_level(int cpu, int bit)
3889 + * ip27_clear_hub_bit - clears a bit in irq_mask for a specific HUB/CPU.
3890 + * @bit: int value of the interrupt bit to clear.
3893 +ip27_clear_hub_bit(int bit)
3895 - nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
3896 - struct slice_data *si = cpu_data[cpu].data;
3897 + struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
3899 - clear_bit(bit, si->irq_enable_mask);
3900 + clear_bit(bit, cpud->irq_mask);
3901 + ip27_update_hub_irq_mask(cpud);
3904 - if (!cputoslice(cpu)) {
3905 - REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
3906 - REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
3908 - REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
3909 - REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
3911 +/* ----------------------------------------------------------------------- */
3916 -/* Startup one of the (PCI ...) IRQs routes over a bridge. */
3917 -static unsigned int startup_bridge_irq(struct irq_data *d)
3918 +/* ----------------------------------------------------------------------- */
3922 + * ip27_startup_hub_irq - assigns a HUB IRQ to a CPU and/or Bridge slot.
3923 + * @d: struct irq_data containing IRQ information.
3927 +static unsigned int
3928 +ip27_startup_hub_irq(struct irq_data *d)
3932 struct bridge_controller *bc;
3935 + struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
3937 - slot = SLOT_FROM_PCI_IRQ(d->irq);
3938 - bc = IRQ_TO_BRIDGE(d->irq);
3939 +#ifdef IP27_DEBUG_IRQ
3940 + pr_info("IP27: %s: IRQ %d startup on CPU %d%c (CPU%d)\n", __func__,
3941 + d->irq, (cpud->nasid + 1), IP27_CPU_SLICE(cpud->slice),
3945 - pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, slot);
3947 - * "map" irq to a swlevel greater than 6 since the first 6 bits
3948 - * of INT_PEND0 are taken
3950 - swlevel = find_level(&cpu, d->irq);
3951 + /* This CPU will now claim ownership of the IRQ. */
3952 + raw_spin_lock(&cpud->hub->lock);
3953 + cpud->hub->irq_owner[d->irq] = cpud->id;
3954 + irq_bit = cpud->hub->irq_to_bit[d->irq];
3955 + raw_spin_unlock(&cpud->hub->lock);
3958 * Handle BRIDGE IRQs.
3959 @@ -167,112 +198,273 @@ static unsigned int startup_bridge_irq(struct irq_data *d)
3961 * XXX: Replace the magic values with readable macros at some point.
3964 - bridge_write_reg((0x20000 | swlevel | (bc->nasid << 8)), bc,
3965 - b_int_addr(slot));
3966 - /* b_int_enable */
3967 - reg = bridge_read_reg(bc, b_int_enable);
3968 - bridge_write_reg((reg | BIT(slot) | 0x7ffffe00), bc, b_int_enable);
3971 - reg = bridge_read_reg(bc, b_int_mode);
3972 - bridge_write_reg((reg | BIT(slot)), bc, b_int_mode);
3974 - /* b_int_device */
3975 - reg = bridge_read_reg(bc, b_int_device);
3976 - reg &= ~BRIDGE_INT_DEV_MASK(slot);
3977 - reg |= BRIDGE_INT_DEV_SET(slot, slot);
3978 - bridge_write_reg(reg, bc, b_int_device);
3982 - intr_connect_level(cpu, swlevel);
3984 - return 0; /* Never anything pending. */
3985 + bc = ip27_irq_to_bridge[d->irq];
3987 + spin_lock(&bc->lock);
3988 + slot = ip27_irq_to_slot[d->irq];
3990 + bridge_write_reg((0x20000 | irq_bit | (bc->nasid << 8)), bc,
3991 + b_int_addr(slot));
3992 + /* b_int_enable */
3993 + reg = bridge_read_reg(bc, b_int_enable);
3994 + bridge_write_reg((reg | BIT(slot) | 0x7ffffe00), bc,
3997 + reg = bridge_read_reg(bc, b_int_mode);
3998 + bridge_write_reg((reg | BIT(slot)), bc, b_int_mode);
3999 + /* b_int_device */
4000 + reg = bridge_read_reg(bc, b_int_device);
4001 + reg &= ~BRIDGE_INT_DEV_MASK(slot);
4002 + reg |= BRIDGE_INT_DEV_SET(slot, slot);
4003 + bridge_write_reg(reg, bc, b_int_device);
4006 + spin_unlock(&bc->lock);
4010 + raw_spin_lock(&cpud->hub->lock);
4011 + ip27_set_hub_bit(irq_bit);
4012 + raw_spin_unlock(&cpud->hub->lock);
4014 + /* Never anything pending. */
4018 -/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */
4019 -static void shutdown_bridge_irq(struct irq_data *d)
4021 + * ip27_shutdown_hub_irq - removes a HUB IRQ from a CPU and/or Bridge slot.
4022 + * @d: struct irq_data containing IRQ information.
4025 +ip27_shutdown_hub_irq(struct irq_data *d)
4028 - struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
4032 + struct bridge_controller *bc;
4033 + struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4035 + /* Mask the IRQ on HUB */
4036 + raw_spin_lock(&cpud->hub->lock);
4037 + irq_bit = cpud->hub->irq_to_bit[d->irq];
4038 + ip27_clear_hub_bit(irq_bit);
4039 + raw_spin_unlock(&cpud->hub->lock);
4041 + /* Ditto for BRIDGE */
4042 + bc = ip27_irq_to_bridge[d->irq];
4044 + spin_lock(&bc->lock);
4045 + slot = ip27_irq_to_slot[d->irq];
4046 + reg = bridge_read_reg(bc, b_int_enable);
4047 + bridge_write_reg((reg & ~(BIT(slot))), bc, b_int_enable);
4049 + spin_unlock(&bc->lock);
4052 - pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
4053 - slot = SLOT_FROM_PCI_IRQ(d->irq);
4054 + /* Release ownership of the IRQ. */
4055 + raw_spin_lock(&cpud->hub->lock);
4056 + cpud->hub->irq_owner[d->irq] = -1;
4057 + raw_spin_unlock(&cpud->hub->lock);
4060 - * map irq to a swlevel greater than 6 since the first 6 bits
4061 - * of INT_PEND0 are taken
4063 - swlevel = find_level(&cpu, d->irq);
4064 - intr_disconnect_level(cpu, swlevel);
4065 +#ifdef IP27_DEBUG_IRQ
4066 + pr_info("IP27: %s: IRQ %d shutdown on CPU %d%c (CPU%d)\n", __func__,
4067 + d->irq, (cpud->nasid + 1), IP27_CPU_SLICE(cpud->slice),
4072 - reg = bridge_read_reg(bc, b_int_enable);
4073 - bridge_write_reg((reg & ~(BIT(slot))), bc, b_int_enable);
4076 + * ip27_ack_hub_irq - acks a HUB IRQ.
4077 + * @d: struct irq_data containing IRQ information.
4080 +ip27_ack_hub_irq(struct irq_data *d)
4082 + unsigned long flags;
4083 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4086 + raw_spin_lock_irqsave(&cpud->hub->lock, flags);
4087 + LOCAL_HUB_CLR_INTR(cpud->hub->irq_to_bit[d->irq]);
4088 + raw_spin_unlock_irqrestore(&cpud->hub->lock, flags);
4091 -static inline void enable_bridge_irq(struct irq_data *d)
4093 + * ip27_mask_hub_irq - masks a HUB IRQ.
4094 + * @d: struct irq_data containing IRQ information.
4097 +ip27_mask_hub_irq(struct irq_data *d)
4101 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4103 - swlevel = find_level(&cpu, d->irq); /* Criminal offence */
4104 - intr_connect_level(cpu, swlevel);
4106 + raw_spin_lock(&cpud->hub->lock);
4107 + ip27_clear_hub_bit(cpud->hub->irq_to_bit[d->irq]);
4108 + raw_spin_unlock(&cpud->hub->lock);
4111 -static inline void disable_bridge_irq(struct irq_data *d)
4113 + * ip27_mask_and_ack_hub_irq - masks and acks a HUB IRQ.
4114 + * @d: struct irq_data containing IRQ information.
4117 +ip27_mask_and_ack_hub_irq(struct irq_data *d)
4121 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4122 + const s8 bit = cpud->hub->irq_to_bit[d->irq];
4124 + raw_spin_lock(&cpud->hub->lock);
4127 + ip27_clear_hub_bit(bit);
4129 - swlevel = find_level(&cpu, d->irq); /* Criminal offence */
4130 - intr_disconnect_level(cpu, swlevel);
4132 + LOCAL_HUB_CLR_INTR(bit);
4133 + raw_spin_unlock(&cpud->hub->lock);
4136 -static struct irq_chip bridge_irq_type = {
4138 - .irq_startup = startup_bridge_irq,
4139 - .irq_shutdown = shutdown_bridge_irq,
4140 - .irq_mask = disable_bridge_irq,
4141 - .irq_unmask = enable_bridge_irq,
4144 + * ip27_unmask_hub_irq - unmasks a HUB IRQ.
4145 + * @d: struct irq_data containing IRQ information.
4148 +ip27_unmask_hub_irq(struct irq_data *d)
4150 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4153 + raw_spin_lock(&cpud->hub->lock);
4154 + ip27_set_hub_bit(cpud->hub->irq_to_bit[d->irq]);
4155 + raw_spin_unlock(&cpud->hub->lock);
4158 -void register_bridge_irq(unsigned int irq)
4160 +static DEFINE_RAW_SPINLOCK(ip27_hub_affinity_lock);
4163 +ip27_set_hub_irq_affinity(struct irq_data *d, const struct cpumask *mask,
4166 - irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
4168 + unsigned long flags;
4169 + struct ip27_percpu_data *old_cpud, *new_cpud;
4171 + /* Get percpu data for the new CPU first. */
4172 + tmp = cpu_logical_map(cpumask_first_and(mask, cpu_online_mask));
4173 + new_cpud = &per_cpu(ip27_cpu, tmp);
4175 + /* Use the new CPU percpu access to fetch the old CPU. */
4176 + tmp = new_cpud->hub->irq_owner[d->irq];
4177 + old_cpud = &per_cpu(ip27_cpu, tmp);
4179 + /* Protect against other affinity changers and IMR manipulation */
4180 + raw_spin_lock_irqsave(&ip27_hub_affinity_lock, flags);
4182 + /* Mask the IRQ on the old CPU, if needed. */
4183 + int_on = !(test_bit(d->irq, old_cpud->irq_mask));
4185 + set_bit(d->irq, old_cpud->irq_mask);
4186 + ip27_update_hub_irq_mask(old_cpud);
4189 + /* Update the mask for the new CPU. */
4190 + new_cpud->hub->irq_owner[d->irq] = new_cpud->id;
4192 + clear_bit(d->irq, new_cpud->irq_mask);
4193 + ip27_update_hub_irq_mask(new_cpud);
4195 + raw_spin_unlock_irqrestore(&ip27_hub_affinity_lock, flags);
4202 + * struct ip27_hub_irq - HUB struct irq_chip ops.
4203 + * @irq_startup: startup function.
4204 + * @irq_shutdown: shutdown function.
4205 + * @irq_ack: ack function.
4206 + * @irq_mask: mask function.
4207 + * @irq_mask_ack: mask & ack function.
4208 + * @irq_unmask: unmask function.
4209 + * @irq_disable: disable (mask) function.
4210 + * @irq_enable: enable (unmask) function.
4212 +static struct irq_chip __read_mostly
4215 + .irq_startup = ip27_startup_hub_irq,
4216 + .irq_shutdown = ip27_shutdown_hub_irq,
4217 + .irq_ack = ip27_ack_hub_irq,
4218 + .irq_mask = ip27_mask_hub_irq,
4219 + .irq_mask_ack = ip27_mask_and_ack_hub_irq,
4220 + .irq_unmask = ip27_unmask_hub_irq,
4221 + .irq_disable = ip27_mask_hub_irq,
4222 + .irq_enable = ip27_unmask_hub_irq,
4224 + .irq_set_affinity = ip27_set_hub_irq_affinity,
4228 +/* ----------------------------------------------------------------------- */
4231 -int request_bridge_irq(struct bridge_controller *bc)
4232 +/* ----------------------------------------------------------------------- */
4235 + * ip27_request_irq - requests an irq number.
4237 + * Returns the allocated IRQ number assigned to a specific HUB interrupt bit.
4240 +ip27_request_irq(void)
4242 - int irq = allocate_irqno();
4245 + int irq_bit, irq_num;
4246 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4250 + /* Bail if ip27_alloc_irq_num() failed. */
4251 + irq_num = ip27_alloc_irq_num();
4256 - * "map" irq to a swlevel greater than 6 since the first 6 bits
4257 - * of INT_PEND0 are taken
4259 - cpu = bc->irq_cpu;
4260 - swlevel = alloc_level(cpu, irq);
4261 - if (unlikely(swlevel < 0)) {
4263 + /* Assign the IRQ to a free HUB interrupt bit. */
4264 + raw_spin_lock(&cpud->hub->lock);
4265 + irq_bit = ip27_earmark_irq_bit(cpud->hub, cpud->nasid, irq_num);
4266 + raw_spin_unlock(&cpud->hub->lock);
4270 + /* Assign the irq_chip handler. */
4271 + irq_set_chip_and_handler(irq_num, &ip27_hub_irq, handle_level_irq);
4273 /* Make sure it's not already pending when we connect it. */
4274 - nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
4275 - REMOTE_HUB_CLR_INTR(nasid, swlevel);
4276 + raw_spin_lock(&cpud->hub->lock);
4277 + REMOTE_HUB_CLR_INTR(cpud->cnodeid, irq_bit);
4278 + raw_spin_unlock(&cpud->hub->lock);
4283 +/* ----------------------------------------------------------------------- */
4285 - intr_connect_level(cpu, swlevel);
4287 - register_bridge_irq(irq);
4288 +/* ----------------------------------------------------------------------- */
4289 +/* Arch IRQ initialization - runs on CPU0 only. */
4293 + * arch_init_irq - arch initialization function.
4296 +arch_init_irq(void)
4299 + irq_set_chip_and_handler(CPU_RESCHED_A_IRQ, &ip27_hub_irq,
4300 + handle_percpu_irq);
4301 + irq_set_chip_and_handler(CPU_RESCHED_B_IRQ, &ip27_hub_irq,
4302 + handle_percpu_irq);
4303 + irq_set_chip_and_handler(CPU_CALL_A_IRQ, &ip27_hub_irq,
4304 + handle_percpu_irq);
4305 + irq_set_chip_and_handler(CPU_CALL_B_IRQ, &ip27_hub_irq,
4306 + handle_percpu_irq);
4310 +/* ----------------------------------------------------------------------- */
4311 diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
4312 index 23b4cd72de3e..f9ffb2ccb0bd 100644
4313 --- a/arch/mips/sgi-ip27/ip27-irq.c
4314 +++ b/arch/mips/sgi-ip27/ip27-irq.c
4319 -#include <linux/init.h>
4320 -#include <linux/irq.h>
4321 +#include <linux/bitops.h>
4322 #include <linux/errno.h>
4323 -#include <linux/signal.h>
4324 -#include <linux/sched.h>
4325 -#include <linux/types.h>
4326 #include <linux/interrupt.h>
4327 -#include <linux/ioport.h>
4328 -#include <linux/timex.h>
4329 +#include <linux/irq.h>
4330 #include <linux/smp.h>
4331 -#include <linux/random.h>
4332 -#include <linux/kernel.h>
4333 -#include <linux/kernel_stat.h>
4334 -#include <linux/delay.h>
4335 -#include <linux/bitops.h>
4336 +#include <linux/types.h>
4338 +#include <asm/barrier.h>
4339 #include <asm/bootinfo.h>
4341 #include <asm/mipsregs.h>
4343 -#include <asm/processor.h>
4344 #include <asm/sn/addrs.h>
4345 #include <asm/sn/agent.h>
4346 #include <asm/sn/arch.h>
4347 #include <asm/sn/hub.h>
4348 #include <asm/sn/intr.h>
4350 -/* XXX: Part of the IP27 "mega update" */
4351 #include <asm/mach-ip27/pcibr.h>
4352 -struct bridge_controller *irq_to_bridge[PCIBR_MAX_BUS_X_DEV];
4353 -u32 irq_to_slot[PCIBR_MAX_BUS_X_DEV];
4356 - * Linux has a controller-independent x86 interrupt architecture.
4357 - * every controller has a 'controller-template', that is used
4358 - * by the main code to do the right thing. Each driver-visible
4359 - * interrupt source is transparently wired to the appropriate
4360 - * controller. Thus drivers need not be aware of the
4361 - * interrupt-controller.
4363 - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
4364 - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
4365 - * (IO-APICs assumed to be messaging to Pentium local-APICs)
4367 - * the code is designed to be easily extended with new/different
4368 - * interrupt controllers, without having to do assembly magic.
4370 +struct bridge_controller *ip27_irq_to_bridge[PCIBR_MAX_BUS_X_DEV];
4371 +u32 ip27_irq_to_slot[PCIBR_MAX_BUS_X_DEV];
4373 -extern asmlinkage void ip27_irq(void);
4374 +/* Defined in ip27-init.c */
4375 +DECLARE_PER_CPU(struct ip27_percpu_data, ip27_cpu);
4378 - * Find first bit set
4379 +/* ----------------------------------------------------------------------- */
4380 +/* HUB Interrupt Handlers */
4383 + * ip27_do_hub_irq - main interrupt servicing routine for IP27.
4384 + * @cpu: u32 value of the cpu processing the interrupt.
4385 + * @pend_reg: u32 value of the PEND0/PEND1 register offset.
4386 + * @mask_reg: u32 value of the MASK0/MASK1 register offset for a cpu.
4388 -static int ms1bit(unsigned long x)
4389 +static noinline void
4390 +ip27_do_hub_irq(u32 pend_reg, u32 mask_reg)
4394 + hubreg_t pend, mask;
4395 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4397 - s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s;
4398 - s = 8; if (x >> 8 == 0) s = 0; b += s; x >>= s;
4399 - s = 4; if (x >> 4 == 0) s = 0; b += s; x >>= s;
4400 - s = 2; if (x >> 2 == 0) s = 0; b += s; x >>= s;
4401 - s = 1; if (x >> 1 == 0) s = 0; b += s;
4402 + pend = LOCAL_HUB_L(pend_reg);
4403 + mask = LOCAL_HUB_L(mask_reg);
4407 + if (unlikely(!pend)) {
4408 + spurious_interrupt();
4412 + /* Poll all IRQs in decreasing priority order */
4414 + irq_bit = (fls64(pend) - 1);
4415 + irq = cpud->hub->bit_to_irq[irq_bit];
4417 + pend &= ~BIT_ULL(irq_bit);
4418 + } while (likely(pend > 0));
4422 - * This code is unnecessarily complex, because we do
4423 - * intr enabling. Basically, once we grab the set of intrs we need
4424 - * to service, we must mask _all_ these interrupts; firstly, to make
4425 - * sure the same intr does not intr again, causing recursion that
4426 - * can lead to stack overflow. Secondly, we can not just mask the
4427 - * one intr we are do_IRQing, because the non-masked intrs in the
4428 - * first set might intr again, causing multiple servicings of the
4429 - * same intr. This effect is mostly seen for intercpu intrs.
4432 + * ip27_do_hub_pend0 - services an interrupt from PEND0.
4433 + * @cpu: u32 value of the cpu processing the interrupt.
4436 -static void ip27_do_irq_mask0(void)
4437 +static noinline void
4438 +ip27_do_hub_pend0(void)
4441 - hubreg_t pend0, mask0;
4442 - cpuid_t cpu = smp_processor_id();
4443 - int pi_int_mask0 =
4444 - (cputoslice(cpu) == 0) ? PI_INT_MASK0_A : PI_INT_MASK0_B;
4446 - /* copied from Irix intpend0() */
4447 - pend0 = LOCAL_HUB_L(PI_INT_PEND0);
4448 - mask0 = LOCAL_HUB_L(pi_int_mask0);
4450 - pend0 &= mask0; /* Pick intrs we should look at */
4453 + int pi_int_mask0 = (!this_cpu_read(ip27_cpu.slice) ?
4454 + PI_INT_MASK0_A : PI_INT_MASK0_B);
4456 - swlevel = ms1bit(pend0);
4458 - if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) {
4459 - LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
4461 - } else if (pend0 & (1UL << CPU_RESCHED_B_IRQ)) {
4462 - LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ);
4464 - } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) {
4465 - LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
4467 - generic_smp_call_function_interrupt();
4469 - } else if (pend0 & (1UL << CPU_CALL_B_IRQ)) {
4470 - LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
4472 - generic_smp_call_function_interrupt();
4477 - /* "map" swlevel to irq */
4478 - struct slice_data *si = cpu_data[cpu].data;
4480 - irq = si->level_to_irq[swlevel];
4484 - LOCAL_HUB_L(PI_INT_PEND0);
4485 + ip27_do_hub_irq(PI_INT_PEND0, pi_int_mask0);
4488 -static void ip27_do_irq_mask1(void)
4490 + * ip27_do_hub_pend1 - services an interrupt from PEND1.
4491 + * @cpu: u32 value of the cpu processing the interrupt.
4493 +static noinline void
4494 +ip27_do_hub_pend1(void)
4497 - hubreg_t pend1, mask1;
4498 - cpuid_t cpu = smp_processor_id();
4499 - int pi_int_mask1 = (cputoslice(cpu) == 0) ? PI_INT_MASK1_A : PI_INT_MASK1_B;
4500 - struct slice_data *si = cpu_data[cpu].data;
4502 - /* copied from Irix intpend0() */
4503 - pend1 = LOCAL_HUB_L(PI_INT_PEND1);
4504 - mask1 = LOCAL_HUB_L(pi_int_mask1);
4506 - pend1 &= mask1; /* Pick intrs we should look at */
4510 - swlevel = ms1bit(pend1);
4511 - /* "map" swlevel to irq */
4512 - irq = si->level_to_irq[swlevel];
4513 - LOCAL_HUB_CLR_INTR(swlevel);
4515 + int pi_int_mask1 = (!this_cpu_read(ip27_cpu.slice) ?
4516 + PI_INT_MASK1_A : PI_INT_MASK1_B);
4518 - LOCAL_HUB_L(PI_INT_PEND1);
4519 + ip27_do_hub_irq(PI_INT_PEND1, pi_int_mask1);
4522 -static void ip27_prof_timer(void)
4524 + * ip27_prof_timer - stub function to handle CAUSEF_IP5 interrupts.
4526 + * XXX: Currently calls panic() - can we do anything useful instead
4527 + * with this interrupt?
4530 +ip27_prof_timer(void)
4532 panic("CPU %d got a profiling interrupt", smp_processor_id());
4535 -static void ip27_hub_error(void)
4537 + * ip27_hub_error - stub function to handle HUB error interrupts.
4539 + * XXX: Currently calls panic() - need to rip HUB error reporting code from
4540 + * the old arch/ia64 code in 2.4.x and late 2.5.x kernels, in which SGI
4541 + * GPL'ed and imported a large amount of IP27 code straight from IRIX
4542 + * during their bringup of the Altix/IA64 platform by using existing
4546 +ip27_hub_error(void)
4548 - panic("CPU %d got a hub error interrupt", smp_processor_id());
4549 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4551 + panic("CPU %d got a hub error interrupt", cpud->id);
4554 -asmlinkage void plat_irq_dispatch(void)
4555 +/* ----------------------------------------------------------------------- */
4558 +/* ----------------------------------------------------------------------- */
4561 + * plat_irq_dispatch - platform IRQ dispatch.
4563 + * Interrupts are disabled.
4566 +plat_irq_dispatch(void)
4568 - unsigned long pending = read_c0_cause() & read_c0_status();
4569 - extern unsigned int rt_timer_irq;
4570 + u32 pending = (read_c0_cause() & read_c0_status() & ST0_IM);
4571 + extern int ip27_hub_rt_irq_num; /* Defined in ip27-timer.c. */
4573 + if (unlikely(!pending)) {
4574 + spurious_interrupt();
4578 + /* IP4, HUB Counter/Compare */
4579 if (pending & CAUSEF_IP4)
4580 - do_IRQ(rt_timer_irq);
4581 - else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */
4582 - ip27_do_irq_mask0();
4583 - else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */
4584 - ip27_do_irq_mask1();
4585 - else if (pending & CAUSEF_IP5)
4586 + do_IRQ(ip27_hub_rt_irq_num);
4587 + /* IP2, HUB INT_PEND0 (also IPI/SMP IRQs) */
4588 + else if (pending & CAUSEF_IP2)
4589 + ip27_do_hub_pend0();
4590 + /* IP3, HUB INT_PEND1 (Error IRQs) */
4591 + else if (pending & CAUSEF_IP3)
4592 + ip27_do_hub_pend1();
4593 + /* IP5, Profiling Clock? (SRB_PROFCLK) */
4594 + else if (unlikely(pending & CAUSEF_IP5))
4596 - else if (pending & CAUSEF_IP6)
4597 + /* IP6, HUB Errors */
4598 + else if (unlikely(pending & CAUSEF_IP6))
4602 -void __init arch_init_irq(void)
4603 +/* ----------------------------------------------------------------------- */
4606 +/* ----------------------------------------------------------------------- */
4609 + * __ip27_install_ipi - sets up interprocessor interrupts on each CPU.
4612 +__ip27_install_ipi(u32 irq)
4614 + struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4615 + struct hub_data *hub = cpud->hub;
4617 + smp_mb__before_atomic();
4618 + set_bit(irq, hub->irq_alloc_map);
4619 + set_bit(irq, cpud->irq_mask);
4620 + hub->irq_owner[irq] = cpud->id;
4621 + hub->irq_to_bit[irq] = irq; /* These two are 1-to-1 mapped. */
4622 + hub->bit_to_irq[irq] = irq;
4623 + smp_mb__after_atomic();
4624 + ip27_assign_irq_num(irq);
4625 + LOCAL_HUB_CLR_INTR(irq);
4628 -void install_ipi(void)
4630 + * ip27_install_ipi - extern func called from either ip27-init or ip27-smp.
4633 +ip27_install_ipi(void)
4635 - int slice = LOCAL_HUB_L(PI_CPU_NUM);
4636 - int cpu = smp_processor_id();
4637 - struct slice_data *si = cpu_data[cpu].data;
4638 - struct hub_data *hub = hub_data(cpu_to_node(cpu));
4639 - int resched, call;
4641 - resched = CPU_RESCHED_A_IRQ + slice;
4642 - __set_bit(resched, hub->irq_alloc_mask);
4643 - __set_bit(resched, si->irq_enable_mask);
4644 - LOCAL_HUB_CLR_INTR(resched);
4646 - call = CPU_CALL_A_IRQ + slice;
4647 - __set_bit(call, hub->irq_alloc_mask);
4648 - __set_bit(call, si->irq_enable_mask);
4649 - LOCAL_HUB_CLR_INTR(call);
4652 - LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]);
4653 - LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]);
4654 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
4655 + u8 slice = cpud->slice;
4657 + __ip27_install_ipi(CPU_RESCHED_A_IRQ + slice);
4658 + __ip27_install_ipi(CPU_CALL_A_IRQ + slice);
4661 + LOCAL_HUB_S(PI_INT_MASK0_A, cpud->irq_mask[0]);
4662 + LOCAL_HUB_S(PI_INT_MASK1_A, cpud->irq_mask[1]);
4664 - LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]);
4665 - LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]);
4666 + LOCAL_HUB_S(PI_INT_MASK0_B, cpud->irq_mask[0]);
4667 + LOCAL_HUB_S(PI_INT_MASK1_B, cpud->irq_mask[1]);
4671 +/* ----------------------------------------------------------------------- */
4672 diff --git a/arch/mips/sgi-ip27/ip27-irqno.c b/arch/mips/sgi-ip27/ip27-irqno.c
4673 index 957ab58e1c00..d7502d384ac6 100644
4674 --- a/arch/mips/sgi-ip27/ip27-irqno.c
4675 +++ b/arch/mips/sgi-ip27/ip27-irqno.c
4678 static DECLARE_BITMAP(irq_map, NR_IRQS);
4680 -int allocate_irqno(void)
4682 +/* ----------------------------------------------------------------------- */
4685 + * ip27_alloc_irq_num - finds a free irq in irq_map.
4687 + * Returns the first free IRQ number in irq_map. This IRQ will later
4688 + * be linked to a specific HUB interrupt bit.
4691 +ip27_alloc_irq_num(void)
4696 irq = find_first_zero_bit(irq_map, NR_IRQS);
4698 - if (irq >= NR_IRQS)
4699 + if (unlikely(irq < 0 || irq >= NR_IRQS))
4702 if (test_and_set_bit(irq, irq_map))
4703 @@ -27,22 +37,28 @@ int allocate_irqno(void)
4708 - * Allocate the 16 legacy interrupts for i8259 devices. This happens early
4709 - * in the kernel initialization so treating allocation failure as BUG() is
4712 + * ip27_assign_irq_num - assign an irq in irq_map.
4713 + * @irq: unsigned int of irq to free.
4715 -void __init alloc_legacy_irqno(void)
4717 +ip27_assign_irq_num(int irq)
4721 - for (i = 0; i <= 16; i++)
4722 - BUG_ON(test_and_set_bit(i, irq_map));
4723 + smp_mb__before_atomic();
4724 + set_bit(irq, irq_map);
4725 + smp_mb__after_atomic();
4728 -void free_irqno(unsigned int irq)
4730 + * ip27_free_irq_num - free an irq in irq_map and make it available again.
4731 + * @irq: unsigned int of irq to free.
4734 +ip27_free_irq_num(int irq)
4736 smp_mb__before_atomic();
4737 clear_bit(irq, irq_map);
4738 smp_mb__after_atomic();
4741 +/* ----------------------------------------------------------------------- */
4742 diff --git a/arch/mips/sgi-ip27/ip27-klconfig.c b/arch/mips/sgi-ip27/ip27-klconfig.c
4743 index 41171ff0c75e..a4e3f2076bb9 100644
4744 --- a/arch/mips/sgi-ip27/ip27-klconfig.c
4745 +++ b/arch/mips/sgi-ip27/ip27-klconfig.c
4747 #include <asm/sn/arch.h>
4748 #include <asm/sn/gda.h>
4750 -klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
4752 + * kl_find_component - navigate the available components on an lboard/rboard.
4757 + * Returns the next component from the KLCONFIG structure on SGI SN systems.
4760 +kl_find_component(struct klc_lboard *brd, struct klc_info *kli, u8 struct_type)
4764 - if (kli == (klinfo_t *)NULL) {
4765 + if (kli == KLCF_CAST_INFO(NULL)) {
4768 for (j = 0; j < KLCF_NUM_COMPS(brd); j++)
4769 @@ -27,8 +36,8 @@ klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type
4772 if (index == KLCF_NUM_COMPS(brd)) {
4773 - printk("find_component: Bad pointer: 0x%p\n", kli);
4774 - return (klinfo_t *)NULL;
4775 + pr_err("KLCONFIG: Bad pointer: 0x%p\n", kli);
4776 + return KLCF_CAST_INFO(NULL);
4778 index++; /* next component */
4780 @@ -40,96 +49,101 @@ klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type
4783 /* Didn't find it. */
4784 - return (klinfo_t *)NULL;
4785 + return KLCF_CAST_INFO(NULL);
4788 -klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
4790 +kl_find_1st_component(struct klc_lboard *brd, u8 struct_type)
4792 - return find_component(brd, (klinfo_t *)NULL, struct_type);
4793 + return kl_find_component(brd, KLCF_CAST_INFO(NULL), struct_type);
4796 -lboard_t *find_lboard(lboard_t *start, unsigned char brd_type)
4797 +struct klc_lboard *
4798 +kl_find_lboard(struct klc_lboard *start, u8 brd_type)
4800 /* Search all boards stored on this node. */
4802 - if (start->brd_type == brd_type)
4803 + if (start->type == brd_type)
4805 start = KLCF_NEXT(start);
4807 /* Didn't find it. */
4808 - return (lboard_t *)NULL;
4809 + return KLCF_CAST_LBOARD(NULL);
4812 -lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_type)
4813 +struct klc_lboard *
4814 +kl_find_lboard_class(struct klc_lboard *start, u8 brd_type)
4816 /* Search all boards stored on this node. */
4818 - if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
4819 + if (KLCLASS(start->type) == KLCLASS(brd_type))
4821 start = KLCF_NEXT(start);
4824 /* Didn't find it. */
4825 - return (lboard_t *)NULL;
4828 -cnodeid_t get_cpu_cnode(cpuid_t cpu)
4830 - return CPUID_TO_COMPACT_NODEID(cpu);
4831 + return KLCF_CAST_LBOARD(NULL);
4834 -klcpu_t *nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
4836 +nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
4840 + struct klc_lboard *brd;
4841 + struct klc_cpu *acpu;
4843 - if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
4844 - return (klcpu_t *)NULL;
4845 + if (!(brd = kl_find_lboard(KLCF_LBOARD_INFO(nasid), KLTYPE_IP27)))
4846 + return KLCF_CAST_CPU(NULL);
4848 - if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
4849 - return (klcpu_t *)NULL;
4850 + if (!(acpu = KLCF_CAST_CPU(kl_find_1st_component(brd, KLSTRUCT_CPU))))
4851 + return KLCF_CAST_CPU(NULL);
4854 - if ((acpu->cpu_info.physid) == slice)
4855 + if ((acpu->kl_info.physid) == slice)
4857 - } while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
4859 - return (klcpu_t *)NULL;
4860 + } while ((acpu = KLCF_CAST_CPU(kl_find_component(brd,
4861 + KLCF_CAST_INFO(acpu),
4863 + return KLCF_CAST_CPU(NULL);
4866 -klcpu_t *sn_get_cpuinfo(cpuid_t cpu)
4867 +static struct klc_cpu * __init
4868 +sn_get_cpuinfo(cpuid_t cpu)
4873 + struct klc_cpu *acpu;
4877 - if (!(cpu < MAXCPUS)) {
4878 - printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu);
4880 + if (cpu > MAXCPUS) {
4881 + pr_err("KLCONFIG: illegal cpuid 0x%lx\n", cpu);
4885 - cnode = get_cpu_cnode(cpu);
4886 + cnode = sn_cpuid_to_cnodeid[cpu];
4887 if (cnode == INVALID_CNODEID)
4891 if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID)
4895 for (slice = 0; slice < CPUS_PER_NODE; slice++) {
4896 acpu = nasid_slice_to_cpuinfo(nasid, slice);
4897 - if (acpu && acpu->cpu_info.virtid == cpu)
4898 + if (acpu && acpu->kl_info.virtid == cpu)
4904 + return KLCF_CAST_CPU(NULL);
4907 -int get_cpu_slice(cpuid_t cpu)
4909 +get_cpu_slice(cpuid_t cpu)
4912 + struct klc_cpu *acpu;
4914 if ((acpu = sn_get_cpuinfo(cpu)) == NULL)
4916 - return acpu->cpu_info.physid;
4918 + return acpu->kl_info.physid;
4920 diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c
4921 index a4f01328de62..15989d4e3258 100644
4922 --- a/arch/mips/sgi-ip27/ip27-klnuma.c
4923 +++ b/arch/mips/sgi-ip27/ip27-klnuma.c
4924 @@ -27,7 +27,8 @@ static cpumask_t ktext_repmask;
4925 * kernel. For example, we should never put a copy on a headless node,
4926 * and we should respect the topology of the machine.
4928 -void __init setup_replication_mask(void)
4930 +setup_replication_mask(void)
4932 /* Set only the master cnode's bit. The master cnode is always 0. */
4933 cpumask_clear(&ktext_repmask);
4934 @@ -53,7 +54,8 @@ void __init setup_replication_mask(void)
4938 -static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
4940 +set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
4944 @@ -70,7 +72,8 @@ static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
4947 /* XXX - When the BTE works, we should use it instead of this. */
4948 -static __init void copy_kernel(nasid_t dest_nasid)
4950 +copy_kernel(nasid_t dest_nasid)
4952 unsigned long dest_kern_start, source_start, source_end, kern_size;
4954 @@ -83,7 +86,8 @@ static __init void copy_kernel(nasid_t dest_nasid)
4955 memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
4958 -void __init replicate_kernel_text(void)
4960 +replicate_kernel_text(void)
4963 nasid_t client_nasid;
4964 @@ -97,7 +101,7 @@ void __init replicate_kernel_text(void)
4965 for_each_online_node(cnode) {
4968 - client_nasid = COMPACT_TO_NASID_NODEID(cnode);
4969 + client_nasid = sn_cnodeid_to_nasid[cnode];
4971 /* Check if this node should get a copy of the kernel */
4972 if (cpumask_test_cpu(cnode, &ktext_repmask)) {
4973 @@ -115,11 +119,12 @@ void __init replicate_kernel_text(void)
4974 * data structures on the first couple of pages of the first slot of each
4975 * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
4977 -unsigned long node_getfirstfree(cnodeid_t cnode)
4979 +node_get_first_free(cnodeid_t cnode)
4981 - unsigned long loadbase = REP_BASE;
4982 - nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
4983 unsigned long offset;
4984 + unsigned long loadbase = REP_BASE;
4985 + nasid_t nasid = sn_cnodeid_to_nasid[cnode];
4987 #ifdef CONFIG_MAPPED_KERNEL
4988 loadbase += 16777216;
4989 diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
4990 index 59133d0abc83..ea9dadd4a35b 100644
4991 --- a/arch/mips/sgi-ip27/ip27-memory.c
4992 +++ b/arch/mips/sgi-ip27/ip27-memory.c
4994 * Copyright (C) 2000 by Silicon Graphics, Inc.
4995 * Copyright (C) 2004 by Christoph Hellwig
4997 - * On SGI IP27 the ARC memory configuration data is completely bogus but
4998 - * alternate easier to use mechanisms are available.
4999 + * On SGI IP27, the ARC memory configuration data is completely bogus. But
5000 + * KLCONFIG is an alternate and easier to use mechanism.
5002 #include <linux/init.h>
5003 #include <linux/kernel.h>
5004 @@ -31,135 +31,153 @@
5005 #include <asm/sn/sn_private.h>
5008 -#define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT)
5009 -#define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT)
5010 +#define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT)
5011 +#define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT)
5013 struct node_data *__node_data[MAX_COMPACT_NODES];
5015 EXPORT_SYMBOL(__node_data);
5017 -static int fine_mode;
5019 -static int is_fine_dirmode(void)
5020 +static int fine_mode __initdata;
5023 +ip27_mem_is_fine_dir_mode(void)
5025 - return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE;
5026 + return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
5027 + >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE;
5030 -static hubreg_t get_region(cnodeid_t cnode)
5031 +static hubreg_t __init
5032 +ip27_mem_get_region(cnodeid_t cnode)
5035 - return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
5036 + return (sn_cnodeid_to_nasid[cnode]
5037 + >> NASID_TO_FINEREG_SHFT);
5039 - return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
5040 + return (sn_cnodeid_to_nasid[cnode]
5041 + >> NASID_TO_COARSEREG_SHFT);
5044 -static hubreg_t region_mask;
5045 +static hubreg_t region_mask __initdata;
5047 -static void gen_region_mask(hubreg_t *region_mask)
5049 +ip27_mem_gen_region_mask(hubreg_t *region_mask)
5054 for_each_online_node(cnode) {
5055 - (*region_mask) |= 1ULL << get_region(cnode);
5056 + (*region_mask) |= BIT_ULL(ip27_mem_get_region(cnode));
5060 -#define rou_rflag rou_flags
5062 -static int router_distance;
5063 +/* XXX: Move to new source file 'ip27-topology.c' */
5064 +static int router_distance __initdata;
5066 -static void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
5067 +/* XXX: Move to new source file 'ip27-topology.c' */
5069 +ip27_topo_router_recurse(struct klc_router *router_a, struct klc_router *router_b,
5076 + struct klc_router *router;
5077 + struct klc_lboard *brd;
5078 + struct klc_port *rport;
5080 - if (router_a->rou_rflag == 1)
5081 + if (router_a->flags == 1)
5084 if (depth >= router_distance)
5087 - router_a->rou_rflag = 1;
5088 + router_a->flags = 1;
5090 for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
5091 - if (router_a->rou_port[port].port_nasid == INVALID_NASID)
5092 + rport = &router_a->port[port];
5093 + if (rport->nasid == INVALID_NASID)
5096 - brd = (lboard_t *)NODE_OFFSET_TO_K0(
5097 - router_a->rou_port[port].port_nasid,
5098 - router_a->rou_port[port].port_offset);
5099 + brd = KLCF_LBOARD_K0(rport->nasid, rport->offset);
5101 - if (brd->brd_type == KLTYPE_ROUTER) {
5102 - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
5103 - if (router == router_b) {
5104 - if (depth < router_distance)
5105 - router_distance = depth;
5108 - router_recurse(router, router_b, depth + 1);
5109 + if (KLCF_TYPE(brd) != KLTYPE_ROUTER)
5112 + router = KLCF_ROUTER_K0(brd, brd->components[0]);
5113 + if (router == router_b) {
5114 + if (depth < router_distance)
5115 + router_distance = depth;
5117 + ip27_topo_router_recurse(router, router_b, depth + 1);
5121 - router_a->rou_rflag = 0;
5122 + router_a->flags = 0;
5125 +/* XXX: Move to new source file 'ip27-topology.c' */
5126 unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
5127 EXPORT_SYMBOL(__node_distances);
5129 -static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
5130 +/* XXX: Move to new source file 'ip27-topology.c' */
5132 +ip27_topo_calc_node_distance(nasid_t nasid_a, nasid_t nasid_b)
5134 - klrou_t *router, *router_a = NULL, *router_b = NULL;
5135 - lboard_t *brd, *dest_brd;
5140 + struct klc_port *rport;
5141 + struct klc_lboard *brd, *dest_brd;
5142 + struct klc_router *router, *router_a = NULL, *router_b = NULL;
5144 /* Figure out which routers nodes in question are connected to */
5145 for_each_online_node(cnode) {
5146 - nasid = COMPACT_TO_NASID_NODEID(cnode);
5147 + nasid = sn_cnodeid_to_nasid[cnode];
5149 if (nasid == -1) continue;
5151 - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
5153 + brd = kl_find_lboard_class(KLCF_LBOARD_INFO(nasid),
5160 - if (brd->brd_flags & DUPLICATE_BOARD)
5161 + if (KL_CONFIG_DUPLICATE_BOARD(brd))
5164 - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
5165 - router->rou_rflag = 0;
5166 + router = KLCF_ROUTER_K0(brd, brd->components[0]);
5167 + router->flags = 0;
5169 for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
5170 - if (router->rou_port[port].port_nasid == INVALID_NASID)
5171 + rport = &router->port[port];
5172 + if (rport->nasid == INVALID_NASID)
5175 + dest_brd = KLCF_LBOARD_K0(rport->nasid,
5178 + if (KLCF_TYPE(dest_brd) != KLTYPE_IP27)
5181 - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
5182 - router->rou_port[port].port_nasid,
5183 - router->rou_port[port].port_offset);
5184 + if (KLCF_BOARD_NASID(dest_brd) == nasid_a)
5185 + router_a = router;
5187 - if (dest_brd->brd_type == KLTYPE_IP27) {
5188 - if (dest_brd->brd_nasid == nasid_a)
5189 - router_a = router;
5190 - if (dest_brd->brd_nasid == nasid_b)
5191 - router_b = router;
5193 + if (KLCF_BOARD_NASID(dest_brd) == nasid_b)
5194 + router_b = router;
5197 - } while ((brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)));
5198 + } while ((brd = kl_find_lboard_class(KLCF_NEXT(brd),
5202 if (router_a == NULL) {
5203 - printk("node_distance: router_a NULL\n");
5204 + pr_debug("IP27: Router A is NULL\n");
5208 if (router_b == NULL) {
5209 - printk("node_distance: router_b NULL\n");
5210 + pr_debug("IP27: Router B is NULL\n");
5214 @@ -170,14 +188,16 @@ static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
5217 router_distance = 100;
5218 - router_recurse(router_a, router_b, 2);
5219 + ip27_topo_router_recurse(router_a, router_b, 2);
5221 return router_distance;
5224 -static void __init init_topology_matrix(void)
5225 +/* XXX: Move to new source file 'ip27-topology.c' */
5227 +ip27_topo_init_matrix(void)
5229 - nasid_t nasid, nasid2;
5230 + nasid_t nasid1, nasid2;
5233 for (row = 0; row < MAX_COMPACT_NODES; row++)
5234 @@ -185,137 +205,141 @@ static void __init init_topology_matrix(void)
5235 __node_distances[row][col] = -1;
5237 for_each_online_node(row) {
5238 - nasid = COMPACT_TO_NASID_NODEID(row);
5239 + nasid1 = sn_cnodeid_to_nasid[row];
5240 for_each_online_node(col) {
5241 - nasid2 = COMPACT_TO_NASID_NODEID(col);
5242 + nasid2 = sn_cnodeid_to_nasid[col];
5243 __node_distances[row][col] =
5244 - compute_node_distance(nasid, nasid2);
5245 + ip27_topo_calc_node_distance(nasid1, nasid2);
5250 -static void __init dump_topology(void)
5251 +/* XXX: Move to new source file 'ip27-topology.c' */
5253 +ip27_topo_dump_matrix(void)
5255 + int port, router_num = 0;
5258 - lboard_t *brd, *dest_brd;
5260 - int router_num = 0;
5262 - cnodeid_t row, col;
5263 + cnodeid_t cnode, row, col;
5264 + struct klc_router *router;
5265 + struct klc_port *rport;
5266 + struct klc_lboard *brd, *dest_brd;
5268 - printk("************** Topology ********************\n");
5269 + pr_info("************** Topology ********************\n");
5273 for_each_online_node(col)
5274 - printk("%02d ", col);
5276 + pr_cont("%02d ", col);
5278 for_each_online_node(row) {
5279 - printk("%02d ", row);
5280 + pr_cont("%02d ", row);
5281 for_each_online_node(col)
5282 - printk("%2d ", node_distance(row, col));
5284 + pr_cont("%2d ", node_distance(row, col));
5288 for_each_online_node(cnode) {
5289 - nasid = COMPACT_TO_NASID_NODEID(cnode);
5290 + nasid = sn_cnodeid_to_nasid[cnode];
5292 if (nasid == -1) continue;
5294 - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
5296 + brd = kl_find_lboard_class(KLCF_LBOARD_INFO(nasid),
5303 - if (brd->brd_flags & DUPLICATE_BOARD)
5304 + if (KL_CONFIG_DUPLICATE_BOARD(brd))
5306 - printk("Router %d:", router_num);
5307 + pr_cont("Router %d:", router_num);
5310 - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
5311 + router = KLCF_ROUTER_K0(brd, brd->components[0]);
5313 for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
5314 - if (router->rou_port[port].port_nasid == INVALID_NASID)
5315 + rport = &router->port[port];
5316 + if (rport->nasid == INVALID_NASID)
5319 - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
5320 - router->rou_port[port].port_nasid,
5321 - router->rou_port[port].port_offset);
5322 + dest_brd = KLCF_LBOARD_K0(rport->nasid,
5325 - if (dest_brd->brd_type == KLTYPE_IP27)
5326 - printk(" %d", dest_brd->brd_nasid);
5327 - if (dest_brd->brd_type == KLTYPE_ROUTER)
5329 + if (KLCF_TYPE(dest_brd) == KLTYPE_IP27)
5330 + pr_cont(" %d", KLCF_BOARD_NASID(dest_brd));
5332 + if (KLCF_TYPE(dest_brd) == KLTYPE_ROUTER)
5338 - } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
5339 + } while ((brd = kl_find_lboard_class(KLCF_NEXT(brd),
5344 -static unsigned long __init slot_getbasepfn(cnodeid_t cnode, int slot)
5346 +ip27_mem_slot_getbasepfn(cnodeid_t cnode, int slot)
5348 - nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
5349 + nasid_t nasid = sn_cnodeid_to_nasid[cnode];
5351 - return ((unsigned long)nasid << PFN_NASIDSHFT) | (slot << SLOT_PFNSHIFT);
5352 + return (((u64)nasid << PFN_NASIDSHFT) |
5353 + (slot << SLOT_PFNSHIFT));
5356 -static unsigned long __init slot_psize_compute(cnodeid_t node, int slot)
5358 +ip27_mem_slot_calc_psize(cnodeid_t cnode, int slot)
5363 - klmembnk_t *banks;
5364 - unsigned long size;
5365 + struct klc_lboard *brd;
5366 + struct klc_membank *banks;
5368 - nasid = COMPACT_TO_NASID_NODEID(node);
5369 + nasid = sn_cnodeid_to_nasid[cnode];
5370 /* Find the node board */
5371 - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
5372 + brd = kl_find_lboard(KLCF_LBOARD_INFO(nasid), KLTYPE_IP27);
5376 /* Get the memory bank structure */
5377 - banks = (klmembnk_t *) find_first_component(brd, KLSTRUCT_MEMBNK);
5378 + banks = KLCF_CAST_MEMBANK(kl_find_1st_component(brd, KLSTRUCT_MEMBNK));
5382 /* Size in _Megabytes_ */
5383 - size = (unsigned long)banks->membnk_bnksz[slot/4];
5385 - /* hack for 128 dimm banks */
5386 - if (size <= 128) {
5387 - if (slot % 4 == 0) {
5388 - size <<= 20; /* size in bytes */
5389 - return size >> PAGE_SHIFT;
5391 + size = (u64)KLCF_MEMBANK_SIZE(banks, (slot / 4));
5393 + /* XXX: Hack for 128MB dimm banks */
5395 + if ((slot % 4) == 0)
5396 + return PFN_DOWN((size << 20));
5402 - return size >> PAGE_SHIFT;
5405 + return PFN_DOWN(((size / 4) << 20));
5408 -static void __init mlreset(void)
5409 +/* XXX: Move to file 'ip27-init.c' */
5411 +ip27_machine_init(void)
5415 - master_nasid = get_nasid();
5416 - fine_mode = is_fine_dirmode();
5417 + master_nasid = ip27_get_nasid();
5418 + fine_mode = ip27_mem_is_fine_dir_mode();
5421 * Probe for all CPUs - this creates the cpumask and sets up the
5422 * mapping tables. We need to do this as early as possible.
5426 + ip27_smp_cpu_node_probe();
5429 - init_topology_matrix();
5431 + ip27_topo_init_matrix();
5432 + ip27_topo_dump_matrix();
5434 - gen_region_mask(®ion_mask);
5435 + ip27_mem_gen_region_mask(®ion_mask);
5437 setup_replication_mask();
5439 @@ -325,7 +349,7 @@ static void __init mlreset(void)
5440 for_each_online_node(i) {
5443 - nasid = COMPACT_TO_NASID_NODEID(i);
5444 + nasid = sn_cnodeid_to_nasid[i];
5447 * Always have node 0 in the region mask, otherwise
5448 @@ -351,78 +375,84 @@ static void __init mlreset(void)
5452 -static void __init szmem(void)
5454 +ip27_mem_init(void)
5456 - unsigned long slot_psize, slot0sz = 0, nodebytes; /* Hack to detect problem configs */
5459 + /* Hack to detect problem configs */
5461 + u64 slot_psize, slot0_size = 0, slot_basepfn;
5462 + u64 node_bytes, node_page;
5465 - for_each_online_node(node) {
5467 + for_each_online_node(cnode) {
5469 for (slot = 0; slot < MAX_MEM_SLOTS; slot++) {
5470 - slot_psize = slot_psize_compute(node, slot);
5471 + slot_psize = ip27_mem_slot_calc_psize(cnode, slot);
5473 - slot0sz = slot_psize;
5474 + slot0_size = (PFN_PHYS(slot_psize));
5476 - * We need to refine the hack when we have replicated
5478 + * XXX: We need to refine this hack when we have
5479 + * replicated kernel text.
5481 - nodebytes += (1LL << SLOT_SHIFT);
5482 + node_bytes += BIT_ULL(SLOT_SHIFT);
5487 - if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
5488 - (slot0sz << PAGE_SHIFT)) {
5489 - printk("Ignoring slot %d onwards on node %d\n",
5491 + node_page = PFN_DOWN(node_bytes);
5492 + if ((node_page * sizeof(struct page)) > slot0_size) {
5493 + pr_notice("IP27: Ignoring memory slot %d and "
5494 + "up on cnode %d\n", slot, cnode);
5495 slot = MAX_MEM_SLOTS;
5498 - memblock_add_node(PFN_PHYS(slot_getbasepfn(node, slot)),
5499 - PFN_PHYS(slot_psize), node);
5500 + slot_basepfn = ip27_mem_slot_getbasepfn(cnode, slot);
5501 + memblock_add_node(PFN_PHYS(slot_basepfn),
5502 + PFN_PHYS(slot_psize), cnode);
5507 -static void __init node_mem_init(cnodeid_t node)
5509 +ip27_mem_node_init(cnodeid_t cnode)
5511 - unsigned long slot_firstpfn = slot_getbasepfn(node, 0);
5512 - unsigned long slot_freepfn = node_getfirstfree(node);
5513 + unsigned long slot_firstpfn = ip27_mem_slot_getbasepfn(cnode, 0);
5514 + unsigned long slot_freepfn = node_get_first_free(cnode);
5515 unsigned long bootmap_size;
5516 unsigned long start_pfn, end_pfn;
5518 - get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
5519 + get_pfn_range_for_nid(cnode, &start_pfn, &end_pfn);
5522 - * Allocate the node data structures on the node first.
5523 + * Allocate the node data structures on the cnode first.
5525 - __node_data[node] = __va(slot_freepfn << PAGE_SHIFT);
5526 - memset(__node_data[node], 0, PAGE_SIZE);
5527 + __node_data[cnode] = __va(PFN_PHYS(slot_freepfn));
5528 + memset(__node_data[cnode], 0, PAGE_SIZE);
5530 - NODE_DATA(node)->bdata = &bootmem_node_data[node];
5531 - NODE_DATA(node)->node_start_pfn = start_pfn;
5532 - NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
5533 + NODE_DATA(cnode)->bdata = &bootmem_node_data[cnode];
5534 + NODE_DATA(cnode)->node_start_pfn = start_pfn;
5535 + NODE_DATA(cnode)->node_spanned_pages = end_pfn - start_pfn;
5537 - cpumask_clear(&hub_data(node)->h_cpus);
5538 + cpumask_clear(&hub_data(cnode)->h_cpus);
5540 slot_freepfn += PFN_UP(sizeof(struct pglist_data) +
5541 sizeof(struct hub_data));
5543 - bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn,
5544 - start_pfn, end_pfn);
5545 - free_bootmem_with_active_regions(node, end_pfn);
5546 - reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
5547 - ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size,
5548 + bootmap_size = init_bootmem_node(NODE_DATA(cnode), slot_freepfn,
5549 + start_pfn, end_pfn);
5550 + free_bootmem_with_active_regions(cnode, end_pfn);
5551 + reserve_bootmem_node(NODE_DATA(cnode), PFN_PHYS(slot_firstpfn),
5552 + (PFN_PHYS(slot_freepfn - slot_firstpfn) + bootmap_size),
5554 - sparse_memory_present_with_active_regions(node);
5555 + sparse_memory_present_with_active_regions(cnode);
5559 - * A node with nothing. We use it to avoid any special casing in
5561 + * A node with nothing. We use it to avoid any special casing in
5562 + * cpumask_of_node.
5564 -static struct node_data null_node = {
5565 +static struct node_data
5566 +ip27_mem_null_node = {
5568 .h_cpus = CPU_MASK_NONE
5570 @@ -430,33 +460,36 @@ static struct node_data null_node = {
5573 * Currently, the intranode memory hole support assumes that each slot
5574 - * contains at least 32 MBytes of memory. We assume all bootmem data
5575 - * fits on the first slot.
5576 + * contains at least 32MB of memory. We assume all bootmem data fits
5577 + * on the first slot.
5579 -void __init prom_meminit(void)
5588 + ip27_machine_init();
5591 - for (node = 0; node < MAX_COMPACT_NODES; node++) {
5592 - if (node_online(node)) {
5593 - node_mem_init(node);
5594 + for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode++) {
5595 + if (node_online(cnode)) {
5596 + ip27_mem_node_init(cnode);
5599 - __node_data[node] = &null_node;
5600 + __node_data[cnode] = &ip27_mem_null_node;
5604 -void __init prom_free_prom_memory(void)
5606 +prom_free_prom_memory(void)
5608 /* We got nothing to free here ... */
5611 extern void setup_zero_pages(void);
5613 -void __init paging_init(void)
5617 unsigned long zones_size[MAX_NR_ZONES] = {0, };
5619 @@ -475,9 +508,10 @@ void __init paging_init(void)
5620 free_area_init_nodes(zones_size);
5623 -void __init mem_init(void)
5627 - high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
5628 + high_memory = (void *) __va(PFN_PHYS(get_num_physpages()));
5630 setup_zero_pages(); /* This comes from node 0 */
5631 mem_init_print_info(NULL);
5632 diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
5633 index 8ac2bfa35fb6..c4aa0731920b 100644
5634 --- a/arch/mips/sgi-ip27/ip27-nmi.c
5635 +++ b/arch/mips/sgi-ip27/ip27-nmi.c
5637 -// SPDX-License-Identifier: GPL-2.0
5638 +/* SPDX-License-Identifier: GPL-2.0 */
5640 #include <linux/kernel.h>
5641 #include <linux/mmzone.h>
5642 #include <linux/nodemask.h>
5643 #include <linux/spinlock.h>
5644 #include <linux/smp.h>
5645 #include <linux/atomic.h>
5646 -#include <asm/sn/types.h>
5648 #include <asm/sn/addrs.h>
5649 -#include <asm/sn/nmi.h>
5650 #include <asm/sn/arch.h>
5651 +#include <asm/sn/gda.h>
5652 +#include <asm/sn/hub.h>
5653 +#include <asm/sn/intr.h>
5654 +#include <asm/sn/nmi.h>
5655 +#include <asm/sn/sn_private.h>
5656 +#include <asm/sn/types.h>
5658 +#include <asm/sn/sn0/addrs.h>
5659 #include <asm/sn/sn0/hub.h>
5660 +#include <asm/sn/sn0/hubni.h>
5661 +#include <asm/sn/sn0/hubio.h>
5662 +#include <asm/sn/sn0/ip27.h>
5665 #define NODE_NUM_CPUS(n) CNODE_NUM_CPUS(n)
5666 @@ -26,18 +37,20 @@ static arch_spinlock_t nmi_lock = __ARCH_SPIN_LOCK_UNLOCKED;
5668 * Let's see what else we need to do here. Set up sp, gp?
5670 -void nmi_dump(void)
5674 void cont_nmi_dump(void);
5679 -void install_cpu_nmi_handler(int slice)
5681 +ip27_install_cpu_nmi_handler(int slice)
5685 - nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);
5686 + nmi_addr = (nmi_t *)NMI_ADDR(ip27_get_nasid(), slice);
5687 if (nmi_addr->call_addr)
5689 nmi_addr->magic = NMI_MAGIC;
5690 @@ -52,90 +65,94 @@ void install_cpu_nmi_handler(int slice)
5691 * into the eframe format for the node under consideration.
5694 -void nmi_cpu_eframe_save(nasid_t nasid, int slice)
5696 +nmi_cpu_eframe_save(nasid_t nasid, int slice)
5699 struct reg_struct *nr;
5702 /* Get the pointer to the current cpu's register set. */
5703 nr = (struct reg_struct *)
5704 (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
5705 slice * IP27_NMI_KREGS_CPU_SIZE);
5707 - printk("NMI nasid %d: slice %d\n", nasid, slice);
5708 + pr_crit("NMI nasid %d: slice %d\n", nasid, slice);
5711 * Saved main processor registers
5713 for (i = 0; i < 32; ) {
5715 - printk("$%2d :", i);
5716 - printk(" %016lx", nr->gpr[i]);
5717 + pr_cont("$%2d :", i);
5718 + pr_cont(" %016lx", nr->gpr[i]);
5726 - printk("Hi : (value lost)\n");
5727 - printk("Lo : (value lost)\n");
5728 + pr_cont("Hi : (value lost)\n");
5729 + pr_cont("Lo : (value lost)\n");
5732 * Saved cp0 registers
5734 - printk("epc : %016lx %pS\n", nr->epc, (void *) nr->epc);
5735 - printk("%s\n", print_tainted());
5736 - printk("ErrEPC: %016lx %pS\n", nr->error_epc, (void *) nr->error_epc);
5737 - printk("ra : %016lx %pS\n", nr->gpr[31], (void *) nr->gpr[31]);
5738 - printk("Status: %08lx ", nr->sr);
5739 + pr_cont("epc : %016lx %pS\n", nr->epc, (void *) nr->epc);
5740 + pr_cont("%s\n", print_tainted());
5741 + pr_cont("ErrEPC: %016lx %pS\n", nr->error_epc, (void *) nr->error_epc);
5742 + pr_cont("ra : %016lx %pS\n", nr->gpr[31], (void *) nr->gpr[31]);
5743 + pr_cont("Status: %08lx ", nr->sr);
5745 if (nr->sr & ST0_KX)
5748 if (nr->sr & ST0_SX)
5751 if (nr->sr & ST0_UX)
5755 switch (nr->sr & ST0_KSU) {
5760 case KSU_SUPERVISOR:
5761 - printk("SUPERVISOR ");
5762 + pr_cont("SUPERVISOR ");
5765 - printk("KERNEL ");
5766 + pr_cont("KERNEL ");
5769 - printk("BAD_MODE ");
5770 + pr_cont("BAD_MODE ");
5774 if (nr->sr & ST0_ERL)
5777 if (nr->sr & ST0_EXL)
5780 if (nr->sr & ST0_IE)
5786 - printk("Cause : %08lx\n", nr->cause);
5787 - printk("PrId : %08x\n", read_c0_prid());
5788 - printk("BadVA : %016lx\n", nr->badva);
5789 - printk("CErr : %016lx\n", nr->cache_err);
5790 - printk("NMI_SR: %016lx\n", nr->nmi_sr);
5791 + pr_cont("Cause : %08lx\n", nr->cause);
5792 + pr_cont("PrId : %08x\n", read_c0_prid());
5793 + pr_cont("BadVA : %016lx\n", nr->badva);
5794 + pr_cont("CErr : %016lx\n", nr->cache_err);
5795 + pr_cont("NMI_SR: %016lx\n", nr->nmi_sr);
5801 -void nmi_dump_hub_irq(nasid_t nasid, int slice)
5803 +nmi_dump_hub_irq(nasid_t nasid, int slice)
5805 hubreg_t mask0, mask1, pend0, pend1;
5807 - if (slice == 0) { /* Slice A */
5810 mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A);
5811 mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_A);
5812 - } else { /* Slice B */
5815 mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_B);
5816 mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_B);
5818 @@ -143,16 +160,18 @@ void nmi_dump_hub_irq(nasid_t nasid, int slice)
5819 pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);
5820 pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);
5822 - printk("PI_INT_MASK0: %16Lx PI_INT_MASK1: %16Lx\n", mask0, mask1);
5823 - printk("PI_INT_PEND0: %16Lx PI_INT_PEND1: %16Lx\n", pend0, pend1);
5825 + pr_crit("PI_INT_PEND0: 0x%.16llx, "
5826 + "PI_INT_MASK0: 0x%.16llx\n", pend0, mask0);
5827 + pr_crit("PI_INT_PEND1: 0x%.16llx, "
5828 + "PI_INT_MASK1: 0x%.16llx\n\n", pend1, mask1);
5832 * Copy the cpu registers which have been saved in the IP27prom format
5833 * into the eframe format for the node under consideration.
5835 -void nmi_node_eframe_save(cnodeid_t cnode)
5837 +nmi_node_eframe_save(cnodeid_t cnode)
5841 @@ -161,7 +180,7 @@ void nmi_node_eframe_save(cnodeid_t cnode)
5842 if (cnode == CNODEID_NONE)
5845 - nasid = COMPACT_TO_NASID_NODEID(cnode);
5846 + nasid = sn_cnodeid_to_nasid[cnode];
5847 if (nasid == INVALID_NASID)
5850 @@ -187,7 +206,10 @@ nmi_eframes_save(void)
5854 -#ifndef REAL_NMI_SIGNAL
5859 static atomic_t nmied_cpus = ATOMIC_INIT(0);
5861 atomic_inc(&nmied_cpus);
5862 @@ -197,49 +219,54 @@ cont_nmi_dump(void)
5864 arch_spin_lock(&nmi_lock);
5866 -#ifdef REAL_NMI_SIGNAL
5868 + /* XXX: Needs a lot of work. Copy missing bits from IA64. */
5871 * Wait up to 15 seconds for the other cpus to respond to the NMI.
5872 * If a cpu has not responded after 10 sec, send it 1 additional NMI.
5873 * This is for 2 reasons:
5874 - * - sometimes a MMSC fail to NMI all cpus.
5875 - * - on 512p SN0 system, the MMSC will only send NMIs to
5876 - * half the cpus. Unfortunately, we don't know which cpus may be
5877 - * NMIed - it depends on how the site chooses to configure.
5878 + * - Sometimes an MMSC fails to NMI all cpus.
5879 + * - On a 512p SN0 system, the MMSC will only send NMIs to
5880 + * half the cpus. Unfortunately, we don't know which cpus
5881 + * may be NMI'ed, as it depends on how the site chooses to
5884 - * Note: it has been measure that it takes the MMSC up to 2.3 secs to
5885 + * Note: it has been measured that it takes the MMSC up to 2.3 secs to
5886 * send NMIs to all cpus on a 256p system.
5888 - for (i=0; i < 1500; i++) {
5889 + for (i = 0; i < 1500; i++) {
5890 for_each_online_node(node)
5891 if (NODEPDA(node)->dump_count == 0)
5894 if (node == MAX_NUMNODES)
5898 - for_each_online_node(node)
5899 - if (NODEPDA(node)->dump_count == 0) {
5900 - cpu = cpumask_first(cpumask_of_node(node));
5901 - for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
5902 - CPUMASK_SETB(nmied_cpus, cpu);
5904 - * cputonasid, cputoslice
5905 - * needs kernel cpuid
5907 - SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
5909 + for_each_online_node(node) {
5910 + if (NODEPDA(node)->dump_count != 0)
5913 + cpu = cpumask_first(cpumask_of_node(node));
5914 + for (n = 0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
5915 + CPUMASK_SETB(nmied_cpus, cpu);
5916 + slice = per_cpu(ip27_cpu, cpu).slice;
5917 + nasid = per_cpu(ip27_cpu, cpu).nasid;
5918 + SEND_NMI(nasid, slice);
5926 - while (atomic_read(&nmied_cpus) != num_online_cpus());
5927 + while (atomic_read(&nmied_cpus) != num_online_cpus())
5932 * Save the nmi cpu registers for all cpu in the eframe format.
5935 - LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
5936 + LOCAL_HUB_S(NI_PORT_RESET, (NPR_PORTRESET | NPR_LOCALRESET));
5938 diff --git a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c
5939 index e44a15d4f573..578363aec47e 100644
5940 --- a/arch/mips/sgi-ip27/ip27-reset.c
5941 +++ b/arch/mips/sgi-ip27/ip27-reset.c
5942 @@ -33,7 +33,8 @@ void machine_power_off(void) __noreturn;
5943 #define noreturn while(1); /* Silence gcc. */
5945 /* XXX How to pass the reboot command to the firmware??? */
5946 -static void ip27_machine_restart(char *command)
5948 +ip27_machine_restart(char *command)
5952 @@ -45,15 +46,16 @@ static void ip27_machine_restart(char *command)
5955 for_each_online_node(i)
5956 - REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
5958 + REMOTE_HUB_S(sn_cnodeid_to_nasid[i], PROMOP_REG,
5961 LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
5966 -static void ip27_machine_halt(void)
5968 +ip27_machine_halt(void)
5972 @@ -61,19 +63,21 @@ static void ip27_machine_halt(void)
5975 for_each_online_node(i)
5976 - REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
5978 + REMOTE_HUB_S(sn_cnodeid_to_nasid[i], PROMOP_REG,
5980 LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
5984 -static void ip27_machine_power_off(void)
5986 +ip27_machine_power_off(void)
5992 -void ip27_reboot_setup(void)
5994 +ip27_reboot_setup(void)
5996 _machine_restart = ip27_machine_restart;
5997 _machine_halt = ip27_machine_halt;
5998 diff --git a/arch/mips/sgi-ip27/ip27-rtc.c b/arch/mips/sgi-ip27/ip27-rtc.c
5999 new file mode 100644
6000 index 000000000000..e9b9af4dfa74
6002 +++ b/arch/mips/sgi-ip27/ip27-rtc.c
6005 + * This file is subject to the terms and conditions of the GNU General Public
6006 + * License. See the file "COPYING" in the main directory of this archive
6007 + * for more details.
6009 + * ip27-rtc.c: RTC submodule for the IOC3 metadriver for IP27.
6011 + * Copyright (C) 2014, 2016 Joshua Kinard <kumba@gentoo.org>
6014 +#include <linux/module.h>
6015 +#include <linux/init.h>
6016 +#include <linux/platform_device.h>
6017 +#include <linux/rtc/m48t35.h>
6018 +#include <linux/ioc3.h>
6020 +#include <asm/addrspace.h>
6021 +#include <asm/pci/bridge.h>
6022 +#include <asm/sgi/ioc3.h>
6023 +#include <asm/sn/klconfig.h>
6024 +#include <asm/sn/arch.h>
6025 +#include <asm/sn/addrs.h>
6026 +#include <asm/sn/sn_private.h>
6027 +#include <asm/sn/sn0/ip27.h>
6030 + * On IP27, the RTC is hidden behind the IOC3 device, attached to a generic
6031 + * ByteBus. Use klconfig routines to safely map to the start address of the
6032 + * RTC area in ByteBus DEV0.
6034 +#define IP27_RTC_RES_START \
6035 + (XPHYSADDR(KL_CONFIG_CONS_INFO(master_nasid)->memory_base + \
6036 + IOC3_BYTEBUS_DEV0))
6037 +#define IP27_RTC_RES_END (IP27_RTC_RES_START + 32767)
6039 +static struct ioc3_driver_data *ioc3;
6040 +static struct resource ip27_rtc_resources[1];
6041 +static int ip27_rtc_probed = 0;
6044 + * ip27_rtc_read - read a value from an rtc register.
6045 + * @rtc: pointer to the m48t35 rtc structure.
6046 + * @reg: the register address to read.
6049 +ip27_rtc_read(struct m48t35_priv *rtc, int reg)
6051 + return readb(((u8 __iomem *)(((u64)(rtc->regs + reg)) ^ 3)));
6055 + * ip27_rtc_write - write a value to an rtc register.
6056 + * @rtc: pointer to the m48t35 rtc structure.
6057 + * @reg: the register address to write.
6058 + * @value: value to write to the register.
6061 +ip27_rtc_write(struct m48t35_priv *rtc, int reg, u8 value)
6063 + writeb(value, ((u8 __iomem *)(((u64)(rtc->regs + reg)) ^ 3)));
6066 +static struct m48t35_rtc_platform_data
6067 +ip27_rtc_platform_data[] = {
6070 + * XXX: set req_mem_region to true after ioc3 resource
6071 + * conflicts are resolved.
6073 + .req_mem_region = false,
6074 + .plat_read = ip27_rtc_read,
6075 + .plat_write = ip27_rtc_write,
6079 +static struct platform_device
6080 +ip27_rtc_device = {
6081 + .name = "rtc-m48t35",
6084 + .platform_data = ip27_rtc_platform_data,
6086 + .num_resources = ARRAY_SIZE(ip27_rtc_resources),
6087 + .resource = ip27_rtc_resources,
6091 +/* IOC3 Metadriver probe/remove */
6093 +ip27_ioc3_rtc_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
6097 + /* This code only applies to an Origin/Onyx2 */
6098 + if (ioc3 || (idd->class != IOC3_CLASS_BASE_IP27))
6103 + if (ip27_rtc_probed)
6106 + ip27_rtc_resources[0].start = IP27_RTC_RES_START,
6107 + ip27_rtc_resources[0].end = IP27_RTC_RES_END,
6108 + ip27_rtc_resources[0].flags = IORESOURCE_MEM,
6110 + ret = platform_device_register(&ip27_rtc_device);
6111 + ip27_rtc_probed = 1;
6118 +ip27_ioc3_rtc_remove(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
6123 + platform_device_unregister(&ip27_rtc_device);
6130 +/* entry/exit functions */
6131 +static struct ioc3_submodule
6132 +ip27_ioc3_rtc_submodule = {
6134 + .probe = ip27_ioc3_rtc_probe,
6135 + .remove = ip27_ioc3_rtc_remove,
6136 + .owner = THIS_MODULE,
6139 +ioc3_submodule_driver(ip27_ioc3_rtc_submodule);
6141 +MODULE_AUTHOR("Joshua Kinard <kumba@gentoo.org>");
6142 +MODULE_LICENSE("GPL");
6143 +MODULE_DESCRIPTION("IP27 RTC Submodule for IOC3");
6144 diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
6145 index 545446dfe7fa..e7019bd73ffc 100644
6146 --- a/arch/mips/sgi-ip27/ip27-smp.c
6147 +++ b/arch/mips/sgi-ip27/ip27-smp.c
6149 * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
6151 #include <linux/init.h>
6152 +#include <linux/interrupt.h>
6153 +#include <linux/kernel_stat.h>
6154 +#include <linux/nodemask.h>
6155 #include <linux/sched.h>
6156 -#include <linux/sched/task_stack.h>
6157 +#include <linux/smp.h>
6158 #include <linux/topology.h>
6159 -#include <linux/nodemask.h>
6160 +#include <linux/sched/task_stack.h>
6162 +#include <asm/barrier.h>
6163 +#include <asm/irq.h>
6164 #include <asm/page.h>
6165 #include <asm/processor.h>
6166 #include <asm/ptrace.h>
6167 +#include <asm/time.h>
6168 #include <asm/sn/arch.h>
6169 #include <asm/sn/gda.h>
6170 #include <asm/sn/intr.h>
6171 @@ -23,82 +29,395 @@
6172 #include <asm/sn/mapped_kernel.h>
6173 #include <asm/sn/sn_private.h>
6174 #include <asm/sn/types.h>
6176 #include <asm/sn/sn0/hubpi.h>
6177 #include <asm/sn/sn0/hubio.h>
6178 #include <asm/sn/sn0/ip27.h>
6181 - * Takes as first input the PROM assigned cpu id, and the kernel
6182 - * assigned cpu id as the second.
6183 +extern void generic_smp_call_function_interrupt(void);
6184 +extern void scheduler_ipi(void);
6186 +/* Defined in ip27-init.c */
6187 +DECLARE_PER_CPU(struct ip27_percpu_data, ip27_cpu);
6190 +/* ----------------------------------------------------------------------- */
6194 + * ip27_smp_send_ipi_single - Send an action to another CPU via IPI.
6195 + * @cpu: integer CPU to send IPI to with action.
6196 + * @action: u32 integer containing list of actions to take OR'ed together.
6198 + * Runs on CPUx and sends an IPI to CPUy.
6201 +ip27_smp_send_ipi_single(int cpu, u32 action)
6206 + case SMP_RESCHEDULE_YOURSELF:
6207 + irq = CPU_RESCHED_A_IRQ;
6209 + case SMP_CALL_FUNCTION:
6210 + irq = CPU_CALL_A_IRQ;
6213 + panic("IP27: Unknown action value in %s!\n", __func__);
6216 + irq += per_cpu(ip27_cpu, cpu).slice;
6219 + * Convert the compact hub number to the NASID to get the correct
6220 + * part of the address space. Then set the interrupt bit associated
6221 + * with the CPU we want to send the interrupt to.
6223 + REMOTE_HUB_SEND_INTR(per_cpu(ip27_cpu, cpu).cnodeid, irq);
6227 + * ip27_smp_send_ipi_mask - Send an action to many CPUs via IPI.
6228 + * @mask: cpumask of CPUs to send IPI to with action.
6229 + * @action: u32 integer containing list of actions to take OR'ed together.
6232 +ip27_smp_send_ipi_mask(const struct cpumask *mask, u32 action)
6235 + unsigned long flags;
6237 + local_irq_save(flags);
6238 + for_each_cpu(i, mask)
6239 + ip27_smp_send_ipi_single(i, action);
6240 + local_irq_restore(flags);
6244 + * IP27_IPI_IRQ_BOILERPLATE - common code used for both IPI IRQ handlers.
6246 + * We use a macro here for static boilerplate code used by both IPI IRQ
6247 + * handlers because the conditional block includes an error check and a
6248 + * subsequent return that can't be implemented in a normal static inline
6251 + * XXX: For IP27, we do not have to manually ack/clear the HUB interrupt
6252 + * used to signal the IPI. But on IP30/Octane, we do in the HEART.
6253 + * This is either a bug on one of these two platforms, or a subtle
6254 + * hardware difference between HUB and HEART.
6256 +#define IP27_IPI_IRQ_BOILERPLATE ({ \
6258 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu); \
6260 + if (unlikely(!cpud->hub->irq_owner[irq])) \
6261 + return IRQ_NONE; \
6263 + hub_bit = cpud->hub->irq_to_bit[irq]; \
6267 + * ip27_smp_ipi_resched_irq - IPI IRQ handler to service reschedules.
6268 + * @irq: integer of IRQ# for IPI being serviced.
6269 + * @dev_id: void pointer to dev_id data.
6272 +ip27_smp_ipi_resched_irq(int irq, void *dev_id)
6274 + IP27_IPI_IRQ_BOILERPLATE;
6277 + return IRQ_HANDLED;
6281 + * ip27_smp_ipi_callfunc_irq - IPI IRQ handler to service call_functions.
6282 + * @irq: integer of IRQ# for IPI being serviced.
6283 + * @dev_id: void pointer to dev_id data.
6286 +ip27_smp_ipi_callfunc_irq(int irq, void *dev_id)
6288 + IP27_IPI_IRQ_BOILERPLATE;
6290 + generic_smp_call_function_interrupt();
6291 + return IRQ_HANDLED;
6294 +/* ----------------------------------------------------------------------- */
6297 +/* ----------------------------------------------------------------------- */
6298 +/* SMP CPU Bringup - CPU0 Code */
6301 + * ip27_smp_setup - performs housekeeping on each CPU as it comes online.
6304 +ip27_smp_setup(void)
6310 + for_each_online_node(cnode) {
6314 + nasid = sn_cnodeid_to_nasid[cnode];
6316 + REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
6317 + REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
6318 + REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
6319 + REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
6321 + for (i = 0; i < BITS_PER_HUB; i++)
6322 + REMOTE_HUB_CLR_INTR(nasid, i);
6325 + replicate_kernel_text();
6329 + * Used to request IRQs.
6331 +DEFINE_PER_CPU(char [9], ip27_ipi_r_name);
6332 +DEFINE_PER_CPU(char [9], ip27_ipi_c_name);
6335 + * ip27_smp_prepare_cpus - requests CPU0 IPI interrupt.
6336 + * @max_cpus: unused by IP27 SMP code.
6341 +ip27_smp_prepare_cpus(unsigned int max_cpus)
6343 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
6344 + unsigned long irq_flags = (IRQF_PERCPU | IRQF_SHARED | IRQF_NO_THREAD);
6345 + u8 *ipi_r_name = per_cpu(ip27_ipi_r_name, cpud->id);
6346 + u8 *ipi_c_name = per_cpu(ip27_ipi_c_name, cpud->id);
6348 + /* Request IRQ numbers for the CPU IPI bits. */
6349 + sprintf(ipi_r_name, "%dA-rsch", (cpud->nasid + 1));
6350 + sprintf(ipi_c_name, "%dA-call", (cpud->nasid + 1));
6351 + if (request_irq(CPU_RESCHED_A_IRQ, ip27_smp_ipi_resched_irq,
6352 + irq_flags, ipi_r_name, ip27_smp_ipi_resched_irq))
6353 + panic("IP27: Can't request CPU%d reschedule IPI",
6355 + if (request_irq(CPU_CALL_A_IRQ, ip27_smp_ipi_callfunc_irq,
6356 + irq_flags, ipi_c_name, ip27_smp_ipi_callfunc_irq))
6357 + panic("IP27: Can't request CPU%d call_function IPI",
6362 + * ip27_smp_boot_secondary - boots remaining CPUs into smp_bootstrap.
6363 + * @cpu: integer of CPUx to prepare before booting.
6364 + * @idle: struct task_struct containing idle task for CPUx.
6366 + * Runs on CPU0 and boots CPUx, where x > 0
6368 -static void alloc_cpupda(cpuid_t cpu, int cpunum)
6370 +ip27_smp_boot_secondary(int cpu, struct task_struct *idle)
6372 - cnodeid_t node = get_cpu_cnode(cpu);
6373 - nasid_t nasid = COMPACT_TO_NASID_NODEID(node);
6374 + cnodeid_t cnode = sn_cpuid_to_cnodeid[cpu];
6375 + nasid_t nasid = sn_cnodeid_to_nasid[cnode];
6376 + unsigned long gp = (unsigned long)task_thread_info(idle);
6377 + unsigned long sp = __KSTK_TOS(idle);
6379 + LAUNCH_SLAVE(nasid, get_cpu_slice(cpu),
6380 + (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
6381 + 0, (void *) sp, (void *) gp);
6383 + /* Kick the CPU awake. */
6386 - cputonasid(cpunum) = nasid;
6387 - sn_cpu_info[cpunum].p_nodeid = node;
6388 - cputoslice(cpunum) = get_cpu_slice(cpu);
6392 +/* ----------------------------------------------------------------------- */
6395 +/* ----------------------------------------------------------------------- */
6396 +/* SMP CPU Bringup - CPUx Code */
6399 + * ip27_smp_init_secondary - requests CPUs's IPI IRQ and unmasks interrupts.
6401 + * Runs on CPUx, where x > 0, after cache probe.
6404 +ip27_smp_init_secondary(void)
6406 + ip27_per_cpu_init();
6409 -static nasid_t get_actual_nasid(lboard_t *brd)
6411 + * ip27_smp_finish - Sets CPU1 counter and enables interrupts.
6413 + * Runs on CPUx, where x > 0, before entering the idle loop.
6416 +ip27_smp_finish(void)
6419 + const struct ip27_percpu_data *cpud;
6420 + unsigned long irq_flags = (IRQF_PERCPU | IRQF_SHARED | IRQF_NO_THREAD);
6421 + u8 *ipi_r_name, *ipi_c_name;
6422 + extern void ip27_hub_clockevent_init(void);
6425 + * HUB has two compare registers, one for each CPU, so need to setup
6426 + * the clock_event stuff on each CPU before enabling interrupts.
6428 + ip27_hub_clockevent_init();
6431 + * Make sure an interrupt won't happen for a little bit.
6433 + write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
6434 + local_irq_enable();
6437 + * Request IRQ numbers for the CPU IPI bits.
6439 + cpud = this_cpu_ptr(&ip27_cpu);
6440 + ipi_r_name = per_cpu(ip27_ipi_r_name, cpud->id);
6441 + ipi_c_name = per_cpu(ip27_ipi_c_name, cpud->id);
6443 + if (!cpud->slice) {
6444 + sprintf(ipi_r_name, "%dA-rsch", (cpud->nasid + 1));
6445 + sprintf(ipi_c_name, "%dA-call", (cpud->nasid + 1));
6446 + if (request_irq(CPU_RESCHED_A_IRQ, ip27_smp_ipi_resched_irq,
6447 + irq_flags, ipi_r_name,
6448 + ip27_smp_ipi_resched_irq))
6449 + panic("IP27: Can't request CPU%d reschedule IPI",
6451 + if (request_irq(CPU_CALL_A_IRQ, ip27_smp_ipi_callfunc_irq,
6452 + irq_flags, ipi_c_name,
6453 + ip27_smp_ipi_callfunc_irq))
6454 + panic("IP27: Can't request CPU%d call_function IPI",
6457 + sprintf(ipi_r_name, "%dB-rsch", (cpud->nasid + 1));
6458 + sprintf(ipi_c_name, "%dB-call", (cpud->nasid + 1));
6459 + if (request_irq(CPU_RESCHED_B_IRQ, ip27_smp_ipi_resched_irq,
6460 + irq_flags, ipi_r_name,
6461 + ip27_smp_ipi_resched_irq))
6462 + panic("IP27: Can't request CPU%d reschedule IPI",
6464 + if (request_irq(CPU_CALL_B_IRQ, ip27_smp_ipi_callfunc_irq,
6465 + irq_flags, ipi_c_name,
6466 + ip27_smp_ipi_callfunc_irq))
6467 + panic("IP27: Can't request CPU%d call_function IPI",
6473 + * struct ip27_smp_ops - IP27 SMP ops.
6474 + * @send_ipi_single: send one interprocessor interrupt.
6475 + * @send_ipi_mask: send interprocessor interrup to each CPU.
6476 + * @smp_setup: probe for additional CPUs.
6477 + * @prepare_cpus: setup CPU0 IPI interrupt.
6478 + * @boot_secondary: boot additional CPUs.
6479 + * @init_secondary: setup CPUx IPI interrupts.
6480 + * @smp_finish: setup CPUx counter, enable IRQs.
6482 +const struct plat_smp_ops __read_mostly
6484 + .send_ipi_single = ip27_smp_send_ipi_single,
6485 + .send_ipi_mask = ip27_smp_send_ipi_mask,
6486 + .smp_setup = ip27_smp_setup,
6487 + .prepare_cpus = ip27_smp_prepare_cpus,
6488 + .boot_secondary = ip27_smp_boot_secondary,
6489 + .init_secondary = ip27_smp_init_secondary,
6490 + .smp_finish = ip27_smp_finish,
6493 +/* ----------------------------------------------------------------------- */
6496 +/* ----------------------------------------------------------------------- */
6497 +/* Misc SMP code used during init. */
6500 + * ip27_smp_kl_nasid - gets the nasid of a nodeboard via klconfig.
6501 + * @brd: struct klc_lboard pointer of a nodeboard to get the nasid from.
6503 +static nasid_t __init
6504 +ip27_smp_kl_nasid(struct klc_lboard *brd)
6506 + struct klc_hub *hub;
6509 return INVALID_NASID;
6511 - /* find out if we are a completely disabled brd. */
6512 - hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
6513 + /* Find out if we are a completely disabled board */
6514 + hub = KLCF_CAST_HUB(kl_find_1st_component(brd, KLSTRUCT_HUB));
6516 return INVALID_NASID;
6517 - if (!(hub->hub_info.flags & KLINFO_ENABLE)) /* disabled node brd */
6518 - return hub->hub_info.physid;
6519 + if (!(KLCF_INFO_ENABLED(hub->kl_info)))
6520 + return hub->kl_info.physid;
6522 - return brd->brd_nasid;
6523 + return KLCF_BOARD_NASID(brd);
6526 -static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest)
6528 + * ip27_smp_do_cpumask - update the smp cpumask for enabled cpus in a nasid.
6529 + * @cnode: cnodeid_t value of the compact node id.
6530 + * @nasid: nasid_t of the node id (physical node).
6531 + * @highest: int value of the highest CPU number discovered.
6533 + * Returns value of 'highest' back to the caller.
6536 +ip27_smp_do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest)
6538 - static int tot_cpus_found = 0;
6541 + static int total_cpus_found = 0;
6542 + struct klc_lboard *brd;
6543 + struct klc_cpu *acpu;
6547 - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
6548 + brd = kl_find_lboard(KLCF_LBOARD_INFO(nasid), KLTYPE_IP27);
6551 - acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
6552 + acpu = KLCF_CAST_CPU(kl_find_1st_component(brd, KLSTRUCT_CPU));
6554 - cpuid = acpu->cpu_info.virtid;
6555 + cpuid = acpu->kl_info.virtid;
6556 /* cnode is not valid for completely disabled brds */
6557 - if (get_actual_nasid(brd) == brd->brd_nasid)
6558 - cpuid_to_compact_node[cpuid] = cnode;
6559 + if (ip27_smp_kl_nasid(brd) == KLCF_BOARD_NASID(brd))
6560 + sn_cpuid_to_cnodeid[cpuid] = cnode;
6561 if (cpuid > highest)
6563 /* Only let it join in if it's marked enabled */
6564 - if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
6565 - (tot_cpus_found != NR_CPUS)) {
6566 + if ((KLCF_INFO_ENABLED(acpu->kl_info)) &&
6567 + (total_cpus_found != NR_CPUS)) {
6568 set_cpu_possible(cpuid, true);
6569 - alloc_cpupda(cpuid, tot_cpus_found);
6572 + total_cpus_found++;
6574 - acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
6576 + acpu = KLCF_CAST_CPU(kl_find_component(brd,
6577 + KLCF_CAST_INFO(acpu),
6580 brd = KLCF_NEXT(brd);
6584 - brd = find_lboard(brd, KLTYPE_IP27);
6585 + brd = kl_find_lboard(brd, KLTYPE_IP27);
6591 -void cpu_node_probe(void)
6593 + * ip27_smp_cpu_node_probe - probe nodeboards for available CPUs via klconfig.
6596 +ip27_smp_cpu_node_probe(void)
6600 @@ -106,138 +425,32 @@ void cpu_node_probe(void)
6602 * Initialize the arrays to invalid nodeid (-1)
6604 - for (i = 0; i < MAX_COMPACT_NODES; i++)
6605 - compact_to_nasid_node[i] = INVALID_NASID;
6606 - for (i = 0; i < MAX_NASIDS; i++)
6607 - nasid_to_compact_node[i] = INVALID_CNODEID;
6608 - for (i = 0; i < MAXCPUS; i++)
6609 - cpuid_to_compact_node[i] = INVALID_CNODEID;
6610 + memset(sn_cnodeid_to_nasid, -1,
6611 + sizeof(this_cpu_ptr(__sn_cnodeid_to_nasid)));
6612 + memset(sn_nasid_to_cnodeid, -1,
6613 + sizeof(this_cpu_ptr(__sn_nasid_to_cnodeid)));
6614 + memset(sn_cpuid_to_cnodeid, -1,
6615 + sizeof(this_cpu_ptr(__sn_cpuid_to_cnodeid)));
6618 - * MCD - this whole "compact node" stuff can probably be dropped,
6619 - * as we can handle sparse numbering now
6620 + * XXX: MCD - this whole "compact node" stuff can probably be dropped,
6621 + * as we can handle sparse numbering now
6623 + nodes_clear(node_possible_map);
6624 nodes_clear(node_online_map);
6625 for (i = 0; i < MAX_COMPACT_NODES; i++) {
6626 nasid_t nasid = gdap->g_nasidtable[i];
6627 if (nasid == INVALID_NASID)
6629 - compact_to_nasid_node[i] = nasid;
6630 - nasid_to_compact_node[nasid] = i;
6631 + sn_nasid_to_cnodeid[nasid] = i;
6632 + sn_cnodeid_to_nasid[i] = nasid;
6633 + node_set_state(num_online_nodes(), N_POSSIBLE);
6634 node_set_online(num_online_nodes());
6635 - highest = do_cpumask(i, nasid, highest);
6636 + highest = ip27_smp_do_cpumask(i, nasid, highest);
6639 - printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
6642 -static __init void intr_clear_all(nasid_t nasid)
6646 - REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
6647 - REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
6648 - REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
6649 - REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
6651 - for (i = 0; i < 128; i++)
6652 - REMOTE_HUB_CLR_INTR(nasid, i);
6653 + pr_info("SMP: Discovered %d cpus on %d nodes\n", (highest + 1),
6654 + num_online_nodes());
6657 -static void ip27_send_ipi_single(int destid, unsigned int action)
6662 - case SMP_RESCHEDULE_YOURSELF:
6663 - irq = CPU_RESCHED_A_IRQ;
6665 - case SMP_CALL_FUNCTION:
6666 - irq = CPU_CALL_A_IRQ;
6669 - panic("sendintr");
6672 - irq += cputoslice(destid);
6675 - * Convert the compact hub number to the NASID to get the correct
6676 - * part of the address space. Then set the interrupt bit associated
6677 - * with the CPU we want to send the interrupt to.
6679 - REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq);
6682 -static void ip27_send_ipi_mask(const struct cpumask *mask, unsigned int action)
6686 - for_each_cpu(i, mask)
6687 - ip27_send_ipi_single(i, action);
6690 -static void ip27_init_secondary(void)
6695 -static void ip27_smp_finish(void)
6697 - extern void hub_rt_clock_event_init(void);
6699 - hub_rt_clock_event_init();
6700 - local_irq_enable();
6704 - * Launch a slave into smp_bootstrap(). It doesn't take an argument, and we
6705 - * set sp to the kernel stack of the newly created idle process, gp to the proc
6706 - * struct so that current_thread_info() will work.
6708 -static int ip27_boot_secondary(int cpu, struct task_struct *idle)
6710 - unsigned long gp = (unsigned long)task_thread_info(idle);
6711 - unsigned long sp = __KSTK_TOS(idle);
6713 - LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
6714 - (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
6715 - 0, (void *) sp, (void *) gp);
6719 -static void __init ip27_smp_setup(void)
6723 - for_each_online_node(cnode) {
6726 - intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
6729 - replicate_kernel_text();
6732 - * Assumption to be fixed: we're always booted on logical / physical
6733 - * processor 0. While we're always running on logical processor 0
6734 - * this still means this is physical processor zero; it might for
6735 - * example be disabled in the firmware.
6737 - alloc_cpupda(0, 0);
6740 -static void __init ip27_prepare_cpus(unsigned int max_cpus)
6742 - /* We already did everything necessary earlier */
6745 -const struct plat_smp_ops ip27_smp_ops = {
6746 - .send_ipi_single = ip27_send_ipi_single,
6747 - .send_ipi_mask = ip27_send_ipi_mask,
6748 - .init_secondary = ip27_init_secondary,
6749 - .smp_finish = ip27_smp_finish,
6750 - .boot_secondary = ip27_boot_secondary,
6751 - .smp_setup = ip27_smp_setup,
6752 - .prepare_cpus = ip27_prepare_cpus,
6754 +/* ----------------------------------------------------------------------- */
6755 diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
6756 index 833744641b01..1c35a43582fa 100644
6757 --- a/arch/mips/sgi-ip27/ip27-timer.c
6758 +++ b/arch/mips/sgi-ip27/ip27-timer.c
6759 @@ -38,201 +38,284 @@
6760 #include <asm/sn/sn0/hubio.h>
6761 #include <asm/pci/bridge.h>
6763 -static void enable_rt_irq(struct irq_data *d)
6766 +/* Defined in ip27-init.c */
6767 +DECLARE_PER_CPU(struct ip27_percpu_data, ip27_cpu);
6769 +int ip27_hub_rt_irq_num;
6771 -static void disable_rt_irq(struct irq_data *d)
6773 +/* ----------------------------------------------------------------------- */
6774 +/* HUB Clocksource setup. */
6777 + * XXX: This is a hack; we really need to figure these values out dynamically
6779 + * Since 800 ns works very well with various HUB frequencies, such as
6780 + * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
6782 + * Ralf: which clock rate is used to feed the counter?
6784 +#define HUB_NSEC_PER_CYCLE 800
6785 +#define HUB_CYCLES_PER_SEC (NSEC_PER_SEC / HUB_NSEC_PER_CYCLE)
6788 + * ip27_hub_csrc_counter_read - read HUB counter register (52-bit).
6789 + * @clocksource: pointer to clocksource struct. (unused)
6791 + * Returns u64 value of the HUB count register.
6794 +ip27_hub_csrc_counter_read(struct clocksource *cs)
6796 + return REMOTE_HUB_L(per_cpu(ip27_cpu, 0).nasid, PI_RT_COUNT);
6799 -static struct irq_chip rt_irq_type = {
6800 - .name = "SN HUB RT timer",
6801 - .irq_mask = disable_rt_irq,
6802 - .irq_unmask = enable_rt_irq,
6804 + * struct ip27_hub_clocksource - HUB clocksource definition.
6805 + * @name: self-explanatory.
6806 + * @rating: quality of this clocksource (HUB has 80ns cycle time).
6807 + * @read: pointer to function to read the counter register.
6808 + * @mask: bitmask for the counter (52bit counter/24bit compare).
6809 + * @flags: clocksource flags.
6811 +static struct clocksource __read_mostly
6812 +ip27_hub_clocksource = {
6815 + .read = ip27_hub_csrc_counter_read,
6816 + .mask = CLOCKSOURCE_MASK(52),
6817 + .flags = (CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_VALID_FOR_HRES),
6820 -static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
6822 + * ip27_hub_read_sched_clock - make the HUB counter the sched_clock() source.
6824 + * Returns u64 value of the HUB count register.
6827 +ip27_hub_csrc_read_sched_clock(void)
6829 - unsigned int cpu = smp_processor_id();
6830 - int slice = cputoslice(cpu);
6831 - unsigned long cnt;
6832 + return REMOTE_HUB_L(per_cpu(ip27_cpu, 0).nasid, PI_RT_COUNT);
6835 - cnt = LOCAL_HUB_L(PI_RT_COUNT);
6837 - LOCAL_HUB_S(PI_RT_COMPARE_A + PI_COUNT_OFFSET * slice, cnt);
6839 + * ip27_hub_clocksource_init - init the clocksource for HUB.
6842 +ip27_hub_clocksource_init(void)
6844 + struct clocksource *cs = &ip27_hub_clocksource;
6846 - return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
6847 + clocksource_register_hz(cs, HUB_CYCLES_PER_SEC);
6849 + sched_clock_register(ip27_hub_csrc_read_sched_clock, 52,
6850 + HUB_CYCLES_PER_SEC);
6853 -unsigned int rt_timer_irq;
6854 +/* ----------------------------------------------------------------------- */
6857 +/* ----------------------------------------------------------------------- */
6858 +/* HUB Clockevent setup. */
6860 -static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
6861 -static DEFINE_PER_CPU(char [11], hub_rt_name);
6862 +/* Should be globally-visible now. */
6863 +DEFINE_PER_CPU(struct clock_event_device, ip27_hub_clockevent);
6864 +DEFINE_PER_CPU(char [11], ip27_hub_cevt_name);
6866 -static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
6868 + * ip27_hub_rt_next_event - resets the compare bit on HUB for CPUA.
6869 + * @delta: difference between count and compare.
6870 + * @evt: pointer to clock_event_device struct.
6872 + * Returns -ETIME if local HUB counter is > cnt, else 0.
6874 + * HUB has one count register (PI_RT_COUNT) and two compare registers
6875 + * (PI_RT_COMPARE_A & PI_RT_COMPARE_B), one for each of the two CPUs attached
6879 +ip27_hub_rt_next_event(unsigned long delta, struct clock_event_device *evt)
6881 - unsigned int cpu = smp_processor_id();
6882 - struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
6883 - int slice = cputoslice(cpu);
6886 + unsigned long flags;
6890 + * Read HUB's current counter for the specified CPU slice, add the
6891 + * delta, then write that value back to HUB's compare register.
6893 - LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, 0);
6894 - cd->event_handler(cd);
6895 + local_irq_save(flags);
6896 + cnt = LOCAL_HUB_L(PI_RT_COUNT);
6897 + cnt += (u64)delta;
6898 + LOCAL_HUB_S(PI_RT_COMPARE_A + PI_COUNT_OFFSET *
6899 + this_cpu_read(ip27_cpu.slice), cnt);
6900 + local_irq_restore(flags);
6902 - return IRQ_HANDLED;
6903 + ret = ((LOCAL_HUB_L(PI_RT_COUNT) >= cnt) ? -ETIME : 0);
6907 -struct irqaction hub_rt_irqaction = {
6908 - .handler = hub_rt_counter_handler,
6909 - .flags = IRQF_PERCPU | IRQF_TIMER,
6914 - * This is a hack; we really need to figure these values out dynamically
6916 - * Since 800 ns works very well with various HUB frequencies, such as
6917 - * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
6919 + * ip27_hub_rt_event_handler - Clock event handler on HUB.
6920 + * @cd: pointer to clock_event_device struct.
6922 - * Ralf: which clock rate is used to feed the counter?
6923 + * Not supported on HUB.
6925 -#define NSEC_PER_CYCLE 800
6926 -#define CYCLES_PER_SEC (NSEC_PER_SEC / NSEC_PER_CYCLE)
6928 -void hub_rt_clock_event_init(void)
6930 +ip27_hub_rt_event_handler(struct clock_event_device *cd)
6932 - unsigned int cpu = smp_processor_id();
6933 - struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
6934 - unsigned char *name = per_cpu(hub_rt_name, cpu);
6935 - int irq = rt_timer_irq;
6937 - sprintf(name, "hub-rt %d", cpu);
6939 - cd->features = CLOCK_EVT_FEAT_ONESHOT;
6940 - clockevent_set_clock(cd, CYCLES_PER_SEC);
6941 - cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd);
6942 - cd->max_delta_ticks = 0xfffffffffffff;
6943 - cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
6944 - cd->min_delta_ticks = 0x300;
6947 - cd->cpumask = cpumask_of(cpu);
6948 - cd->set_next_event = rt_next_event;
6949 - clockevents_register_device(cd);
6950 + /* Nothing to do */
6953 -static void __init hub_rt_clock_event_global_init(void)
6955 + * ip27_hub_rt_compare_irq - IRQ handler for the HUB compare interrupt.
6956 + * @irq: IRQ number.
6957 + * @dev_id: void pointer to the clock_event_device struct. (unused on IP27)
6959 + * Always returns IRQ_HANDLED.
6962 +ip27_hub_rt_compare_irq(int irq, void *dev_id)
6968 - irq = rt_timer_irq;
6972 - irq = allocate_irqno();
6974 - panic("Allocation of irq number for timer failed");
6975 - } while (xchg(&rt_timer_irq, irq));
6977 - irq_set_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
6978 - setup_irq(irq, &hub_rt_irqaction);
6980 + struct clock_event_device *cd = this_cpu_ptr(&ip27_hub_clockevent);
6981 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
6984 + raw_spin_lock(&cpud->hub->lock);
6985 + LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET *
6986 + this_cpu_read(ip27_cpu.slice), 0);
6987 + raw_spin_unlock(&cpud->hub->lock);
6988 + cd->event_handler(cd);
6990 -static u64 hub_rt_read(struct clocksource *cs)
6992 - return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
6993 + return IRQ_HANDLED;
6996 -struct clocksource hub_rt_clocksource = {
6999 - .read = hub_rt_read,
7000 - .mask = CLOCKSOURCE_MASK(52),
7001 - .flags = CLOCK_SOURCE_IS_CONTINUOUS,
7003 + * struct ip27_hub_rt_irqaction - irqaction block for HUB.
7004 + * @name: self-explanatory.
7005 + * @flags: HUB counter IRQ flags.
7006 + * @handler: pointer to IRQ handler for the counter interrupt.
7009 +ip27_hub_rt_irqaction = {
7010 + .name = "hub_timer",
7011 + .flags = (IRQF_PERCPU | IRQF_TIMER | IRQF_NOBALANCING),
7012 + .handler = ip27_hub_rt_compare_irq,
7015 -static u64 notrace hub_rt_read_sched_clock(void)
7017 + * ip27_hub_clockevent_init - per-HUB clockevent initialization.
7020 +ip27_hub_clockevent_init(void)
7022 - return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
7023 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
7024 + struct clock_event_device *cd = this_cpu_ptr(&ip27_hub_clockevent);
7025 + unsigned char *name = per_cpu(ip27_hub_cevt_name, cpud->id);
7027 + sprintf(name, "HUB %d", cpud->id);
7029 + cd->features = CLOCK_EVT_FEAT_ONESHOT;
7030 + clockevent_set_clock(cd, HUB_CYCLES_PER_SEC);
7031 + cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd);
7032 + cd->max_delta_ticks = 0xfffffffffffff;
7033 + cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
7034 + cd->min_delta_ticks = 0x300;
7036 + cd->irq = ip27_hub_rt_irq_num;
7037 + cd->cpumask = cpumask_of(cpud->id);
7038 + cd->set_next_event = ip27_hub_rt_next_event;
7039 + cd->event_handler = ip27_hub_rt_event_handler;
7041 + clockevents_register_device(cd);
7044 -static void __init hub_rt_clocksource_init(void)
7046 - struct clocksource *cs = &hub_rt_clocksource;
7047 +/* ----------------------------------------------------------------------- */
7049 - clocksource_register_hz(cs, CYCLES_PER_SEC);
7051 - sched_clock_register(hub_rt_read_sched_clock, 52, CYCLES_PER_SEC);
7053 +/* ----------------------------------------------------------------------- */
7054 +/* HUB "RT" IRQ. */
7056 -void __init plat_time_init(void)
7058 + * HUB has a separate interrupt pending register for its "realtime" (RT)
7059 + * counter component, PI_RT_PEND_A or PI_RT_PEND_B. We use dummy irq_chip
7060 + * stubs to handle this, because the real ack'ing happens in
7061 + * ip27_hub_compare_irq, when invoked by the clockevent subsystem.
7065 + * ip27_mask_hub_rt_irq - masks a HUB RT IRQ.
7066 + * @d: struct irq_data containing IRQ information.
7069 +ip27_mask_hub_rt_irq(struct irq_data *d)
7071 - hub_rt_clocksource_init();
7072 - hub_rt_clock_event_global_init();
7073 - hub_rt_clock_event_init();
7077 -void cpu_time_init(void)
7079 + * ip27_unmask_hub_rt_irq - unmasks a HUB RT IRQ.
7080 + * @d: struct irq_data containing IRQ information.
7083 +ip27_unmask_hub_rt_irq(struct irq_data *d)
7089 - /* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */
7090 - board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
7092 - panic("Can't find board info for myself.");
7096 - cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
7097 - cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
7099 - panic("No information about myself?");
7101 + * struct ip27_hub_rt_irq - HUB struct irq_chip ops.
7102 + * @irq_mask: mask function.
7103 + * @irq_unmask: unmask function.
7105 +static struct irq_chip __read_mostly
7106 +ip27_hub_rt_irq = {
7108 + .irq_mask = ip27_mask_hub_rt_irq,
7109 + .irq_unmask = ip27_unmask_hub_rt_irq,
7112 - printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
7114 + * ip27_hub_clock_event_irq_init - allocates a dynamic IRQ for HUB RT.
7115 + * @d: struct irq_data containing IRQ information.
7118 +ip27_hub_rt_irq_init(void)
7121 + const struct ip27_percpu_data *cpud = this_cpu_ptr(&ip27_cpu);
7123 - set_c0_status(SRB_TIMOCLK);
7127 + irq = ip27_hub_rt_irq_num;
7131 -void hub_rtc_init(cnodeid_t cnode)
7133 + irq = ip27_alloc_irq_num();
7135 + panic("Allocation of HUB timer IRQ number failed!");
7136 + } while (xchg(&ip27_hub_rt_irq_num, irq));
7139 - * We only need to initialize the current node.
7140 - * If this is not the current node then it is a cpuless
7141 - * node and timeouts will not happen there.
7143 - if (get_compact_nodeid() == cnode) {
7144 - LOCAL_HUB_S(PI_RT_EN_A, 1);
7145 - LOCAL_HUB_S(PI_RT_EN_B, 1);
7146 - LOCAL_HUB_S(PI_PROF_EN_A, 0);
7147 - LOCAL_HUB_S(PI_PROF_EN_B, 0);
7148 - LOCAL_HUB_S(PI_RT_COUNT, 0);
7149 - LOCAL_HUB_S(PI_RT_PEND_A, 0);
7150 - LOCAL_HUB_S(PI_RT_PEND_B, 0);
7152 + irq_set_chip_and_handler(irq, &ip27_hub_rt_irq, handle_percpu_irq);
7153 + irq_set_affinity(irq, cpumask_of(cpud->id));
7154 + setup_irq(ip27_hub_rt_irq_num, &ip27_hub_rt_irqaction);
7157 -static int __init sgi_ip27_rtc_devinit(void)
7159 - struct resource res;
7160 +/* ----------------------------------------------------------------------- */
7162 - memset(&res, 0, sizeof(res));
7163 - res.start = XPHYSADDR(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base +
7164 - IOC3_BYTEBUS_DEV0);
7165 - res.end = res.start + 32767;
7166 - res.flags = IORESOURCE_MEM;
7168 - return IS_ERR(platform_device_register_simple("rtc-m48t35", -1,
7171 +/* ----------------------------------------------------------------------- */
7174 - * kludge make this a device_initcall after ioc3 resource conflicts
7177 + * plat_time_init - platform time initialization.
7179 -late_initcall(sgi_ip27_rtc_devinit);
7181 +plat_time_init(void)
7183 + /* Init clocksource and clockevent for HUB on CPU0. */
7184 + ip27_hub_clocksource_init();
7185 + ip27_hub_rt_irq_init();
7186 + ip27_hub_clockevent_init();
7189 +/* ----------------------------------------------------------------------- */
7190 diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
7191 index cd522a45a781..ff9e24e7b108 100644
7192 --- a/arch/mips/sgi-ip27/ip27-xtalk.c
7193 +++ b/arch/mips/sgi-ip27/ip27-xtalk.c
7196 #include <linux/kernel.h>
7197 #include <linux/smp.h>
7198 -#include <asm/sn/types.h>
7199 -#include <asm/sn/klconfig.h>
7200 -#include <asm/sn/hub.h>
7201 -#include <asm/pci/bridge.h>
7202 +#include <linux/platform_device.h>
7204 #include <asm/xtalk/xtalk.h>
7205 +#include <asm/xtalk/xwidget.h>
7207 +#include <asm/pci/bridge.h>
7209 +#include <asm/sn/addrs.h>
7210 +#include <asm/sn/hub.h>
7211 +#include <asm/sn/klconfig.h>
7212 +#include <asm/sn/types.h>
7214 +#define xtalk_read __raw_readl
7216 -#define XBOW_WIDGET_PART_NUM 0x0
7217 -#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */
7218 #define BASE_XBOW_PORT 8 /* Lowest external port */
7220 -extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
7221 +struct widget_data {
7229 +unsigned long inline
7230 +xtalk_get_swin(int node, int wid)
7232 + return NODE_SWIN_BASE(node, wid);
7235 -static int probe_one_port(nasid_t nasid, int widget, int masterwid)
7237 +xtalk_bridge_platform_setup(nasid_t nasid, const struct widget_data *wd,
7238 + s8 widget, s8 master_wid)
7240 - widgetreg_t widget_id;
7242 + struct platform_device *xw_pdev;
7243 + struct xwidget_platform_data *xw_pdata;
7244 + extern struct bridge_platform_data ip27_bridge_platform_data;
7246 + xw_pdata = kzalloc(sizeof(struct xwidget_platform_data), GFP_KERNEL);
7247 + xw_pdata->nasid = nasid;
7248 + xw_pdata->masterwid = master_wid;
7249 + xw_pdata->bridge_pdata = &ip27_bridge_platform_data;
7251 + xw_pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
7252 + xw_pdev->name = wd->name;
7253 + xw_pdev->id = widget;
7254 + xw_pdev->dev.platform_data = xw_pdata;
7256 + platform_device_register(xw_pdev);
7257 + pr_info("xtalk:n%d/%x %s widget (rev %s) registered as a "
7258 + "platform device.\n", nasid, widget, wd->name, wd->rev);
7261 - widget_id = *(volatile widgetreg_t *)
7262 - (RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID);
7263 - partnum = XWIDGET_PART_NUM(widget_id);
7264 +static unsigned int __init
7265 +xtalk_get_widget_data(nasid_t nasid, s8 wid)
7269 + if (wid != XTALK_XBOW &&
7270 + (wid < XTALK_LOW_DEV || wid > XTALK_HIGH_DEV))
7271 + return XTALK_NODEV;
7274 + link_stat = xtalk_read((void *)(RAW_NODE_SWIN_BASE(nasid, 0) +
7275 + XBOW_REG_LINK_STAT_0 +
7276 + XBOW_REG_LINK_BLK_SIZE *
7277 + (wid - XTALK_LOW_DEV)));
7278 + /* Is the link alive? */
7279 + if (!(link_stat & XBOW_REG_LINK_ALIVE))
7280 + return XTALK_NODEV;
7283 - printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ",
7284 - smp_processor_id(), nasid, widget, partnum);
7285 + return xtalk_read((void *)(RAW_NODE_SWIN_BASE(nasid, wid) + WIDGET_ID));
7288 - switch (partnum) {
7289 - case BRIDGE_WIDGET_PART_NUM:
7290 - case XBRIDGE_WIDGET_PART_NUM:
7291 - bridge_probe(nasid, widget, masterwid);
7295 +static struct widget_data __init *
7296 +xtalk_get_widget_info(nasid_t nasid, s8 widget)
7298 + u32 wid_data, rev;
7299 + struct widget_data *wd;
7300 + const struct widget_ident *wi;
7302 + wd = kzalloc(sizeof(struct widget_data), GFP_KERNEL);
7306 + wid_data = xtalk_get_widget_data(nasid, widget);
7307 + if (wid_data == XTALK_NODEV)
7310 + rev = XWIDGET_REV_NUM(wid_data);
7311 + for (wi = widget_idents; wi->name; wi++)
7312 + if ((wi->mfgr == XWIDGET_MFG_NUM(wid_data)) &&
7313 + (wi->part == XWIDGET_PART_NUM(wid_data)))
7316 + if (unlikely(wi->name == NULL)) {
7317 + pr_info("xtalk:n%d/%x unknown widget 0x%x\n", nasid,
7318 + widget, wid_data);
7323 + wd->mfgr = wi->mfgr;
7324 + wd->part = wi->part;
7325 + wd->name = wi->name;
7326 + wd->rev = (wi->revs[rev] ? wi->revs[rev] : "unknown");
7331 -static int xbow_probe(nasid_t nasid)
7333 +xtalk_init_widget(nasid_t nasid, s8 widget, s8 masterwid)
7337 - unsigned masterwid, i;
7338 + struct widget_data *wd;
7340 - printk("is xbow\n");
7341 + wd = xtalk_get_widget_info(nasid, widget);
7345 + switch (wd->part) {
7346 + case WIDGET_BRIDG_PART_NUM:
7347 + case WIDGET_XBRDG_PART_NUM:
7348 + xtalk_bridge_platform_setup(nasid, wd, widget, masterwid);
7351 + if (platform_device_register_simple(wd->name, widget, NULL, 0))
7352 + pr_info("xtalk:n%d/%x %s widget (rev %s) "
7353 + "registered as a platform device.\n", nasid,
7354 + widget, wd->name, wd->rev);
7360 +xbow_probe(nasid_t nasid)
7362 + struct klc_lboard *brd;
7363 + struct klc_xbow *xbow_p;
7367 * found xbow, so may have multiple bridges
7368 * need to probe xbow
7370 - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8);
7371 + brd = kl_find_lboard(KLCF_LBOARD_INFO(nasid), KLTYPE_MIDPLANE);
7375 - xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW);
7376 + xbow_p = KLCF_CAST_XBOW(kl_find_component(brd, NULL, KLSTRUCT_XBOW));
7380 @@ -72,19 +167,11 @@ static int xbow_probe(nasid_t nasid)
7381 * hub connected at highest or lowest widget as
7385 - i = HUB_WIDGET_ID_MAX + 1;
7388 - } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
7389 - (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
7391 i = HUB_WIDGET_ID_MIN - 1;
7394 } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
7395 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
7399 if (nasid != XBOW_PORT_NASID(xbow_p, i))
7400 @@ -93,43 +180,62 @@ static int xbow_probe(nasid_t nasid)
7401 for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) {
7402 if (XBOW_PORT_IS_ENABLED(xbow_p, i) &&
7403 XBOW_PORT_TYPE_IO(xbow_p, i))
7404 - probe_one_port(nasid, i, masterwid);
7405 + xtalk_init_widget(nasid, i, masterwid);
7411 -void xtalk_probe_node(cnodeid_t nid)
7413 +xtalk_probe_node(cnodeid_t cnodeid)
7415 - volatile u64 hubreg;
7418 - widgetreg_t widget_id;
7419 + volatile u64 hubreg;
7421 + struct widget_data *wd;
7423 - nasid = COMPACT_TO_NASID_NODEID(nid);
7424 + nasid = sn_cnodeid_to_nasid[cnodeid];
7425 hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
7427 /* check whether the link is up */
7428 if (!(hubreg & IIO_LLP_CSR_IS_UP))
7431 - widget_id = *(volatile widgetreg_t *)
7432 - (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
7433 - partnum = XWIDGET_PART_NUM(widget_id);
7435 - printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ",
7436 - smp_processor_id(), nasid, partnum);
7437 + wd = xtalk_get_widget_info(nasid, XTALK_XBOW);
7441 - switch (partnum) {
7442 - case BRIDGE_WIDGET_PART_NUM:
7443 - bridge_probe(nasid, 0x8, 0xa);
7444 + switch (wd->part) {
7445 + case WIDGET_BRIDG_PART_NUM:
7446 + xtalk_bridge_platform_setup(nasid, wd, 0x8, 0xa);
7448 - case XBOW_WIDGET_PART_NUM:
7449 - case XXBOW_WIDGET_PART_NUM:
7450 + case WIDGET_XBOW_PART_NUM:
7451 + case WIDGET_XXBOW_PART_NUM:
7452 + pr_info("xtalk:n%d/%lx %s widget (rev %s)\n",
7453 + nasid, XTALK_XBOW, wd->name, wd->rev);
7457 - printk(" unknown widget??\n");
7459 + if (platform_device_register_simple(wd->name, XTALK_XBOW, NULL, 0))
7460 + pr_info("xtalk:n%d/%lx %s widget (rev %s) "
7461 + "registered as platform device.\n", nasid,
7462 + XTALK_XBOW, wd->name, wd->rev);
7468 +ip27_xtalk_init(void)
7472 + /* XXX: kludge alert.. */
7473 + ioport_resource.end = ~0UL;
7475 + for_each_online_node(cnode) {
7476 + xtalk_probe_node(cnode);
7482 +arch_initcall(ip27_xtalk_init);