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) ...@@ -256,9 +256,12 @@ unsigned long __init find_and_init_phbs(void)
int ret = HvCallXm_testBus(bus); int ret = HvCallXm_testBus(bus);
if (ret == 0) { if (ret == 0) {
printk("bus %d appears to exist\n", bus); 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) if (phb == NULL)
return -1; return -ENOMEM;
pci_setup_pci_controller(phb);
phb->pci_mem_offset = phb->local_number = bus; phb->pci_mem_offset = phb->local_number = bus;
phb->first_busno = bus; phb->first_busno = bus;
phb->last_busno = bus; phb->last_busno = bus;
......
...@@ -325,9 +325,11 @@ static int __init add_bridge(struct device_node *dev) ...@@ -325,9 +325,11 @@ static int __init add_bridge(struct device_node *dev)
dev->full_name); dev->full_name);
} }
hose = pci_alloc_pci_controller(); hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
if (!hose) if (hose == NULL)
return -ENOMEM; return -ENOMEM;
pci_setup_pci_controller(hose);
hose->arch_data = dev; hose->arch_data = dev;
hose->first_busno = bus_range ? bus_range[0] : 0; hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff; hose->last_busno = bus_range ? bus_range[1] : 0xff;
......
...@@ -266,48 +266,61 @@ static int phb_set_bus_ranges(struct device_node *dev, ...@@ -266,48 +266,61 @@ static int phb_set_bus_ranges(struct device_node *dev,
return 0; return 0;
} }
static struct pci_controller *alloc_phb(struct device_node *dev, static int __devinit setup_phb(struct device_node *dev,
struct pci_controller *phb,
unsigned int addr_size_words) unsigned int addr_size_words)
{ {
struct pci_controller *phb;
struct reg_property64 reg_struct; struct reg_property64 reg_struct;
struct property *of_prop;
int rc;
rc = get_phb_reg_prop(dev, addr_size_words, &reg_struct); if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
if (rc) return 1;
return NULL;
phb = pci_alloc_pci_controller(); pci_setup_pci_controller(phb);
if (phb == NULL)
return NULL;
if (is_python(dev)) if (is_python(dev))
python_countermeasures(reg_struct.address); python_countermeasures(reg_struct.address);
rc = phb_set_bus_ranges(dev, phb); if (phb_set_bus_ranges(dev, phb))
if (rc) return 1;
return NULL;
of_prop = (struct property *)alloc_bootmem(sizeof(struct property) + phb->arch_data = dev;
sizeof(phb->global_number)); phb->ops = &rtas_pci_ops;
phb->buid = get_phb_buid(dev);
if (!of_prop) { return 0;
kfree(phb); }
return NULL;
}
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)); memset(of_prop, 0, sizeof(struct property));
of_prop->name = "linux,pci-domain"; of_prop->name = "linux,pci-domain";
of_prop->length = sizeof(phb->global_number); of_prop->length = sizeof(phb->global_number);
of_prop->value = (unsigned char *)&of_prop[1]; of_prop->value = (unsigned char *)&of_prop[1];
memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number)); memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
prom_add_property(dev, of_prop); prom_add_property(dev, of_prop);
}
phb->arch_data = dev; static struct pci_controller * __init alloc_phb(struct device_node *dev,
phb->ops = &rtas_pci_ops; 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; return phb;
} }
...@@ -315,30 +328,18 @@ static struct pci_controller *alloc_phb(struct device_node *dev, ...@@ -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) static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
{ {
struct pci_controller *phb; 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) if (phb == NULL)
return NULL; return NULL;
if (is_python(dev)) if (setup_phb(dev, phb, addr_size_words))
python_countermeasures(reg_struct.address);
rc = phb_set_bus_ranges(dev, phb);
if (rc)
return NULL; return NULL;
/* TODO: linux,pci-domain? */ phb->is_dynamic = 1;
phb->arch_data = dev;
phb->ops = &rtas_pci_ops;
phb->buid = get_phb_buid(dev); /* TODO: linux,pci-domain? */
return phb; return phb;
} }
......
...@@ -157,54 +157,19 @@ void pcibios_align_resource(void *data, struct resource *res, ...@@ -157,54 +157,19 @@ void pcibios_align_resource(void *data, struct resource *res,
res->start = start; res->start = start;
} }
/* static spinlock_t hose_spinlock = SPIN_LOCK_UNLOCKED;
* 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;
}
/* /*
* 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)); memset(hose, 0, sizeof(struct pci_controller));
hose->is_dynamic = 1; spin_lock(&hose_spinlock);
hose->global_number = global_phb_number++; hose->global_number = global_phb_number++;
list_add_tail(&hose->list_node, &hose_list); list_add_tail(&hose->list_node, &hose_list);
spin_unlock(&hose_spinlock);
return hose;
} }
static void __init pcibios_claim_one_bus(struct pci_bus *b) static void __init pcibios_claim_one_bus(struct pci_bus *b)
......
...@@ -14,8 +14,7 @@ ...@@ -14,8 +14,7 @@
extern unsigned long isa_io_base; extern unsigned long isa_io_base;
extern struct pci_controller* pci_alloc_pci_controller(void); extern void pci_setup_pci_controller(struct pci_controller *hose);
extern struct pci_controller* pci_alloc_phb_dynamic(void);
extern void pci_setup_phb_io(struct pci_controller *hose, int primary); 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); 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) ...@@ -614,9 +614,11 @@ static int __init add_bridge(struct device_node *dev)
dev->full_name); dev->full_name);
} }
hose = pci_alloc_pci_controller(); hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
if (!hose) if (hose == NULL)
return -ENOMEM; return -ENOMEM;
pci_setup_pci_controller(hose);
hose->arch_data = dev; hose->arch_data = dev;
hose->first_busno = bus_range ? bus_range[0] : 0; hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff; 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