Commit 9075e85f46c598e4dfc852b16b256a32e2fb396f

Authored by Peter Lekensteyn
Committed by Dave Airlie
1 parent 3b32a592ea

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)