patch-2.4.1 linux/arch/ppc/kernel/chrp_pci.c

Next file: linux/arch/ppc/kernel/chrp_setup.c
Previous file: linux/arch/ppc/kernel/apus_setup.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0/linux/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c
@@ -8,8 +8,8 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/openpic.h>
 #include <linux/ide.h>
+#include <linux/bootmem.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -19,16 +19,19 @@
 #include <asm/gg2.h>
 #include <asm/machdep.h>
 #include <asm/init.h>
+#include <asm/pci-bridge.h>
 
+#include "open_pic.h"
 #include "pci.h"
 
+
 #ifdef CONFIG_POWER4
-static unsigned long pci_address_offset(int, unsigned int);
+extern unsigned long pci_address_offset(int, unsigned int);
 #endif /* CONFIG_POWER4 */
 
 /* LongTrail */
-#define pci_config_addr(bus, dev, offset) \
-(GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset))
+#define pci_config_addr(dev, offset) \
+(GG2_PCI_CONFIG_BASE | ((dev->bus->number)<<16) | ((dev->devfn)<<8) | (offset))
 
 volatile struct Hydra *Hydra = NULL;
 
@@ -37,205 +40,127 @@
  * limit the bus number to 3 bits
  */
 
-int __chrp gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
-				 unsigned char offset, unsigned char *val)
-{
-	if (bus > 7) {
-		*val = 0xff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	*val = in_8((unsigned char *)pci_config_addr(bus, dev_fn, offset));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
-				 unsigned char offset, unsigned short *val)
-{
-	if (bus > 7) {
-		*val = 0xffff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	*val = in_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset));
-	return PCIBIOS_SUCCESSFUL;
-}
-
+#define cfg_read(val, addr, type, op)	*val = op((type)(addr))
+#define cfg_write(val, addr, type, op)	op((type *)(addr), (val))
 
-int __chrp gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
-				  unsigned char offset, unsigned int *val)
-{
-	if (bus > 7) {
-		*val = 0xffffffff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	*val = in_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
-				  unsigned char offset, unsigned char val)
-{
-	if (bus > 7)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	out_8((unsigned char *)pci_config_addr(bus, dev_fn, offset), val);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
-				  unsigned char offset, unsigned short val)
-{
-	if (bus > 7)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	out_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset), val);
-	return PCIBIOS_SUCCESSFUL;
-}
+#define cfg_read_bad(val, size)		*val = bad_##size;
+#define cfg_write_bad(val, size)
 
-int __chrp gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
-				   unsigned char offset, unsigned int val)
-{
-	if (bus > 7)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	out_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset), val);
-	return PCIBIOS_SUCCESSFUL;
-}
+#define bad_byte	0xff
+#define bad_word	0xffff
+#define bad_dword	0xffffffffU
+
+#define GG2_PCI_OP(rw, size, type, op)					    \
+int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
+{									    \
+	if (dev->bus->number > 7) {					    \
+		cfg_##rw##_bad(val, size)				    \
+		return PCIBIOS_DEVICE_NOT_FOUND;			    \
+	}								    \
+	cfg_##rw(val, pci_config_addr(dev, off), type, op);		    \
+	return PCIBIOS_SUCCESSFUL;					    \
+}
+
+GG2_PCI_OP(read, byte, u8 *, in_8)
+GG2_PCI_OP(read, word, u16 *, in_le16)
+GG2_PCI_OP(read, dword, u32 *, in_le32)
+GG2_PCI_OP(write, byte, u8, out_8)
+GG2_PCI_OP(write, word, u16, out_le16)
+GG2_PCI_OP(write, dword, u32, out_le32)
+
+static struct pci_ops gg2_pci_ops =
+{
+	gg2_read_config_byte,
+	gg2_read_config_word,
+	gg2_read_config_dword,
+	gg2_write_config_byte,
+	gg2_write_config_word,
+	gg2_write_config_dword
+};
 
-#define python_config_address(bus) (unsigned *)((0xfef00000+0xf8000)-(bus*0x100000))
-#define python_config_data(bus) ((0xfef00000+0xf8010)-(bus*0x100000))
-#define PYTHON_CFA(b, d, o)	(0x80 | ((b<<6) << 8) | ((d) << 16) \
+/*
+ * Access functions for PCI config space on IBM "python" host bridges.
+ */
+#define PYTHON_CFA(b, d, o)	(0x80 | ((b) << 8) | ((d) << 16) \
 				 | (((o) & ~3) << 24))
-unsigned int python_busnr = 0;
-
-int __chrp python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
-				    unsigned char offset, unsigned char *val)
-{
-	if (bus > python_busnr) {
-		*val = 0xff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
-	*val = in_8((unsigned char *)python_config_data(bus) + (offset&3));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
-				    unsigned char offset, unsigned short *val)
-{
-	if (bus > python_busnr) {
-		*val = 0xffff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
-	*val = in_le16((unsigned short *)(python_config_data(bus) + (offset&3)));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
-				     unsigned char offset, unsigned int *val)
-{
-	if (bus > python_busnr) {
-		*val = 0xffffffff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
-	*val = in_le32((unsigned *)python_config_data(bus));
-	return PCIBIOS_SUCCESSFUL;
-}
 
-int __chrp python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
-				     unsigned char offset, unsigned char val)
-{
-	if (bus > python_busnr)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
-	out_8((volatile unsigned char *)python_config_data(bus) + (offset&3), val);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
-				     unsigned char offset, unsigned short val)
-{
-	if (bus > python_busnr)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
-	out_le16((volatile unsigned short *)python_config_data(bus) + (offset&3),
-		 val);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
-				      unsigned char offset, unsigned int val)
-{
-	if (bus > python_busnr)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
-	out_le32((unsigned *)python_config_data(bus) + (offset&3), val);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
-				    unsigned char offset, unsigned char *val)
-{
-	unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
-	unsigned long ret;
-
-	if (call_rtas( "read-pci-config", 2, 2, &ret, addr, 1) != 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	*val = ret;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
-				    unsigned char offset, unsigned short *val)
-{
-	unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
-	unsigned long ret;
-
-	if (call_rtas("read-pci-config", 2, 2, &ret, addr, 2) != 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	*val = ret;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
-				     unsigned char offset, unsigned int *val)
-{
-	unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
-	unsigned long ret;
-
-	if (call_rtas("read-pci-config", 2, 2, &ret, addr, 4) != 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	*val = ret;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
-				     unsigned char offset, unsigned char val)
-{
-	unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
-	if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 1, (ulong)val ) != 0 )
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
-				     unsigned char offset, unsigned short val)
-{
-	unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
-	if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 2, (ulong)val ) != 0 )
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	return PCIBIOS_SUCCESSFUL;
-}
+#define PYTHON_PCI_OP(rw, size, type, op, mask)			    	     \
+int __chrp								     \
+python_##rw##_config_##size(struct pci_dev *dev, int offset, type val) 	     \
+{									     \
+	struct pci_controller *hose = dev->sysdata;			     \
+									     \
+	out_be32(hose->cfg_addr,					     \
+		 PYTHON_CFA(dev->bus->number, dev->devfn, offset));	     \
+	cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);   	     \
+	return PCIBIOS_SUCCESSFUL;					     \
+}
+
+PYTHON_PCI_OP(read, byte, u8 *, in_8, 3)
+PYTHON_PCI_OP(read, word, u16 *, in_le16, 2)
+PYTHON_PCI_OP(read, dword, u32 *, in_le32, 0)
+PYTHON_PCI_OP(write, byte, u8, out_8, 3)
+PYTHON_PCI_OP(write, word, u16, out_le16, 2)
+PYTHON_PCI_OP(write, dword, u32, out_le32, 0)
+
+static struct pci_ops python_pci_ops =
+{
+	python_read_config_byte,
+	python_read_config_word,
+	python_read_config_dword,
+	python_write_config_byte,
+	python_write_config_word,
+	python_write_config_dword
+};
 
-int __chrp rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
-				      unsigned char offset, unsigned int val)
-{
-	unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
-	if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 4, (ulong)val ) != 0 )
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	return PCIBIOS_SUCCESSFUL;
-}
+#ifdef CONFIG_POWER4
+/*
+ * Access functions for PCI config space using RTAS calls.
+ */
+#define RTAS_PCI_READ_OP(size, type, nbytes)			    	  \
+int __chrp								  \
+rtas_read_config_##size(struct pci_dev *dev, int offset, type val) 	  \
+{									  \
+	unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
+		| ((dev->bus->number & 0xff) << 16);			  \
+	unsigned long ret = ~0UL;					  \
+	int rval;							  \
+									  \
+	rval = call_rtas("read-pci-config", 2, 2, &ret, addr, nbytes);	  \
+	*val = ret;							  \
+	return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;    	  \
+}
+
+#define RTAS_PCI_WRITE_OP(size, type, nbytes)				  \
+int __chrp								  \
+rtas_write_config_##size(struct pci_dev *dev, int offset, type val)	  \
+{									  \
+	unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
+		| ((dev->bus->number & 0xff) << 16);			  \
+	int rval;							  \
+									  \
+	rval = call_rtas("write-pci-config", 3, 1, NULL,		  \
+			 addr, nbytes, (ulong)val);			  \
+	return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;	  \
+}
+
+RTAS_PCI_READ_OP(byte, u8 *, 1)
+RTAS_PCI_READ_OP(word, u16 *, 2)
+RTAS_PCI_READ_OP(dword, u32 *, 4)
+RTAS_PCI_WRITE_OP(byte, u8, 1)
+RTAS_PCI_WRITE_OP(word, u16, 2)
+RTAS_PCI_WRITE_OP(dword, u32, 4)
+
+static struct pci_ops rtas_pci_ops =
+{
+	rtas_read_config_byte,
+	rtas_read_config_word,
+	rtas_read_config_dword,
+	rtas_write_config_byte,
+	rtas_write_config_word,
+	rtas_write_config_dword
+};
+#endif /* CONFIG_POWER4 */
 
     /*
      *  Temporary fixes for PCI devices. These should be replaced by OF query
@@ -278,7 +203,7 @@
 					   HYDRA_FC_MPIC_ENABLE |
 					   HYDRA_FC_SLOW_SCC_PCLK |
 					   HYDRA_FC_MPIC_IS_MASTER));
-	OpenPIC = (volatile struct OpenPIC *)&Hydra->OpenPIC;
+	OpenPIC_Addr = &Hydra->OpenPIC;
 	OpenPIC_InitSenses = hydra_openpic_initsenses;
 	OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses);
 	return 1;
@@ -316,54 +241,25 @@
 chrp_pcibios_fixup(void)
 {
 	struct pci_dev *dev;
-	int *brp;
 	struct device_node *np;
-	extern struct pci_ops generic_pci_ops;
-
-#ifndef CONFIG_POWER4
-	np = find_devices("device-tree");
-	if (np != 0) {
-		for (np = np->child; np != NULL; np = np->sibling) {
-			if (np->type == NULL || strcmp(np->type, "pci") != 0)
-				continue;
-			if ((brp = (int *) get_property(np, "bus-range", NULL)) == 0)
-				continue;
-			if (brp[0] != 0)	/* bus 0 is already done */
-				pci_scan_bus(brp[0], &generic_pci_ops, NULL);
-		}
-	}
-#else
-	/* XXX kludge for now because we can't properly handle
-	   physical addresses > 4GB.  -- paulus */
-	pci_scan_bus(0x1e, &generic_pci_ops, NULL);
-#endif /* CONFIG_POWER4 */
 
 	/* PCI interrupts are controlled by the OpenPIC */
 	pci_for_each_dev(dev) {
-		np = find_pci_device_OFnode(dev->bus->number, dev->devfn);
+		np = pci_device_to_OF_node(dev);
 		if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
 			dev->irq = np->intrs[0].line;
-		/* these need to be absolute addrs for OF and Matrox FB -- Cort */
-		if ( dev->vendor == PCI_VENDOR_ID_MATROX )
-		{
-			if ( dev->resource[0].start < isa_mem_base )
-				dev->resource[0].start += isa_mem_base;
-			if ( dev->resource[1].start < isa_mem_base )
-				dev->resource[1].start += isa_mem_base;
-		}
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
 		/* the F50 identifies the amd as a trident */
 		if ( (dev->vendor == PCI_VENDOR_ID_TRIDENT) &&
 		      (dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET) )
 		{
 			dev->vendor = PCI_VENDOR_ID_AMD;
-			pcibios_write_config_word(dev->bus->number,
-			  dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+			pci_write_config_word(dev, PCI_VENDOR_ID,
+					      PCI_VENDOR_ID_AMD);
 		}
 #ifdef CONFIG_POWER4
 		power4_fixup_dev(dev);
-#else
-		if (dev->bus->number > 0 && python_busnr > 0)
-			dev->resource[0].start += dev->bus->number*0x01000000;
 #endif
 	}
 }
@@ -402,86 +298,213 @@
     	bus->resource[1] = &gg2_resources.pci_mem;
 }
 
-decl_config_access_method(grackle);
-decl_config_access_method(indirect);
-decl_config_access_method(rtas);
+static void process_bridge_ranges(struct pci_controller *hose,
+				  struct device_node *dev, int index)
+{
+	unsigned int *ranges;
+	int rlen = 0;
+	int memno = 0;
+	struct resource *res;
+
+	hose->io_base_phys = 0;
+	ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+	while ((rlen -= 6 * sizeof(unsigned int)) >= 0) {
+		res = NULL;
+		switch (ranges[0] >> 24) {
+		case 1:		/* I/O space */
+			if (ranges[2] != 0)
+				break;
+			hose->io_base_phys = ranges[3];
+			hose->io_base_virt = ioremap(ranges[3], ranges[5]);
+			if (index == 0) {
+				isa_io_base = (unsigned long) hose->io_base_virt;
+				printk("isa_io_base=%lx\n", isa_io_base);
+			}
+			res = &hose->io_resource;
+			res->flags = IORESOURCE_IO;
+			break;
+		case 2:		/* memory space */
+			if (index == 0 && ranges[1] == 0 && ranges[2] == 0){
+				isa_mem_base = ranges[3];
+				printk("isa_mem_base=%lx\n", isa_mem_base);
+			}
+			if (memno == 0) {
+				hose->pci_mem_offset = ranges[3] - ranges[2];
+				printk("pci_mem_offset=%lx for this bridge\n",
+				       hose->pci_mem_offset);
+			}
+			res = &hose->mem_resources[memno];
+			res->flags = IORESOURCE_MEM;
+			++memno;
+			break;
+		}
+		if (res != NULL) {
+			res->name = dev->full_name;
+			res->start = ranges[3];
+			res->end = res->start + ranges[5] - 1;
+			res->parent = NULL;
+			res->sibling = NULL;
+			res->child = NULL;
+		}
+		ranges += 6;
+	}
+}
+
+/* this is largely modeled and stolen after the pmac_pci code -- tgall
+ */
+
+static void __init
+ibm_add_bridges(struct device_node *dev)
+{
+	int *bus_range;
+	int len, index = 0;
+	struct pci_controller *hose;
+	volatile unsigned char *cfg;
+	unsigned int *dma;
+#ifdef CONFIG_POWER3
+	unsigned long *opprop = (unsigned long *)
+		get_property(find_path_device("/"), "platform-open-pic", NULL);
+#endif
+
+	for(; dev != NULL; dev = dev->next, ++index) {
+		if (dev->n_addrs < 1) {
+			printk(KERN_WARNING "Can't use %s: no address\n",
+			       dev->full_name);
+			continue;
+		}
+		bus_range = (int *) get_property(dev, "bus-range", &len);
+		if (bus_range == NULL || len < 2 * sizeof(int)) {
+			printk(KERN_WARNING "Can't get bus-range for %s\n",
+				dev->full_name);
+			continue;
+		}
+		if (bus_range[1] == bus_range[0])
+			printk(KERN_INFO "PCI bus %d", bus_range[0]);
+		else
+			printk(KERN_INFO "PCI buses %d..%d",
+			       bus_range[0], bus_range[1]);
+		printk(" controlled by %s at %x\n", dev->type,
+		       dev->addrs[0].address);
+
+		hose = pcibios_alloc_controller();
+		if (!hose) {
+			printk("Can't allocate PCI controller structure for %s\n",
+				dev->full_name);
+			continue;
+		}
+		hose->arch_data = dev;
+		hose->first_busno = bus_range[0];
+		hose->last_busno = bus_range[1];
+		hose->ops = &python_pci_ops;
+
+		cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20);
+       		hose->cfg_addr = (volatile unsigned int *) cfg;
+       		hose->cfg_data = cfg + 0x10;
+
+		process_bridge_ranges(hose, dev, index);
+
+#ifdef CONFIG_POWER3
+                openpic_setup_ISU(index, opprop[index+1]);
+#endif /* CONFIG_POWER3 */
+
+		/* check the first bridge for a property that we can
+		   use to set pci_dram_offset */
+		dma = (unsigned int *)
+			get_property(dev, "ibm,dma-ranges", &len);
+		if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
+			pci_dram_offset = dma[2] - dma[3];
+			printk("pci_dram_offset = %lx\n", pci_dram_offset);
+		}
+	}
+}
 
+#ifdef CONFIG_POWER4
 void __init
-chrp_setup_pci_ptrs(void)
+power4_add_bridge(void)
+{
+	struct pci_controller* hose;
+
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		return;
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+	
+	hose->ops = &rtas_pci_ops;
+	pci_dram_offset = 0;
+}
+#endif /* CONFIG_POWER4 */
+
+void __init
+chrp_find_bridges(void)
 {
 	struct device_node *py;
+	char *model, *name;
+	struct pci_controller* hose;
 
 	ppc_md.pcibios_fixup = chrp_pcibios_fixup;
+
 #ifdef CONFIG_POWER4
-	set_config_access_method(rtas);
-	pci_dram_offset = 0;
+	power4_add_bridge();
 #else /* CONFIG_POWER4 */
-        if ( !strncmp("MOT",
-                      get_property(find_path_device("/"), "model", NULL),3) )
-        {
-                pci_dram_offset = 0;
-                isa_mem_base = 0xf7000000;
-                isa_io_base = 0xfe000000;
-                set_config_access_method(grackle);
+	model = get_property(find_path_device("/"), "model", NULL);
+        if (!strncmp("MOT", model, 3)) {
+		struct pci_controller* hose;
+
+		hose = pcibios_alloc_controller();
+		if (!hose)
+			return;
+		hose->first_busno = 0;
+		hose->last_busno = 0xff;
+        	/* Check that please. This must be the root of the OF
+        	 * PCI tree (the root host bridge
+        	 */
+               	hose->arch_data = find_devices("pci");
+                setup_grackle(hose, 0x20000);
+		return;
         }
-        else
-        {
-		if ((py = find_compatible_devices("pci", "IBM,python")) != 0
-		    || (py = find_compatible_devices("pci", "IBM,python3.0")) != 0)
-		{
-			char *name = get_property(find_path_device("/"), "name", NULL);
 
-			/* find out how many pythons */
-			while ( (py = py->next) ) python_busnr++;
-			set_config_access_method(python);
-
-			/*
-			 * We base these values on the machine type but should
-			 * try to read them from the python controller itself.
-			 * -- Cort
-			 */
-			if ( !strncmp("IBM,7025-F50", name, 12) )
-			{
-				pci_dram_offset = 0x80000000;
-				isa_mem_base = 0xa0000000;
-				isa_io_base = 0x88000000;
-			} else if ( !strncmp("IBM,7043-260", name, 12)
-				    || !strncmp("IBM,7044-270", name, 12))
-			{
-				pci_dram_offset = 0x0;
-				isa_mem_base = 0xc0000000;
-				isa_io_base = 0xf8000000;
-			}
-                }
-                else
-                {
-			if ( !strncmp("IBM,7043-150", get_property(find_path_device("/"), "name", NULL),12) ||
-			     !strncmp("IBM,7046-155", get_property(find_path_device("/"), "name", NULL),12) ||
-			     !strncmp("IBM,7046-B50", get_property(find_path_device("/"), "name", NULL),12) )
-			{
-				pci_dram_offset = 0;
-				isa_mem_base = 0x80000000;
-				isa_io_base = 0xfe000000;
-				pci_config_address = (unsigned int *)0xfec00000;
-				pci_config_data = (unsigned char *)0xfee00000;
-				set_config_access_method(indirect);
-			}
-			else
-			{
-				/* LongTrail */
-				pci_dram_offset = 0;
-				isa_mem_base = 0xf7000000;
-				isa_io_base = 0xf8000000;
-				set_config_access_method(gg2);
-				ppc_md.pcibios_fixup = gg2_pcibios_fixup;
-				ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
-			}
-                }
-        }
+	if ((py = find_compatible_devices("pci", "IBM,python")))
+	{
+		/* XXX xmon_init_scc needs this set and the BAT
+		   set up in MMU_init */
+		ibm_add_bridges(find_devices("pci"));
+		return;
+	}
+
+
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		return;
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+	/* Check that please. This must be the root of the OF
+	 * PCI tree (the root host bridge
+	 */
+	hose->arch_data = find_devices("pci");
+	name = get_property(find_path_device("/"), "name", NULL);
+	if (!strncmp("IBM,7043-150", name, 12) ||
+	    !strncmp("IBM,7046-155", name, 12) ||
+	    !strncmp("IBM,7046-B50", name, 12) ) {
+		setup_grackle(hose, 0x01000000);
+		isa_mem_base = 0x80000000;
+		return;
+	}
+
+	/* LongTrail */
+	hose->ops = &gg2_pci_ops;
+	pci_dram_offset = 0;
+	isa_mem_base = 0xf7000000;
+	hose->io_base_phys = (unsigned long) 0xf8000000;
+	hose->io_base_virt = ioremap(hose->io_base_phys, 0x10000);
+	isa_io_base = (unsigned long) hose->io_base_virt;
+	ppc_md.pcibios_fixup = gg2_pcibios_fixup;
+	ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
 #endif /* CONFIG_POWER4 */
 }
 
 #ifdef CONFIG_PPC64BRIDGE
+#ifdef CONFIG_POWER4
 /*
  * Hack alert!!!
  * 64-bit machines like POWER3 and POWER4 have > 32 bit
@@ -490,9 +513,7 @@
  * page table gives us into parts of the physical address
  * space above 4GB so we can access the I/O devices.
  */
-
-#ifdef CONFIG_POWER4
-static unsigned long pci_address_offset(int busnr, unsigned int flags)
+unsigned long pci_address_offset(int busnr, unsigned int flags)
 {
 	unsigned long offset = 0;
 
@@ -507,35 +528,6 @@
 		else
 	}
 	return offset;
-}
-
-unsigned long phys_to_bus(unsigned long pa)
-{
-	if (pa >= 0xf8000000)
-		pa -= 0x38000000;
-	else if (pa >= 0x80000000 && pa < 0xc0000000)
-		pa += 0x40000000;
-	return pa;
-}
-
-unsigned long bus_to_phys(unsigned int ba, int busnr)
-{
-	return ba + pci_address_offset(busnr, IORESOURCE_MEM);
-}
-
-#else /* CONFIG_POWER4 */
-/*
- * For now assume I/O addresses are < 4GB and PCI bridges don't
- * remap addresses on POWER3 machines.
- */
-unsigned long phys_to_bus(unsigned long pa)
-{
-	return pa;
-}
-
-unsigned long bus_to_phys(unsigned int ba, int busnr)
-{
-	return ba;
 }
 #endif /* CONFIG_POWER4 */
 #endif /* CONFIG_PPC64BRIDGE */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)