aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-24 18:51:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-24 18:51:02 -0500
commit09da8dfa98682d871987145ed11e3232accac860 (patch)
tree152a9bb1e52f70db6efb66fffbdc4871f749d7df /drivers/gpu
parent3aacd625f20129f5a41ea3ff3b5353b0e4dabd01 (diff)
parent7744064731a9543105e207504e0262f883bc14c0 (diff)
Merge tag 'pm+acpi-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael Wysocki: "As far as the number of commits goes, the top spot belongs to ACPI this time with cpufreq in the second position and a handful of PM core, PNP and cpuidle updates. They are fixes and cleanups mostly, as usual, with a couple of new features in the mix. The most visible change is probably that we will create struct acpi_device objects (visible in sysfs) for all devices represented in the ACPI tables regardless of their status and there will be a new sysfs attribute under those objects allowing user space to check that status via _STA. Consequently, ACPI device eject or generally hot-removal will not delete those objects, unless the table containing the corresponding namespace nodes is unloaded, which is extremely rare. Also ACPI container hotplug will be handled quite a bit differently and cpufreq will support CPU boost ("turbo") generically and not only in the acpi-cpufreq driver. Specifics: - ACPI core changes to make it create a struct acpi_device object for every device represented in the ACPI tables during all namespace scans regardless of the current status of that device. In accordance with this, ACPI hotplug operations will not delete those objects, unless the underlying ACPI tables go away. - On top of the above, new sysfs attribute for ACPI device objects allowing user space to check device status by triggering the execution of _STA for its ACPI object. From Srinivas Pandruvada. - ACPI core hotplug changes reducing code duplication, integrating the PCI root hotplug with the core and reworking container hotplug. - ACPI core simplifications making it use ACPI_COMPANION() in the code "glueing" ACPI device objects to "physical" devices. - ACPICA update to upstream version 20131218. This adds support for the DBG2 and PCCT tables to ACPICA, fixes some bugs and improves debug facilities. From Bob Moore, Lv Zheng and Betty Dall. - Init code change to carry out the early ACPI initialization earlier. That should allow us to use ACPI during the timekeeping initialization and possibly to simplify the EFI initialization too. From Chun-Yi Lee. - Clenups of the inclusions of ACPI headers in many places all over from Lv Zheng and Rashika Kheria (work in progress). - New helper for ACPI _DSM execution and rework of the code in drivers that uses _DSM to execute it via the new helper. From Jiang Liu. - New Win8 OSI blacklist entries from Takashi Iwai. - Assorted ACPI fixes and cleanups from Al Stone, Emil Goode, Hanjun Guo, Lan Tianyu, Masanari Iida, Oliver Neukum, Prarit Bhargava, Rashika Kheria, Tang Chen, Zhang Rui. - intel_pstate driver updates, including proper Baytrail support, from Dirk Brandewie and intel_pstate documentation from Ramkumar Ramachandra. - Generic CPU boost ("turbo") support for cpufreq from Lukasz Majewski. - powernow-k6 cpufreq driver fixes from Mikulas Patocka. - cpufreq core fixes and cleanups from Viresh Kumar, Jane Li, Mark Brown. - Assorted cpufreq drivers fixes and cleanups from Anson Huang, John Tobias, Paul Bolle, Paul Walmsley, Sachin Kamat, Shawn Guo, Viresh Kumar. - cpuidle cleanups from Bartlomiej Zolnierkiewicz. - Support for hibernation APM events from Bin Shi. - Hibernation fix to avoid bringing up nonboot CPUs with ACPI EC disabled during thaw transitions from Bjørn Mork. - PM core fixes and cleanups from Ben Dooks, Leonardo Potenza, Ulf Hansson. - PNP subsystem fixes and cleanups from Dmitry Torokhov, Levente Kurusa, Rashika Kheria. - New tool for profiling system suspend from Todd E Brandt and a cpupower tool cleanup from One Thousand Gnomes" * tag 'pm+acpi-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (153 commits) thermal: exynos: boost: Automatic enable/disable of BOOST feature (at Exynos4412) cpufreq: exynos4x12: Change L0 driver data to CPUFREQ_BOOST_FREQ Documentation: cpufreq / boost: Update BOOST documentation cpufreq: exynos: Extend Exynos cpufreq driver to support boost cpufreq / boost: Kconfig: Support for software-managed BOOST acpi-cpufreq: Adjust the code to use the common boost attribute cpufreq: Add boost frequency support in core intel_pstate: Add trace point to report internal state. cpufreq: introduce cpufreq_generic_get() routine ARM: SA1100: Create dummy clk_get_rate() to avoid build failures cpufreq: stats: create sysfs entries when cpufreq_stats is a module cpufreq: stats: free table and remove sysfs entry in a single routine cpufreq: stats: remove hotplug notifiers cpufreq: stats: handle cpufreq_unregister_driver() and suspend/resume properly cpufreq: speedstep: remove unused speedstep_get_state platform: introduce OF style 'modalias' support for platform bus PM / tools: new tool for suspend/resume performance optimization ACPI: fix module autoloading for ACPI enumerated devices ACPI: add module autoloading support for ACPI enumerated devices ACPI: fix create_modalias() return value handling ...
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/gma500/opregion.c1
-rw-r--r--drivers/gpu/drm/i915/Makefile3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/intel_acpi.c146
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/base.c48
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c138
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c6
8 files changed, 88 insertions, 258 deletions
diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c
index ad0d6de938f3..13ec6283bf59 100644
--- a/drivers/gpu/drm/gma500/opregion.c
+++ b/drivers/gpu/drm/gma500/opregion.c
@@ -22,7 +22,6 @@
22 * 22 *
23 */ 23 */
24#include <linux/acpi.h> 24#include <linux/acpi.h>
25#include <linux/acpi_io.h>
26#include "psb_drv.h" 25#include "psb_drv.h"
27#include "psb_intel_reg.h" 26#include "psb_intel_reg.h"
28 27
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 41838eaa799c..d4ae48b04cf2 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -38,7 +38,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
38 intel_ringbuffer.o \ 38 intel_ringbuffer.o \
39 intel_overlay.o \ 39 intel_overlay.o \
40 intel_sprite.o \ 40 intel_sprite.o \
41 intel_opregion.o \
42 intel_sideband.o \ 41 intel_sideband.o \
43 intel_uncore.o \ 42 intel_uncore.o \
44 dvo_ch7xxx.o \ 43 dvo_ch7xxx.o \
@@ -51,7 +50,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
51 50
52i915-$(CONFIG_COMPAT) += i915_ioc32.o 51i915-$(CONFIG_COMPAT) += i915_ioc32.o
53 52
54i915-$(CONFIG_ACPI) += intel_acpi.o 53i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o
55 54
56i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o 55i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o
57 56
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 90fcccba17b0..1caa5e34fbe3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2339,8 +2339,8 @@ extern void intel_i2c_reset(struct drm_device *dev);
2339 2339
2340/* intel_opregion.c */ 2340/* intel_opregion.c */
2341struct intel_encoder; 2341struct intel_encoder;
2342extern int intel_opregion_setup(struct drm_device *dev);
2343#ifdef CONFIG_ACPI 2342#ifdef CONFIG_ACPI
2343extern int intel_opregion_setup(struct drm_device *dev);
2344extern void intel_opregion_init(struct drm_device *dev); 2344extern void intel_opregion_init(struct drm_device *dev);
2345extern void intel_opregion_fini(struct drm_device *dev); 2345extern void intel_opregion_fini(struct drm_device *dev);
2346extern void intel_opregion_asle_intr(struct drm_device *dev); 2346extern void intel_opregion_asle_intr(struct drm_device *dev);
@@ -2349,6 +2349,7 @@ extern int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
2349extern int intel_opregion_notify_adapter(struct drm_device *dev, 2349extern int intel_opregion_notify_adapter(struct drm_device *dev,
2350 pci_power_t state); 2350 pci_power_t state);
2351#else 2351#else
2352static inline int intel_opregion_setup(struct drm_device *dev) { return 0; }
2352static inline void intel_opregion_init(struct drm_device *dev) { return; } 2353static inline void intel_opregion_init(struct drm_device *dev) { return; }
2353static inline void intel_opregion_fini(struct drm_device *dev) { return; } 2354static inline void intel_opregion_fini(struct drm_device *dev) { return; }
2354static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } 2355static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
index dfff0907f70e..d96eee1ae9c5 100644
--- a/drivers/gpu/drm/i915/intel_acpi.c
+++ b/drivers/gpu/drm/i915/intel_acpi.c
@@ -6,14 +6,10 @@
6#include <linux/pci.h> 6#include <linux/pci.h>
7#include <linux/acpi.h> 7#include <linux/acpi.h>
8#include <linux/vga_switcheroo.h> 8#include <linux/vga_switcheroo.h>
9#include <acpi/acpi_drivers.h>
10
11#include <drm/drmP.h> 9#include <drm/drmP.h>
12#include "i915_drv.h" 10#include "i915_drv.h"
13 11
14#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ 12#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
15
16#define INTEL_DSM_FN_SUPPORTED_FUNCTIONS 0 /* No args */
17#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ 13#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */
18 14
19static struct intel_dsm_priv { 15static struct intel_dsm_priv {
@@ -28,61 +24,6 @@ static const u8 intel_dsm_guid[] = {
28 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c 24 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c
29}; 25};
30 26
31static int intel_dsm(acpi_handle handle, int func)
32{
33 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
34 struct acpi_object_list input;
35 union acpi_object params[4];
36 union acpi_object *obj;
37 u32 result;
38 int ret = 0;
39
40 input.count = 4;
41 input.pointer = params;
42 params[0].type = ACPI_TYPE_BUFFER;
43 params[0].buffer.length = sizeof(intel_dsm_guid);
44 params[0].buffer.pointer = (char *)intel_dsm_guid;
45 params[1].type = ACPI_TYPE_INTEGER;
46 params[1].integer.value = INTEL_DSM_REVISION_ID;
47 params[2].type = ACPI_TYPE_INTEGER;
48 params[2].integer.value = func;
49 params[3].type = ACPI_TYPE_PACKAGE;
50 params[3].package.count = 0;
51 params[3].package.elements = NULL;
52
53 ret = acpi_evaluate_object(handle, "_DSM", &input, &output);
54 if (ret) {
55 DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
56 return ret;
57 }
58
59 obj = (union acpi_object *)output.pointer;
60
61 result = 0;
62 switch (obj->type) {
63 case ACPI_TYPE_INTEGER:
64 result = obj->integer.value;
65 break;
66
67 case ACPI_TYPE_BUFFER:
68 if (obj->buffer.length == 4) {
69 result = (obj->buffer.pointer[0] |
70 (obj->buffer.pointer[1] << 8) |
71 (obj->buffer.pointer[2] << 16) |
72 (obj->buffer.pointer[3] << 24));
73 break;
74 }
75 default:
76 ret = -EINVAL;
77 break;
78 }
79 if (result == 0x80000002)
80 ret = -ENODEV;
81
82 kfree(output.pointer);
83 return ret;
84}
85
86static char *intel_dsm_port_name(u8 id) 27static char *intel_dsm_port_name(u8 id)
87{ 28{
88 switch (id) { 29 switch (id) {
@@ -137,83 +78,56 @@ static char *intel_dsm_mux_type(u8 type)
137 78
138static void intel_dsm_platform_mux_info(void) 79static void intel_dsm_platform_mux_info(void)
139{ 80{
140 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 81 int i;
141 struct acpi_object_list input; 82 union acpi_object *pkg, *connector_count;
142 union acpi_object params[4]; 83
143 union acpi_object *pkg; 84 pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid,
144 int i, ret; 85 INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO,
145 86 NULL, ACPI_TYPE_PACKAGE);
146 input.count = 4; 87 if (!pkg) {
147 input.pointer = params; 88 DRM_DEBUG_DRIVER("failed to evaluate _DSM\n");
148 params[0].type = ACPI_TYPE_BUFFER; 89 return;
149 params[0].buffer.length = sizeof(intel_dsm_guid);
150 params[0].buffer.pointer = (char *)intel_dsm_guid;
151 params[1].type = ACPI_TYPE_INTEGER;
152 params[1].integer.value = INTEL_DSM_REVISION_ID;
153 params[2].type = ACPI_TYPE_INTEGER;
154 params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO;
155 params[3].type = ACPI_TYPE_PACKAGE;
156 params[3].package.count = 0;
157 params[3].package.elements = NULL;
158
159 ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input,
160 &output);
161 if (ret) {
162 DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
163 goto out;
164 } 90 }
165 91
166 pkg = (union acpi_object *)output.pointer; 92 connector_count = &pkg->package.elements[0];
167 93 DRM_DEBUG_DRIVER("MUX info connectors: %lld\n",
168 if (pkg->type == ACPI_TYPE_PACKAGE) { 94 (unsigned long long)connector_count->integer.value);
169 union acpi_object *connector_count = &pkg->package.elements[0]; 95 for (i = 1; i < pkg->package.count; i++) {
170 DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", 96 union acpi_object *obj = &pkg->package.elements[i];
171 (unsigned long long)connector_count->integer.value); 97 union acpi_object *connector_id = &obj->package.elements[0];
172 for (i = 1; i < pkg->package.count; i++) { 98 union acpi_object *info = &obj->package.elements[1];
173 union acpi_object *obj = &pkg->package.elements[i]; 99 DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n",
174 union acpi_object *connector_id = 100 (unsigned long long)connector_id->integer.value);
175 &obj->package.elements[0]; 101 DRM_DEBUG_DRIVER(" port id: %s\n",
176 union acpi_object *info = &obj->package.elements[1]; 102 intel_dsm_port_name(info->buffer.pointer[0]));
177 DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", 103 DRM_DEBUG_DRIVER(" display mux info: %s\n",
178 (unsigned long long)connector_id->integer.value); 104 intel_dsm_mux_type(info->buffer.pointer[1]));
179 DRM_DEBUG_DRIVER(" port id: %s\n", 105 DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n",
180 intel_dsm_port_name(info->buffer.pointer[0])); 106 intel_dsm_mux_type(info->buffer.pointer[2]));
181 DRM_DEBUG_DRIVER(" display mux info: %s\n", 107 DRM_DEBUG_DRIVER(" hpd mux info: %s\n",
182 intel_dsm_mux_type(info->buffer.pointer[1])); 108 intel_dsm_mux_type(info->buffer.pointer[3]));
183 DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n",
184 intel_dsm_mux_type(info->buffer.pointer[2]));
185 DRM_DEBUG_DRIVER(" hpd mux info: %s\n",
186 intel_dsm_mux_type(info->buffer.pointer[3]));
187 }
188 } 109 }
189 110
190out: 111 ACPI_FREE(pkg);
191 kfree(output.pointer);
192} 112}
193 113
194static bool intel_dsm_pci_probe(struct pci_dev *pdev) 114static bool intel_dsm_pci_probe(struct pci_dev *pdev)
195{ 115{
196 acpi_handle dhandle; 116 acpi_handle dhandle;
197 int ret;
198 117
199 dhandle = ACPI_HANDLE(&pdev->dev); 118 dhandle = ACPI_HANDLE(&pdev->dev);
200 if (!dhandle) 119 if (!dhandle)
201 return false; 120 return false;
202 121
203 if (!acpi_has_method(dhandle, "_DSM")) { 122 if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID,
123 1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) {
204 DRM_DEBUG_KMS("no _DSM method for intel device\n"); 124 DRM_DEBUG_KMS("no _DSM method for intel device\n");
205 return false; 125 return false;
206 } 126 }
207 127
208 ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS);
209 if (ret < 0) {
210 DRM_DEBUG_KMS("failed to get supported _DSM functions\n");
211 return false;
212 }
213
214 intel_dsm_priv.dhandle = dhandle; 128 intel_dsm_priv.dhandle = dhandle;
215
216 intel_dsm_platform_mux_info(); 129 intel_dsm_platform_mux_info();
130
217 return true; 131 return true;
218} 132}
219 133
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 6d69a9bad865..9a8804bee5cd 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -28,7 +28,6 @@
28#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 28#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29 29
30#include <linux/acpi.h> 30#include <linux/acpi.h>
31#include <linux/acpi_io.h>
32#include <acpi/video.h> 31#include <acpi/video.h>
33 32
34#include <drm/drmP.h> 33#include <drm/drmP.h>
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
index 129120473f6c..13c5af88a601 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
@@ -87,55 +87,39 @@ mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version)
87 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65 87 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65
88 }; 88 };
89 u32 mxms_args[] = { 0x00000000 }; 89 u32 mxms_args[] = { 0x00000000 };
90 union acpi_object args[4] = { 90 union acpi_object argv4 = {
91 /* _DSM MUID */ 91 .buffer.type = ACPI_TYPE_BUFFER,
92 { .buffer.type = 3, 92 .buffer.length = sizeof(mxms_args),
93 .buffer.length = sizeof(muid), 93 .buffer.pointer = (char *)mxms_args,
94 .buffer.pointer = muid,
95 },
96 /* spec says this can be zero to mean "highest revision", but
97 * of course there's at least one bios out there which fails
98 * unless you pass in exactly the version it supports..
99 */
100 { .integer.type = ACPI_TYPE_INTEGER,
101 .integer.value = (version & 0xf0) << 4 | (version & 0x0f),
102 },
103 /* MXMS function */
104 { .integer.type = ACPI_TYPE_INTEGER,
105 .integer.value = 0x00000010,
106 },
107 /* Pointer to MXMS arguments */
108 { .buffer.type = ACPI_TYPE_BUFFER,
109 .buffer.length = sizeof(mxms_args),
110 .buffer.pointer = (char *)mxms_args,
111 },
112 }; 94 };
113 struct acpi_object_list list = { ARRAY_SIZE(args), args };
114 struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
115 union acpi_object *obj; 95 union acpi_object *obj;
116 acpi_handle handle; 96 acpi_handle handle;
117 int ret; 97 int rev;
118 98
119 handle = ACPI_HANDLE(&device->pdev->dev); 99 handle = ACPI_HANDLE(&device->pdev->dev);
120 if (!handle) 100 if (!handle)
121 return false; 101 return false;
122 102
123 ret = acpi_evaluate_object(handle, "_DSM", &list, &retn); 103 /*
124 if (ret) { 104 * spec says this can be zero to mean "highest revision", but
125 nv_debug(mxm, "DSM MXMS failed: %d\n", ret); 105 * of course there's at least one bios out there which fails
106 * unless you pass in exactly the version it supports..
107 */
108 rev = (version & 0xf0) << 4 | (version & 0x0f);
109 obj = acpi_evaluate_dsm(handle, muid, rev, 0x00000010, &argv4);
110 if (!obj) {
111 nv_debug(mxm, "DSM MXMS failed\n");
126 return false; 112 return false;
127 } 113 }
128 114
129 obj = retn.pointer;
130 if (obj->type == ACPI_TYPE_BUFFER) { 115 if (obj->type == ACPI_TYPE_BUFFER) {
131 mxm->mxms = kmemdup(obj->buffer.pointer, 116 mxm->mxms = kmemdup(obj->buffer.pointer,
132 obj->buffer.length, GFP_KERNEL); 117 obj->buffer.length, GFP_KERNEL);
133 } else 118 } else if (obj->type == ACPI_TYPE_INTEGER) {
134 if (obj->type == ACPI_TYPE_INTEGER) {
135 nv_debug(mxm, "DSM MXMS returned 0x%llx\n", obj->integer.value); 119 nv_debug(mxm, "DSM MXMS returned 0x%llx\n", obj->integer.value);
136 } 120 }
137 121
138 kfree(obj); 122 ACPI_FREE(obj);
139 return mxm->mxms != NULL; 123 return mxm->mxms != NULL;
140} 124}
141#endif 125#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index ba0183fb84f3..3c149617cfcb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -1,15 +1,10 @@
1#include <linux/pci.h> 1#include <linux/pci.h>
2#include <linux/acpi.h> 2#include <linux/acpi.h>
3#include <linux/slab.h> 3#include <linux/slab.h>
4#include <acpi/acpi_drivers.h>
5#include <acpi/acpi_bus.h>
6#include <acpi/video.h>
7#include <acpi/acpi.h>
8#include <linux/mxm-wmi.h> 4#include <linux/mxm-wmi.h>
9
10#include <linux/vga_switcheroo.h> 5#include <linux/vga_switcheroo.h>
11
12#include <drm/drm_edid.h> 6#include <drm/drm_edid.h>
7#include <acpi/video.h>
13 8
14#include "nouveau_drm.h" 9#include "nouveau_drm.h"
15#include "nouveau_acpi.h" 10#include "nouveau_acpi.h"
@@ -78,124 +73,66 @@ static const char nouveau_op_dsm_muid[] = {
78 73
79static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) 74static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
80{ 75{
81 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 76 int i;
82 struct acpi_object_list input;
83 union acpi_object params[4];
84 union acpi_object *obj; 77 union acpi_object *obj;
85 int i, err;
86 char args_buff[4]; 78 char args_buff[4];
79 union acpi_object argv4 = {
80 .buffer.type = ACPI_TYPE_BUFFER,
81 .buffer.length = 4,
82 .buffer.pointer = args_buff
83 };
87 84
88 input.count = 4;
89 input.pointer = params;
90 params[0].type = ACPI_TYPE_BUFFER;
91 params[0].buffer.length = sizeof(nouveau_op_dsm_muid);
92 params[0].buffer.pointer = (char *)nouveau_op_dsm_muid;
93 params[1].type = ACPI_TYPE_INTEGER;
94 params[1].integer.value = 0x00000100;
95 params[2].type = ACPI_TYPE_INTEGER;
96 params[2].integer.value = func;
97 params[3].type = ACPI_TYPE_BUFFER;
98 params[3].buffer.length = 4;
99 /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ 85 /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */
100 for (i = 0; i < 4; i++) 86 for (i = 0; i < 4; i++)
101 args_buff[i] = (arg >> i * 8) & 0xFF; 87 args_buff[i] = (arg >> i * 8) & 0xFF;
102 params[3].buffer.pointer = args_buff;
103
104 err = acpi_evaluate_object(handle, "_DSM", &input, &output);
105 if (err) {
106 printk(KERN_INFO "failed to evaluate _DSM: %d\n", err);
107 return err;
108 }
109
110 obj = (union acpi_object *)output.pointer;
111 88
112 if (obj->type == ACPI_TYPE_INTEGER) 89 *result = 0;
113 if (obj->integer.value == 0x80000002) { 90 obj = acpi_evaluate_dsm_typed(handle, nouveau_op_dsm_muid, 0x00000100,
114 return -ENODEV; 91 func, &argv4, ACPI_TYPE_BUFFER);
115 } 92 if (!obj) {
116 93 acpi_handle_info(handle, "failed to evaluate _DSM\n");
117 if (obj->type == ACPI_TYPE_BUFFER) { 94 return AE_ERROR;
118 if (obj->buffer.length == 4 && result) { 95 } else {
119 *result = 0; 96 if (obj->buffer.length == 4) {
120 *result |= obj->buffer.pointer[0]; 97 *result |= obj->buffer.pointer[0];
121 *result |= (obj->buffer.pointer[1] << 8); 98 *result |= (obj->buffer.pointer[1] << 8);
122 *result |= (obj->buffer.pointer[2] << 16); 99 *result |= (obj->buffer.pointer[2] << 16);
123 *result |= (obj->buffer.pointer[3] << 24); 100 *result |= (obj->buffer.pointer[3] << 24);
124 } 101 }
102 ACPI_FREE(obj);
125 } 103 }
126 104
127 kfree(output.pointer);
128 return 0; 105 return 0;
129} 106}
130 107
131static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) 108static int nouveau_dsm(acpi_handle handle, int func, int arg)
132{ 109{
133 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 110 int ret = 0;
134 struct acpi_object_list input;
135 union acpi_object params[4];
136 union acpi_object *obj; 111 union acpi_object *obj;
137 int err; 112 union acpi_object argv4 = {
138 113 .integer.type = ACPI_TYPE_INTEGER,
139 input.count = 4; 114 .integer.value = arg,
140 input.pointer = params; 115 };
141 params[0].type = ACPI_TYPE_BUFFER; 116
142 params[0].buffer.length = sizeof(nouveau_dsm_muid); 117 obj = acpi_evaluate_dsm_typed(handle, nouveau_dsm_muid, 0x00000102,
143 params[0].buffer.pointer = (char *)nouveau_dsm_muid; 118 func, &argv4, ACPI_TYPE_INTEGER);
144 params[1].type = ACPI_TYPE_INTEGER; 119 if (!obj) {
145 params[1].integer.value = 0x00000102; 120 acpi_handle_info(handle, "failed to evaluate _DSM\n");
146 params[2].type = ACPI_TYPE_INTEGER; 121 return AE_ERROR;
147 params[2].integer.value = func; 122 } else {
148 params[3].type = ACPI_TYPE_INTEGER;
149 params[3].integer.value = arg;
150
151 err = acpi_evaluate_object(handle, "_DSM", &input, &output);
152 if (err) {
153 printk(KERN_INFO "failed to evaluate _DSM: %d\n", err);
154 return err;
155 }
156
157 obj = (union acpi_object *)output.pointer;
158
159 if (obj->type == ACPI_TYPE_INTEGER)
160 if (obj->integer.value == 0x80000002) 123 if (obj->integer.value == 0x80000002)
161 return -ENODEV; 124 ret = -ENODEV;
162 125 ACPI_FREE(obj);
163 if (obj->type == ACPI_TYPE_BUFFER) {
164 if (obj->buffer.length == 4 && result) {
165 *result = 0;
166 *result |= obj->buffer.pointer[0];
167 *result |= (obj->buffer.pointer[1] << 8);
168 *result |= (obj->buffer.pointer[2] << 16);
169 *result |= (obj->buffer.pointer[3] << 24);
170 }
171 } 126 }
172 127
173 kfree(output.pointer); 128 return ret;
174 return 0;
175}
176
177/* Returns 1 if a DSM function is usable and 0 otherwise */
178static int nouveau_test_dsm(acpi_handle test_handle,
179 int (*dsm_func)(acpi_handle, int, int, uint32_t *),
180 int sfnc)
181{
182 u32 result = 0;
183
184 /* Function 0 returns a Buffer containing available functions. The args
185 * parameter is ignored for function 0, so just put 0 in it */
186 if (dsm_func(test_handle, 0, 0, &result))
187 return 0;
188
189 /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If
190 * the n-th bit is enabled, function n is supported */
191 return result & 1 && result & (1 << sfnc);
192} 129}
193 130
194static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) 131static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
195{ 132{
196 mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); 133 mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0);
197 mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); 134 mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0);
198 return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL); 135 return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id);
199} 136}
200 137
201static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state) 138static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state)
@@ -205,7 +142,7 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
205 arg = NOUVEAU_DSM_POWER_SPEED; 142 arg = NOUVEAU_DSM_POWER_SPEED;
206 else 143 else
207 arg = NOUVEAU_DSM_POWER_STAMINA; 144 arg = NOUVEAU_DSM_POWER_STAMINA;
208 nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg, NULL); 145 nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg);
209 return 0; 146 return 0;
210} 147}
211 148
@@ -265,11 +202,12 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
265 nouveau_dsm_priv.other_handle = dhandle; 202 nouveau_dsm_priv.other_handle = dhandle;
266 return false; 203 return false;
267 } 204 }
268 if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) 205 if (acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102,
206 1 << NOUVEAU_DSM_POWER))
269 retval |= NOUVEAU_DSM_HAS_MUX; 207 retval |= NOUVEAU_DSM_HAS_MUX;
270 208
271 if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm, 209 if (acpi_check_dsm(dhandle, nouveau_op_dsm_muid, 0x00000100,
272 NOUVEAU_DSM_OPTIMUS_CAPS)) 210 1 << NOUVEAU_DSM_OPTIMUS_CAPS))
273 retval |= NOUVEAU_DSM_HAS_OPT; 211 retval |= NOUVEAU_DSM_HAS_OPT;
274 212
275 if (retval & NOUVEAU_DSM_HAS_OPT) { 213 if (retval & NOUVEAU_DSM_HAS_OPT) {
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 98a9074b306b..77e9d07c55b6 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -25,18 +25,14 @@
25#include <linux/acpi.h> 25#include <linux/acpi.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/power_supply.h> 27#include <linux/power_supply.h>
28#include <acpi/acpi_drivers.h> 28#include <linux/vga_switcheroo.h>
29#include <acpi/acpi_bus.h>
30#include <acpi/video.h> 29#include <acpi/video.h>
31
32#include <drm/drmP.h> 30#include <drm/drmP.h>
33#include <drm/drm_crtc_helper.h> 31#include <drm/drm_crtc_helper.h>
34#include "radeon.h" 32#include "radeon.h"
35#include "radeon_acpi.h" 33#include "radeon_acpi.h"
36#include "atom.h" 34#include "atom.h"
37 35
38#include <linux/vga_switcheroo.h>
39
40#define ACPI_AC_CLASS "ac_adapter" 36#define ACPI_AC_CLASS "ac_adapter"
41 37
42extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev); 38extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev);