]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From 0ef5f8f6159e44b4faa997be08d1a3bcbf44ad08 Mon Sep 17 00:00:00 2001 |
2 | From: Andrew Patterson <andrew.patterson@hp.com> | |
3 | Date: Mon, 10 Nov 2008 15:30:50 -0700 | |
4 | Subject: ACPI/PCI: PCI extended config _OSC support called when root bridge added | |
5 | Patch-mainline: 2.6.29 | |
6 | References: bnc#438941 | |
7 | ||
8 | The _OSC capability OSC_EXT_PCI_CONFIG_SUPPORT is set when the root | |
9 | bridge is added with pci_acpi_osc_support() if we can access PCI | |
10 | extended config space. | |
11 | ||
12 | This adds the function pci_ext_cfg_avail which returns true if we can | |
13 | access PCI extended config space (offset greater than 0xff). It | |
14 | currently only returns false if arch=x86 and raw_pci_ext_ops is not set | |
15 | (which might happen if pci=nommcfg is set on the kernel command-line). | |
16 | ||
17 | Signed-off-by: Andrew Patterson <andrew.patterson@hp.com> | |
18 | Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> | |
19 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
20 | ||
21 | --- | |
22 | arch/x86/pci/common.c | 8 ++++++++ | |
23 | drivers/acpi/pci_root.c | 10 ++++++++-- | |
24 | drivers/pci/pci.c | 13 +++++++++++++ | |
25 | include/linux/pci.h | 2 ++ | |
26 | 4 files changed, 31 insertions(+), 2 deletions(-) | |
27 | ||
28 | --- a/arch/x86/pci/common.c | |
29 | +++ b/arch/x86/pci/common.c | |
30 | @@ -563,6 +563,14 @@ void pcibios_disable_device (struct pci_ | |
31 | pcibios_disable_irq(dev); | |
32 | } | |
33 | ||
34 | +int pci_ext_cfg_avail(struct pci_dev *dev) | |
35 | +{ | |
36 | + if (raw_pci_ext_ops) | |
37 | + return 1; | |
38 | + else | |
39 | + return 0; | |
40 | +} | |
41 | + | |
42 | struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) | |
43 | { | |
44 | struct pci_bus *bus = NULL; | |
45 | --- a/drivers/acpi/pci_root.c | |
46 | +++ b/drivers/acpi/pci_root.c | |
47 | @@ -194,7 +194,7 @@ static int __devinit acpi_pci_root_add(s | |
48 | unsigned long long value = 0; | |
49 | acpi_handle handle = NULL; | |
50 | struct acpi_device *child; | |
51 | - u32 flags; | |
52 | + u32 flags, base_flags; | |
53 | ||
54 | ||
55 | if (!device) | |
56 | @@ -216,7 +216,7 @@ static int __devinit acpi_pci_root_add(s | |
57 | * All supported architectures that use ACPI have support for | |
58 | * PCI domains, so we indicate this in _OSC support capabilities. | |
59 | */ | |
60 | - flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | |
61 | + flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | |
62 | pci_acpi_osc_support(device->handle, flags); | |
63 | ||
64 | /* | |
65 | @@ -344,6 +344,12 @@ static int __devinit acpi_pci_root_add(s | |
66 | list_for_each_entry(child, &device->children, node) | |
67 | acpi_pci_bridge_scan(child); | |
68 | ||
69 | + /* Indicate support for various _OSC capabilities. */ | |
70 | + if (pci_ext_cfg_avail(root->bus->self)) | |
71 | + flags |= OSC_EXT_PCI_CONFIG_SUPPORT; | |
72 | + if (flags != base_flags) | |
73 | + pci_acpi_osc_support(device->handle, flags); | |
74 | + | |
75 | end: | |
76 | if (result) { | |
77 | if (!list_empty(&root->node)) | |
78 | --- a/drivers/pci/pci.c | |
79 | +++ b/drivers/pci/pci.c | |
80 | @@ -1899,6 +1899,19 @@ static void __devinit pci_no_domains(voi | |
81 | #endif | |
82 | } | |
83 | ||
84 | +/** | |
85 | + * pci_ext_cfg_enabled - can we access extended PCI config space? | |
86 | + * @dev: The PCI device of the root bridge. | |
87 | + * | |
88 | + * Returns 1 if we can access PCI extended config space (offsets | |
89 | + * greater than 0xff). This is the default implementation. Architecture | |
90 | + * implementations can override this. | |
91 | + */ | |
92 | +int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) | |
93 | +{ | |
94 | + return 1; | |
95 | +} | |
96 | + | |
97 | static int __devinit pci_init(void) | |
98 | { | |
99 | struct pci_dev *dev = NULL; | |
100 | --- a/include/linux/pci.h | |
101 | +++ b/include/linux/pci.h | |
102 | @@ -1128,5 +1128,7 @@ static inline void pci_mmcfg_early_init( | |
103 | static inline void pci_mmcfg_late_init(void) { } | |
104 | #endif | |
105 | ||
106 | +int pci_ext_cfg_avail(struct pci_dev *dev); | |
107 | + | |
108 | #endif /* __KERNEL__ */ | |
109 | #endif /* LINUX_PCI_H */ |