Commit 9075e85f46c598e4dfc852b16b256a32e2fb396f
Committed by
Dave Airlie
1 parent
3b32a592ea
Exists in
master
and in
38 other branches
nouveau: properly check for _DSM function support
According to the ACPI spec version 4, section 9.14.1, _DSM functions must return a value with the first bit enabled if any DSM functions are supported for the given UUID and revision ID. For a given function index n to be marked supported, bit n must be enabled. Signed-off-by: Peter Lekensteyn <lekensteyn@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Showing 1 changed file with 22 additions and 13 deletions Side-by-side Diff
drivers/gpu/drm/nouveau/nouveau_acpi.c
... | ... | @@ -18,12 +18,6 @@ |
18 | 18 | |
19 | 19 | #include <linux/vga_switcheroo.h> |
20 | 20 | |
21 | -#define NOUVEAU_DSM_SUPPORTED 0x00 | |
22 | -#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00 | |
23 | - | |
24 | -#define NOUVEAU_DSM_ACTIVE 0x01 | |
25 | -#define NOUVEAU_DSM_ACTIVE_QUERY 0x00 | |
26 | - | |
27 | 21 | #define NOUVEAU_DSM_LED 0x02 |
28 | 22 | #define NOUVEAU_DSM_LED_STATE 0x00 |
29 | 23 | #define NOUVEAU_DSM_LED_OFF 0x10 |
... | ... | @@ -35,6 +29,7 @@ |
35 | 29 | #define NOUVEAU_DSM_POWER_SPEED 0x01 |
36 | 30 | #define NOUVEAU_DSM_POWER_STAMINA 0x02 |
37 | 31 | |
32 | +#define NOUVEAU_DSM_OPTIMUS_FN 0x1A | |
38 | 33 | static struct nouveau_dsm_priv { |
39 | 34 | bool dsm_detected; |
40 | 35 | bool optimus_detected; |
... | ... | @@ -148,6 +143,23 @@ |
148 | 143 | return 0; |
149 | 144 | } |
150 | 145 | |
146 | +/* Returns 1 if a DSM function is usable and 0 otherwise */ | |
147 | +static int nouveau_test_dsm(acpi_handle test_handle, | |
148 | + int (*dsm_func)(acpi_handle, int, int, uint32_t *), | |
149 | + int sfnc) | |
150 | +{ | |
151 | + u32 result = 0; | |
152 | + | |
153 | + /* Function 0 returns a Buffer containing available functions. The args | |
154 | + * parameter is ignored for function 0, so just put 0 in it */ | |
155 | + if (dsm_func(test_handle, 0, 0, &result)) | |
156 | + return 0; | |
157 | + | |
158 | + /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If | |
159 | + * the n-th bit is enabled, function n is supported */ | |
160 | + return result & 1 && result & (1 << sfnc); | |
161 | +} | |
162 | + | |
151 | 163 | static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) |
152 | 164 | { |
153 | 165 | mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); |
... | ... | @@ -212,8 +224,7 @@ |
212 | 224 | { |
213 | 225 | acpi_handle dhandle, nvidia_handle; |
214 | 226 | acpi_status status; |
215 | - int ret, retval = 0; | |
216 | - uint32_t result; | |
227 | + int retval = 0; | |
217 | 228 | |
218 | 229 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); |
219 | 230 | if (!dhandle) |
220 | 231 | |
... | ... | @@ -224,13 +235,11 @@ |
224 | 235 | return false; |
225 | 236 | } |
226 | 237 | |
227 | - ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED, | |
228 | - NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); | |
229 | - if (ret == 0) | |
238 | + if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) | |
230 | 239 | retval |= NOUVEAU_DSM_HAS_MUX; |
231 | 240 | |
232 | - ret = nouveau_optimus_dsm(dhandle, 0, 0, &result); | |
233 | - if (ret == 0) | |
241 | + if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm, | |
242 | + NOUVEAU_DSM_OPTIMUS_FN)) | |
234 | 243 | retval |= NOUVEAU_DSM_HAS_OPT; |
235 | 244 | |
236 | 245 | if (retval) |