Skip to contentSkip to conversation

powerpc: Update OF address parsers

PATCH New Benjamin Herrenschmidt 1 participant 1 message Nov 30, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 powerpc: Update OF address parsers

This updates the OF address parsers to return the IO flags indicating the type of address obtained. It also adds a PCI call for converting physical addresses that hit IO space into into IO tokens, and add routines that return the translated addresses into struct resource

---

For powerpc tree, not for 2.6.15

include/asm-powerpc/prom.h +25 -3
Index: linux-work/include/asm-powerpc/prom.h
===================================================================
@@ -223,14 +223,36 @@ extern struct resource *request_OF_resou
 				int index, const char* name_postfix);
 extern int release_OF_resource(struct device_node* node, int index);
 
+
 /*
- * Address translation function(s)
+ * OF address retreival & translation
+ */
+
+
+/* Translate an OF address block into a CPU physical address
  */
 #define OF_BAD_ADDR	((u64)-1)
 extern u64 of_translate_address(struct device_node *np, u32 *addr);
-extern u32 *of_get_address(struct device_node *dev, int index, u64 *size);
-extern u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size);
 
+/* Extract an address from a device, returns the region size and
+ * the address space flags too. The PCI version uses a BAR number
+ * instead of an absolute index
+ */
+extern u32 *of_get_address(struct device_node *dev, int index,
+			   u64 *size, unsigned int *flags);
+extern u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+			       u64 *size, unsigned int *flags);
+
+/* Get an address as a resource. Note that if your address is
+ * a PIO address, the conversion will fail if the physical address
+ * can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early
+ * or it can't be matched to any host bridge IO space
+ */
+extern int of_address_to_resource(struct device_node *dev, int index,
+				  struct resource *r);
+extern int of_pci_address_to_resource(struct device_node *dev, int bar,
+				      struct resource *r);
 
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */
arch/powerpc/kernel/legacy_serial.c +3 -2
Index: linux-work/arch/powerpc/kernel/legacy_serial.c
===================================================================
@@ -146,6 +146,7 @@ static int __init add_legacy_pci_port(st
 {
 	phys_addr_t addr, base;
 	u32 *addrp;
+	unsigned int flags;
 	int iotype, index = -1, lindex = 0;
 
 	/* We only support ports that have a clock frequency properly
@@ -159,12 +160,12 @@ static int __init add_legacy_pci_port(st
 		return -1;
 
 	/* Get the PCI address. Assume BAR 0 */
-	addrp = of_get_pci_address(pci_dev, 0, NULL);
+	addrp = of_get_pci_address(pci_dev, 0, NULL, &flags);
 	if (addrp == NULL)
 		return -1;
 
 	/* We only support BAR 0 for now */
-	iotype = (addrp[0] & 0x02000000) ? UPIO_MEM : UPIO_PORT;
+	iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;
 	addr = of_translate_address(pci_dev, addrp);
 
 	/* Set the IO base to the same as the translated address for MMIO,
arch/powerpc/kernel/pci_64.c +14 -0
Index: linux-work/arch/powerpc/kernel/pci_64.c
===================================================================
@@ -1181,6 +1181,20 @@ void phbs_remap_io(void)
 		remap_bus_range(hose->bus);
 }
 
+unsigned int pci_address_to_pio(phys_addr_t address)
+{
+	struct pci_controller *hose, *tmp;
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+		if (address >= hose->io_base_phys &&
+		    address < (hose->io_base_phys + hose->pci_io_size))
+			return (unsigned int)hose->io_base_virt +
+				(address - hose->io_base_phys);
+	}
+	return (unsigned int)-1;
+}
+EXPORT_SYMBOL_GPL(pci_address_to_pio);
+
 static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 {
 	struct pci_controller *hose = pci_bus_to_host(dev->bus);
arch/powerpc/kernel/prom_parse.c +146 -19

260 lines not on this page · raw message

arch/powerpc/platforms/powermac/feature.c +1 -1
Index: linux-work/arch/powerpc/platforms/powermac/feature.c
===================================================================
@@ -2672,7 +2672,7 @@ static void __init probe_one_macio(const
 		printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
 		return;
 	}
-	addrp = of_get_pci_address(node, 0, &size);
+	addrp = of_get_pci_address(node, 0, &size, NULL);
 	if (addrp == NULL) {
 		printk(KERN_ERR "pmac_feature: %s: can't find base !\n",
 		       node->full_name);
arch/ppc/kernel/pci.c +15 -0
Index: linux-work/arch/ppc/kernel/pci.c
===================================================================
@@ -1805,6 +1805,21 @@ void pci_iounmap(struct pci_dev *dev, vo
 EXPORT_SYMBOL(pci_iomap);
 EXPORT_SYMBOL(pci_iounmap);
 
+unsigned int pci_address_to_pio(phys_addr_t address)
+{
+	struct pci_controller* hose = hose_head;
+
+	for (; hose; hose = hose->next) {
+		unsigned int size = hose->io_resource.end -
+			hose->io_resource.start + 1;
+		if (address >= hose->io_base_phys &&
+		    address < (hose->io_base_phys + size))
+			return (unsigned int)hose->io_base_virt +
+				(address - hose->io_base_phys);
+	}
+	return (unsigned int)-1;
+}
+EXPORT_SYMBOL(pci_address_to_pio);
 
 /*
  * Null PCI config access functions, for the case when we can't
drivers/macintosh/macio_asic.c +4 -8
Index: linux-work/drivers/macintosh/macio_asic.c
===================================================================
@@ -332,18 +332,14 @@ static void macio_setup_resources(struct
 				  struct resource *parent_res)
 {
 	struct device_node *np = dev->ofdev.node;
-	u32 *addr;
-	u64 size;
+	struct resource r;
 	int index;
 
-	for (index = 0; (addr = of_get_address(np, index, &size)) != NULL;
-	     index++) {
+	for (index = 0; of_address_to_resource(np, index, &r) == 0; index++) {
 		struct resource *res = &dev->resource[index];
 		if (index >= MACIO_DEV_COUNT_RESOURCES)
 			break;
-		res->start = of_translate_address(np, addr);
-		res->end = res->start + (unsigned long)size - 1;
-		res->flags = IORESOURCE_MEM;
+		*res = r;
 		res->name = dev->ofdev.dev.bus_id;
 
 		if (macio_resource_quirks(np, res, index)) {
@@ -353,7 +349,7 @@ static void macio_setup_resources(struct
 		/* Currently, we consider failure as harmless, this may
 		 * change in the future, once I've found all the device
 		 * tree bugs in older machines & worked around them
-		 */
+l		 */
 		if (insert_resource(parent_res, res)) {
 			printk(KERN_WARNING "Can't request resource "
 			       "%d for MacIO device %s\n",
include/asm-powerpc/pci-bridge.h +9 -0
Index: linux-work/include/asm-powerpc/pci-bridge.h
===================================================================
@@ -157,6 +157,15 @@ extern struct pci_controller *
 pcibios_alloc_controller(struct device_node *dev);
 extern void pcibios_free_controller(struct pci_controller *phb);
 
+#ifdef CONFIG_PCI
+extern unsigned int pci_address_to_pio(phys_addr_t address);
+#else
+static inline unsigned int pci_address_to_pio(phys_addr_t address)
+{
+	return (unsigned int)-1;
+}
+#endif
+
 /* Return values for ppc_md.pci_probe_mode function */
 #define PCI_PROBE_NONE		-1	/* Don't look at this bus at all */
 #define PCI_PROBE_NORMAL	0	/* Do normal PCI probing */
include/asm-ppc/pci-bridge.h +9 -0
Index: linux-work/include/asm-ppc/pci-bridge.h
===================================================================
@@ -137,5 +137,14 @@ static inline unsigned char bridge_swizz
  */
 extern int pciauto_bus_scan(struct pci_controller *, int);
 
+#ifdef CONFIG_PCI
+extern unsigned int pci_address_to_pio(phys_addr_t address);
+#else
+static inline unsigned int pci_address_to_pio(phys_addr_t address)
+{
+	return (unsigned int)-1;
+}
+#endif
+
 #endif
 #endif /* __KERNEL__ */
include/asm-ppc/prom.h +25 -3
Index: linux-work/include/asm-ppc/prom.h
===================================================================
@@ -138,12 +138,34 @@ extern unsigned long sub_reloc_offset(un
 
 
 /*
- * Address translation function(s)
+ * OF address retreival & translation
+ */
+
+
+/* Translate an OF address block into a CPU physical address
  */
 #define OF_BAD_ADDR	((u64)-1)
 extern u64 of_translate_address(struct device_node *np, u32 *addr);
-extern u32 *of_get_address(struct device_node *dev, int index, u64 *size);
-extern u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size);
+
+/* Extract an address from a device, returns the region size and
+ * the address space flags too. The PCI version uses a BAR number
+ * instead of an absolute index
+ */
+extern u32 *of_get_address(struct device_node *dev, int index,
+			   u64 *size, unsigned int *flags);
+extern u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+			       u64 *size, unsigned int *flags);
+
+/* Get an address as a resource. Note that if your address is
+ * a PIO address, the conversion will fail if the physical address
+ * can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early
+ * or it can't be matched to any host bridge IO space
+ */
+extern int of_address_to_resource(struct device_node *dev, int index,
+				  struct resource *r);
+extern int of_pci_address_to_resource(struct device_node *dev, int bar,
+				      struct resource *r);
 
 
 #endif /* _PPC_PROM_H */