x86/PCI: use _CRS bus number aperture for host bridges from ACPI
[deliverable/linux.git] / arch / x86 / pci / bus_numa.c
CommitLineData
67f241f4
YL
1#include <linux/init.h>
2#include <linux/pci.h>
9ad3f2c7 3#include <linux/range.h>
67f241f4
YL
4
5#include "bus_numa.h"
6
d28e5ac2 7LIST_HEAD(pci_root_infos);
67f241f4 8
d28e5ac2 9static struct pci_root_info *x86_find_pci_root_info(int bus)
67f241f4 10{
67f241f4
YL
11 struct pci_root_info *info;
12
d28e5ac2
YL
13 if (list_empty(&pci_root_infos))
14 return NULL;
67f241f4 15
d28e5ac2
YL
16 list_for_each_entry(info, &pci_root_infos, list)
17 if (info->bus_min == bus)
18 return info;
19
20 return NULL;
21}
67f241f4 22
d28e5ac2
YL
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)
2cd6975a 29 goto default_resources;
67f241f4 30
2cd6975a
BH
31 printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
32 bus);
67f241f4 33
d28e5ac2 34 list_for_each_entry(root_res, &info->resources, list) {
67f241f4
YL
35 struct resource *res;
36 struct resource *root;
37
d28e5ac2 38 res = &root_res->res;
2cd6975a 39 pci_add_resource(resources, res);
67f241f4
YL
40 if (res->flags & IORESOURCE_IO)
41 root = &ioport_resource;
42 else
43 root = &iomem_resource;
44 insert_resource(root, res);
45 }
2cd6975a
BH
46 return;
47
48default_resources:
49 /*
50 * We don't have any host bridge aperture information from the
51 * "native host bridge drivers," e.g., amd_bus or broadcom_bus,
52 * so fall back to the defaults historically used by pci_create_bus().
53 */
54 printk(KERN_DEBUG "PCI: root bus %02x: using default resources\n", bus);
55 pci_add_resource(resources, &ioport_resource);
56 pci_add_resource(resources, &iomem_resource);
67f241f4
YL
57}
58
d28e5ac2
YL
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
b74fd238
YL
80void __devinit update_res(struct pci_root_info *info, resource_size_t start,
81 resource_size_t end, unsigned long flags, int merge)
67f241f4 82{
67f241f4 83 struct resource *res;
d28e5ac2 84 struct pci_root_res *root_res;
67f241f4
YL
85
86 if (start > end)
87 return;
88
9ad3f2c7
YL
89 if (start == MAX_RESOURCE)
90 return;
91
67f241f4
YL
92 if (!merge)
93 goto addit;
94
95 /* try to merge it with old one */
d28e5ac2 96 list_for_each_entry(root_res, &info->resources, list) {
b74fd238
YL
97 resource_size_t final_start, final_end;
98 resource_size_t common_start, common_end;
67f241f4 99
d28e5ac2 100 res = &root_res->res;
67f241f4
YL
101 if (res->flags != flags)
102 continue;
103
b74fd238
YL
104 common_start = max(res->start, start);
105 common_end = min(res->end, end);
67f241f4
YL
106 if (common_start > common_end + 1)
107 continue;
108
b74fd238
YL
109 final_start = min(res->start, start);
110 final_end = max(res->end, end);
67f241f4
YL
111
112 res->start = final_start;
113 res->end = final_end;
114 return;
115 }
116
117addit:
118
119 /* need to add that */
d28e5ac2
YL
120 root_res = kzalloc(sizeof(*root_res), GFP_KERNEL);
121 if (!root_res)
67f241f4
YL
122 return;
123
d28e5ac2 124 res = &root_res->res;
67f241f4
YL
125 res->name = info->name;
126 res->flags = flags;
127 res->start = start;
128 res->end = end;
d28e5ac2
YL
129
130 list_add_tail(&root_res->list, &info->resources);
67f241f4 131}
This page took 0.231314 seconds and 5 git commands to generate.