diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-06-21 21:18:47 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-24 02:15:07 -0400 |
commit | e87dc35020bc555969810452f44bceaf8394eafa (patch) | |
tree | b58f14d41f8e147f6ddc2d9657a88813fdb73bdf /arch/sparc64/kernel/pci.c | |
parent | aaf7cec2769942035985716452107fc5ba0b11f6 (diff) |
[SPARC64]: Use in-kernel OBP device tree for PCI controller probing.
It can be pushed even further down, but this is a first step.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci.c')
-rw-r--r-- | arch/sparc64/kernel/pci.c | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 9472580a4319..a868c3792efb 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
23 | #include <asm/ebus.h> | 23 | #include <asm/ebus.h> |
24 | #include <asm/isa.h> | 24 | #include <asm/isa.h> |
25 | #include <asm/prom.h> | ||
25 | 26 | ||
26 | unsigned long pci_memspace_mask = 0xffffffffUL; | 27 | unsigned long pci_memspace_mask = 0xffffffffUL; |
27 | 28 | ||
@@ -177,16 +178,16 @@ void pci_config_write32(u32 *addr, u32 val) | |||
177 | } | 178 | } |
178 | 179 | ||
179 | /* Probe for all PCI controllers in the system. */ | 180 | /* Probe for all PCI controllers in the system. */ |
180 | extern void sabre_init(int, char *); | 181 | extern void sabre_init(struct device_node *, const char *); |
181 | extern void psycho_init(int, char *); | 182 | extern void psycho_init(struct device_node *, const char *); |
182 | extern void schizo_init(int, char *); | 183 | extern void schizo_init(struct device_node *, const char *); |
183 | extern void schizo_plus_init(int, char *); | 184 | extern void schizo_plus_init(struct device_node *, const char *); |
184 | extern void tomatillo_init(int, char *); | 185 | extern void tomatillo_init(struct device_node *, const char *); |
185 | extern void sun4v_pci_init(int, char *); | 186 | extern void sun4v_pci_init(struct device_node *, const char *); |
186 | 187 | ||
187 | static struct { | 188 | static struct { |
188 | char *model_name; | 189 | char *model_name; |
189 | void (*init)(int, char *); | 190 | void (*init)(struct device_node *, const char *); |
190 | } pci_controller_table[] __initdata = { | 191 | } pci_controller_table[] __initdata = { |
191 | { "SUNW,sabre", sabre_init }, | 192 | { "SUNW,sabre", sabre_init }, |
192 | { "pci108e,a000", sabre_init }, | 193 | { "pci108e,a000", sabre_init }, |
@@ -204,7 +205,7 @@ static struct { | |||
204 | #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ | 205 | #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ |
205 | sizeof(pci_controller_table[0])) | 206 | sizeof(pci_controller_table[0])) |
206 | 207 | ||
207 | static int __init pci_controller_init(char *model_name, int namelen, int node) | 208 | static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp) |
208 | { | 209 | { |
209 | int i; | 210 | int i; |
210 | 211 | ||
@@ -212,18 +213,15 @@ static int __init pci_controller_init(char *model_name, int namelen, int node) | |||
212 | if (!strncmp(model_name, | 213 | if (!strncmp(model_name, |
213 | pci_controller_table[i].model_name, | 214 | pci_controller_table[i].model_name, |
214 | namelen)) { | 215 | namelen)) { |
215 | pci_controller_table[i].init(node, model_name); | 216 | pci_controller_table[i].init(dp, model_name); |
216 | return 1; | 217 | return 1; |
217 | } | 218 | } |
218 | } | 219 | } |
219 | printk("PCI: Warning unknown controller, model name [%s]\n", | ||
220 | model_name); | ||
221 | printk("PCI: Ignoring controller...\n"); | ||
222 | 220 | ||
223 | return 0; | 221 | return 0; |
224 | } | 222 | } |
225 | 223 | ||
226 | static int __init pci_is_controller(char *model_name, int namelen, int node) | 224 | static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp) |
227 | { | 225 | { |
228 | int i; | 226 | int i; |
229 | 227 | ||
@@ -237,36 +235,35 @@ static int __init pci_is_controller(char *model_name, int namelen, int node) | |||
237 | return 0; | 235 | return 0; |
238 | } | 236 | } |
239 | 237 | ||
240 | static int __init pci_controller_scan(int (*handler)(char *, int, int)) | 238 | static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *)) |
241 | { | 239 | { |
242 | char namebuf[64]; | 240 | struct device_node *dp; |
243 | int node; | ||
244 | int count = 0; | 241 | int count = 0; |
245 | 242 | ||
246 | node = prom_getchild(prom_root_node); | 243 | for_each_node_by_name(dp, "pci") { |
247 | while ((node = prom_searchsiblings(node, "pci")) != 0) { | 244 | struct property *prop; |
248 | int len; | 245 | int len; |
249 | 246 | ||
250 | if ((len = prom_getproperty(node, "model", namebuf, sizeof(namebuf))) > 0 || | 247 | prop = of_find_property(dp, "model", &len); |
251 | (len = prom_getproperty(node, "compatible", namebuf, sizeof(namebuf))) > 0) { | 248 | if (!prop) |
249 | prop = of_find_property(dp, "compatible", &len); | ||
250 | |||
251 | if (prop) { | ||
252 | const char *model = prop->value; | ||
252 | int item_len = 0; | 253 | int item_len = 0; |
253 | 254 | ||
254 | /* Our value may be a multi-valued string in the | 255 | /* Our value may be a multi-valued string in the |
255 | * case of some compatible properties. For sanity, | 256 | * case of some compatible properties. For sanity, |
256 | * only try the first one. */ | 257 | * only try the first one. |
257 | 258 | */ | |
258 | while (namebuf[item_len] && len) { | 259 | while (model[item_len] && len) { |
259 | len--; | 260 | len--; |
260 | item_len++; | 261 | item_len++; |
261 | } | 262 | } |
262 | 263 | ||
263 | if (handler(namebuf, item_len, node)) | 264 | if (handler(model, item_len, dp)) |
264 | count++; | 265 | count++; |
265 | } | 266 | } |
266 | |||
267 | node = prom_getsibling(node); | ||
268 | if (!node) | ||
269 | break; | ||
270 | } | 267 | } |
271 | 268 | ||
272 | return count; | 269 | return count; |