Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 14265
b: refs/heads/master
c: b5166cc
h: refs/heads/master
i:
  14263: e8dd657
v: v3
  • Loading branch information
Benjamin Herrenschmidt authored and Paul Mackerras committed Nov 16, 2005
1 parent 92531d6 commit 94088a6
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 119 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f9e4ec57c66586d0c165ed9373efaf9e329d5766
refs/heads/master: b5166cc252190be80465f3b4f050e4a0310f71af
68 changes: 65 additions & 3 deletions trunk/arch/powerpc/kernel/pci_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ static DEFINE_SPINLOCK(hose_spinlock);
/*
* pci_controller(phb) initialized common variables.
*/
void __devinit pci_setup_pci_controller(struct pci_controller *hose)
static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
{
memset(hose, 0, sizeof(struct pci_controller));

Expand All @@ -197,6 +197,65 @@ void __devinit pci_setup_pci_controller(struct pci_controller *hose)
spin_unlock(&hose_spinlock);
}

static void add_linux_pci_domain(struct device_node *dev,
struct pci_controller *phb)
{
struct property *of_prop;
unsigned int size;

of_prop = (struct property *)
get_property(dev, "linux,pci-domain", &size);
if (of_prop != NULL)
return;
WARN_ON(of_prop && size < sizeof(int));
if (of_prop && size < sizeof(int))
of_prop = NULL;
size = sizeof(struct property) + sizeof(int);
if (of_prop == NULL) {
if (mem_init_done)
of_prop = kmalloc(size, GFP_KERNEL);
else
of_prop = alloc_bootmem(size);
}
memset(of_prop, 0, sizeof(struct property));
of_prop->name = "linux,pci-domain";
of_prop->length = sizeof(int);
of_prop->value = (unsigned char *)&of_prop[1];
*((int *)of_prop->value) = phb->global_number;
prom_add_property(dev, of_prop);
}

struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
{
struct pci_controller *phb;

if (mem_init_done)
phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
else
phb = alloc_bootmem(sizeof (struct pci_controller));
if (phb == NULL)
return NULL;
pci_setup_pci_controller(phb);
phb->arch_data = dev;
phb->is_dynamic = mem_init_done;
if (dev)
add_linux_pci_domain(dev, phb);
return phb;
}

void pcibios_free_controller(struct pci_controller *phb)
{
if (phb->arch_data) {
struct device_node *np = phb->arch_data;
int *domain = (int *)get_property(np,
"linux,pci-domain", NULL);
if (domain)
*domain = -1;
}
if (phb->is_dynamic)
kfree(phb);
}

static void __init pcibios_claim_one_bus(struct pci_bus *b)
{
struct pci_dev *dev;
Expand Down Expand Up @@ -907,9 +966,10 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
* (size depending on dev->n_addr_cells)
* cells 4+5 or 5+6: the size of the range
*/
rlen = 0;
hose->io_base_phys = 0;
ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
if (ranges == NULL)
return;
hose->io_base_phys = 0;
while ((rlen -= np * sizeof(unsigned int)) >= 0) {
res = NULL;
pci_space = ranges[0];
Expand Down Expand Up @@ -1107,6 +1167,8 @@ int remap_bus_range(struct pci_bus *bus)

if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
return 1;
if (start_phys == 0)
return 1;
printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size);
if (__ioremap_explicit(start_phys, start_virt, size,
_PAGE_NO_CACHE | _PAGE_GUARDED))
Expand Down
68 changes: 5 additions & 63 deletions trunk/arch/powerpc/kernel/rtas_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,75 +304,18 @@ static int __devinit setup_phb(struct device_node *dev,
struct pci_controller *phb,
unsigned int addr_size_words)
{
pci_setup_pci_controller(phb);

if (is_python(dev))
python_countermeasures(dev, addr_size_words);

if (phb_set_bus_ranges(dev, phb))
return 1;

phb->arch_data = dev;
phb->ops = &rtas_pci_ops;
phb->buid = get_phb_buid(dev);

return 0;
}

static void __devinit add_linux_pci_domain(struct device_node *dev,
struct pci_controller *phb,
struct property *of_prop)
{
memset(of_prop, 0, sizeof(struct property));
of_prop->name = "linux,pci-domain";
of_prop->length = sizeof(phb->global_number);
of_prop->value = (unsigned char *)&of_prop[1];
memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
prom_add_property(dev, of_prop);
}

static struct pci_controller * __init alloc_phb(struct device_node *dev,
unsigned int addr_size_words)
{
struct pci_controller *phb;
struct property *of_prop;

phb = alloc_bootmem(sizeof(struct pci_controller));
if (phb == NULL)
return NULL;

of_prop = alloc_bootmem(sizeof(struct property) +
sizeof(phb->global_number));
if (!of_prop)
return NULL;

if (setup_phb(dev, phb, addr_size_words))
return NULL;

add_linux_pci_domain(dev, phb, of_prop);

return phb;
}

static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
{
struct pci_controller *phb;

phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
GFP_KERNEL);
if (phb == NULL)
return NULL;

if (setup_phb(dev, phb, addr_size_words))
return NULL;

phb->is_dynamic = 1;

/* TODO: linux,pci-domain? */

return phb;
}

unsigned long __init find_and_init_phbs(void)
{
struct device_node *node;
Expand All @@ -397,10 +340,10 @@ unsigned long __init find_and_init_phbs(void)
if (node->type == NULL || strcmp(node->type, "pci") != 0)
continue;

phb = alloc_phb(node, root_size_cells);
phb = pcibios_alloc_controller(node);
if (!phb)
continue;

setup_phb(node, phb, root_size_cells);
pci_process_bridge_OF_ranges(phb, node, 0);
pci_setup_phb_io(phb, index == 0);
#ifdef CONFIG_PPC_PSERIES
Expand Down Expand Up @@ -446,10 +389,10 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
root_size_cells = prom_n_size_cells(root);

primary = list_empty(&hose_list);
phb = alloc_phb_dynamic(dn, root_size_cells);
phb = pcibios_alloc_controller(dn);
if (!phb)
return NULL;

setup_phb(dn, phb, root_size_cells);
pci_process_bridge_OF_ranges(phb, dn, primary);

pci_setup_phb_io_dynamic(phb, primary);
Expand Down Expand Up @@ -505,8 +448,7 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
}

list_del(&phb->list_node);
if (phb->is_dynamic)
kfree(phb);
pcibios_free_controller(phb);

return 0;
}
Expand Down
3 changes: 1 addition & 2 deletions trunk/arch/powerpc/platforms/iseries/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,9 @@ unsigned long __init find_and_init_phbs(void)
if (ret == 0) {
printk("bus %d appears to exist\n", bus);

phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
phb = pcibios_alloc_controller(NULL);
if (phb == NULL)
return -ENOMEM;
pci_setup_pci_controller(phb);

phb->pci_mem_offset = phb->local_number = bus;
phb->first_busno = bus;
Expand Down
16 changes: 1 addition & 15 deletions trunk/arch/powerpc/platforms/maple/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,26 +326,12 @@ static int __init add_bridge(struct device_node *dev)
dev->full_name);
}

hose = alloc_bootmem(sizeof(struct pci_controller));
hose = pcibios_alloc_controller(dev);
if (hose == NULL)
return -ENOMEM;
pci_setup_pci_controller(hose);

hose->arch_data = dev;
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;

of_prop = alloc_bootmem(sizeof(struct property) +
sizeof(hose->global_number));
if (of_prop) {
memset(of_prop, 0, sizeof(struct property));
of_prop->name = "linux,pci-domain";
of_prop->length = sizeof(hose->global_number);
of_prop->value = (unsigned char *)&of_prop[1];
memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
prom_add_property(dev, of_prop);
}

disp_name = NULL;
if (device_is_compatible(dev, "u3-agp")) {
setup_u3_agp(hose);
Expand Down
62 changes: 32 additions & 30 deletions trunk/arch/powerpc/platforms/powermac/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,15 +640,16 @@ static void __init setup_u3_ht(struct pci_controller* hose)
* the reg address cell, we shall fix that by killing struct
* reg_property and using some accessor functions instead
*/
hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000,
0x02000000);

/*
* /ht node doesn't expose a "ranges" property, so we "remove" regions that
* have been allocated to AGP. So far, this version of the code doesn't assign
* any of the 0xfxxxxxxx "fine" memory regions to /ht.
* We need to fix that sooner or later by either parsing all child "ranges"
* properties or figuring out the U3 address space decoding logic and
* then read its configuration register (if any).
* /ht node doesn't expose a "ranges" property, so we "remove"
* regions that have been allocated to AGP. So far, this version of
* the code doesn't assign any of the 0xfxxxxxxx "fine" memory regions
* to /ht. We need to fix that sooner or later by either parsing all
* child "ranges" properties or figuring out the U3 address space
* decoding logic and then read its configuration register (if any).
*/
hose->io_base_phys = 0xf4000000;
hose->pci_io_size = 0x00400000;
Expand All @@ -671,10 +672,10 @@ static void __init setup_u3_ht(struct pci_controller* hose)
return;
}

/* We "remove" the AGP resources from the resources allocated to HT, that
* is we create "holes". However, that code does assumptions that so far
* happen to be true (cross fingers...), typically that resources in the
* AGP node are properly ordered
/* We "remove" the AGP resources from the resources allocated to HT,
* that is we create "holes". However, that code does assumptions
* that so far happen to be true (cross fingers...), typically that
* resources in the AGP node are properly ordered
*/
cur = 0;
for (i=0; i<3; i++) {
Expand All @@ -684,23 +685,30 @@ static void __init setup_u3_ht(struct pci_controller* hose)
/* We don't care about "fine" resources */
if (res->start >= 0xf0000000)
continue;
/* Check if it's just a matter of "shrinking" us in one direction */
/* Check if it's just a matter of "shrinking" us in one
* direction
*/
if (hose->mem_resources[cur].start == res->start) {
DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
cur, hose->mem_resources[cur].start, res->end + 1);
cur, hose->mem_resources[cur].start,
res->end + 1);
hose->mem_resources[cur].start = res->end + 1;
continue;
}
if (hose->mem_resources[cur].end == res->end) {
DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
cur, hose->mem_resources[cur].end, res->start - 1);
cur, hose->mem_resources[cur].end,
res->start - 1);
hose->mem_resources[cur].end = res->start - 1;
continue;
}
/* No, it's not the case, we need a hole */
if (cur == 2) {
/* not enough resources for a hole, we drop part of the range */
printk(KERN_WARNING "Running out of resources for /ht host !\n");
/* not enough resources for a hole, we drop part
* of the range
*/
printk(KERN_WARNING "Running out of resources"
" for /ht host !\n");
hose->mem_resources[cur].end = res->start - 1;
continue;
}
Expand All @@ -714,17 +722,6 @@ static void __init setup_u3_ht(struct pci_controller* hose)
hose->mem_resources[cur-1].end = res->start - 1;
}
}

/* XXX this needs to be converged between ppc32 and ppc64... */
static struct pci_controller * __init pcibios_alloc_controller(void)
{
struct pci_controller *hose;

hose = alloc_bootmem(sizeof(struct pci_controller));
if (hose)
pci_setup_pci_controller(hose);
return hose;
}
#endif

/*
Expand Down Expand Up @@ -756,19 +753,24 @@ static int __init add_bridge(struct device_node *dev)
#endif
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, assume bus 0\n",
dev->full_name);
printk(KERN_WARNING "Can't get bus-range for %s, assume"
" bus 0\n", dev->full_name);
}

/* XXX Different prototypes, to be merged */
#ifdef CONFIG_PPC64
hose = pcibios_alloc_controller(dev);
#else
hose = pcibios_alloc_controller();
#endif
if (!hose)
return -ENOMEM;
hose->arch_data = dev;
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;

disp_name = NULL;
#ifdef CONFIG_POWER4
#ifdef CONFIG_PPC64
if (device_is_compatible(dev, "u3-agp")) {
setup_u3_agp(hose);
disp_name = "U3-AGP";
Expand Down
1 change: 0 additions & 1 deletion trunk/include/asm-powerpc/ppc-pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

extern unsigned long isa_io_base;

extern void pci_setup_pci_controller(struct pci_controller *hose);
extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary);

Expand Down
Loading

0 comments on commit 94088a6

Please sign in to comment.