diff options
Diffstat (limited to 'arch/sparc64/kernel/devices.c')
-rw-r--r-- | arch/sparc64/kernel/devices.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c index ac11d872ef74..817132826e09 100644 --- a/arch/sparc64/kernel/devices.c +++ b/arch/sparc64/kernel/devices.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/bootmem.h> | ||
15 | 16 | ||
16 | #include <asm/page.h> | 17 | #include <asm/page.h> |
17 | #include <asm/oplib.h> | 18 | #include <asm/oplib.h> |
@@ -20,6 +21,7 @@ | |||
20 | #include <asm/spitfire.h> | 21 | #include <asm/spitfire.h> |
21 | #include <asm/timer.h> | 22 | #include <asm/timer.h> |
22 | #include <asm/cpudata.h> | 23 | #include <asm/cpudata.h> |
24 | #include <asm/vdev.h> | ||
23 | 25 | ||
24 | /* Used to synchronize acceses to NatSemi SUPER I/O chip configure | 26 | /* Used to synchronize acceses to NatSemi SUPER I/O chip configure |
25 | * operations in asm/ns87303.h | 27 | * operations in asm/ns87303.h |
@@ -29,6 +31,61 @@ DEFINE_SPINLOCK(ns87303_lock); | |||
29 | extern void cpu_probe(void); | 31 | extern void cpu_probe(void); |
30 | extern void central_probe(void); | 32 | extern void central_probe(void); |
31 | 33 | ||
34 | u32 sun4v_vdev_devhandle; | ||
35 | int sun4v_vdev_root; | ||
36 | struct linux_prom_pci_intmap *sun4v_vdev_intmap; | ||
37 | int sun4v_vdev_num_intmap; | ||
38 | struct linux_prom_pci_intmap sun4v_vdev_intmask; | ||
39 | |||
40 | static void __init sun4v_virtual_device_probe(void) | ||
41 | { | ||
42 | struct linux_prom64_registers regs; | ||
43 | struct linux_prom_pci_intmap *ip; | ||
44 | int node, sz, err; | ||
45 | |||
46 | if (tlb_type != hypervisor) | ||
47 | return; | ||
48 | |||
49 | node = prom_getchild(prom_root_node); | ||
50 | node = prom_searchsiblings(node, "virtual-devices"); | ||
51 | if (!node) { | ||
52 | prom_printf("SUN4V: Fatal error, no virtual-devices node.\n"); | ||
53 | prom_halt(); | ||
54 | } | ||
55 | |||
56 | sun4v_vdev_root = node; | ||
57 | |||
58 | prom_getproperty(node, "reg", (char *)®s, sizeof(regs)); | ||
59 | sun4v_vdev_devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff; | ||
60 | |||
61 | sz = sizeof(*ip) * 64; | ||
62 | sun4v_vdev_intmap = ip = alloc_bootmem_low_pages(sz); | ||
63 | if (!sun4v_vdev_intmap) { | ||
64 | prom_printf("SUN4V: Error, cannot allocate vdev intmap.\n"); | ||
65 | prom_halt(); | ||
66 | } | ||
67 | |||
68 | err = prom_getproperty(node, "interrupt-map", (char *) ip, sz); | ||
69 | if (err == -1) { | ||
70 | prom_printf("SUN4V: Fatal error, no vdev interrupt-map.\n"); | ||
71 | prom_halt(); | ||
72 | } | ||
73 | |||
74 | sun4v_vdev_num_intmap = err / sizeof(*ip); | ||
75 | |||
76 | err = prom_getproperty(node, "interrupt-map-mask", | ||
77 | (char *) &sun4v_vdev_intmask, | ||
78 | sizeof(sun4v_vdev_intmask)); | ||
79 | if (err == -1) { | ||
80 | prom_printf("SUN4V: Fatal error, no vdev " | ||
81 | "interrupt-map-mask.\n"); | ||
82 | prom_halt(); | ||
83 | } | ||
84 | |||
85 | printk("SUN4V: virtual-devices devhandle[%x]\n", | ||
86 | sun4v_vdev_devhandle); | ||
87 | } | ||
88 | |||
32 | static const char *cpu_mid_prop(void) | 89 | static const char *cpu_mid_prop(void) |
33 | { | 90 | { |
34 | if (tlb_type == spitfire) | 91 | if (tlb_type == spitfire) |
@@ -177,6 +234,7 @@ void __init device_scan(void) | |||
177 | } | 234 | } |
178 | #endif | 235 | #endif |
179 | 236 | ||
237 | sun4v_virtual_device_probe(); | ||
180 | central_probe(); | 238 | central_probe(); |
181 | 239 | ||
182 | cpu_probe(); | 240 | cpu_probe(); |