aboutsummaryrefslogtreecommitdiff
path: root/arch/ppc64/kernel/pci.c
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2005-10-31 10:51:57 -0800
committerTony Luck <tony.luck@intel.com>2005-10-31 10:51:57 -0800
commitc7fb577e2a6cb04732541f2dc402bd46747f7558 (patch)
treedf3b1a1922ed13bfbcc45d08650c38beeb1a7bd1 /arch/ppc64/kernel/pci.c
parent9cec58dc138d6fcad9f447a19c8ff69f6540e667 (diff)
parent581c1b14394aee60aff46ea67d05483261ed6527 (diff)
manual update from upstream:
Applied Al's change 06a544971fad0992fe8b92c5647538d573089dd4 to new location of swiotlb.c Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ppc64/kernel/pci.c')
-rw-r--r--arch/ppc64/kernel/pci.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index ff4be1da69d..3d2106b022a 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -31,8 +31,7 @@
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/udbg.h>
-
-#include "pci.h"
+#include <asm/ppc-pci.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -727,16 +726,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
* above routine
*/
pgprot_t pci_phys_mem_access_prot(struct file *file,
- unsigned long offset,
+ unsigned long pfn,
unsigned long size,
pgprot_t protection)
{
struct pci_dev *pdev = NULL;
struct resource *found = NULL;
unsigned long prot = pgprot_val(protection);
+ unsigned long offset = pfn << PAGE_SHIFT;
int i;
- if (page_is_ram(offset >> PAGE_SHIFT))
+ if (page_is_ram(pfn))
return __pgprot(prot);
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
@@ -881,9 +881,9 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
}
void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
- struct device_node *dev)
+ struct device_node *dev, int prim)
{
- unsigned int *ranges;
+ unsigned int *ranges, pci_space;
unsigned long size;
int rlen = 0;
int memno = 0;
@@ -906,16 +906,39 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
while ((rlen -= np * sizeof(unsigned int)) >= 0) {
res = NULL;
- pci_addr = (unsigned long)ranges[1] << 32 | ranges[2];
+ pci_space = ranges[0];
+ pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
cpu_phys_addr = ranges[3];
- if (na == 2)
- cpu_phys_addr = cpu_phys_addr << 32 | ranges[4];
+ if (na >= 2)
+ cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
- size = (unsigned long)ranges[na+3] << 32 | ranges[na+4];
+ size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
+ ranges += np;
if (size == 0)
continue;
- switch ((ranges[0] >> 24) & 0x3) {
+
+ /* Now consume following elements while they are contiguous */
+ while (rlen >= np * sizeof(unsigned int)) {
+ unsigned long addr, phys;
+
+ if (ranges[0] != pci_space)
+ break;
+ addr = ((unsigned long)ranges[1] << 32) | ranges[2];
+ phys = ranges[3];
+ if (na >= 2)
+ phys = (phys << 32) | ranges[4];
+ if (addr != pci_addr + size ||
+ phys != cpu_phys_addr + size)
+ break;
+
+ size += ((unsigned long)ranges[na+3] << 32)
+ | ranges[na+4];
+ ranges += np;
+ rlen -= np * sizeof(unsigned int);
+ }
+
+ switch ((pci_space >> 24) & 0x3) {
case 1: /* I/O space */
hose->io_base_phys = cpu_phys_addr;
hose->pci_io_size = size;
@@ -949,7 +972,6 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
res->sibling = NULL;
res->child = NULL;
}
- ranges += np;
}
}