aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/amd_bus.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/amd_bus.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/amd_bus.c')
-rw-r--r--arch/x86/pci/amd_bus.c76
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
35static 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;