aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/of_device.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@ultra5.davemloft.net>2007-03-04 15:53:19 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 04:55:10 -0400
commit01f94c4a6ced476ce69b895426fc29bfc48c69bd (patch)
tree68866108644a1e90ae7688d2e35cb8462ab6a07c /arch/sparc64/kernel/of_device.c
parenta378fd0ee8ea6af5dafd0ab3d634f22b926b5ac4 (diff)
[SPARC64]: Fix sabre pci controllers with new probing scheme.
The SIMBA APB bridge is strange, it is a PCI bridge but it lacks some standard OF properties, in particular it lacks a 'ranges' property. What you have to do is read the IO and MEM range registers in the APB bridge to determine the ranges handled by each bridge. So fill in the bus resources by doing that. Since we now handle this quirk in the generic PCI and OF device probing layers, we can flat out eliminate all of that code from the sabre pci controller driver. In fact we can thus eliminate completely another quirk of the sabre driver. It tried to make the two APB bridges look like PBMs but that makes zero sense now (and it's questionable whether it ever made sense). So now just use pbm_A and probe the whole PCI hierarchy using that as the root. This simplification allows many future cleanups to occur. Also, I've found yet another quirk that needs to be worked around while testing this. You can't use the 'class-code' OF firmware property, especially for IDE controllers. We have to read the value out of PCI config space or else we'll see the value the device was showing before it was programmed into native mode. I'm starting to think it might be wise to just read all of the values out of PCI config space instead of using the OF properties. :-/ Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/of_device.c')
-rw-r--r--arch/sparc64/kernel/of_device.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 6b8798141f2c..8964eacb0048 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -317,6 +317,11 @@ static unsigned int of_bus_default_get_flags(const u32 *addr)
317static int of_bus_pci_match(struct device_node *np) 317static int of_bus_pci_match(struct device_node *np)
318{ 318{
319 if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { 319 if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
320 char *model = of_get_property(np, "model", NULL);
321
322 if (model && !strcmp(model, "SUNW,simba"))
323 return 0;
324
320 /* Do not do PCI specific frobbing if the 325 /* Do not do PCI specific frobbing if the
321 * PCI bridge lacks a ranges property. We 326 * PCI bridge lacks a ranges property. We
322 * want to pass it through up to the next 327 * want to pass it through up to the next
@@ -332,6 +337,21 @@ static int of_bus_pci_match(struct device_node *np)
332 return 0; 337 return 0;
333} 338}
334 339
340static int of_bus_simba_match(struct device_node *np)
341{
342 char *model = of_get_property(np, "model", NULL);
343
344 if (model && !strcmp(model, "SUNW,simba"))
345 return 1;
346 return 0;
347}
348
349static int of_bus_simba_map(u32 *addr, const u32 *range,
350 int na, int ns, int pna)
351{
352 return 0;
353}
354
335static void of_bus_pci_count_cells(struct device_node *np, 355static void of_bus_pci_count_cells(struct device_node *np,
336 int *addrc, int *sizec) 356 int *addrc, int *sizec)
337{ 357{
@@ -436,6 +456,15 @@ static struct of_bus of_busses[] = {
436 .map = of_bus_pci_map, 456 .map = of_bus_pci_map,
437 .get_flags = of_bus_pci_get_flags, 457 .get_flags = of_bus_pci_get_flags,
438 }, 458 },
459 /* SIMBA */
460 {
461 .name = "simba",
462 .addr_prop_name = "assigned-addresses",
463 .match = of_bus_simba_match,
464 .count_cells = of_bus_pci_count_cells,
465 .map = of_bus_simba_map,
466 .get_flags = of_bus_pci_get_flags,
467 },
439 /* SBUS */ 468 /* SBUS */
440 { 469 {
441 .name = "sbus", 470 .name = "sbus",