[SPARC64]: Kill sun4v virtual device layer.
[pandora-kernel.git] / arch / sparc64 / kernel / devices.c
1 /* devices.c: Initial scan of the prom device tree for important
2  *            Sparc device nodes which we need to find.
3  *
4  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
5  */
6
7 #include <linux/config.h>
8 #include <linux/kernel.h>
9 #include <linux/threads.h>
10 #include <linux/init.h>
11 #include <linux/ioport.h>
12 #include <linux/string.h>
13 #include <linux/spinlock.h>
14 #include <linux/errno.h>
15 #include <linux/bootmem.h>
16
17 #include <asm/page.h>
18 #include <asm/oplib.h>
19 #include <asm/system.h>
20 #include <asm/smp.h>
21 #include <asm/spitfire.h>
22 #include <asm/timer.h>
23 #include <asm/cpudata.h>
24
25 /* Used to synchronize acceses to NatSemi SUPER I/O chip configure
26  * operations in asm/ns87303.h
27  */
28 DEFINE_SPINLOCK(ns87303_lock);
29
30 extern void cpu_probe(void);
31 extern void central_probe(void);
32
33 static const char *cpu_mid_prop(void)
34 {
35         if (tlb_type == spitfire)
36                 return "upa-portid";
37         return "portid";
38 }
39
40 static int get_cpu_mid(struct device_node *dp)
41 {
42         struct property *prop;
43
44         if (tlb_type == hypervisor) {
45                 struct linux_prom64_registers *reg;
46                 int len;
47
48                 prop = of_find_property(dp, "cpuid", &len);
49                 if (prop && len == 4)
50                         return *(int *) prop->value;
51
52                 prop = of_find_property(dp, "reg", NULL);
53                 reg = prop->value;
54                 return (reg[0].phys_addr >> 32) & 0x0fffffffUL;
55         } else {
56                 const char *prop_name = cpu_mid_prop();
57
58                 prop = of_find_property(dp, prop_name, NULL);
59                 if (prop)
60                         return *(int *) prop->value;
61                 return 0;
62         }
63 }
64
65 static int check_cpu_node(struct device_node *dp, int *cur_inst,
66                           int (*compare)(struct device_node *, int, void *),
67                           void *compare_arg,
68                           struct device_node **dev_node, int *mid)
69 {
70         if (strcmp(dp->type, "cpu"))
71                 return -ENODEV;
72
73         if (!compare(dp, *cur_inst, compare_arg)) {
74                 if (dev_node)
75                         *dev_node = dp;
76                 if (mid)
77                         *mid = get_cpu_mid(dp);
78                 return 0;
79         }
80
81         (*cur_inst)++;
82
83         return -ENODEV;
84 }
85
86 static int __cpu_find_by(int (*compare)(struct device_node *, int, void *),
87                          void *compare_arg,
88                          struct device_node **dev_node, int *mid)
89 {
90         struct device_node *dp;
91         int cur_inst;
92
93         cur_inst = 0;
94         for_each_node_by_type(dp, "cpu") {
95                 int err = check_cpu_node(dp, &cur_inst,
96                                          compare, compare_arg,
97                                          dev_node, mid);
98                 if (err == 0)
99                         return 0;
100         }
101
102         return -ENODEV;
103 }
104
105 static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg)
106 {
107         int desired_instance = (int) (long) _arg;
108
109         if (instance == desired_instance)
110                 return 0;
111         return -ENODEV;
112 }
113
114 int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid)
115 {
116         return __cpu_find_by(cpu_instance_compare, (void *)(long)instance,
117                              dev_node, mid);
118 }
119
120 static int cpu_mid_compare(struct device_node *dp, int instance, void *_arg)
121 {
122         int desired_mid = (int) (long) _arg;
123         int this_mid;
124
125         this_mid = get_cpu_mid(dp);
126         if (this_mid == desired_mid)
127                 return 0;
128         return -ENODEV;
129 }
130
131 int cpu_find_by_mid(int mid, struct device_node **dev_node)
132 {
133         return __cpu_find_by(cpu_mid_compare, (void *)(long)mid,
134                              dev_node, NULL);
135 }
136
137 void __init device_scan(void)
138 {
139         /* FIX ME FAST... -DaveM */
140         ioport_resource.end = 0xffffffffffffffffUL;
141
142         prom_printf("Booting Linux...\n");
143
144 #ifndef CONFIG_SMP
145         {
146                 struct device_node *dp;
147                 int err, def;
148
149                 err = cpu_find_by_instance(0, &dp, NULL);
150                 if (err) {
151                         prom_printf("No cpu nodes, cannot continue\n");
152                         prom_halt();
153                 }
154                 cpu_data(0).clock_tick =
155                         of_getintprop_default(dp, "clock-frequency", 0);
156
157                 def = ((tlb_type == hypervisor) ?
158                        (8 * 1024) :
159                        (16 * 1024));
160                 cpu_data(0).dcache_size = of_getintprop_default(dp,
161                                                                 "dcache-size",
162                                                                 def);
163
164                 def = 32;
165                 cpu_data(0).dcache_line_size =
166                         of_getintprop_default(dp, "dcache-line-size", def);
167
168                 def = 16 * 1024;
169                 cpu_data(0).icache_size = of_getintprop_default(dp,
170                                                                 "icache-size",
171                                                                 def);
172
173                 def = 32;
174                 cpu_data(0).icache_line_size =
175                         of_getintprop_default(dp, "icache-line-size", def);
176
177                 def = ((tlb_type == hypervisor) ?
178                        (3 * 1024 * 1024) :
179                        (4 * 1024 * 1024));
180                 cpu_data(0).ecache_size = of_getintprop_default(dp,
181                                                                 "ecache-size",
182                                                                 def);
183
184                 def = 64;
185                 cpu_data(0).ecache_line_size =
186                         of_getintprop_default(dp, "ecache-line-size", def);
187                 printk("CPU[0]: Caches "
188                        "D[sz(%d):line_sz(%d)] "
189                        "I[sz(%d):line_sz(%d)] "
190                        "E[sz(%d):line_sz(%d)]\n",
191                        cpu_data(0).dcache_size, cpu_data(0).dcache_line_size,
192                        cpu_data(0).icache_size, cpu_data(0).icache_line_size,
193                        cpu_data(0).ecache_size, cpu_data(0).ecache_line_size);
194         }
195 #endif
196
197         central_probe();
198
199         cpu_probe();
200 }