]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From 990a7ac5645883a833a11b900bb6f25b65dea65b Mon Sep 17 00:00:00 2001 |
2 | From: Andrew Patterson <andrew.patterson@hp.com> | |
3 | Date: Mon, 10 Nov 2008 15:30:45 -0700 | |
4 | Subject: ACPI/PCI: call _OSC support during root bridge discovery | |
5 | Patch-mainline: 2.6.29 | |
6 | References: bnc#438941 | |
7 | ||
8 | Add pci_acpi_osc_support() and call it when a PCI bridge is added. This | |
9 | allows us to avoid having every individual PCI root bridge driver call | |
10 | _OSC support for every root bridge in their probe functions, a | |
11 | significant savings in boot time. | |
12 | ||
13 | Signed-off-by: Matthew Wilcox <willy@linux.intel.com> | |
14 | Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> | |
15 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
16 | ||
17 | --- | |
18 | drivers/acpi/pci_root.c | 9 +++++++++ | |
19 | drivers/pci/pci-acpi.c | 27 ++++++++++++++++++++------- | |
20 | include/linux/pci-acpi.h | 1 + | |
21 | 3 files changed, 30 insertions(+), 7 deletions(-) | |
22 | ||
23 | --- a/drivers/acpi/pci_root.c | |
24 | +++ b/drivers/acpi/pci_root.c | |
25 | @@ -31,6 +31,7 @@ | |
26 | #include <linux/spinlock.h> | |
27 | #include <linux/pm.h> | |
28 | #include <linux/pci.h> | |
29 | +#include <linux/pci-acpi.h> | |
30 | #include <linux/acpi.h> | |
31 | #include <acpi/acpi_bus.h> | |
32 | #include <acpi/acpi_drivers.h> | |
33 | @@ -193,6 +194,7 @@ static int __devinit acpi_pci_root_add(s | |
34 | unsigned long long value = 0; | |
35 | acpi_handle handle = NULL; | |
36 | struct acpi_device *child; | |
37 | + u32 flags; | |
38 | ||
39 | ||
40 | if (!device) | |
41 | @@ -210,6 +212,13 @@ static int __devinit acpi_pci_root_add(s | |
42 | ||
43 | device->ops.bind = acpi_pci_bind; | |
44 | ||
45 | + /* | |
46 | + * All supported architectures that use ACPI have support for | |
47 | + * PCI domains, so we indicate this in _OSC support capabilities. | |
48 | + */ | |
49 | + flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | |
50 | + pci_acpi_osc_support(device->handle, flags); | |
51 | + | |
52 | /* | |
53 | * Segment | |
54 | * ------- | |
55 | --- a/drivers/pci/pci-acpi.c | |
56 | +++ b/drivers/pci/pci-acpi.c | |
57 | @@ -142,32 +142,45 @@ static acpi_status __acpi_query_osc(u32 | |
58 | return status; | |
59 | } | |
60 | ||
61 | -static acpi_status acpi_query_osc(acpi_handle handle, | |
62 | - u32 level, void *context, void **retval) | |
63 | +/* | |
64 | + * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature | |
65 | + * @flags: Bitmask of flags to support | |
66 | + * | |
67 | + * See the ACPI spec for the definition of the flags | |
68 | + */ | |
69 | +int pci_acpi_osc_support(acpi_handle handle, u32 flags) | |
70 | { | |
71 | acpi_status status; | |
72 | - struct acpi_osc_data *osc_data; | |
73 | - u32 flags = (unsigned long)context; | |
74 | acpi_handle tmp; | |
75 | + struct acpi_osc_data *osc_data; | |
76 | + int rc = 0; | |
77 | ||
78 | status = acpi_get_handle(handle, "_OSC", &tmp); | |
79 | if (ACPI_FAILURE(status)) | |
80 | - return status; | |
81 | + return -ENOTTY; | |
82 | ||
83 | mutex_lock(&pci_acpi_lock); | |
84 | osc_data = acpi_get_osc_data(handle); | |
85 | if (!osc_data) { | |
86 | printk(KERN_ERR "acpi osc data array is full\n"); | |
87 | - status = AE_ERROR; | |
88 | + rc = -ENOMEM; | |
89 | goto out; | |
90 | } | |
91 | ||
92 | status = __acpi_query_osc(flags, osc_data); | |
93 | out: | |
94 | mutex_unlock(&pci_acpi_lock); | |
95 | - return status; | |
96 | + return rc; | |
97 | +} | |
98 | + | |
99 | +static acpi_status acpi_query_osc(acpi_handle handle, u32 level, | |
100 | + void *context, void **retval) | |
101 | +{ | |
102 | + pci_acpi_osc_support(handle, (unsigned long)context); | |
103 | + return AE_OK; | |
104 | } | |
105 | ||
106 | + | |
107 | /** | |
108 | * __pci_osc_support_set - register OS support to Firmware | |
109 | * @flags: OS support bits | |
110 | --- a/include/linux/pci-acpi.h | |
111 | +++ b/include/linux/pci-acpi.h | |
112 | @@ -51,6 +51,7 @@ | |
113 | #ifdef CONFIG_ACPI | |
114 | extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags); | |
115 | extern acpi_status __pci_osc_support_set(u32 flags, const char *hid); | |
116 | +int pci_acpi_osc_support(acpi_handle handle, u32 flags); | |
117 | static inline acpi_status pci_osc_support_set(u32 flags) | |
118 | { | |
119 | return __pci_osc_support_set(flags, PCI_ROOT_HID_STRING); |