diff options
author | Yinghai Lu <yinghai@kernel.org> | 2012-04-02 21:31:54 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-04-30 16:52:43 -0400 |
commit | d28e5ac2a07e27638cf5ac061721b7969e17fe78 (patch) | |
tree | 4ae91ae8d95f3ef23d8fa9be5f1d02b8cdc53715 /arch/x86/pci/amd_bus.c | |
parent | 35cb05e5bdac209cfdfafbe50d89ee7069cb6237 (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/amd_bus.c')
-rw-r--r-- | arch/x86/pci/amd_bus.c | 76 |
1 files changed, 27 insertions, 49 deletions
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 0567df3890e1..459a7316375c 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -32,6 +32,18 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = { | |||
32 | 32 | ||
33 | #define RANGE_NUM 16 | 33 | #define RANGE_NUM 16 |
34 | 34 | ||
35 | static struct pci_root_info __init *find_pci_root_info(int node, int link) | ||
36 | { | ||
37 | struct pci_root_info *info; | ||
38 | |||
39 | /* find the position */ | ||
40 | list_for_each_entry(info, &pci_root_infos, list) | ||
41 | if (info->node == node && info->link == link) | ||
42 | return info; | ||
43 | |||
44 | return NULL; | ||
45 | } | ||
46 | |||
35 | /** | 47 | /** |
36 | * early_fill_mp_bus_to_node() | 48 | * early_fill_mp_bus_to_node() |
37 | * called before pcibios_scan_root and pci_scan_bus | 49 | * called before pcibios_scan_root and pci_scan_bus |
@@ -50,7 +62,6 @@ static int __init early_fill_mp_bus_info(void) | |||
50 | int def_link; | 62 | int def_link; |
51 | struct pci_root_info *info; | 63 | struct pci_root_info *info; |
52 | u32 reg; | 64 | u32 reg; |
53 | struct resource *res; | ||
54 | u64 start; | 65 | u64 start; |
55 | u64 end; | 66 | u64 end; |
56 | struct range range[RANGE_NUM]; | 67 | struct range range[RANGE_NUM]; |
@@ -86,7 +97,6 @@ static int __init early_fill_mp_bus_info(void) | |||
86 | if (!found) | 97 | if (!found) |
87 | return 0; | 98 | return 0; |
88 | 99 | ||
89 | pci_root_num = 0; | ||
90 | for (i = 0; i < 4; i++) { | 100 | for (i = 0; i < 4; i++) { |
91 | int min_bus; | 101 | int min_bus; |
92 | int max_bus; | 102 | int max_bus; |
@@ -105,13 +115,8 @@ static int __init early_fill_mp_bus_info(void) | |||
105 | #endif | 115 | #endif |
106 | link = (reg >> 8) & 0x03; | 116 | link = (reg >> 8) & 0x03; |
107 | 117 | ||
108 | info = &pci_root_info[pci_root_num]; | 118 | info = alloc_pci_root_info(min_bus, max_bus, node, link); |
109 | info->bus_min = min_bus; | ||
110 | info->bus_max = max_bus; | ||
111 | info->node = node; | ||
112 | info->link = link; | ||
113 | sprintf(info->name, "PCI Bus #%02x", min_bus); | 119 | sprintf(info->name, "PCI Bus #%02x", min_bus); |
114 | pci_root_num++; | ||
115 | } | 120 | } |
116 | 121 | ||
117 | /* get the default node and link for left over res */ | 122 | /* get the default node and link for left over res */ |
@@ -134,16 +139,10 @@ static int __init early_fill_mp_bus_info(void) | |||
134 | link = (reg >> 4) & 0x03; | 139 | link = (reg >> 4) & 0x03; |
135 | end = (reg & 0xfff000) | 0xfff; | 140 | end = (reg & 0xfff000) | 0xfff; |
136 | 141 | ||
137 | /* find the position */ | 142 | info = find_pci_root_info(node, link); |
138 | for (j = 0; j < pci_root_num; j++) { | 143 | if (!info) |
139 | info = &pci_root_info[j]; | ||
140 | if (info->node == node && info->link == link) | ||
141 | break; | ||
142 | } | ||
143 | if (j == pci_root_num) | ||
144 | continue; /* not found */ | 144 | continue; /* not found */ |
145 | 145 | ||
146 | info = &pci_root_info[j]; | ||
147 | printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n", | 146 | printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n", |
148 | node, link, start, end); | 147 | node, link, start, end); |
149 | 148 | ||
@@ -155,13 +154,8 @@ static int __init early_fill_mp_bus_info(void) | |||
155 | } | 154 | } |
156 | /* add left over io port range to def node/link, [0, 0xffff] */ | 155 | /* add left over io port range to def node/link, [0, 0xffff] */ |
157 | /* find the position */ | 156 | /* find the position */ |
158 | for (j = 0; j < pci_root_num; j++) { | 157 | info = find_pci_root_info(def_node, def_link); |
159 | info = &pci_root_info[j]; | 158 | if (info) { |
160 | if (info->node == def_node && info->link == def_link) | ||
161 | break; | ||
162 | } | ||
163 | if (j < pci_root_num) { | ||
164 | info = &pci_root_info[j]; | ||
165 | for (i = 0; i < RANGE_NUM; i++) { | 159 | for (i = 0; i < RANGE_NUM; i++) { |
166 | if (!range[i].end) | 160 | if (!range[i].end) |
167 | continue; | 161 | continue; |
@@ -214,16 +208,10 @@ static int __init early_fill_mp_bus_info(void) | |||
214 | end <<= 8; | 208 | end <<= 8; |
215 | end |= 0xffff; | 209 | end |= 0xffff; |
216 | 210 | ||
217 | /* find the position */ | 211 | info = find_pci_root_info(node, link); |
218 | for (j = 0; j < pci_root_num; j++) { | ||
219 | info = &pci_root_info[j]; | ||
220 | if (info->node == node && info->link == link) | ||
221 | break; | ||
222 | } | ||
223 | if (j == pci_root_num) | ||
224 | continue; /* not found */ | ||
225 | 212 | ||
226 | info = &pci_root_info[j]; | 213 | if (!info) |
214 | continue; | ||
227 | 215 | ||
228 | printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]", | 216 | printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]", |
229 | node, link, start, end); | 217 | node, link, start, end); |
@@ -291,14 +279,8 @@ static int __init early_fill_mp_bus_info(void) | |||
291 | * add left over mmio range to def node/link ? | 279 | * add left over mmio range to def node/link ? |
292 | * that is tricky, just record range in from start_min to 4G | 280 | * that is tricky, just record range in from start_min to 4G |
293 | */ | 281 | */ |
294 | for (j = 0; j < pci_root_num; j++) { | 282 | info = find_pci_root_info(def_node, def_link); |
295 | info = &pci_root_info[j]; | 283 | if (info) { |
296 | if (info->node == def_node && info->link == def_link) | ||
297 | break; | ||
298 | } | ||
299 | if (j < pci_root_num) { | ||
300 | info = &pci_root_info[j]; | ||
301 | |||
302 | for (i = 0; i < RANGE_NUM; i++) { | 284 | for (i = 0; i < RANGE_NUM; i++) { |
303 | if (!range[i].end) | 285 | if (!range[i].end) |
304 | continue; | 286 | continue; |
@@ -309,20 +291,16 @@ static int __init early_fill_mp_bus_info(void) | |||
309 | } | 291 | } |
310 | } | 292 | } |
311 | 293 | ||
312 | for (i = 0; i < pci_root_num; i++) { | 294 | list_for_each_entry(info, &pci_root_infos, list) { |
313 | int res_num; | ||
314 | int busnum; | 295 | int busnum; |
296 | struct pci_root_res *root_res; | ||
315 | 297 | ||
316 | info = &pci_root_info[i]; | ||
317 | res_num = info->res_num; | ||
318 | busnum = info->bus_min; | 298 | busnum = info->bus_min; |
319 | printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", | 299 | printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", |
320 | info->bus_min, info->bus_max, info->node, info->link); | 300 | info->bus_min, info->bus_max, info->node, info->link); |
321 | for (j = 0; j < res_num; j++) { | 301 | list_for_each_entry(root_res, &info->resources, list) |
322 | res = &info->res[j]; | 302 | printk(KERN_DEBUG "bus: %02x %pR\n", |
323 | printk(KERN_DEBUG "bus: %02x index %x %pR\n", | 303 | busnum, &root_res->res); |
324 | busnum, j, res); | ||
325 | } | ||
326 | } | 304 | } |
327 | 305 | ||
328 | return 0; | 306 | return 0; |