blob: f67c946a861292f72a06b89cbe1c3bb07dbbe646 [file] [log] [blame]
Paul Mundt85b59f52010-02-01 13:01:42 +09001#include <linux/pci.h>
2#include <linux/kernel.h>
3
4static int __init
5early_read_config_word(struct pci_channel *hose,
6 int top_bus, int bus, int devfn, int offset, u16 *value)
7{
8 struct pci_dev fake_dev;
9 struct pci_bus fake_bus;
10
11 fake_dev.bus = &fake_bus;
12 fake_dev.sysdata = hose;
13 fake_dev.devfn = devfn;
14 fake_bus.number = bus;
15 fake_bus.sysdata = hose;
16 fake_bus.ops = hose->pci_ops;
17
18 if (bus != top_bus)
19 /* Fake a parent bus structure. */
20 fake_bus.parent = &fake_bus;
21 else
22 fake_bus.parent = NULL;
23
24 return pci_read_config_word(&fake_dev, offset, value);
25}
26
27int __init pci_is_66mhz_capable(struct pci_channel *hose,
28 int top_bus, int current_bus)
29{
30 u32 pci_devfn;
31 unsigned short vid;
32 int cap66 = -1;
33 u16 stat;
34
35 printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n");
36
37 for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
38 if (PCI_FUNC(pci_devfn))
39 continue;
40 if (early_read_config_word(hose, top_bus, current_bus,
41 pci_devfn, PCI_VENDOR_ID, &vid) !=
42 PCIBIOS_SUCCESSFUL)
43 continue;
44 if (vid == 0xffff)
45 continue;
46
47 /* check 66MHz capability */
48 if (cap66 < 0)
49 cap66 = 1;
50 if (cap66) {
51 early_read_config_word(hose, top_bus, current_bus,
52 pci_devfn, PCI_STATUS, &stat);
53 if (!(stat & PCI_STATUS_66MHZ)) {
54 printk(KERN_DEBUG
55 "PCI: %02x:%02x not 66MHz capable.\n",
56 current_bus, pci_devfn);
57 cap66 = 0;
58 break;
59 }
60 }
61 }
62
63 return cap66 > 0;
64}