aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-21 21:18:47 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:07 -0400
commite87dc35020bc555969810452f44bceaf8394eafa (patch)
treeb58f14d41f8e147f6ddc2d9657a88813fdb73bdf /arch/sparc64/kernel/pci.c
parentaaf7cec2769942035985716452107fc5ba0b11f6 (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.c53
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
26unsigned long pci_memspace_mask = 0xffffffffUL; 27unsigned 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. */
180extern void sabre_init(int, char *); 181extern void sabre_init(struct device_node *, const char *);
181extern void psycho_init(int, char *); 182extern void psycho_init(struct device_node *, const char *);
182extern void schizo_init(int, char *); 183extern void schizo_init(struct device_node *, const char *);
183extern void schizo_plus_init(int, char *); 184extern void schizo_plus_init(struct device_node *, const char *);
184extern void tomatillo_init(int, char *); 185extern void tomatillo_init(struct device_node *, const char *);
185extern void sun4v_pci_init(int, char *); 186extern void sun4v_pci_init(struct device_node *, const char *);
186 187
187static struct { 188static 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
207static int __init pci_controller_init(char *model_name, int namelen, int node) 208static 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
226static int __init pci_is_controller(char *model_name, int namelen, int node) 224static 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
240static int __init pci_controller_scan(int (*handler)(char *, int, int)) 238static 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;