aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/pci.h6
-rw-r--r--arch/mips/pci/fixup-cobalt.c61
-rw-r--r--arch/mips/pci/pci.c70
3 files changed, 4 insertions, 133 deletions
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 1e4fa3da3f70..6420e8df4e45 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -113,11 +113,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
113} 113}
114#endif 114#endif
115 115
116extern void pcibios_resource_to_bus(struct pci_dev *dev, 116#define ARCH_HAS_GENERIC_PCI_OFFSETS
117 struct pci_bus_region *region, struct resource *res);
118
119extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
120 struct pci_bus_region *region);
121 117
122#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index 118#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
123 119
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index acacd1407c63..9553b14002dd 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -51,67 +51,6 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
51DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, 51DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
52 qube_raq_galileo_early_fixup); 52 qube_raq_galileo_early_fixup);
53 53
54static void __devinit cobalt_legacy_ide_resource_fixup(struct pci_dev *dev,
55 struct resource *res)
56{
57 struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
58 unsigned long offset = hose->io_offset;
59 struct resource orig = *res;
60
61 if (!(res->flags & IORESOURCE_IO) ||
62 !(res->flags & IORESOURCE_PCI_FIXED))
63 return;
64
65 res->start -= offset;
66 res->end -= offset;
67 dev_printk(KERN_DEBUG, &dev->dev, "converted legacy %pR to bus %pR\n",
68 &orig, res);
69}
70
71static void __devinit cobalt_legacy_ide_fixup(struct pci_dev *dev)
72{
73 u32 class;
74 u8 progif;
75
76 /*
77 * If the IDE controller is in legacy mode, pci_setup_device() fills in
78 * the resources with the legacy addresses that normally appear on the
79 * PCI bus, just as if we had read them from a BAR.
80 *
81 * However, with the GT-64111, those legacy addresses, e.g., 0x1f0,
82 * will never appear on the PCI bus because it converts memory accesses
83 * in the PCI I/O region (which is never at address zero) into I/O port
84 * accesses with no address translation.
85 *
86 * For example, if GT_DEF_PCI0_IO_BASE is 0x10000000, a load or store
87 * to physical address 0x100001f0 will become a PCI access to I/O port
88 * 0x100001f0. There's no way to generate an access to I/O port 0x1f0,
89 * but the VT82C586 IDE controller does respond at 0x100001f0 because
90 * it only decodes the low 24 bits of the address.
91 *
92 * When this quirk runs, the pci_dev resources should contain bus
93 * addresses, not Linux I/O port numbers, so convert legacy addresses
94 * like 0x1f0 to bus addresses like 0x100001f0. Later, we'll convert
95 * them back with pcibios_fixup_bus() or pcibios_bus_to_resource().
96 */
97 class = dev->class >> 8;
98 if (class != PCI_CLASS_STORAGE_IDE)
99 return;
100
101 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
102 if ((progif & 1) == 0) {
103 cobalt_legacy_ide_resource_fixup(dev, &dev->resource[0]);
104 cobalt_legacy_ide_resource_fixup(dev, &dev->resource[1]);
105 }
106 if ((progif & 4) == 0) {
107 cobalt_legacy_ide_resource_fixup(dev, &dev->resource[2]);
108 cobalt_legacy_ide_resource_fixup(dev, &dev->resource[3]);
109 }
110}
111
112DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
113 cobalt_legacy_ide_fixup);
114
115static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) 54static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
116{ 55{
117 unsigned short cfgword; 56 unsigned short cfgword;
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 19f6d194a568..0514866fa925 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -88,8 +88,9 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
88 if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) 88 if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY))
89 next_busno = (*hose->get_busno)(); 89 next_busno = (*hose->get_busno)();
90 90
91 pci_add_resource(&resources, hose->mem_resource); 91 pci_add_resource_offset(&resources,
92 pci_add_resource(&resources, hose->io_resource); 92 hose->mem_resource, hose->mem_offset);
93 pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset);
93 bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, 94 bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
94 &resources); 95 &resources);
95 if (!bus) 96 if (!bus)
@@ -247,45 +248,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
247 return pcibios_plat_dev_init(dev); 248 return pcibios_plat_dev_init(dev);
248} 249}
249 250
250static void pcibios_fixup_device_resources(struct pci_dev *dev,
251 struct pci_bus *bus)
252{
253 /* Update device resources. */
254 struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
255 unsigned long offset = 0;
256 int i;
257
258 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
259 if (!dev->resource[i].start)
260 continue;
261 if (dev->resource[i].flags & IORESOURCE_IO)
262 offset = hose->io_offset;
263 else if (dev->resource[i].flags & IORESOURCE_MEM)
264 offset = hose->mem_offset;
265
266 dev->resource[i].start += offset;
267 dev->resource[i].end += offset;
268 }
269}
270
271void __devinit pcibios_fixup_bus(struct pci_bus *bus) 251void __devinit pcibios_fixup_bus(struct pci_bus *bus)
272{ 252{
273 /* Propagate hose info into the subordinate devices. */
274
275 struct list_head *ln;
276 struct pci_dev *dev = bus->self; 253 struct pci_dev *dev = bus->self;
277 254
278 if (pci_has_flag(PCI_PROBE_ONLY) && dev && 255 if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
279 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 256 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
280 pci_read_bridge_bases(bus); 257 pci_read_bridge_bases(bus);
281 pcibios_fixup_device_resources(dev, bus);
282 }
283
284 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
285 dev = pci_dev_b(ln);
286
287 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
288 pcibios_fixup_device_resources(dev, bus);
289 } 258 }
290} 259}
291 260
@@ -295,40 +264,7 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
295 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); 264 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
296} 265}
297 266
298void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
299 struct resource *res)
300{
301 struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
302 unsigned long offset = 0;
303
304 if (res->flags & IORESOURCE_IO)
305 offset = hose->io_offset;
306 else if (res->flags & IORESOURCE_MEM)
307 offset = hose->mem_offset;
308
309 region->start = res->start - offset;
310 region->end = res->end - offset;
311}
312
313void __devinit
314pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
315 struct pci_bus_region *region)
316{
317 struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
318 unsigned long offset = 0;
319
320 if (res->flags & IORESOURCE_IO)
321 offset = hose->io_offset;
322 else if (res->flags & IORESOURCE_MEM)
323 offset = hose->mem_offset;
324
325 res->start = region->start + offset;
326 res->end = region->end + offset;
327}
328
329#ifdef CONFIG_HOTPLUG 267#ifdef CONFIG_HOTPLUG
330EXPORT_SYMBOL(pcibios_resource_to_bus);
331EXPORT_SYMBOL(pcibios_bus_to_resource);
332EXPORT_SYMBOL(PCIBIOS_MIN_IO); 268EXPORT_SYMBOL(PCIBIOS_MIN_IO);
333EXPORT_SYMBOL(PCIBIOS_MIN_MEM); 269EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
334#endif 270#endif