aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/pci_32.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-19 22:54:51 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-20 00:18:09 -0500
commitbf5e2ba28f24f82a64524ef4772c9ebe12e2cd2a (patch)
treef35c139d124a9276b71260c13c8bddf0aa02b4d7 /arch/powerpc/kernel/pci_32.c
parentfe2d338cdcc628e0abdb4f70570a7fa864c617db (diff)
[POWERPC] Merge PCI resource fixups
The PCI code in 32 and 64 bits fixes up resources differently. 32 bits uses a header quirk plus handles bridges in pcibios_fixup_bus() while 64 bits does things in various places depending on whether you are using OF probing, using PCI hotplug, etc... This merges those by basically using the 32 bits approach for both, with various tweaks to make 64 bits work with the new approach. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/pci_32.c')
-rw-r--r--arch/powerpc/kernel/pci_32.c83
1 files changed, 2 insertions, 81 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index f05ef5b17892..717c554d4658 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -40,7 +40,6 @@ unsigned int ppc_pci_flags;
40 40
41void pcibios_make_OF_bus_map(void); 41void pcibios_make_OF_bus_map(void);
42 42
43static void pcibios_fixup_resources(struct pci_dev* dev);
44static void fixup_broken_pcnet32(struct pci_dev* dev); 43static void fixup_broken_pcnet32(struct pci_dev* dev);
45static int reparent_resources(struct resource *parent, struct resource *res); 44static int reparent_resources(struct resource *parent, struct resource *res);
46static void fixup_cpc710_pci64(struct pci_dev* dev); 45static void fixup_cpc710_pci64(struct pci_dev* dev);
@@ -98,53 +97,6 @@ fixup_cpc710_pci64(struct pci_dev* dev)
98} 97}
99DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64); 98DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64);
100 99
101static void
102pcibios_fixup_resources(struct pci_dev *dev)
103{
104 struct pci_controller* hose = (struct pci_controller *)dev->sysdata;
105 int i;
106 resource_size_t offset, mask;
107
108 if (!hose) {
109 printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev));
110 return;
111 }
112 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
113 struct resource *res = dev->resource + i;
114 if (!res->flags)
115 continue;
116 if (res->end == 0xffffffff) {
117 DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n",
118 pci_name(dev), i, (u64)res->start, (u64)res->end);
119 res->end -= res->start;
120 res->start = 0;
121 res->flags |= IORESOURCE_UNSET;
122 continue;
123 }
124 offset = 0;
125 mask = (resource_size_t)-1;
126 if (res->flags & IORESOURCE_MEM) {
127 offset = hose->pci_mem_offset;
128 } else if (res->flags & IORESOURCE_IO) {
129 offset = (unsigned long) hose->io_base_virt
130 - isa_io_base;
131 mask = 0xffffffffu;
132 }
133 if (offset != 0) {
134 res->start = (res->start + offset) & mask;
135 res->end = (res->end + offset) & mask;
136 DBG("PCI: Fixup res %d (0x%lx) of dev %s: %llx -> %llx\n",
137 i, res->flags, pci_name(dev),
138 (u64)res->start - offset, (u64)res->start);
139 }
140 }
141
142 /* Call machine specific resource fixup */
143 if (ppc_md.pcibios_fixup_resources)
144 ppc_md.pcibios_fixup_resources(dev);
145}
146DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
147
148static int skip_isa_ioresource_align(struct pci_dev *dev) 100static int skip_isa_ioresource_align(struct pci_dev *dev)
149{ 101{
150 if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && 102 if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
@@ -757,14 +709,14 @@ pcibios_init(void)
757 709
758subsys_initcall(pcibios_init); 710subsys_initcall(pcibios_init);
759 711
760void pcibios_fixup_bus(struct pci_bus *bus) 712void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
761{ 713{
762 struct pci_controller *hose = (struct pci_controller *) bus->sysdata; 714 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
763 unsigned long io_offset; 715 unsigned long io_offset;
764 struct resource *res; 716 struct resource *res;
765 struct pci_dev *dev;
766 int i; 717 int i;
767 718
719 /* Hookup PHB resources */
768 io_offset = (unsigned long)hose->io_base_virt - isa_io_base; 720 io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
769 if (bus->parent == NULL) { 721 if (bus->parent == NULL) {
770 /* This is a host bridge - fill in its resources */ 722 /* This is a host bridge - fill in its resources */
@@ -795,37 +747,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
795 } 747 }
796 bus->resource[i+1] = res; 748 bus->resource[i+1] = res;
797 } 749 }
798 } else {
799 /* This is a subordinate bridge */
800 pci_read_bridge_bases(bus);
801
802 for (i = 0; i < 4; ++i) {
803 if ((res = bus->resource[i]) == NULL)
804 continue;
805 if (!res->flags || bus->self->transparent)
806 continue;
807 if (io_offset && (res->flags & IORESOURCE_IO)) {
808 res->start = (res->start + io_offset) &
809 0xffffffffu;
810 res->end = (res->end + io_offset) &
811 0xffffffffu;
812 } else if (hose->pci_mem_offset
813 && (res->flags & IORESOURCE_MEM)) {
814 res->start += hose->pci_mem_offset;
815 res->end += hose->pci_mem_offset;
816 }
817 }
818 }
819
820 /* Platform specific bus fixups */
821 if (ppc_md.pcibios_fixup_bus)
822 ppc_md.pcibios_fixup_bus(bus);
823
824 /* Read default IRQs and fixup if necessary */
825 list_for_each_entry(dev, &bus->devices, bus_list) {
826 pci_read_irq_line(dev);
827 if (ppc_md.pci_irq_fixup)
828 ppc_md.pci_irq_fixup(dev);
829 } 750 }
830} 751}
831 752