Commit 2321acc0 authored by Anton Blanchard's avatar Anton Blanchard Committed by Linus Torvalds

[PATCH] ppc64: remove duplication in pci_alloc_*

We duplicated the code in pci_alloc_pci_controller twice and had an ifdef for
iseries as well, just to select between kmalloc and bootmem memory.  Change
this so we instead pass the allocation into a common function -
pci_setup_pci_controller.

Also use a spinlock around the host_list and global_phb_number code since we
now can modify it at runtime via hotplug.
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 647022af
......@@ -256,9 +256,12 @@ unsigned long __init find_and_init_phbs(void)
int ret = HvCallXm_testBus(bus);
if (ret == 0) {
printk("bus %d appears to exist\n", bus);
phb = pci_alloc_pci_controller();
phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
if (phb == NULL)
return -1;
return -ENOMEM;
pci_setup_pci_controller(phb);
phb->pci_mem_offset = phb->local_number = bus;
phb->first_busno = bus;
phb->last_busno = bus;
......
......@@ -325,9 +325,11 @@ static int __init add_bridge(struct device_node *dev)
dev->full_name);
}
hose = pci_alloc_pci_controller();
if (!hose)
return -ENOMEM;
hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
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;
......
......@@ -266,48 +266,61 @@ static int phb_set_bus_ranges(struct device_node *dev,
return 0;
}
static struct pci_controller *alloc_phb(struct device_node *dev,
unsigned int addr_size_words)
static int __devinit setup_phb(struct device_node *dev,
struct pci_controller *phb,
unsigned int addr_size_words)
{
struct pci_controller *phb;
struct reg_property64 reg_struct;
struct property *of_prop;
int rc;
rc = get_phb_reg_prop(dev, addr_size_words, &reg_struct);
if (rc)
return NULL;
if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
return 1;
phb = pci_alloc_pci_controller();
if (phb == NULL)
return NULL;
pci_setup_pci_controller(phb);
if (is_python(dev))
python_countermeasures(reg_struct.address);
rc = phb_set_bus_ranges(dev, phb);
if (rc)
return NULL;
if (phb_set_bus_ranges(dev, phb))
return 1;
of_prop = (struct property *)alloc_bootmem(sizeof(struct property) +
sizeof(phb->global_number));
phb->arch_data = dev;
phb->ops = &rtas_pci_ops;
phb->buid = get_phb_buid(dev);
if (!of_prop) {
kfree(phb);
return NULL;
}
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);
}
phb->arch_data = dev;
phb->ops = &rtas_pci_ops;
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->buid = get_phb_buid(dev);
phb = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
if (phb == NULL)
return NULL;
of_prop = (struct property *)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;
}
......@@ -315,30 +328,18 @@ static struct pci_controller *alloc_phb(struct device_node *dev,
static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
{
struct pci_controller *phb;
struct reg_property64 reg_struct;
int rc;
rc = get_phb_reg_prop(dev, addr_size_words, &reg_struct);
if (rc)
return NULL;
phb = pci_alloc_phb_dynamic();
phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
GFP_KERNEL);
if (phb == NULL)
return NULL;
if (is_python(dev))
python_countermeasures(reg_struct.address);
rc = phb_set_bus_ranges(dev, phb);
if (rc)
if (setup_phb(dev, phb, addr_size_words))
return NULL;
/* TODO: linux,pci-domain? */
phb->arch_data = dev;
phb->ops = &rtas_pci_ops;
phb->is_dynamic = 1;
phb->buid = get_phb_buid(dev);
/* TODO: linux,pci-domain? */
return phb;
}
......
......@@ -157,54 +157,19 @@ void pcibios_align_resource(void *data, struct resource *res,
res->start = start;
}
/*
* Allocate pci_controller(phb) initialized common variables.
*/
struct pci_controller * __init pci_alloc_pci_controller()
{
struct pci_controller *hose;
#ifdef CONFIG_PPC_ISERIES
hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
GFP_KERNEL);
#else
hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
#endif
if (hose == NULL) {
printk(KERN_ERR "PCI: Allocate pci_controller failed.\n");
return NULL;
}
memset(hose, 0, sizeof(struct pci_controller));
hose->is_dynamic = 0;
hose->global_number = global_phb_number++;
list_add_tail(&hose->list_node, &hose_list);
return hose;
}
static spinlock_t hose_spinlock = SPIN_LOCK_UNLOCKED;
/*
* Dymnamically allocate pci_controller(phb), initialize common variables.
* pci_controller(phb) initialized common variables.
*/
struct pci_controller * pci_alloc_phb_dynamic()
void __devinit pci_setup_pci_controller(struct pci_controller *hose)
{
struct pci_controller *hose;
hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
GFP_KERNEL);
if(hose == NULL) {
printk(KERN_ERR "PCI: Allocate pci_controller failed.\n");
return NULL;
}
memset(hose, 0, sizeof(struct pci_controller));
hose->is_dynamic = 1;
spin_lock(&hose_spinlock);
hose->global_number = global_phb_number++;
list_add_tail(&hose->list_node, &hose_list);
return hose;
spin_unlock(&hose_spinlock);
}
static void __init pcibios_claim_one_bus(struct pci_bus *b)
......
......@@ -14,8 +14,7 @@
extern unsigned long isa_io_base;
extern struct pci_controller* pci_alloc_pci_controller(void);
extern struct pci_controller* pci_alloc_phb_dynamic(void);
extern void pci_setup_pci_controller(struct pci_controller *hose);
extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node);
......
......@@ -614,9 +614,11 @@ static int __init add_bridge(struct device_node *dev)
dev->full_name);
}
hose = pci_alloc_pci_controller();
if (!hose)
return -ENOMEM;
hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment