| @@ -1,336 +1,337 @@ | | | @@ -1,336 +1,337 @@ |
1 | /* $NetBSD: intel_acpi.c,v 1.4 2021/12/19 11:38:03 riastradh Exp $ */ | | 1 | /* $NetBSD: intel_acpi.c,v 1.5 2022/02/27 14:19:35 riastradh Exp $ */ |
2 | | | 2 | |
3 | // SPDX-License-Identifier: GPL-2.0 | | 3 | // SPDX-License-Identifier: GPL-2.0 |
4 | /* | | 4 | /* |
5 | * Intel ACPI functions | | 5 | * Intel ACPI functions |
6 | * | | 6 | * |
7 | * _DSM related code stolen from nouveau_acpi.c. | | 7 | * _DSM related code stolen from nouveau_acpi.c. |
8 | */ | | 8 | */ |
9 | | | 9 | |
10 | #include <sys/cdefs.h> | | 10 | #include <sys/cdefs.h> |
11 | __KERNEL_RCSID(0, "$NetBSD: intel_acpi.c,v 1.4 2021/12/19 11:38:03 riastradh Exp $"); | | 11 | __KERNEL_RCSID(0, "$NetBSD: intel_acpi.c,v 1.5 2022/02/27 14:19:35 riastradh Exp $"); |
12 | | | 12 | |
13 | #include <linux/pci.h> | | 13 | #include <linux/pci.h> |
14 | #include <linux/acpi.h> | | 14 | #include <linux/acpi.h> |
15 | | | 15 | |
16 | #include "i915_drv.h" | | 16 | #include "i915_drv.h" |
17 | #include "intel_acpi.h" | | 17 | #include "intel_acpi.h" |
18 | | | 18 | |
19 | #ifdef __NetBSD__ | | 19 | #ifdef __NetBSD__ |
20 | | | 20 | |
21 | #include <dev/acpi/acpireg.h> | | 21 | #include <dev/acpi/acpireg.h> |
22 | #define _COMPONENT ACPI_BUTTON_COMPONENT | | 22 | #define _COMPONENT ACPI_BUTTON_COMPONENT |
23 | ACPI_MODULE_NAME("acpi_intel_brightness") | | 23 | ACPI_MODULE_NAME("acpi_intel_brightness") |
24 | | | 24 | |
25 | #include <dev/acpi/acpi_pci.h> | | 25 | #include <dev/acpi/acpi_pci.h> |
26 | | | 26 | |
27 | #define acpi_handle ACPI_HANDLE | | 27 | #define acpi_handle ACPI_HANDLE |
28 | #define buffer Buffer | | 28 | #define buffer Buffer |
29 | #define count Count | | 29 | #define count Count |
30 | #define elements Elements | | 30 | #define elements Elements |
31 | #define integer Integer | | 31 | #define integer Integer |
32 | #define package Package | | 32 | #define package Package |
33 | #define pointer Pointer | | 33 | #define pointer Pointer |
34 | #define value Value | | 34 | #define value Value |
35 | | | 35 | |
36 | static ACPI_OBJECT * | | 36 | static ACPI_OBJECT * |
37 | acpi_evaluate_dsm(ACPI_HANDLE handle, const guid_t *uuid, int rev, int func, | | 37 | acpi_evaluate_dsm(ACPI_HANDLE handle, const guid_t *uuid, int rev, int func, |
38 | ACPI_OBJECT *argv4) | | 38 | ACPI_OBJECT *argv4) |
39 | { | | 39 | { |
40 | ACPI_OBJECT_LIST arg; | | 40 | ACPI_OBJECT_LIST arg; |
41 | ACPI_OBJECT params[4]; | | 41 | ACPI_OBJECT params[4]; |
42 | ACPI_BUFFER buf; | | 42 | ACPI_BUFFER buf; |
43 | ACPI_STATUS rv; | | 43 | ACPI_STATUS rv; |
44 | | | 44 | |
45 | if (handle == NULL) | | 45 | if (handle == NULL) |
46 | handle = ACPI_ROOT_OBJECT; | | 46 | handle = ACPI_ROOT_OBJECT; |
47 | | | 47 | |
48 | arg.Count = 4; | | 48 | arg.Count = 4; |
49 | arg.Pointer = params; | | 49 | arg.Pointer = params; |
50 | params[0].Type = ACPI_TYPE_BUFFER; | | 50 | params[0].Type = ACPI_TYPE_BUFFER; |
51 | params[0].Buffer.Length = 16; | | 51 | params[0].Buffer.Length = 16; |
52 | params[0].Buffer.Pointer = (char *)__UNCONST(uuid); | | 52 | params[0].Buffer.Pointer = (char *)__UNCONST(uuid); |
53 | params[1].Type = ACPI_TYPE_INTEGER; | | 53 | params[1].Type = ACPI_TYPE_INTEGER; |
54 | params[1].Integer.Value = rev; | | 54 | params[1].Integer.Value = rev; |
55 | params[2].Type = ACPI_TYPE_INTEGER; | | 55 | params[2].Type = ACPI_TYPE_INTEGER; |
56 | params[2].Integer.Value = func; | | 56 | params[2].Integer.Value = func; |
57 | if (argv4 != NULL) { | | 57 | if (argv4 != NULL) { |
58 | params[3] = *argv4; | | 58 | params[3] = *argv4; |
59 | } else { | | 59 | } else { |
60 | params[3].Type = ACPI_TYPE_PACKAGE; | | 60 | params[3].Type = ACPI_TYPE_PACKAGE; |
61 | params[3].Package.Count = 0; | | 61 | params[3].Package.Count = 0; |
62 | params[3].Package.Elements = NULL; | | 62 | params[3].Package.Elements = NULL; |
63 | } | | 63 | } |
64 | | | 64 | |
65 | buf.Pointer = NULL; | | 65 | buf.Pointer = NULL; |
66 | buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER; | | 66 | buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER; |
67 | | | 67 | |
68 | rv = AcpiEvaluateObject(handle, "_DSM", &arg, &buf); | | 68 | rv = AcpiEvaluateObject(handle, "_DSM", &arg, &buf); |
69 | if (ACPI_SUCCESS(rv)) | | 69 | if (ACPI_SUCCESS(rv)) |
70 | return (ACPI_OBJECT *)buf.Pointer; | | 70 | return (ACPI_OBJECT *)buf.Pointer; |
71 | return NULL; | | 71 | return NULL; |
72 | } | | 72 | } |
73 | | | 73 | |
74 | static inline ACPI_OBJECT * | | 74 | static inline ACPI_OBJECT * |
75 | acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const guid_t *uuid, int rev, | | 75 | acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const guid_t *uuid, int rev, |
76 | int func, ACPI_OBJECT *argv4, ACPI_OBJECT_TYPE type) | | 76 | int func, ACPI_OBJECT *argv4, ACPI_OBJECT_TYPE type) |
77 | { | | 77 | { |
78 | ACPI_OBJECT *obj; | | 78 | ACPI_OBJECT *obj; |
79 | | | 79 | |
80 | obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4); | | 80 | obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4); |
81 | if (obj != NULL && obj->Type != type) { | | 81 | if (obj != NULL && obj->Type != type) { |
82 | ACPI_FREE(obj); | | 82 | ACPI_FREE(obj); |
83 | obj = NULL; | | 83 | obj = NULL; |
84 | } | | 84 | } |
85 | return obj; | | 85 | return obj; |
86 | } | | 86 | } |
87 | | | 87 | |
88 | #define ACPI_INIT_DSM_ARGV4(cnt, eles) \ | | 88 | #define ACPI_INIT_DSM_ARGV4(cnt, eles) \ |
89 | { \ | | 89 | { \ |
90 | .Package.Type = ACPI_TYPE_PACKAGE, \ | | 90 | .Package.Type = ACPI_TYPE_PACKAGE, \ |
91 | .Package.Count = (cnt), \ | | 91 | .Package.Count = (cnt), \ |
92 | .Package.Elements = (eles) \ | | 92 | .Package.Elements = (eles) \ |
93 | } | | 93 | } |
94 | | | 94 | |
95 | static bool | | 95 | static bool |
96 | acpi_check_dsm(ACPI_HANDLE handle, const guid_t *uuid, int rev, uint64_t funcs) | | 96 | acpi_check_dsm(ACPI_HANDLE handle, const guid_t *uuid, int rev, uint64_t funcs) |
97 | { | | 97 | { |
98 | ACPI_OBJECT *obj; | | 98 | ACPI_OBJECT *obj; |
99 | uint64_t mask = 0; | | 99 | uint64_t mask = 0; |
100 | int i; | | 100 | int i; |
101 | | | 101 | |
102 | if (funcs == 0) | | 102 | if (funcs == 0) |
103 | return false; | | 103 | return false; |
104 | | | 104 | |
105 | obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL); | | 105 | obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL); |
106 | if (obj == NULL) | | 106 | if (obj == NULL) |
107 | return false; | | 107 | return false; |
108 | | | 108 | |
109 | if (obj->Type == ACPI_TYPE_INTEGER) | | 109 | if (obj->Type == ACPI_TYPE_INTEGER) |
110 | mask = obj->Integer.Value; | | 110 | mask = obj->Integer.Value; |
111 | else if (obj->Type == ACPI_TYPE_BUFFER) | | 111 | else if (obj->Type == ACPI_TYPE_BUFFER) |
112 | for (i = 0; i < obj->Buffer.Length && i < 8; i++) | | 112 | for (i = 0; i < obj->Buffer.Length && i < 8; i++) |
113 | mask |= (uint64_t)obj->Buffer.Pointer[i] << (i * 8); | | 113 | mask |= (uint64_t)obj->Buffer.Pointer[i] << (i * 8); |
114 | ACPI_FREE(obj); | | 114 | ACPI_FREE(obj); |
115 | | | 115 | |
116 | if ((mask & 0x1) == 0x1 && (mask & funcs) == funcs) | | 116 | if ((mask & 0x1) == 0x1 && (mask & funcs) == funcs) |
117 | return true; | | 117 | return true; |
118 | return false; | | 118 | return false; |
119 | } | | 119 | } |
120 | #endif | | 120 | #endif |
121 | | | 121 | |
122 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ | | 122 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ |
123 | #define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ | | 123 | #define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ |
124 | | | 124 | |
125 | static const guid_t intel_dsm_guid = | | 125 | static const guid_t intel_dsm_guid = |
126 | GUID_INIT(0x7ed873d3, 0xc2d0, 0x4e4f, | | 126 | GUID_INIT(0x7ed873d3, 0xc2d0, 0x4e4f, |
127 | 0xa8, 0x54, 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c); | | 127 | 0xa8, 0x54, 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c); |
128 | | | 128 | |
129 | static const char *intel_dsm_port_name(u8 id) | | 129 | static const char *intel_dsm_port_name(u8 id) |
130 | { | | 130 | { |
131 | switch (id) { | | 131 | switch (id) { |
132 | case 0: | | 132 | case 0: |
133 | return "Reserved"; | | 133 | return "Reserved"; |
134 | case 1: | | 134 | case 1: |
135 | return "Analog VGA"; | | 135 | return "Analog VGA"; |
136 | case 2: | | 136 | case 2: |
137 | return "LVDS"; | | 137 | return "LVDS"; |
138 | case 3: | | 138 | case 3: |
139 | return "Reserved"; | | 139 | return "Reserved"; |
140 | case 4: | | 140 | case 4: |
141 | return "HDMI/DVI_B"; | | 141 | return "HDMI/DVI_B"; |
142 | case 5: | | 142 | case 5: |
143 | return "HDMI/DVI_C"; | | 143 | return "HDMI/DVI_C"; |
144 | case 6: | | 144 | case 6: |
145 | return "HDMI/DVI_D"; | | 145 | return "HDMI/DVI_D"; |
146 | case 7: | | 146 | case 7: |
147 | return "DisplayPort_A"; | | 147 | return "DisplayPort_A"; |
148 | case 8: | | 148 | case 8: |
149 | return "DisplayPort_B"; | | 149 | return "DisplayPort_B"; |
150 | case 9: | | 150 | case 9: |
151 | return "DisplayPort_C"; | | 151 | return "DisplayPort_C"; |
152 | case 0xa: | | 152 | case 0xa: |
153 | return "DisplayPort_D"; | | 153 | return "DisplayPort_D"; |
154 | case 0xb: | | 154 | case 0xb: |
155 | case 0xc: | | 155 | case 0xc: |
156 | case 0xd: | | 156 | case 0xd: |
157 | return "Reserved"; | | 157 | return "Reserved"; |
158 | case 0xe: | | 158 | case 0xe: |
159 | return "WiDi"; | | 159 | return "WiDi"; |
160 | default: | | 160 | default: |
161 | return "bad type"; | | 161 | return "bad type"; |
162 | } | | 162 | } |
163 | } | | 163 | } |
164 | | | 164 | |
165 | static const char *intel_dsm_mux_type(u8 type) | | 165 | static const char *intel_dsm_mux_type(u8 type) |
166 | { | | 166 | { |
167 | switch (type) { | | 167 | switch (type) { |
168 | case 0: | | 168 | case 0: |
169 | return "unknown"; | | 169 | return "unknown"; |
170 | case 1: | | 170 | case 1: |
171 | return "No MUX, iGPU only"; | | 171 | return "No MUX, iGPU only"; |
172 | case 2: | | 172 | case 2: |
173 | return "No MUX, dGPU only"; | | 173 | return "No MUX, dGPU only"; |
174 | case 3: | | 174 | case 3: |
175 | return "MUXed between iGPU and dGPU"; | | 175 | return "MUXed between iGPU and dGPU"; |
176 | default: | | 176 | default: |
177 | return "bad type"; | | 177 | return "bad type"; |
178 | } | | 178 | } |
179 | } | | 179 | } |
180 | | | 180 | |
181 | static void intel_dsm_platform_mux_info(acpi_handle dhandle) | | 181 | static void intel_dsm_platform_mux_info(acpi_handle dhandle) |
182 | { | | 182 | { |
183 | int i; | | 183 | int i; |
184 | #ifdef __NetBSD__ | | 184 | #ifdef __NetBSD__ |
185 | ACPI_OBJECT *pkg, *connector_count; | | 185 | ACPI_OBJECT *pkg, *connector_count; |
186 | #else | | 186 | #else |
187 | union acpi_object *pkg, *connector_count; | | 187 | union acpi_object *pkg, *connector_count; |
188 | #endif | | 188 | #endif |
189 | | | 189 | |
190 | pkg = acpi_evaluate_dsm_typed(dhandle, &intel_dsm_guid, | | 190 | pkg = acpi_evaluate_dsm_typed(dhandle, &intel_dsm_guid, |
191 | INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO, | | 191 | INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO, |
192 | NULL, ACPI_TYPE_PACKAGE); | | 192 | NULL, ACPI_TYPE_PACKAGE); |
193 | if (!pkg) { | | 193 | if (!pkg) { |
194 | DRM_DEBUG_DRIVER("failed to evaluate _DSM\n"); | | 194 | DRM_DEBUG_DRIVER("failed to evaluate _DSM\n"); |
195 | return; | | 195 | return; |
196 | } | | 196 | } |
197 | | | 197 | |
198 | connector_count = &pkg->package.elements[0]; | | 198 | connector_count = &pkg->package.elements[0]; |
199 | DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", | | 199 | DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", |
200 | (unsigned long long)connector_count->integer.value); | | 200 | (unsigned long long)connector_count->integer.value); |
201 | for (i = 1; i < pkg->package.count; i++) { | | 201 | for (i = 1; i < pkg->package.count; i++) { |
202 | #ifdef __NetBSD__ | | 202 | #ifdef __NetBSD__ |
203 | ACPI_OBJECT *obj = &pkg->package.elements[i]; | | 203 | ACPI_OBJECT *obj = &pkg->package.elements[i]; |
204 | ACPI_OBJECT *connector_id = &obj->package.elements[0]; | | 204 | ACPI_OBJECT *connector_id = &obj->package.elements[0]; |
205 | ACPI_OBJECT *info = &obj->package.elements[1]; | | 205 | ACPI_OBJECT *info = &obj->package.elements[1]; |
206 | #else | | 206 | #else |
207 | union acpi_object *obj = &pkg->package.elements[i]; | | 207 | union acpi_object *obj = &pkg->package.elements[i]; |
208 | union acpi_object *connector_id = &obj->package.elements[0]; | | 208 | union acpi_object *connector_id = &obj->package.elements[0]; |
209 | union acpi_object *info = &obj->package.elements[1]; | | 209 | union acpi_object *info = &obj->package.elements[1]; |
210 | #endif | | 210 | #endif |
211 | DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", | | 211 | DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", |
212 | (unsigned long long)connector_id->integer.value); | | 212 | (unsigned long long)connector_id->integer.value); |
213 | DRM_DEBUG_DRIVER(" port id: %s\n", | | 213 | DRM_DEBUG_DRIVER(" port id: %s\n", |
214 | intel_dsm_port_name(info->buffer.pointer[0])); | | 214 | intel_dsm_port_name(info->buffer.pointer[0])); |
215 | DRM_DEBUG_DRIVER(" display mux info: %s\n", | | 215 | DRM_DEBUG_DRIVER(" display mux info: %s\n", |
216 | intel_dsm_mux_type(info->buffer.pointer[1])); | | 216 | intel_dsm_mux_type(info->buffer.pointer[1])); |
217 | DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n", | | 217 | DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n", |
218 | intel_dsm_mux_type(info->buffer.pointer[2])); | | 218 | intel_dsm_mux_type(info->buffer.pointer[2])); |
219 | DRM_DEBUG_DRIVER(" hpd mux info: %s\n", | | 219 | DRM_DEBUG_DRIVER(" hpd mux info: %s\n", |
220 | intel_dsm_mux_type(info->buffer.pointer[3])); | | 220 | intel_dsm_mux_type(info->buffer.pointer[3])); |
221 | } | | 221 | } |
222 | | | 222 | |
223 | ACPI_FREE(pkg); | | 223 | ACPI_FREE(pkg); |
224 | } | | 224 | } |
225 | | | 225 | |
226 | #ifdef __NetBSD__ | | 226 | #ifdef __NetBSD__ |
227 | static ACPI_HANDLE intel_dsm_pci_probe(ACPI_HANDLE dhandle) | | 227 | static ACPI_HANDLE intel_dsm_pci_probe(ACPI_HANDLE dhandle) |
228 | #else | | 228 | #else |
229 | static acpi_handle intel_dsm_pci_probe(struct pci_dev *pdev) | | 229 | static acpi_handle intel_dsm_pci_probe(struct pci_dev *pdev) |
230 | #endif | | 230 | #endif |
231 | { | | 231 | { |
232 | #ifndef __NetBSD__ | | 232 | #ifndef __NetBSD__ |
233 | acpi_handle dhandle; | | 233 | acpi_handle dhandle; |
234 | | | 234 | |
235 | dhandle = ACPI_HANDLE(&pdev->dev); | | 235 | dhandle = ACPI_HANDLE(&pdev->dev); |
236 | if (!dhandle) | | 236 | if (!dhandle) |
237 | return NULL; | | 237 | return NULL; |
238 | #endif | | 238 | #endif |
239 | | | 239 | |
240 | if (!acpi_check_dsm(dhandle, &intel_dsm_guid, INTEL_DSM_REVISION_ID, | | 240 | if (!acpi_check_dsm(dhandle, &intel_dsm_guid, INTEL_DSM_REVISION_ID, |
241 | 1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) { | | 241 | 1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) { |
242 | DRM_DEBUG_KMS("no _DSM method for intel device\n"); | | 242 | DRM_DEBUG_KMS("no _DSM method for intel device\n"); |
243 | return NULL; | | 243 | return NULL; |
244 | } | | 244 | } |
245 | | | 245 | |
246 | intel_dsm_platform_mux_info(dhandle); | | 246 | intel_dsm_platform_mux_info(dhandle); |
247 | | | 247 | |
248 | return dhandle; | | 248 | return dhandle; |
249 | } | | 249 | } |
250 | | | 250 | |
251 | #ifdef __NetBSD__ | | 251 | #ifdef __NetBSD__ |
252 | | | 252 | |
253 | static int vga_count; | | 253 | static int vga_count; |
254 | static ACPI_HANDLE intel_dsm_handle; | | 254 | static ACPI_HANDLE intel_dsm_handle; |
255 | | | 255 | |
256 | /* XXX from sys/dev/pci/vga_pcivar.h */ | | 256 | /* XXX from sys/dev/pci/vga_pcivar.h */ |
257 | #define DEVICE_IS_VGA_PCI(class, id) \ | | 257 | #define DEVICE_IS_VGA_PCI(class, id) \ |
258 | (((PCI_CLASS(class) == PCI_CLASS_DISPLAY && \ | | 258 | (((PCI_CLASS(class) == PCI_CLASS_DISPLAY && \ |
259 | PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) || \ | | 259 | PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) || \ |
260 | (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \ | | 260 | (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \ |
261 | PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0) | | 261 | PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0) |
262 | | | 262 | |
263 | static int | | 263 | static int |
264 | intel_dsm_vga_match(const struct pci_attach_args *pa) | | 264 | intel_dsm_vga_match(const struct pci_attach_args *pa) |
265 | { | | 265 | { |
266 | | | 266 | |
267 | if (!DEVICE_IS_VGA_PCI(pa->pa_class, pa->pa_id)) | | 267 | if (!DEVICE_IS_VGA_PCI(pa->pa_class, pa->pa_id)) |
268 | return 0; | | 268 | return 0; |
269 | | | 269 | |
270 | vga_count++; | | 270 | vga_count++; |
271 | struct acpi_devnode *node = acpi_pcidev_find(0 /*XXX segment*/, | | 271 | struct acpi_devnode *node = |
272 | pa->pa_bus, pa->pa_device, pa->pa_function); | | 272 | acpi_pcidev_find(pci_get_segment(pa->pa_pc), |
| | | 273 | pa->pa_bus, pa->pa_device, pa->pa_function); |
273 | if (node != NULL && intel_dsm_handle == NULL) | | 274 | if (node != NULL && intel_dsm_handle == NULL) |
274 | intel_dsm_handle = intel_dsm_pci_probe(node->ad_handle); | | 275 | intel_dsm_handle = intel_dsm_pci_probe(node->ad_handle); |
275 | return 0; | | 276 | return 0; |
276 | } | | 277 | } |
277 | | | 278 | |
278 | static bool intel_dsm_detect(struct drm_device *dev) | | 279 | static bool intel_dsm_detect(struct drm_device *dev) |
279 | { | | 280 | { |
280 | char acpi_method_name[255] = { 0 }; | | 281 | char acpi_method_name[255] = { 0 }; |
281 | | | 282 | |
282 | vga_count = 0; | | 283 | vga_count = 0; |
283 | pci_find_device(&dev->pdev->pd_pa, intel_dsm_vga_match); | | 284 | pci_find_device(&dev->pdev->pd_pa, intel_dsm_vga_match); |
284 | | | 285 | |
285 | if (vga_count == 2 && intel_dsm_handle) { | | 286 | if (vga_count == 2 && intel_dsm_handle) { |
286 | const char *name = acpi_name(intel_dsm_handle); | | 287 | const char *name = acpi_name(intel_dsm_handle); |
287 | strlcpy(acpi_method_name, name, sizeof(acpi_method_name)); | | 288 | strlcpy(acpi_method_name, name, sizeof(acpi_method_name)); |
288 | DRM_DEBUG_DRIVER("VGA switcheroo: detected DSM switching method %s handle\n", | | 289 | DRM_DEBUG_DRIVER("VGA switcheroo: detected DSM switching method %s handle\n", |
289 | acpi_method_name); | | 290 | acpi_method_name); |
290 | return true; | | 291 | return true; |
291 | } | | 292 | } |
292 | | | 293 | |
293 | return false; | | 294 | return false; |
294 | } | | 295 | } |
295 | #else | | 296 | #else |
296 | static bool intel_dsm_detect(void) | | 297 | static bool intel_dsm_detect(void) |
297 | { | | 298 | { |
298 | acpi_handle dhandle = NULL; | | 299 | acpi_handle dhandle = NULL; |
299 | char acpi_method_name[255] = { 0 }; | | 300 | char acpi_method_name[255] = { 0 }; |
300 | struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; | | 301 | struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; |
301 | struct pci_dev *pdev = NULL; | | 302 | struct pci_dev *pdev = NULL; |
302 | int vga_count = 0; | | 303 | int vga_count = 0; |
303 | | | 304 | |
304 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { | | 305 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { |
305 | vga_count++; | | 306 | vga_count++; |
306 | dhandle = intel_dsm_pci_probe(pdev) ?: dhandle; | | 307 | dhandle = intel_dsm_pci_probe(pdev) ?: dhandle; |
307 | } | | 308 | } |
308 | | | 309 | |
309 | if (vga_count == 2 && dhandle) { | | 310 | if (vga_count == 2 && dhandle) { |
310 | acpi_get_name(dhandle, ACPI_FULL_PATHNAME, &buffer); | | 311 | acpi_get_name(dhandle, ACPI_FULL_PATHNAME, &buffer); |
311 | DRM_DEBUG_DRIVER("vga_switcheroo: detected DSM switching method %s handle\n", | | 312 | DRM_DEBUG_DRIVER("vga_switcheroo: detected DSM switching method %s handle\n", |
312 | acpi_method_name); | | 313 | acpi_method_name); |
313 | return true; | | 314 | return true; |
314 | } | | 315 | } |
315 | | | 316 | |
316 | return false; | | 317 | return false; |
317 | } | | 318 | } |
318 | #endif | | 319 | #endif |
319 | | | 320 | |
320 | #ifdef __NetBSD__ | | 321 | #ifdef __NetBSD__ |
321 | void intel_register_dsm_handler(struct drm_i915_private *i915) | | 322 | void intel_register_dsm_handler(struct drm_i915_private *i915) |
322 | { | | 323 | { |
323 | if (!intel_dsm_detect(&i915->drm)) | | 324 | if (!intel_dsm_detect(&i915->drm)) |
324 | return; | | 325 | return; |
325 | } | | 326 | } |
326 | #else | | 327 | #else |
327 | void intel_register_dsm_handler(void) | | 328 | void intel_register_dsm_handler(void) |
328 | { | | 329 | { |
329 | if (!intel_dsm_detect()) | | 330 | if (!intel_dsm_detect()) |
330 | return; | | 331 | return; |
331 | } | | 332 | } |
332 | #endif | | 333 | #endif |
333 | | | 334 | |
334 | void intel_unregister_dsm_handler(void) | | 335 | void intel_unregister_dsm_handler(void) |
335 | { | | 336 | { |
336 | } | | 337 | } |