aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/pci-common.c163
1 files changed, 116 insertions, 47 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 8c0270929cc0..01ce8c38bae6 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -780,11 +780,6 @@ static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
780 780
781 res->start = (res->start + offset) & mask; 781 res->start = (res->start + offset) & mask;
782 res->end = (res->end + offset) & mask; 782 res->end = (res->end + offset) & mask;
783
784 pr_debug("PCI:%s %016llx-%016llx\n",
785 pci_name(dev),
786 (unsigned long long)res->start,
787 (unsigned long long)res->end);
788} 783}
789 784
790 785
@@ -830,6 +825,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
830 (unsigned int)res->flags); 825 (unsigned int)res->flags);
831 826
832 fixup_resource(res, dev); 827 fixup_resource(res, dev);
828
829 pr_debug("PCI:%s %016llx-%016llx\n",
830 pci_name(dev),
831 (unsigned long long)res->start,
832 (unsigned long long)res->end);
833 } 833 }
834 834
835 /* Call machine specific resource fixup */ 835 /* Call machine specific resource fixup */
@@ -838,58 +838,127 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
838} 838}
839DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); 839DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
840 840
841static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) 841/* This function tries to figure out if a bridge resource has been initialized
842 * by the firmware or not. It doesn't have to be absolutely bullet proof, but
843 * things go more smoothly when it gets it right. It should covers cases such
844 * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges
845 */
846static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
847 struct resource *res)
842{ 848{
843 struct pci_controller *hose = pci_bus_to_host(bus); 849 struct pci_controller *hose = pci_bus_to_host(bus);
844 struct pci_dev *dev = bus->self; 850 struct pci_dev *dev = bus->self;
851 resource_size_t offset;
852 u16 command;
853 int i;
845 854
846 pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB"); 855 /* We don't do anything if PCI_PROBE_ONLY is set */
856 if (ppc_pci_flags & PPC_PCI_PROBE_ONLY)
857 return 0;
847 858
848 /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for 859 /* Job is a bit different between memory and IO */
849 * now differently between 32 and 64 bits. 860 if (res->flags & IORESOURCE_MEM) {
850 */ 861 /* If the BAR is non-0 (res != pci_mem_offset) then it's probably been
851 if (dev != NULL) { 862 * initialized by somebody
852 struct resource *res; 863 */
853 int i; 864 if (res->start != hose->pci_mem_offset)
865 return 0;
854 866
855 for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { 867 /* The BAR is 0, let's check if memory decoding is enabled on
856 if ((res = bus->resource[i]) == NULL) 868 * the bridge. If not, we consider it unassigned
857 continue; 869 */
858 if (!res->flags) 870 pci_read_config_word(dev, PCI_COMMAND, &command);
859 continue; 871 if ((command & PCI_COMMAND_MEMORY) == 0)
860 if (i >= 3 && bus->self->transparent) 872 return 1;
861 continue;
862 /* On PowerMac, Apple leaves bridge windows open over
863 * an inaccessible region of memory space (0...fffff)
864 * which is somewhat bogus, but that's what they think
865 * means disabled...
866 *
867 * We clear those to force them to be reallocated later
868 *
869 * We detect such regions by the fact that the base is
870 * equal to the pci_mem_offset of the host bridge and
871 * their size is smaller than 1M.
872 */
873 if (res->flags & IORESOURCE_MEM &&
874 res->start == hose->pci_mem_offset &&
875 res->end < 0x100000) {
876 printk(KERN_INFO
877 "PCI: Closing bogus Apple Firmware"
878 " region %d on bus 0x%02x\n",
879 i, bus->number);
880 res->flags = 0;
881 continue;
882 }
883 873
884 pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", 874 /* Memory decoding is enabled and the BAR is 0. If any of the bridge
885 pci_name(dev), i, 875 * resources covers that starting address (0 then it's good enough for
886 (unsigned long long)res->start,\ 876 * us for memory
887 (unsigned long long)res->end, 877 */
888 (unsigned int)res->flags); 878 for (i = 0; i < 3; i++) {
879 if ((hose->mem_resources[i].flags & IORESOURCE_MEM) &&
880 hose->mem_resources[i].start == hose->pci_mem_offset)
881 return 0;
882 }
883
884 /* Well, it starts at 0 and we know it will collide so we may as
885 * well consider it as unassigned. That covers the Apple case.
886 */
887 return 1;
888 } else {
889 /* If the BAR is non-0, then we consider it assigned */
890 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
891 if (((res->start - offset) & 0xfffffffful) != 0)
892 return 0;
893
894 /* Here, we are a bit different than memory as typically IO space
895 * starting at low addresses -is- valid. What we do instead if that
896 * we consider as unassigned anything that doesn't have IO enabled
897 * in the PCI command register, and that's it.
898 */
899 pci_read_config_word(dev, PCI_COMMAND, &command);
900 if (command & PCI_COMMAND_IO)
901 return 0;
902
903 /* It's starting at 0 and IO is disabled in the bridge, consider
904 * it unassigned
905 */
906 return 1;
907 }
908}
909
910/* Fixup resources of a PCI<->PCI bridge */
911static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
912{
913 struct resource *res;
914 int i;
915
916 struct pci_dev *dev = bus->self;
889 917
890 fixup_resource(res, dev); 918 for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
919 if ((res = bus->resource[i]) == NULL)
920 continue;
921 if (!res->flags)
922 continue;
923 if (i >= 3 && bus->self->transparent)
924 continue;
925
926 pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
927 pci_name(dev), i,
928 (unsigned long long)res->start,\
929 (unsigned long long)res->end,
930 (unsigned int)res->flags);
931
932 /* Perform fixup */
933 fixup_resource(res, dev);
934
935 /* Try to detect uninitialized P2P bridge resources,
936 * and clear them out so they get re-assigned later
937 */
938 if (pcibios_uninitialized_bridge_resource(bus, res)) {
939 res->flags = 0;
940 pr_debug("PCI:%s (unassigned)\n", pci_name(dev));
941 } else {
942
943 pr_debug("PCI:%s %016llx-%016llx\n",
944 pci_name(dev),
945 (unsigned long long)res->start,
946 (unsigned long long)res->end);
891 } 947 }
892 } 948 }
949}
950
951static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
952{
953 struct pci_dev *dev = bus->self;
954
955 pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
956
957 /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
958 * now differently between 32 and 64 bits.
959 */
960 if (dev != NULL)
961 pcibios_fixup_bridge(bus);
893 962
894 /* Additional setup that is different between 32 and 64 bits for now */ 963 /* Additional setup that is different between 32 and 64 bits for now */
895 pcibios_do_bus_setup(bus); 964 pcibios_do_bus_setup(bus);