]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - arch/x86/pci/common.c
Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
[mirror_ubuntu-bionic-kernel.git] / arch / x86 / pci / common.c
CommitLineData
1da177e4
LT
1/*
2 * Low-Level PCI Support for PC
3 *
4 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
5 */
6
7#include <linux/sched.h>
8#include <linux/pci.h>
9#include <linux/ioport.h>
10#include <linux/init.h>
8c4b2cf9 11#include <linux/dmi.h>
1da177e4
LT
12
13#include <asm/acpi.h>
14#include <asm/segment.h>
15#include <asm/io.h>
16#include <asm/smp.h>
17
18#include "pci.h"
19
1da177e4
LT
20unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
21 PCI_PROBE_MMCONF;
22
e3f2baeb 23unsigned int pci_early_dump_regs;
2b290da0 24static int pci_bf_sort;
1da177e4
LT
25int pci_routeirq;
26int pcibios_last_bus = -1;
120bb424 27unsigned long pirq_table_addr;
28struct pci_bus *pci_root_bus;
1da177e4 29struct pci_raw_ops *raw_pci_ops;
b6ce068a
MW
30struct pci_raw_ops *raw_pci_ext_ops;
31
32int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
33 int reg, int len, u32 *val)
34{
beef3129 35 if (domain == 0 && reg < 256 && raw_pci_ops)
b6ce068a
MW
36 return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
37 if (raw_pci_ext_ops)
38 return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
39 return -EINVAL;
40}
41
42int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
43 int reg, int len, u32 val)
44{
beef3129 45 if (domain == 0 && reg < 256 && raw_pci_ops)
b6ce068a
MW
46 return raw_pci_ops->write(domain, bus, devfn, reg, len, val);
47 if (raw_pci_ext_ops)
48 return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
49 return -EINVAL;
50}
1da177e4
LT
51
52static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
53{
b6ce068a 54 return raw_pci_read(pci_domain_nr(bus), bus->number,
a79e4198 55 devfn, where, size, value);
1da177e4
LT
56}
57
58static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
59{
b6ce068a 60 return raw_pci_write(pci_domain_nr(bus), bus->number,
a79e4198 61 devfn, where, size, value);
1da177e4
LT
62}
63
64struct pci_ops pci_root_ops = {
65 .read = pci_read,
66 .write = pci_write,
67};
68
69/*
70 * legacy, numa, and acpi all want to call pcibios_scan_root
71 * from their initcalls. This flag prevents that.
72 */
73int pcibios_scanned;
74
75/*
76 * This interrupt-safe spinlock protects all accesses to PCI
77 * configuration space.
78 */
79DEFINE_SPINLOCK(pci_config_lock);
80
13a6ddb0
YL
81static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
82{
83 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
84 printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
85 return 0;
86}
87
88static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = {
89/*
90 * Systems where PCI IO resource ISA alignment can be skipped
91 * when the ISA enable bit in the bridge control is not set
92 */
93 {
94 .callback = can_skip_ioresource_align,
95 .ident = "IBM System x3800",
96 .matches = {
97 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
98 DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
99 },
100 },
101 {
102 .callback = can_skip_ioresource_align,
103 .ident = "IBM System x3850",
104 .matches = {
105 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
106 DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
107 },
108 },
109 {
110 .callback = can_skip_ioresource_align,
111 .ident = "IBM System x3950",
112 .matches = {
113 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
114 DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
115 },
116 },
117 {}
118};
119
120void __init dmi_check_skip_isa_align(void)
121{
122 dmi_check_system(can_skip_pciprobe_dmi_table);
123}
124
bb71ad88
GH
125static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
126{
127 struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
128
129 if (pci_probe & PCI_NOASSIGN_ROMS) {
130 if (rom_r->parent)
131 return;
132 if (rom_r->start) {
133 /* we deal with BIOS assigned ROM later */
134 return;
135 }
136 rom_r->start = rom_r->end = rom_r->flags = 0;
137 }
138}
139
1da177e4
LT
140/*
141 * Called after each bus is probed, but before its children
142 * are examined.
143 */
144
145void __devinit pcibios_fixup_bus(struct pci_bus *b)
146{
bb71ad88
GH
147 struct pci_dev *dev;
148
1da177e4 149 pci_read_bridge_bases(b);
bb71ad88
GH
150 list_for_each_entry(dev, &b->devices, bus_list)
151 pcibios_fixup_device_resources(dev);
1da177e4
LT
152}
153
6b4b78fe
MD
154/*
155 * Only use DMI information to set this if nothing was passed
156 * on the kernel command line (which was parsed earlier).
157 */
158
1855256c 159static int __devinit set_bf_sort(const struct dmi_system_id *d)
6b4b78fe
MD
160{
161 if (pci_bf_sort == pci_bf_sort_default) {
162 pci_bf_sort = pci_dmi_bf;
163 printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident);
164 }
165 return 0;
166}
167
8c4b2cf9
BK
168/*
169 * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
170 */
171#ifdef __i386__
1855256c 172static int __devinit assign_all_busses(const struct dmi_system_id *d)
8c4b2cf9
BK
173{
174 pci_probe |= PCI_ASSIGN_ALL_BUSSES;
175 printk(KERN_INFO "%s detected: enabling PCI bus# renumbering"
176 " (pci=assign-busses)\n", d->ident);
177 return 0;
178}
179#endif
180
6b4b78fe
MD
181static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
182#ifdef __i386__
8c4b2cf9
BK
183/*
184 * Laptops which need pci=assign-busses to see Cardbus cards
185 */
8c4b2cf9
BK
186 {
187 .callback = assign_all_busses,
188 .ident = "Samsung X20 Laptop",
189 .matches = {
190 DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
191 DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"),
192 },
193 },
194#endif /* __i386__ */
6b4b78fe
MD
195 {
196 .callback = set_bf_sort,
197 .ident = "Dell PowerEdge 1950",
198 .matches = {
199 DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
200 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"),
201 },
202 },
203 {
204 .callback = set_bf_sort,
205 .ident = "Dell PowerEdge 1955",
206 .matches = {
207 DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
208 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"),
209 },
210 },
211 {
212 .callback = set_bf_sort,
213 .ident = "Dell PowerEdge 2900",
214 .matches = {
215 DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
216 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"),
217 },
218 },
219 {
220 .callback = set_bf_sort,
221 .ident = "Dell PowerEdge 2950",
222 .matches = {
223 DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
224 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
225 },
226 },
f7a9dae7
MD
227 {
228 .callback = set_bf_sort,
229 .ident = "Dell PowerEdge R900",
230 .matches = {
231 DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
232 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"),
233 },
234 },
f52383d3
AG
235 {
236 .callback = set_bf_sort,
237 .ident = "HP ProLiant BL20p G3",
238 .matches = {
239 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
240 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"),
241 },
242 },
243 {
244 .callback = set_bf_sort,
245 .ident = "HP ProLiant BL20p G4",
246 .matches = {
247 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
248 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"),
249 },
250 },
251 {
252 .callback = set_bf_sort,
253 .ident = "HP ProLiant BL30p G1",
254 .matches = {
255 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
256 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"),
257 },
258 },
259 {
260 .callback = set_bf_sort,
261 .ident = "HP ProLiant BL25p G1",
262 .matches = {
263 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
264 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"),
265 },
266 },
267 {
268 .callback = set_bf_sort,
269 .ident = "HP ProLiant BL35p G1",
270 .matches = {
271 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
272 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"),
273 },
274 },
275 {
276 .callback = set_bf_sort,
277 .ident = "HP ProLiant BL45p G1",
278 .matches = {
279 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
280 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"),
281 },
282 },
283 {
284 .callback = set_bf_sort,
285 .ident = "HP ProLiant BL45p G2",
286 .matches = {
287 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
288 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"),
289 },
290 },
291 {
292 .callback = set_bf_sort,
293 .ident = "HP ProLiant BL460c G1",
294 .matches = {
295 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
296 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"),
297 },
298 },
299 {
300 .callback = set_bf_sort,
301 .ident = "HP ProLiant BL465c G1",
302 .matches = {
303 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
304 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"),
305 },
306 },
307 {
308 .callback = set_bf_sort,
309 .ident = "HP ProLiant BL480c G1",
310 .matches = {
311 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
312 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"),
313 },
314 },
315 {
316 .callback = set_bf_sort,
317 .ident = "HP ProLiant BL685c G1",
318 .matches = {
319 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
320 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
321 },
322 },
8f8ae1a7
MS
323 {
324 .callback = set_bf_sort,
8d64c781 325 .ident = "HP ProLiant DL360",
8f8ae1a7
MS
326 .matches = {
327 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
8d64c781 328 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL360"),
8f8ae1a7
MS
329 },
330 },
331 {
332 .callback = set_bf_sort,
8d64c781 333 .ident = "HP ProLiant DL380",
8f8ae1a7
MS
334 .matches = {
335 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
8d64c781 336 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL380"),
8f8ae1a7
MS
337 },
338 },
5b1ea82f
JL
339#ifdef __i386__
340 {
341 .callback = assign_all_busses,
342 .ident = "Compaq EVO N800c",
343 .matches = {
344 DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
345 DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"),
346 },
347 },
348#endif
c82bc5ad
MS
349 {
350 .callback = set_bf_sort,
739db07f 351 .ident = "HP ProLiant DL385 G2",
c82bc5ad
MS
352 .matches = {
353 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
739db07f 354 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"),
c82bc5ad
MS
355 },
356 },
357 {
358 .callback = set_bf_sort,
739db07f 359 .ident = "HP ProLiant DL585 G2",
c82bc5ad
MS
360 .matches = {
361 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
739db07f 362 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
c82bc5ad
MS
363 },
364 },
8c4b2cf9
BK
365 {}
366};
1da177e4 367
0df18ff3
YL
368void __init dmi_check_pciprobe(void)
369{
370 dmi_check_system(pciprobe_dmi_table);
371}
372
1da177e4
LT
373struct pci_bus * __devinit pcibios_scan_root(int busnum)
374{
375 struct pci_bus *bus = NULL;
08f1c192 376 struct pci_sysdata *sd;
1da177e4
LT
377
378 while ((bus = pci_find_next_bus(bus)) != NULL) {
379 if (bus->number == busnum) {
380 /* Already scanned */
381 return bus;
382 }
383 }
384
08f1c192
MBY
385 /* Allocate per-root-bus (not per bus) arch-specific data.
386 * TODO: leak; this memory is never freed.
387 * It's arguable whether it's worth the trouble to care.
388 */
389 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
390 if (!sd) {
391 printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum);
392 return NULL;
393 }
394
871d5f8d
YL
395 sd->node = get_mp_bus_to_node(busnum);
396