diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2012-07-09 15:39:52 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-07-10 10:34:59 -0400 |
commit | 1c975931128c1128892981095a64fb8eabf240eb (patch) | |
tree | 48060e9f4dd7d7c9a97235de16bb323951bb5c9a /arch/sparc | |
parent | fd591341102ba5eb9e517d3889e7566fa45e021e (diff) |
sparc/PCI: replace pci_cfg_fake_ranges() with pci_read_bridge_bases()
The generic code to read P2P bridge windows is functionally equivalent
to the sparc-specific pci_cfg_fake_ranges(), so use the generic code.
The "if (!res->start) res->start = ..." removed from the I/O window code
here was an artifact of the Intel 1K window support from 9d265124d051 and
is no longer necessary (it probably was just cloned from x86 and was never
useful on sparc).
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/kernel/pci.c | 89 |
1 files changed, 1 insertions, 88 deletions
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index fdaf21811670..fa53d552875f 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -375,93 +375,6 @@ static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) | |||
375 | *last_p = last; | 375 | *last_p = last; |
376 | } | 376 | } |
377 | 377 | ||
378 | /* For PCI bus devices which lack a 'ranges' property we interrogate | ||
379 | * the config space values to set the resources, just like the generic | ||
380 | * Linux PCI probing code does. | ||
381 | */ | ||
382 | static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | ||
383 | struct pci_bus *bus, | ||
384 | struct pci_pbm_info *pbm) | ||
385 | { | ||
386 | struct pci_bus_region region; | ||
387 | struct resource *res, res2; | ||
388 | u8 io_base_lo, io_limit_lo; | ||
389 | u16 mem_base_lo, mem_limit_lo; | ||
390 | unsigned long base, limit; | ||
391 | |||
392 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | ||
393 | pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); | ||
394 | base = (io_base_lo & PCI_IO_RANGE_MASK) << 8; | ||
395 | limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8; | ||
396 | |||
397 | if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { | ||
398 | u16 io_base_hi, io_limit_hi; | ||
399 | |||
400 | pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi); | ||
401 | pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi); | ||
402 | base |= (io_base_hi << 16); | ||
403 | limit |= (io_limit_hi << 16); | ||
404 | } | ||
405 | |||
406 | res = bus->resource[0]; | ||
407 | if (base <= limit) { | ||
408 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | ||
409 | res2.flags = res->flags; | ||
410 | region.start = base; | ||
411 | region.end = limit + 0xfff; | ||
412 | pcibios_bus_to_resource(dev, &res2, ®ion); | ||
413 | if (!res->start) | ||
414 | res->start = res2.start; | ||
415 | if (!res->end) | ||
416 | res->end = res2.end; | ||
417 | } | ||
418 | |||
419 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); | ||
420 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); | ||
421 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
422 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
423 | |||
424 | res = bus->resource[1]; | ||
425 | if (base <= limit) { | ||
426 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
427 | IORESOURCE_MEM); | ||
428 | region.start = base; | ||
429 | region.end = limit + 0xfffff; | ||
430 | pcibios_bus_to_resource(dev, res, ®ion); | ||
431 | } | ||
432 | |||
433 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | ||
434 | pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); | ||
435 | base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; | ||
436 | limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; | ||
437 | |||
438 | if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { | ||
439 | u32 mem_base_hi, mem_limit_hi; | ||
440 | |||
441 | pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi); | ||
442 | pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi); | ||
443 | |||
444 | /* | ||
445 | * Some bridges set the base > limit by default, and some | ||
446 | * (broken) BIOSes do not initialize them. If we find | ||
447 | * this, just assume they are not being used. | ||
448 | */ | ||
449 | if (mem_base_hi <= mem_limit_hi) { | ||
450 | base |= ((long) mem_base_hi) << 32; | ||
451 | limit |= ((long) mem_limit_hi) << 32; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | res = bus->resource[2]; | ||
456 | if (base <= limit) { | ||
457 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
458 | IORESOURCE_MEM | IORESOURCE_PREFETCH); | ||
459 | region.start = base; | ||
460 | region.end = limit + 0xfffff; | ||
461 | pcibios_bus_to_resource(dev, res, ®ion); | ||
462 | } | ||
463 | } | ||
464 | |||
465 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack | 378 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack |
466 | * a proper 'ranges' property. | 379 | * a proper 'ranges' property. |
467 | */ | 380 | */ |
@@ -550,7 +463,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
550 | apb_fake_ranges(dev, bus, pbm); | 463 | apb_fake_ranges(dev, bus, pbm); |
551 | goto after_ranges; | 464 | goto after_ranges; |
552 | } else if (ranges == NULL) { | 465 | } else if (ranges == NULL) { |
553 | pci_cfg_fake_ranges(dev, bus, pbm); | 466 | pci_read_bridge_bases(bus); |
554 | goto after_ranges; | 467 | goto after_ranges; |
555 | } | 468 | } |
556 | i = 1; | 469 | i = 1; |