[PATCH] powerpc: pci_address_to_pio fix

This fixes pci_address_to_pio() to return an unsigned long (to be safe)
and fixes a bug in the implementation that caused it to return a bogus
IO port number

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index f73a16e..fc60a77 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -1365,16 +1365,17 @@
 
 #endif /* CONFIG_PPC_MULTIPLATFORM */
 
-unsigned int pci_address_to_pio(phys_addr_t address)
+unsigned long 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)
-				((unsigned long)hose->io_base_virt +
-				 (address - hose->io_base_phys));
+		    address < (hose->io_base_phys + hose->pci_io_size)) {
+			unsigned long base =
+				(unsigned long)hose->io_base_virt - pci_io_base;
+			return base + (address - hose->io_base_phys);
+		}
 	}
 	return (unsigned int)-1;
 }
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 5b76427..309ae1d 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -503,9 +503,9 @@
 		return -EINVAL;
 	memset(r, 0, sizeof(struct resource));
 	if (flags & IORESOURCE_IO) {
-		unsigned int port;
+		unsigned long port;
 		port = pci_address_to_pio(taddr);
-		if (port == (unsigned int)-1)
+		if (port == (unsigned long)-1)
 			return -EINVAL;
 		r->start = port;
 		r->end = port + size - 1;
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 8de3203..c8b48f1 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -1811,7 +1811,7 @@
 EXPORT_SYMBOL(pci_iomap);
 EXPORT_SYMBOL(pci_iounmap);
 
-unsigned int pci_address_to_pio(phys_addr_t address)
+unsigned long pci_address_to_pio(phys_addr_t address)
 {
 	struct pci_controller* hose = hose_head;
 
@@ -1819,9 +1819,11 @@
 		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);
+		    address < (hose->io_base_phys + size)) {
+			unsigned long base =
+				(unsigned long)hose->io_base_virt - _IO_BASE;
+			return base + (address - hose->io_base_phys);
+
 	}
 	return (unsigned int)-1;
 }
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index 3d94e55..443c75a 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -158,11 +158,11 @@
 extern void pcibios_free_controller(struct pci_controller *phb);
 
 #ifdef CONFIG_PCI
-extern unsigned int pci_address_to_pio(phys_addr_t address);
+extern unsigned long pci_address_to_pio(phys_addr_t address);
 #else
-static inline unsigned int pci_address_to_pio(phys_addr_t address)
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
 {
-	return (unsigned int)-1;
+	return (unsigned long)-1;
 }
 #endif
 
diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
index 95672dd..9d52306 100644
--- a/include/asm-ppc/pci-bridge.h
+++ b/include/asm-ppc/pci-bridge.h
@@ -138,11 +138,11 @@
 extern int pciauto_bus_scan(struct pci_controller *, int);
 
 #ifdef CONFIG_PCI
-extern unsigned int pci_address_to_pio(phys_addr_t address);
+extern unsigned long pci_address_to_pio(phys_addr_t address);
 #else
-static inline unsigned int pci_address_to_pio(phys_addr_t address)
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
 {
-	return (unsigned int)-1;
+	return (unsigned long)-1;
 }
 #endif