aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/bus_numa.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-04-02 21:31:54 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-04-30 16:52:43 -0400
commitd28e5ac2a07e27638cf5ac061721b7969e17fe78 (patch)
tree4ae91ae8d95f3ef23d8fa9be5f1d02b8cdc53715 /arch/x86/pci/bus_numa.c
parent35cb05e5bdac209cfdfafbe50d89ee7069cb6237 (diff)
x86/PCI: dynamically allocate pci_root_info for native host bridge drivers
This dynamically allocates struct pci_root_info instead of using a static array. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'arch/x86/pci/bus_numa.c')
-rw-r--r--arch/x86/pci/bus_numa.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
index fd3f65510e9d..306579f7d0fd 100644
--- a/arch/x86/pci/bus_numa.c
+++ b/arch/x86/pci/bus_numa.c
@@ -4,35 +4,38 @@
4 4
5#include "bus_numa.h" 5#include "bus_numa.h"
6 6
7int pci_root_num; 7LIST_HEAD(pci_root_infos);
8struct pci_root_info pci_root_info[PCI_ROOT_NR];
9 8
10void x86_pci_root_bus_resources(int bus, struct list_head *resources) 9static struct pci_root_info *x86_find_pci_root_info(int bus)
11{ 10{
12 int i;
13 int j;
14 struct pci_root_info *info; 11 struct pci_root_info *info;
15 12
16 if (!pci_root_num) 13 if (list_empty(&pci_root_infos))
17 goto default_resources; 14 return NULL;
18 15
19 for (i = 0; i < pci_root_num; i++) { 16 list_for_each_entry(info, &pci_root_infos, list)
20 if (pci_root_info[i].bus_min == bus) 17 if (info->bus_min == bus)
21 break; 18 return info;
22 } 19
20 return NULL;
21}
23 22
24 if (i == pci_root_num) 23void x86_pci_root_bus_resources(int bus, struct list_head *resources)
24{
25 struct pci_root_info *info = x86_find_pci_root_info(bus);
26 struct pci_root_res *root_res;
27
28 if (!info)
25 goto default_resources; 29 goto default_resources;
26 30
27 printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", 31 printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
28 bus); 32 bus);
29 33
30 info = &pci_root_info[i]; 34 list_for_each_entry(root_res, &info->resources, list) {
31 for (j = 0; j < info->res_num; j++) {
32 struct resource *res; 35 struct resource *res;
33 struct resource *root; 36 struct resource *root;
34 37
35 res = &info->res[j]; 38 res = &root_res->res;
36 pci_add_resource(resources, res); 39 pci_add_resource(resources, res);
37 if (res->flags & IORESOURCE_IO) 40 if (res->flags & IORESOURCE_IO)
38 root = &ioport_resource; 41 root = &ioport_resource;
@@ -53,11 +56,32 @@ default_resources:
53 pci_add_resource(resources, &iomem_resource); 56 pci_add_resource(resources, &iomem_resource);
54} 57}
55 58
59struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max,
60 int node, int link)
61{
62 struct pci_root_info *info;
63
64 info = kzalloc(sizeof(*info), GFP_KERNEL);
65
66 if (!info)
67 return info;
68
69 INIT_LIST_HEAD(&info->resources);
70 info->bus_min = bus_min;
71 info->bus_max = bus_max;
72 info->node = node;
73 info->link = link;
74
75 list_add_tail(&info->list, &pci_root_infos);
76
77 return info;
78}
79
56void __devinit update_res(struct pci_root_info *info, resource_size_t start, 80void __devinit update_res(struct pci_root_info *info, resource_size_t start,
57 resource_size_t end, unsigned long flags, int merge) 81 resource_size_t end, unsigned long flags, int merge)
58{ 82{
59 int i;
60 struct resource *res; 83 struct resource *res;
84 struct pci_root_res *root_res;
61 85
62 if (start > end) 86 if (start > end)
63 return; 87 return;
@@ -69,11 +93,11 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
69 goto addit; 93 goto addit;
70 94
71 /* try to merge it with old one */ 95 /* try to merge it with old one */
72 for (i = 0; i < info->res_num; i++) { 96 list_for_each_entry(root_res, &info->resources, list) {
73 resource_size_t final_start, final_end; 97 resource_size_t final_start, final_end;
74 resource_size_t common_start, common_end; 98 resource_size_t common_start, common_end;
75 99
76 res = &info->res[i]; 100 res = &root_res->res;
77 if (res->flags != flags) 101 if (res->flags != flags)
78 continue; 102 continue;
79 103
@@ -93,14 +117,15 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
93addit: 117addit:
94 118
95 /* need to add that */ 119 /* need to add that */
96 if (info->res_num >= RES_NUM) 120 root_res = kzalloc(sizeof(*root_res), GFP_KERNEL);
121 if (!root_res)
97 return; 122 return;
98 123
99 res = &info->res[info->res_num]; 124 res = &root_res->res;
100 res->name = info->name; 125 res->name = info->name;
101 res->flags = flags; 126 res->flags = flags;
102 res->start = start; 127 res->start = start;
103 res->end = end; 128 res->end = end;
104 res->child = NULL; 129
105 info->res_num++; 130 list_add_tail(&root_res->list, &info->resources);
106} 131}