ppc64: Add a `primary' argument to pci_process_bridge_OF_ranges
... for consistency with ppc32 and to make the powermac merge easier. Also make it use just a single resource in the host bridge for multiple consecutive elements of the ranges property. Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Родитель
a5b518ed31
Коммит
f7abbc190b
|
@ -359,7 +359,7 @@ static int __init add_bridge(struct device_node *dev)
|
||||||
|
|
||||||
/* Interpret the "ranges" property */
|
/* Interpret the "ranges" property */
|
||||||
/* This also maps the I/O region and sets isa_io/mem_base */
|
/* This also maps the I/O region and sets isa_io/mem_base */
|
||||||
pci_process_bridge_OF_ranges(hose, dev);
|
pci_process_bridge_OF_ranges(hose, dev, primary);
|
||||||
pci_setup_phb_io(hose, primary);
|
pci_setup_phb_io(hose, primary);
|
||||||
|
|
||||||
/* Fixup "bus-range" OF property */
|
/* Fixup "bus-range" OF property */
|
||||||
|
|
|
@ -880,9 +880,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,
|
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;
|
unsigned long size;
|
||||||
int rlen = 0;
|
int rlen = 0;
|
||||||
int memno = 0;
|
int memno = 0;
|
||||||
|
@ -905,16 +905,39 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||||
ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
|
ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
|
||||||
while ((rlen -= np * sizeof(unsigned int)) >= 0) {
|
while ((rlen -= np * sizeof(unsigned int)) >= 0) {
|
||||||
res = NULL;
|
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];
|
cpu_phys_addr = ranges[3];
|
||||||
if (na == 2)
|
if (na >= 2)
|
||||||
cpu_phys_addr = cpu_phys_addr << 32 | ranges[4];
|
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)
|
if (size == 0)
|
||||||
continue;
|
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 */
|
case 1: /* I/O space */
|
||||||
hose->io_base_phys = cpu_phys_addr;
|
hose->io_base_phys = cpu_phys_addr;
|
||||||
hose->pci_io_size = size;
|
hose->pci_io_size = size;
|
||||||
|
@ -948,7 +971,6 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||||
res->sibling = NULL;
|
res->sibling = NULL;
|
||||||
res->child = NULL;
|
res->child = NULL;
|
||||||
}
|
}
|
||||||
ranges += np;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,7 @@ unsigned long __init find_and_init_phbs(void)
|
||||||
if (!phb)
|
if (!phb)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pci_process_bridge_OF_ranges(phb, node);
|
pci_process_bridge_OF_ranges(phb, node, 0);
|
||||||
pci_setup_phb_io(phb, index == 0);
|
pci_setup_phb_io(phb, index == 0);
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
#ifdef CONFIG_PPC_PSERIES
|
||||||
if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
|
if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
|
||||||
|
@ -450,7 +450,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
|
||||||
if (!phb)
|
if (!phb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pci_process_bridge_OF_ranges(phb, dn);
|
pci_process_bridge_OF_ranges(phb, dn, primary);
|
||||||
|
|
||||||
pci_setup_phb_io_dynamic(phb, primary);
|
pci_setup_phb_io_dynamic(phb, primary);
|
||||||
of_node_put(root);
|
of_node_put(root);
|
||||||
|
|
|
@ -123,7 +123,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||||
struct device_node *dev);
|
struct device_node *dev, int primary);
|
||||||
|
|
||||||
extern int pcibios_remove_root_bus(struct pci_controller *phb);
|
extern int pcibios_remove_root_bus(struct pci_controller *phb);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче