aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-12 17:45:52 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-12 17:45:52 -0500
commitfbb9c10d40f88011ac72f855c97e3bdd981026a9 (patch)
tree255b3c21fd859004310bfad0a829ea4392d4851b
parent3e7cc142c1e040fd4629ad34a54b1c5b46dc3dd3 (diff)
parent7ede9f8a1805b26b3141730c9deaea8bc95a64bc (diff)
Merge branch 'acpi-dsm'
* acpi-dsm: ACPI / extlog: replace open-coded _DSM code with helper functions ACPI / nouveau: replace open-coded _DSM code with helper functions nouveau / ACPI: fix memory leak in ACPI _DSM related code ACPI / i915: replace open-coded _DSM code with helper functions ACPI / i2c-hid: replace open-coded _DSM code with helper functions ACPI / TPM: detect PPI features by checking availability of _DSM functions ACPI / TPM: replace open-coded _DSM code with helper functions ACPI / TPM: match node name instead of full path when searching for TPM device PCI / pci-label: treat PCI label with index 0 as valid label ACPI / PCI: replace open-coded _DSM code with helper functions PCI / pci-label: release allocated ACPI object on error recovery path ACPI: introduce helper interfaces for _DSM method
-rw-r--r--drivers/acpi/acpi_extlog.c61
-rw-r--r--drivers/acpi/utils.c97
-rw-r--r--drivers/char/tpm/tpm_ppi.c405
-rw-r--r--drivers/gpu/drm/i915/intel_acpi.c144
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/base.c48
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c131
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c26
-rw-r--r--drivers/pci/pci-label.c129
-rw-r--r--include/acpi/acpi_bus.h26
9 files changed, 403 insertions, 664 deletions
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 2635a01c5b3e..94166680b3a3 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -19,11 +19,9 @@
19#define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ 19#define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */
20 20
21#define EXTLOG_DSM_REV 0x0 21#define EXTLOG_DSM_REV 0x0
22#define EXTLOG_FN_QUERY 0x0
23#define EXTLOG_FN_ADDR 0x1 22#define EXTLOG_FN_ADDR 0x1
24 23
25#define FLAG_OS_OPTIN BIT(0) 24#define FLAG_OS_OPTIN BIT(0)
26#define EXTLOG_QUERY_L1_EXIST BIT(1)
27#define ELOG_ENTRY_VALID (1ULL<<63) 25#define ELOG_ENTRY_VALID (1ULL<<63)
28#define ELOG_ENTRY_LEN 0x1000 26#define ELOG_ENTRY_LEN 0x1000
29 27
@@ -42,7 +40,7 @@ struct extlog_l1_head {
42 u8 rev1[12]; 40 u8 rev1[12];
43}; 41};
44 42
45static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; 43static u8 extlog_dsm_uuid[] __initdata = "663E35AF-CC10-41A4-88EA-5470AF055295";
46 44
47/* L1 table related physical address */ 45/* L1 table related physical address */
48static u64 elog_base; 46static u64 elog_base;
@@ -152,62 +150,27 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
152 return NOTIFY_DONE; 150 return NOTIFY_DONE;
153} 151}
154 152
155static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret) 153static bool __init extlog_get_l1addr(void)
156{ 154{
157 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
158 struct acpi_object_list input;
159 union acpi_object params[4], *obj;
160 u8 uuid[16]; 155 u8 uuid[16];
161 int i; 156 acpi_handle handle;
157 union acpi_object *obj;
162 158
163 acpi_str_to_uuid(extlog_dsm_uuid, uuid); 159 acpi_str_to_uuid(extlog_dsm_uuid, uuid);
164 input.count = 4;
165 input.pointer = params;
166 params[0].type = ACPI_TYPE_BUFFER;
167 params[0].buffer.length = 16;
168 params[0].buffer.pointer = uuid;
169 params[1].type = ACPI_TYPE_INTEGER;
170 params[1].integer.value = rev;
171 params[2].type = ACPI_TYPE_INTEGER;
172 params[2].integer.value = func;
173 params[3].type = ACPI_TYPE_PACKAGE;
174 params[3].package.count = 0;
175 params[3].package.elements = NULL;
176
177 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf)))
178 return -1;
179
180 *ret = 0;
181 obj = (union acpi_object *)buf.pointer;
182 if (obj->type == ACPI_TYPE_INTEGER) {
183 *ret = obj->integer.value;
184 } else if (obj->type == ACPI_TYPE_BUFFER) {
185 if (obj->buffer.length <= 8) {
186 for (i = 0; i < obj->buffer.length; i++)
187 *ret |= (obj->buffer.pointer[i] << (i * 8));
188 }
189 }
190 kfree(buf.pointer);
191
192 return 0;
193}
194
195static bool extlog_get_l1addr(void)
196{
197 acpi_handle handle;
198 u64 ret;
199 160
200 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) 161 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
201 return false; 162 return false;
202 163 if (!acpi_check_dsm(handle, uuid, EXTLOG_DSM_REV, 1 << EXTLOG_FN_ADDR))
203 if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_QUERY, &ret) ||
204 !(ret & EXTLOG_QUERY_L1_EXIST))
205 return false; 164 return false;
206 165 obj = acpi_evaluate_dsm_typed(handle, uuid, EXTLOG_DSM_REV,
207 if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret)) 166 EXTLOG_FN_ADDR, NULL, ACPI_TYPE_INTEGER);
167 if (!obj) {
208 return false; 168 return false;
169 } else {
170 l1_dirbase = obj->integer.value;
171 ACPI_FREE(obj);
172 }
209 173
210 l1_dirbase = ret;
211 /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ 174 /* Spec says L1 directory must be 4K aligned, bail out if it isn't */
212 if (l1_dirbase & ((1 << 12) - 1)) { 175 if (l1_dirbase & ((1 << 12) - 1)) {
213 pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", 176 pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n",
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 1336b9151479..0347a37eb438 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -572,3 +572,100 @@ acpi_status acpi_evaluate_lck(acpi_handle handle, int lock)
572 572
573 return status; 573 return status;
574} 574}
575
576/**
577 * acpi_evaluate_dsm - evaluate device's _DSM method
578 * @handle: ACPI device handle
579 * @uuid: UUID of requested functions, should be 16 bytes
580 * @rev: revision number of requested function
581 * @func: requested function number
582 * @argv4: the function specific parameter
583 *
584 * Evaluate device's _DSM method with specified UUID, revision id and
585 * function number. Caller needs to free the returned object.
586 *
587 * Though ACPI defines the fourth parameter for _DSM should be a package,
588 * some old BIOSes do expect a buffer or an integer etc.
589 */
590union acpi_object *
591acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, int rev, int func,
592 union acpi_object *argv4)
593{
594 acpi_status ret;
595 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
596 union acpi_object params[4];
597 struct acpi_object_list input = {
598 .count = 4,
599 .pointer = params,
600 };
601
602 params[0].type = ACPI_TYPE_BUFFER;
603 params[0].buffer.length = 16;
604 params[0].buffer.pointer = (char *)uuid;
605 params[1].type = ACPI_TYPE_INTEGER;
606 params[1].integer.value = rev;
607 params[2].type = ACPI_TYPE_INTEGER;
608 params[2].integer.value = func;
609 if (argv4) {
610 params[3] = *argv4;
611 } else {
612 params[3].type = ACPI_TYPE_PACKAGE;
613 params[3].package.count = 0;
614 params[3].package.elements = NULL;
615 }
616
617 ret = acpi_evaluate_object(handle, "_DSM", &input, &buf);
618 if (ACPI_SUCCESS(ret))
619 return (union acpi_object *)buf.pointer;
620
621 if (ret != AE_NOT_FOUND)
622 acpi_handle_warn(handle,
623 "failed to evaluate _DSM (0x%x)\n", ret);
624
625 return NULL;
626}
627EXPORT_SYMBOL(acpi_evaluate_dsm);
628
629/**
630 * acpi_check_dsm - check if _DSM method supports requested functions.
631 * @handle: ACPI device handle
632 * @uuid: UUID of requested functions, should be 16 bytes at least
633 * @rev: revision number of requested functions
634 * @funcs: bitmap of requested functions
635 * @exclude: excluding special value, used to support i915 and nouveau
636 *
637 * Evaluate device's _DSM method to check whether it supports requested
638 * functions. Currently only support 64 functions at maximum, should be
639 * enough for now.
640 */
641bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs)
642{
643 int i;
644 u64 mask = 0;
645 union acpi_object *obj;
646
647 if (funcs == 0)
648 return false;
649
650 obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
651 if (!obj)
652 return false;
653
654 /* For compatibility, old BIOSes may return an integer */
655 if (obj->type == ACPI_TYPE_INTEGER)
656 mask = obj->integer.value;
657 else if (obj->type == ACPI_TYPE_BUFFER)
658 for (i = 0; i < obj->buffer.length && i < 8; i++)
659 mask |= (((u8)obj->buffer.pointer[i]) << (i * 8));
660 ACPI_FREE(obj);
661
662 /*
663 * Bit 0 indicates whether there's support for any functions other than
664 * function 0 for the specified UUID and revision.
665 */
666 if ((mask & 0x1) && (mask & funcs) == funcs)
667 return true;
668
669 return false;
670}
671EXPORT_SYMBOL(acpi_check_dsm);
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c
index 70dbee4b50e9..b3ea223585bd 100644
--- a/drivers/char/tpm/tpm_ppi.c
+++ b/drivers/char/tpm/tpm_ppi.c
@@ -1,15 +1,6 @@
1#include <linux/acpi.h> 1#include <linux/acpi.h>
2#include "tpm.h" 2#include "tpm.h"
3 3
4static const u8 tpm_ppi_uuid[] = {
5 0xA6, 0xFA, 0xDD, 0x3D,
6 0x1B, 0x36,
7 0xB4, 0x4E,
8 0xA4, 0x24,
9 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53
10};
11static char *tpm_device_name = "TPM";
12
13#define TPM_PPI_REVISION_ID 1 4#define TPM_PPI_REVISION_ID 1
14#define TPM_PPI_FN_VERSION 1 5#define TPM_PPI_FN_VERSION 1
15#define TPM_PPI_FN_SUBREQ 2 6#define TPM_PPI_FN_SUBREQ 2
@@ -23,250 +14,178 @@ static char *tpm_device_name = "TPM";
23#define PPI_VS_REQ_END 255 14#define PPI_VS_REQ_END 255
24#define PPI_VERSION_LEN 3 15#define PPI_VERSION_LEN 3
25 16
17static const u8 tpm_ppi_uuid[] = {
18 0xA6, 0xFA, 0xDD, 0x3D,
19 0x1B, 0x36,
20 0xB4, 0x4E,
21 0xA4, 0x24,
22 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53
23};
24
25static char tpm_ppi_version[PPI_VERSION_LEN + 1];
26static acpi_handle tpm_ppi_handle;
27
26static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context, 28static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context,
27 void **return_value) 29 void **return_value)
28{ 30{
29 acpi_status status = AE_OK; 31 union acpi_object *obj;
30 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
31 32
32 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer))) { 33 if (!acpi_check_dsm(handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID,
33 if (strstr(buffer.pointer, context) != NULL) { 34 1 << TPM_PPI_FN_VERSION))
34 *return_value = handle; 35 return AE_OK;
35 status = AE_CTRL_TERMINATE; 36
36 } 37 /* Cache version string */
37 kfree(buffer.pointer); 38 obj = acpi_evaluate_dsm_typed(handle, tpm_ppi_uuid,
39 TPM_PPI_REVISION_ID, TPM_PPI_FN_VERSION,
40 NULL, ACPI_TYPE_STRING);
41 if (obj) {
42 strlcpy(tpm_ppi_version, obj->string.pointer,
43 PPI_VERSION_LEN + 1);
44 ACPI_FREE(obj);
38 } 45 }
39 46
40 return status; 47 *return_value = handle;
48
49 return AE_CTRL_TERMINATE;
41} 50}
42 51
43static inline void ppi_assign_params(union acpi_object params[4], 52static inline union acpi_object *
44 u64 function_num) 53tpm_eval_dsm(int func, acpi_object_type type, union acpi_object *argv4)
45{ 54{
46 params[0].type = ACPI_TYPE_BUFFER; 55 BUG_ON(!tpm_ppi_handle);
47 params[0].buffer.length = sizeof(tpm_ppi_uuid); 56 return acpi_evaluate_dsm_typed(tpm_ppi_handle, tpm_ppi_uuid,
48 params[0].buffer.pointer = (char *)tpm_ppi_uuid; 57 TPM_PPI_REVISION_ID, func, argv4, type);
49 params[1].type = ACPI_TYPE_INTEGER;
50 params[1].integer.value = TPM_PPI_REVISION_ID;
51 params[2].type = ACPI_TYPE_INTEGER;
52 params[2].integer.value = function_num;
53 params[3].type = ACPI_TYPE_PACKAGE;
54 params[3].package.count = 0;
55 params[3].package.elements = NULL;
56} 58}
57 59
58static ssize_t tpm_show_ppi_version(struct device *dev, 60static ssize_t tpm_show_ppi_version(struct device *dev,
59 struct device_attribute *attr, char *buf) 61 struct device_attribute *attr, char *buf)
60{ 62{
61 acpi_handle handle; 63 return scnprintf(buf, PAGE_SIZE, "%s\n", tpm_ppi_version);
62 acpi_status status;
63 struct acpi_object_list input;
64 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
65 union acpi_object params[4];
66 union acpi_object *obj;
67
68 input.count = 4;
69 ppi_assign_params(params, TPM_PPI_FN_VERSION);
70 input.pointer = params;
71 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
72 ACPI_UINT32_MAX, ppi_callback, NULL,
73 tpm_device_name, &handle);
74 if (ACPI_FAILURE(status))
75 return -ENXIO;
76
77 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
78 ACPI_TYPE_STRING);
79 if (ACPI_FAILURE(status))
80 return -ENOMEM;
81 obj = (union acpi_object *)output.pointer;
82 status = scnprintf(buf, PAGE_SIZE, "%s\n", obj->string.pointer);
83 kfree(output.pointer);
84 return status;
85} 64}
86 65
87static ssize_t tpm_show_ppi_request(struct device *dev, 66static ssize_t tpm_show_ppi_request(struct device *dev,
88 struct device_attribute *attr, char *buf) 67 struct device_attribute *attr, char *buf)
89{ 68{
90 acpi_handle handle; 69 ssize_t size = -EINVAL;
91 acpi_status status; 70 union acpi_object *obj;
92 struct acpi_object_list input; 71
93 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 72 obj = tpm_eval_dsm(TPM_PPI_FN_GETREQ, ACPI_TYPE_PACKAGE, NULL);
94 union acpi_object params[4]; 73 if (!obj)
95 union acpi_object *ret_obj;
96
97 input.count = 4;
98 ppi_assign_params(params, TPM_PPI_FN_GETREQ);
99 input.pointer = params;
100 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
101 ACPI_UINT32_MAX, ppi_callback, NULL,
102 tpm_device_name, &handle);
103 if (ACPI_FAILURE(status))
104 return -ENXIO; 74 return -ENXIO;
105 75
106 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
107 ACPI_TYPE_PACKAGE);
108 if (ACPI_FAILURE(status))
109 return -ENOMEM;
110 /* 76 /*
111 * output.pointer should be of package type, including two integers. 77 * output.pointer should be of package type, including two integers.
112 * The first is function return code, 0 means success and 1 means 78 * The first is function return code, 0 means success and 1 means
113 * error. The second is pending TPM operation requested by the OS, 0 79 * error. The second is pending TPM operation requested by the OS, 0
114 * means none and >0 means operation value. 80 * means none and >0 means operation value.
115 */ 81 */
116 ret_obj = ((union acpi_object *)output.pointer)->package.elements; 82 if (obj->package.count == 2 &&
117 if (ret_obj->type == ACPI_TYPE_INTEGER) { 83 obj->package.elements[0].type == ACPI_TYPE_INTEGER &&
118 if (ret_obj->integer.value) { 84 obj->package.elements[1].type == ACPI_TYPE_INTEGER) {
119 status = -EFAULT; 85 if (obj->package.elements[0].integer.value)
120 goto cleanup; 86 size = -EFAULT;
121 }
122 ret_obj++;
123 if (ret_obj->type == ACPI_TYPE_INTEGER)
124 status = scnprintf(buf, PAGE_SIZE, "%llu\n",
125 ret_obj->integer.value);
126 else 87 else
127 status = -EINVAL; 88 size = scnprintf(buf, PAGE_SIZE, "%llu\n",
128 } else { 89 obj->package.elements[1].integer.value);
129 status = -EINVAL;
130 } 90 }
131cleanup: 91
132 kfree(output.pointer); 92 ACPI_FREE(obj);
133 return status; 93
94 return size;
134} 95}
135 96
136static ssize_t tpm_store_ppi_request(struct device *dev, 97static ssize_t tpm_store_ppi_request(struct device *dev,
137 struct device_attribute *attr, 98 struct device_attribute *attr,
138 const char *buf, size_t count) 99 const char *buf, size_t count)
139{ 100{
140 char version[PPI_VERSION_LEN + 1];
141 acpi_handle handle;
142 acpi_status status;
143 struct acpi_object_list input;
144 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
145 union acpi_object params[4];
146 union acpi_object obj;
147 u32 req; 101 u32 req;
148 u64 ret; 102 u64 ret;
103 int func = TPM_PPI_FN_SUBREQ;
104 union acpi_object *obj, tmp;
105 union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp);
149 106
150 input.count = 4;
151 ppi_assign_params(params, TPM_PPI_FN_VERSION);
152 input.pointer = params;
153 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
154 ACPI_UINT32_MAX, ppi_callback, NULL,
155 tpm_device_name, &handle);
156 if (ACPI_FAILURE(status))
157 return -ENXIO;
158
159 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
160 ACPI_TYPE_STRING);
161 if (ACPI_FAILURE(status))
162 return -ENOMEM;
163 strlcpy(version,
164 ((union acpi_object *)output.pointer)->string.pointer,
165 PPI_VERSION_LEN + 1);
166 kfree(output.pointer);
167 output.length = ACPI_ALLOCATE_BUFFER;
168 output.pointer = NULL;
169 /* 107 /*
170 * the function to submit TPM operation request to pre-os environment 108 * the function to submit TPM operation request to pre-os environment
171 * is updated with function index from SUBREQ to SUBREQ2 since PPI 109 * is updated with function index from SUBREQ to SUBREQ2 since PPI
172 * version 1.1 110 * version 1.1
173 */ 111 */
174 if (strcmp(version, "1.1") == -1) 112 if (acpi_check_dsm(tpm_ppi_handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID,
175 params[2].integer.value = TPM_PPI_FN_SUBREQ; 113 1 << TPM_PPI_FN_SUBREQ2))
176 else 114 func = TPM_PPI_FN_SUBREQ2;
177 params[2].integer.value = TPM_PPI_FN_SUBREQ2; 115
178 /* 116 /*
179 * PPI spec defines params[3].type as ACPI_TYPE_PACKAGE. Some BIOS 117 * PPI spec defines params[3].type as ACPI_TYPE_PACKAGE. Some BIOS
180 * accept buffer/string/integer type, but some BIOS accept buffer/ 118 * accept buffer/string/integer type, but some BIOS accept buffer/
181 * string/package type. For PPI version 1.0 and 1.1, use buffer type 119 * string/package type. For PPI version 1.0 and 1.1, use buffer type
182 * for compatibility, and use package type since 1.2 according to spec. 120 * for compatibility, and use package type since 1.2 according to spec.
183 */ 121 */
184 if (strcmp(version, "1.2") == -1) { 122 if (strcmp(tpm_ppi_version, "1.2") < 0) {
185 params[3].type = ACPI_TYPE_BUFFER; 123 if (sscanf(buf, "%d", &req) != 1)
186 params[3].buffer.length = sizeof(req); 124 return -EINVAL;
187 sscanf(buf, "%d", &req); 125 argv4.type = ACPI_TYPE_BUFFER;
188 params[3].buffer.pointer = (char *)&req; 126 argv4.buffer.length = sizeof(req);
127 argv4.buffer.pointer = (u8 *)&req;
128 } else {
129 tmp.type = ACPI_TYPE_INTEGER;
130 if (sscanf(buf, "%llu", &tmp.integer.value) != 1)
131 return -EINVAL;
132 }
133
134 obj = tpm_eval_dsm(func, ACPI_TYPE_INTEGER, &argv4);
135 if (!obj) {
136 return -ENXIO;
189 } else { 137 } else {
190 params[3].package.count = 1; 138 ret = obj->integer.value;
191 obj.type = ACPI_TYPE_INTEGER; 139 ACPI_FREE(obj);
192 sscanf(buf, "%llu", &obj.integer.value);
193 params[3].package.elements = &obj;
194 } 140 }
195 141
196 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
197 ACPI_TYPE_INTEGER);
198 if (ACPI_FAILURE(status))
199 return -ENOMEM;
200 ret = ((union acpi_object *)output.pointer)->integer.value;
201 if (ret == 0) 142 if (ret == 0)
202 status = (acpi_status)count; 143 return (acpi_status)count;
203 else if (ret == 1) 144
204 status = -EPERM; 145 return (ret == 1) ? -EPERM : -EFAULT;
205 else
206 status = -EFAULT;
207 kfree(output.pointer);
208 return status;
209} 146}
210 147
211static ssize_t tpm_show_ppi_transition_action(struct device *dev, 148static ssize_t tpm_show_ppi_transition_action(struct device *dev,
212 struct device_attribute *attr, 149 struct device_attribute *attr,
213 char *buf) 150 char *buf)
214{ 151{
215 char version[PPI_VERSION_LEN + 1];
216 acpi_handle handle;
217 acpi_status status;
218 struct acpi_object_list input;
219 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
220 union acpi_object params[4];
221 u32 ret; 152 u32 ret;
222 char *info[] = { 153 acpi_status status;
154 union acpi_object *obj = NULL;
155 union acpi_object tmp = {
156 .buffer.type = ACPI_TYPE_BUFFER,
157 .buffer.length = 0,
158 .buffer.pointer = NULL
159 };
160
161 static char *info[] = {
223 "None", 162 "None",
224 "Shutdown", 163 "Shutdown",
225 "Reboot", 164 "Reboot",
226 "OS Vendor-specific", 165 "OS Vendor-specific",
227 "Error", 166 "Error",
228 }; 167 };
229 input.count = 4;
230 ppi_assign_params(params, TPM_PPI_FN_VERSION);
231 input.pointer = params;
232 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
233 ACPI_UINT32_MAX, ppi_callback, NULL,
234 tpm_device_name, &handle);
235 if (ACPI_FAILURE(status))
236 return -ENXIO;
237 168
238 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
239 ACPI_TYPE_STRING);
240 if (ACPI_FAILURE(status))
241 return -ENOMEM;
242 strlcpy(version,
243 ((union acpi_object *)output.pointer)->string.pointer,
244 PPI_VERSION_LEN + 1);
245 /* 169 /*
246 * PPI spec defines params[3].type as empty package, but some platforms 170 * PPI spec defines params[3].type as empty package, but some platforms
247 * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for 171 * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for
248 * compatibility, define params[3].type as buffer, if PPI version < 1.2 172 * compatibility, define params[3].type as buffer, if PPI version < 1.2
249 */ 173 */
250 if (strcmp(version, "1.2") == -1) { 174 if (strcmp(tpm_ppi_version, "1.2") < 0)
251 params[3].type = ACPI_TYPE_BUFFER; 175 obj = &tmp;
252 params[3].buffer.length = 0; 176 obj = tpm_eval_dsm(TPM_PPI_FN_GETACT, ACPI_TYPE_INTEGER, obj);
253 params[3].buffer.pointer = NULL; 177 if (!obj) {
178 return -ENXIO;
179 } else {
180 ret = obj->integer.value;
181 ACPI_FREE(obj);
254 } 182 }
255 params[2].integer.value = TPM_PPI_FN_GETACT; 183
256 kfree(output.pointer);
257 output.length = ACPI_ALLOCATE_BUFFER;
258 output.pointer = NULL;
259 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
260 ACPI_TYPE_INTEGER);
261 if (ACPI_FAILURE(status))
262 return -ENOMEM;
263 ret = ((union acpi_object *)output.pointer)->integer.value;
264 if (ret < ARRAY_SIZE(info) - 1) 184 if (ret < ARRAY_SIZE(info) - 1)
265 status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, info[ret]); 185 status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, info[ret]);
266 else 186 else
267 status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, 187 status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret,
268 info[ARRAY_SIZE(info)-1]); 188 info[ARRAY_SIZE(info)-1]);
269 kfree(output.pointer);
270 return status; 189 return status;
271} 190}
272 191
@@ -274,27 +193,14 @@ static ssize_t tpm_show_ppi_response(struct device *dev,
274 struct device_attribute *attr, 193 struct device_attribute *attr,
275 char *buf) 194 char *buf)
276{ 195{
277 acpi_handle handle; 196 acpi_status status = -EINVAL;
278 acpi_status status; 197 union acpi_object *obj, *ret_obj;
279 struct acpi_object_list input; 198 u64 req, res;
280 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 199
281 union acpi_object params[4]; 200 obj = tpm_eval_dsm(TPM_PPI_FN_GETRSP, ACPI_TYPE_PACKAGE, NULL);
282 union acpi_object *ret_obj; 201 if (!obj)
283 u64 req;
284
285 input.count = 4;
286 ppi_assign_params(params, TPM_PPI_FN_GETRSP);
287 input.pointer = params;
288 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
289 ACPI_UINT32_MAX, ppi_callback, NULL,
290 tpm_device_name, &handle);
291 if (ACPI_FAILURE(status))
292 return -ENXIO; 202 return -ENXIO;
293 203
294 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
295 ACPI_TYPE_PACKAGE);
296 if (ACPI_FAILURE(status))
297 return -ENOMEM;
298 /* 204 /*
299 * parameter output.pointer should be of package type, including 205 * parameter output.pointer should be of package type, including
300 * 3 integers. The first means function return code, the second means 206 * 3 integers. The first means function return code, the second means
@@ -302,115 +208,82 @@ static ssize_t tpm_show_ppi_response(struct device *dev,
302 * the most recent TPM operation request. Only if the first is 0, and 208 * the most recent TPM operation request. Only if the first is 0, and
303 * the second integer is not 0, the response makes sense. 209 * the second integer is not 0, the response makes sense.
304 */ 210 */
305 ret_obj = ((union acpi_object *)output.pointer)->package.elements; 211 ret_obj = obj->package.elements;
306 if (ret_obj->type != ACPI_TYPE_INTEGER) { 212 if (obj->package.count < 3 ||
307 status = -EINVAL; 213 ret_obj[0].type != ACPI_TYPE_INTEGER ||
214 ret_obj[1].type != ACPI_TYPE_INTEGER ||
215 ret_obj[2].type != ACPI_TYPE_INTEGER)
308 goto cleanup; 216 goto cleanup;
309 } 217
310 if (ret_obj->integer.value) { 218 if (ret_obj[0].integer.value) {
311 status = -EFAULT; 219 status = -EFAULT;
312 goto cleanup; 220 goto cleanup;
313 } 221 }
314 ret_obj++; 222
315 if (ret_obj->type != ACPI_TYPE_INTEGER) { 223 req = ret_obj[1].integer.value;
316 status = -EINVAL; 224 res = ret_obj[2].integer.value;
317 goto cleanup; 225 if (req) {
318 } 226 if (res == 0)
319 if (ret_obj->integer.value) {
320 req = ret_obj->integer.value;
321 ret_obj++;
322 if (ret_obj->type != ACPI_TYPE_INTEGER) {
323 status = -EINVAL;
324 goto cleanup;
325 }
326 if (ret_obj->integer.value == 0)
327 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, 227 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
328 "0: Success"); 228 "0: Success");
329 else if (ret_obj->integer.value == 0xFFFFFFF0) 229 else if (res == 0xFFFFFFF0)
330 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, 230 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
331 "0xFFFFFFF0: User Abort"); 231 "0xFFFFFFF0: User Abort");
332 else if (ret_obj->integer.value == 0xFFFFFFF1) 232 else if (res == 0xFFFFFFF1)
333 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, 233 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
334 "0xFFFFFFF1: BIOS Failure"); 234 "0xFFFFFFF1: BIOS Failure");
335 else if (ret_obj->integer.value >= 1 && 235 else if (res >= 1 && res <= 0x00000FFF)
336 ret_obj->integer.value <= 0x00000FFF)
337 status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n", 236 status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n",
338 req, ret_obj->integer.value, 237 req, res, "Corresponding TPM error");
339 "Corresponding TPM error");
340 else 238 else
341 status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n", 239 status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n",
342 req, ret_obj->integer.value, 240 req, res, "Error");
343 "Error");
344 } else { 241 } else {
345 status = scnprintf(buf, PAGE_SIZE, "%llu: %s\n", 242 status = scnprintf(buf, PAGE_SIZE, "%llu: %s\n",
346 ret_obj->integer.value, "No Recent Request"); 243 req, "No Recent Request");
347 } 244 }
245
348cleanup: 246cleanup:
349 kfree(output.pointer); 247 ACPI_FREE(obj);
350 return status; 248 return status;
351} 249}
352 250
353static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) 251static ssize_t show_ppi_operations(char *buf, u32 start, u32 end)
354{ 252{
355 char *str = buf;
356 char version[PPI_VERSION_LEN + 1];
357 acpi_handle handle;
358 acpi_status status;
359 struct acpi_object_list input;
360 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
361 union acpi_object params[4];
362 union acpi_object obj;
363 int i; 253 int i;
364 u32 ret; 254 u32 ret;
365 char *info[] = { 255 char *str = buf;
256 union acpi_object *obj, tmp;
257 union acpi_object argv = ACPI_INIT_DSM_ARGV4(1, &tmp);
258
259 static char *info[] = {
366 "Not implemented", 260 "Not implemented",
367 "BIOS only", 261 "BIOS only",
368 "Blocked for OS by BIOS", 262 "Blocked for OS by BIOS",
369 "User required", 263 "User required",
370 "User not required", 264 "User not required",
371 }; 265 };
372 input.count = 4;
373 ppi_assign_params(params, TPM_PPI_FN_VERSION);
374 input.pointer = params;
375 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
376 ACPI_UINT32_MAX, ppi_callback, NULL,
377 tpm_device_name, &handle);
378 if (ACPI_FAILURE(status))
379 return -ENXIO;
380 266
381 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 267 if (!acpi_check_dsm(tpm_ppi_handle, tpm_ppi_uuid, TPM_PPI_REVISION_ID,
382 ACPI_TYPE_STRING); 268 1 << TPM_PPI_FN_GETOPR))
383 if (ACPI_FAILURE(status))
384 return -ENOMEM;
385
386 strlcpy(version,
387 ((union acpi_object *)output.pointer)->string.pointer,
388 PPI_VERSION_LEN + 1);
389 kfree(output.pointer);
390 output.length = ACPI_ALLOCATE_BUFFER;
391 output.pointer = NULL;
392 if (strcmp(version, "1.2") == -1)
393 return -EPERM; 269 return -EPERM;
394 270
395 params[2].integer.value = TPM_PPI_FN_GETOPR; 271 tmp.integer.type = ACPI_TYPE_INTEGER;
396 params[3].package.count = 1;
397 obj.type = ACPI_TYPE_INTEGER;
398 params[3].package.elements = &obj;
399 for (i = start; i <= end; i++) { 272 for (i = start; i <= end; i++) {
400 obj.integer.value = i; 273 tmp.integer.value = i;
401 status = acpi_evaluate_object_typed(handle, "_DSM", 274 obj = tpm_eval_dsm(TPM_PPI_FN_GETOPR, ACPI_TYPE_INTEGER, &argv);
402 &input, &output, ACPI_TYPE_INTEGER); 275 if (!obj) {
403 if (ACPI_FAILURE(status))
404 return -ENOMEM; 276 return -ENOMEM;
277 } else {
278 ret = obj->integer.value;
279 ACPI_FREE(obj);
280 }
405 281
406 ret = ((union acpi_object *)output.pointer)->integer.value;
407 if (ret > 0 && ret < ARRAY_SIZE(info)) 282 if (ret > 0 && ret < ARRAY_SIZE(info))
408 str += scnprintf(str, PAGE_SIZE, "%d %d: %s\n", 283 str += scnprintf(str, PAGE_SIZE, "%d %d: %s\n",
409 i, ret, info[ret]); 284 i, ret, info[ret]);
410 kfree(output.pointer);
411 output.length = ACPI_ALLOCATE_BUFFER;
412 output.pointer = NULL;
413 } 285 }
286
414 return str - buf; 287 return str - buf;
415} 288}
416 289
@@ -452,6 +325,12 @@ static struct attribute_group ppi_attr_grp = {
452 325
453int tpm_add_ppi(struct kobject *parent) 326int tpm_add_ppi(struct kobject *parent)
454{ 327{
328 /* Cache TPM ACPI handle and version string */
329 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
330 ppi_callback, NULL, NULL, &tpm_ppi_handle);
331 if (tpm_ppi_handle == NULL)
332 return -ENODEV;
333
455 return sysfs_create_group(parent, &ppi_attr_grp); 334 return sysfs_create_group(parent, &ppi_attr_grp);
456} 335}
457 336
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
index 5325b25ccbb4..d96eee1ae9c5 100644
--- a/drivers/gpu/drm/i915/intel_acpi.c
+++ b/drivers/gpu/drm/i915/intel_acpi.c
@@ -10,8 +10,6 @@
10#include "i915_drv.h" 10#include "i915_drv.h"
11 11
12#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ 12#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
13
14#define INTEL_DSM_FN_SUPPORTED_FUNCTIONS 0 /* No args */
15#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ 13#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */
16 14
17static struct intel_dsm_priv { 15static struct intel_dsm_priv {
@@ -26,61 +24,6 @@ static const u8 intel_dsm_guid[] = {
26 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c 24 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c
27}; 25};
28 26
29static int intel_dsm(acpi_handle handle, int func)
30{
31 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
32 struct acpi_object_list input;
33 union acpi_object params[4];
34 union acpi_object *obj;
35 u32 result;
36 int ret = 0;
37
38 input.count = 4;
39 input.pointer = params;
40 params[0].type = ACPI_TYPE_BUFFER;
41 params[0].buffer.length = sizeof(intel_dsm_guid);
42 params[0].buffer.pointer = (char *)intel_dsm_guid;
43 params[1].type = ACPI_TYPE_INTEGER;
44 params[1].integer.value = INTEL_DSM_REVISION_ID;
45 params[2].type = ACPI_TYPE_INTEGER;
46 params[2].integer.value = func;
47 params[3].type = ACPI_TYPE_PACKAGE;
48 params[3].package.count = 0;
49 params[3].package.elements = NULL;
50
51 ret = acpi_evaluate_object(handle, "_DSM", &input, &output);
52 if (ret) {
53 DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
54 return ret;
55 }
56
57 obj = (union acpi_object *)output.pointer;
58
59 result = 0;
60 switch (obj->type) {
61 case ACPI_TYPE_INTEGER:
62 result = obj->integer.value;
63 break;
64
65 case ACPI_TYPE_BUFFER:
66 if (obj->buffer.length == 4) {
67 result = (obj->buffer.pointer[0] |
68 (obj->buffer.pointer[1] << 8) |
69 (obj->buffer.pointer[2] << 16) |
70 (obj->buffer.pointer[3] << 24));
71 break;
72 }
73 default:
74 ret = -EINVAL;
75 break;
76 }
77 if (result == 0x80000002)
78 ret = -ENODEV;
79
80 kfree(output.pointer);
81 return ret;
82}
83
84static char *intel_dsm_port_name(u8 id) 27static char *intel_dsm_port_name(u8 id)
85{ 28{
86 switch (id) { 29 switch (id) {
@@ -135,83 +78,56 @@ static char *intel_dsm_mux_type(u8 type)
135 78
136static void intel_dsm_platform_mux_info(void) 79static void intel_dsm_platform_mux_info(void)
137{ 80{
138 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 81 int i;
139 struct acpi_object_list input; 82 union acpi_object *pkg, *connector_count;
140 union acpi_object params[4]; 83
141 union acpi_object *pkg; 84 pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid,
142 int i, ret; 85 INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO,
143 86 NULL, ACPI_TYPE_PACKAGE);
144 input.count = 4; 87 if (!pkg) {
145 input.pointer = params; 88 DRM_DEBUG_DRIVER("failed to evaluate _DSM\n");
146 params[0].type = ACPI_TYPE_BUFFER; 89 return;
147 params[0].buffer.length = sizeof(intel_dsm_guid);
148 params[0].buffer.pointer = (char *)intel_dsm_guid;
149 params[1].type = ACPI_TYPE_INTEGER;
150 params[1].integer.value = INTEL_DSM_REVISION_ID;
151 params[2].type = ACPI_TYPE_INTEGER;
152 params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO;
153 params[3].type = ACPI_TYPE_PACKAGE;
154 params[3].package.count = 0;
155 params[3].package.elements = NULL;
156
157 ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input,
158 &output);
159 if (ret) {
160 DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret);
161 goto out;
162 } 90 }
163 91
164 pkg = (union acpi_object *)output.pointer; 92 connector_count = &pkg->package.elements[0];
165 93 DRM_DEBUG_DRIVER("MUX info connectors: %lld\n",
166 if (pkg->type == ACPI_TYPE_PACKAGE) { 94 (unsigned long long)connector_count->integer.value);
167 union acpi_object *connector_count = &pkg->package.elements[0]; 95 for (i = 1; i < pkg->package.count; i++) {
168 DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", 96 union acpi_object *obj = &pkg->package.elements[i];
169 (unsigned long long)connector_count->integer.value); 97 union acpi_object *connector_id = &obj->package.elements[0];
170 for (i = 1; i < pkg->package.count; i++) { 98 union acpi_object *info = &obj->package.elements[1];
171 union acpi_object *obj = &pkg->package.elements[i]; 99 DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n",
172 union acpi_object *connector_id = 100 (unsigned long long)connector_id->integer.value);
173 &obj->package.elements[0]; 101 DRM_DEBUG_DRIVER(" port id: %s\n",
174 union acpi_object *info = &obj->package.elements[1]; 102 intel_dsm_port_name(info->buffer.pointer[0]));
175 DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", 103 DRM_DEBUG_DRIVER(" display mux info: %s\n",
176 (unsigned long long)connector_id->integer.value); 104 intel_dsm_mux_type(info->buffer.pointer[1]));
177 DRM_DEBUG_DRIVER(" port id: %s\n", 105 DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n",
178 intel_dsm_port_name(info->buffer.pointer[0])); 106 intel_dsm_mux_type(info->buffer.pointer[2]));
179 DRM_DEBUG_DRIVER(" display mux info: %s\n", 107 DRM_DEBUG_DRIVER(" hpd mux info: %s\n",
180 intel_dsm_mux_type(info->buffer.pointer[1])); 108 intel_dsm_mux_type(info->buffer.pointer[3]));
181 DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n",
182 intel_dsm_mux_type(info->buffer.pointer[2]));
183 DRM_DEBUG_DRIVER(" hpd mux info: %s\n",
184 intel_dsm_mux_type(info->buffer.pointer[3]));
185 }
186 } 109 }
187 110
188out: 111 ACPI_FREE(pkg);
189 kfree(output.pointer);
190} 112}
191 113
192static bool intel_dsm_pci_probe(struct pci_dev *pdev) 114static bool intel_dsm_pci_probe(struct pci_dev *pdev)
193{ 115{
194 acpi_handle dhandle; 116 acpi_handle dhandle;
195 int ret;
196 117
197 dhandle = ACPI_HANDLE(&pdev->dev); 118 dhandle = ACPI_HANDLE(&pdev->dev);
198 if (!dhandle) 119 if (!dhandle)
199 return false; 120 return false;
200 121
201 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)) {
202 DRM_DEBUG_KMS("no _DSM method for intel device\n"); 124 DRM_DEBUG_KMS("no _DSM method for intel device\n");
203 return false; 125 return false;
204 } 126 }
205 127
206 ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS);
207 if (ret < 0) {
208 DRM_DEBUG_KMS("failed to get supported _DSM functions\n");
209 return false;
210 }
211
212 intel_dsm_priv.dhandle = dhandle; 128 intel_dsm_priv.dhandle = dhandle;
213
214 intel_dsm_platform_mux_info(); 129 intel_dsm_platform_mux_info();
130
215 return true; 131 return true;
216} 132}
217 133
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 1bc996c4f121..3c149617cfcb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -73,124 +73,66 @@ static const char nouveau_op_dsm_muid[] = {
73 73
74static 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)
75{ 75{
76 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 76 int i;
77 struct acpi_object_list input;
78 union acpi_object params[4];
79 union acpi_object *obj; 77 union acpi_object *obj;
80 int i, err;
81 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 };
82 84
83 input.count = 4;
84 input.pointer = params;
85 params[0].type = ACPI_TYPE_BUFFER;
86 params[0].buffer.length = sizeof(nouveau_op_dsm_muid);
87 params[0].buffer.pointer = (char *)nouveau_op_dsm_muid;
88 params[1].type = ACPI_TYPE_INTEGER;
89 params[1].integer.value = 0x00000100;
90 params[2].type = ACPI_TYPE_INTEGER;
91 params[2].integer.value = func;
92 params[3].type = ACPI_TYPE_BUFFER;
93 params[3].buffer.length = 4;
94 /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ 85 /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */
95 for (i = 0; i < 4; i++) 86 for (i = 0; i < 4; i++)
96 args_buff[i] = (arg >> i * 8) & 0xFF; 87 args_buff[i] = (arg >> i * 8) & 0xFF;
97 params[3].buffer.pointer = args_buff;
98 88
99 err = acpi_evaluate_object(handle, "_DSM", &input, &output); 89 *result = 0;
100 if (err) { 90 obj = acpi_evaluate_dsm_typed(handle, nouveau_op_dsm_muid, 0x00000100,
101 printk(KERN_INFO "failed to evaluate _DSM: %d\n", err); 91 func, &argv4, ACPI_TYPE_BUFFER);
102 return err; 92 if (!obj) {
103 } 93 acpi_handle_info(handle, "failed to evaluate _DSM\n");
104 94 return AE_ERROR;
105 obj = (union acpi_object *)output.pointer; 95 } else {
106 96 if (obj->buffer.length == 4) {
107 if (obj->type == ACPI_TYPE_INTEGER)
108 if (obj->integer.value == 0x80000002) {
109 return -ENODEV;
110 }
111
112 if (obj->type == ACPI_TYPE_BUFFER) {
113 if (obj->buffer.length == 4 && result) {
114 *result = 0;
115 *result |= obj->buffer.pointer[0]; 97 *result |= obj->buffer.pointer[0];
116 *result |= (obj->buffer.pointer[1] << 8); 98 *result |= (obj->buffer.pointer[1] << 8);
117 *result |= (obj->buffer.pointer[2] << 16); 99 *result |= (obj->buffer.pointer[2] << 16);
118 *result |= (obj->buffer.pointer[3] << 24); 100 *result |= (obj->buffer.pointer[3] << 24);
119 } 101 }
102 ACPI_FREE(obj);
120 } 103 }
121 104
122 kfree(output.pointer);
123 return 0; 105 return 0;
124} 106}
125 107
126static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) 108static int nouveau_dsm(acpi_handle handle, int func, int arg)
127{ 109{
128 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 110 int ret = 0;
129 struct acpi_object_list input;
130 union acpi_object params[4];
131 union acpi_object *obj; 111 union acpi_object *obj;
132 int err; 112 union acpi_object argv4 = {
133 113 .integer.type = ACPI_TYPE_INTEGER,
134 input.count = 4; 114 .integer.value = arg,
135 input.pointer = params; 115 };
136 params[0].type = ACPI_TYPE_BUFFER; 116
137 params[0].buffer.length = sizeof(nouveau_dsm_muid); 117 obj = acpi_evaluate_dsm_typed(handle, nouveau_dsm_muid, 0x00000102,
138 params[0].buffer.pointer = (char *)nouveau_dsm_muid; 118 func, &argv4, ACPI_TYPE_INTEGER);
139 params[1].type = ACPI_TYPE_INTEGER; 119 if (!obj) {
140 params[1].integer.value = 0x00000102; 120 acpi_handle_info(handle, "failed to evaluate _DSM\n");
141 params[2].type = ACPI_TYPE_INTEGER; 121 return AE_ERROR;
142 params[2].integer.value = func; 122 } else {
143 params[3].type = ACPI_TYPE_INTEGER;
144 params[3].integer.value = arg;
145
146 err = acpi_evaluate_object(handle, "_DSM", &input, &output);
147 if (err) {
148 printk(KERN_INFO "failed to evaluate _DSM: %d\n", err);
149 return err;
150 }
151
152 obj = (union acpi_object *)output.pointer;
153
154 if (obj->type == ACPI_TYPE_INTEGER)
155 if (obj->integer.value == 0x80000002) 123 if (obj->integer.value == 0x80000002)
156 return -ENODEV; 124 ret = -ENODEV;
157 125 ACPI_FREE(obj);
158 if (obj->type == ACPI_TYPE_BUFFER) {
159 if (obj->buffer.length == 4 && result) {
160 *result = 0;
161 *result |= obj->buffer.pointer[0];
162 *result |= (obj->buffer.pointer[1] << 8);
163 *result |= (obj->buffer.pointer[2] << 16);
164 *result |= (obj->buffer.pointer[3] << 24);
165 }
166 } 126 }
167 127
168 kfree(output.pointer); 128 return ret;
169 return 0;
170}
171
172/* Returns 1 if a DSM function is usable and 0 otherwise */
173static int nouveau_test_dsm(acpi_handle test_handle,
174 int (*dsm_func)(acpi_handle, int, int, uint32_t *),
175 int sfnc)
176{
177 u32 result = 0;
178
179 /* Function 0 returns a Buffer containing available functions. The args
180 * parameter is ignored for function 0, so just put 0 in it */
181 if (dsm_func(test_handle, 0, 0, &result))
182 return 0;
183
184 /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If
185 * the n-th bit is enabled, function n is supported */
186 return result & 1 && result & (1 << sfnc);
187} 129}
188 130
189static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) 131static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
190{ 132{
191 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);
192 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);
193 return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL); 135 return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id);
194} 136}
195 137
196static 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)
@@ -200,7 +142,7 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
200 arg = NOUVEAU_DSM_POWER_SPEED; 142 arg = NOUVEAU_DSM_POWER_SPEED;
201 else 143 else
202 arg = NOUVEAU_DSM_POWER_STAMINA; 144 arg = NOUVEAU_DSM_POWER_STAMINA;
203 nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg, NULL); 145 nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg);
204 return 0; 146 return 0;
205} 147}
206 148
@@ -260,11 +202,12 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
260 nouveau_dsm_priv.other_handle = dhandle; 202 nouveau_dsm_priv.other_handle = dhandle;
261 return false; 203 return false;
262 } 204 }
263 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))
264 retval |= NOUVEAU_DSM_HAS_MUX; 207 retval |= NOUVEAU_DSM_HAS_MUX;
265 208
266 if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm, 209 if (acpi_check_dsm(dhandle, nouveau_op_dsm_muid, 0x00000100,
267 NOUVEAU_DSM_OPTIMUS_CAPS)) 210 1 << NOUVEAU_DSM_OPTIMUS_CAPS))
268 retval |= NOUVEAU_DSM_HAS_OPT; 211 retval |= NOUVEAU_DSM_HAS_OPT;
269 212
270 if (retval & NOUVEAU_DSM_HAS_OPT) { 213 if (retval & NOUVEAU_DSM_HAS_OPT) {
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 5f7e55f4b7f0..d22668f7d982 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -850,37 +850,23 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
850 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45, 850 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45,
851 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE, 851 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE,
852 }; 852 };
853 union acpi_object params[4]; 853 union acpi_object *obj;
854 struct acpi_object_list input;
855 struct acpi_device *adev; 854 struct acpi_device *adev;
856 unsigned long long value;
857 acpi_handle handle; 855 acpi_handle handle;
858 856
859 handle = ACPI_HANDLE(&client->dev); 857 handle = ACPI_HANDLE(&client->dev);
860 if (!handle || acpi_bus_get_device(handle, &adev)) 858 if (!handle || acpi_bus_get_device(handle, &adev))
861 return -ENODEV; 859 return -ENODEV;
862 860
863 input.count = ARRAY_SIZE(params); 861 obj = acpi_evaluate_dsm_typed(handle, i2c_hid_guid, 1, 1, NULL,
864 input.pointer = params; 862 ACPI_TYPE_INTEGER);
865 863 if (!obj) {
866 params[0].type = ACPI_TYPE_BUFFER;
867 params[0].buffer.length = sizeof(i2c_hid_guid);
868 params[0].buffer.pointer = i2c_hid_guid;
869 params[1].type = ACPI_TYPE_INTEGER;
870 params[1].integer.value = 1;
871 params[2].type = ACPI_TYPE_INTEGER;
872 params[2].integer.value = 1; /* HID function */
873 params[3].type = ACPI_TYPE_PACKAGE;
874 params[3].package.count = 0;
875 params[3].package.elements = NULL;
876
877 if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_DSM", &input,
878 &value))) {
879 dev_err(&client->dev, "device _DSM execution failed\n"); 864 dev_err(&client->dev, "device _DSM execution failed\n");
880 return -ENODEV; 865 return -ENODEV;
881 } 866 }
882 867
883 pdata->hid_descriptor_address = value; 868 pdata->hid_descriptor_address = obj->integer.value;
869 ACPI_FREE(obj);
884 870
885 return 0; 871 return 0;
886} 872}
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index dbafcc8ef673..d2d1ceccad4b 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -186,7 +186,6 @@ static const char device_label_dsm_uuid[] = {
186}; 186};
187 187
188enum acpi_attr_enum { 188enum acpi_attr_enum {
189 ACPI_ATTR_NONE = 0,
190 ACPI_ATTR_LABEL_SHOW, 189 ACPI_ATTR_LABEL_SHOW,
191 ACPI_ATTR_INDEX_SHOW, 190 ACPI_ATTR_INDEX_SHOW,
192}; 191};
@@ -194,84 +193,61 @@ enum acpi_attr_enum {
194static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) 193static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
195{ 194{
196 int len; 195 int len;
197 len = utf16s_to_utf8s((const wchar_t *)obj-> 196 len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer,
198 package.elements[1].string.pointer, 197 obj->string.length,
199 obj->package.elements[1].string.length,
200 UTF16_LITTLE_ENDIAN, 198 UTF16_LITTLE_ENDIAN,
201 buf, PAGE_SIZE); 199 buf, PAGE_SIZE);
202 buf[len] = '\n'; 200 buf[len] = '\n';
203} 201}
204 202
205static int 203static int
206dsm_get_label(acpi_handle handle, int func, 204dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr)
207 struct acpi_buffer *output,
208 char *buf, enum acpi_attr_enum attribute)
209{ 205{
210 struct acpi_object_list input; 206 acpi_handle handle;
211 union acpi_object params[4]; 207 union acpi_object *obj, *tmp;
212 union acpi_object *obj; 208 int len = -1;
213 int len = 0; 209
214 210 handle = ACPI_HANDLE(dev);
215 int err; 211 if (!handle)
216
217 input.count = 4;
218 input.pointer = params;
219 params[0].type = ACPI_TYPE_BUFFER;
220 params[0].buffer.length = sizeof(device_label_dsm_uuid);
221 params[0].buffer.pointer = (char *)device_label_dsm_uuid;
222 params[1].type = ACPI_TYPE_INTEGER;
223 params[1].integer.value = 0x02;
224 params[2].type = ACPI_TYPE_INTEGER;
225 params[2].integer.value = func;
226 params[3].type = ACPI_TYPE_PACKAGE;
227 params[3].package.count = 0;
228 params[3].package.elements = NULL;
229
230 err = acpi_evaluate_object(handle, "_DSM", &input, output);
231 if (err)
232 return -1; 212 return -1;
233 213
234 obj = (union acpi_object *)output->pointer; 214 obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2,
235 215 DEVICE_LABEL_DSM, NULL);
236 switch (obj->type) { 216 if (!obj)
237 case ACPI_TYPE_PACKAGE: 217 return -1;
238 if (obj->package.count != 2) 218
239 break; 219 tmp = obj->package.elements;
240 len = obj->package.elements[0].integer.value; 220 if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 &&
241 if (buf) { 221 tmp[0].type == ACPI_TYPE_INTEGER &&
242 if (attribute == ACPI_ATTR_INDEX_SHOW) 222 tmp[1].type == ACPI_TYPE_STRING) {
243 scnprintf(buf, PAGE_SIZE, "%llu\n", 223 /*
244 obj->package.elements[0].integer.value); 224 * The second string element is optional even when
245 else if (attribute == ACPI_ATTR_LABEL_SHOW) 225 * this _DSM is implemented; when not implemented,
246 dsm_label_utf16s_to_utf8s(obj, buf); 226 * this entry must return a null string.
247 kfree(output->pointer); 227 */
248 return strlen(buf); 228 if (attr == ACPI_ATTR_INDEX_SHOW)
249 } 229 scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value);
250 kfree(output->pointer); 230 else if (attr == ACPI_ATTR_LABEL_SHOW)
251 return len; 231 dsm_label_utf16s_to_utf8s(tmp + 1, buf);
252 break; 232 len = strlen(buf) > 0 ? strlen(buf) : -1;
253 default:
254 kfree(output->pointer);
255 } 233 }
256 return -1; 234
235 ACPI_FREE(obj);
236
237 return len;
257} 238}
258 239
259static bool 240static bool
260device_has_dsm(struct device *dev) 241device_has_dsm(struct device *dev)
261{ 242{
262 acpi_handle handle; 243 acpi_handle handle;
263 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
264 244
265 handle = ACPI_HANDLE(dev); 245 handle = ACPI_HANDLE(dev);
266
267 if (!handle) 246 if (!handle)
268 return FALSE; 247 return false;
269 248
270 if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL, 249 return !!acpi_check_dsm(handle, device_label_dsm_uuid, 0x2,
271 ACPI_ATTR_NONE) > 0) 250 1 << DEVICE_LABEL_DSM);
272 return TRUE;
273
274 return FALSE;
275} 251}
276 252
277static umode_t 253static umode_t
@@ -290,44 +266,13 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n)
290static ssize_t 266static ssize_t
291acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf) 267acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf)
292{ 268{
293 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; 269 return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW);
294 acpi_handle handle;
295 int length;
296
297 handle = ACPI_HANDLE(dev);
298
299 if (!handle)
300 return -1;
301
302 length = dsm_get_label(handle, DEVICE_LABEL_DSM,
303 &output, buf, ACPI_ATTR_LABEL_SHOW);
304
305 if (length < 1)
306 return -1;
307
308 return length;
309} 270}
310 271
311static ssize_t 272static ssize_t
312acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf) 273acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf)
313{ 274{
314 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; 275 return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW);
315 acpi_handle handle;
316 int length;
317
318 handle = ACPI_HANDLE(dev);
319
320 if (!handle)
321 return -1;
322
323 length = dsm_get_label(handle, DEVICE_LABEL_DSM,
324 &output, buf, ACPI_ATTR_INDEX_SHOW);
325
326 if (length < 0)
327 return -1;
328
329 return length;
330
331} 276}
332 277
333static struct device_attribute acpi_attr_label = { 278static struct device_attribute acpi_attr_label = {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index e4ab7be65637..8256eb4ad057 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -64,6 +64,32 @@ bool acpi_ata_match(acpi_handle handle);
64bool acpi_bay_match(acpi_handle handle); 64bool acpi_bay_match(acpi_handle handle);
65bool acpi_dock_match(acpi_handle handle); 65bool acpi_dock_match(acpi_handle handle);
66 66
67bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs);
68union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid,
69 int rev, int func, union acpi_object *argv4);
70
71static inline union acpi_object *
72acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, int rev, int func,
73 union acpi_object *argv4, acpi_object_type type)
74{
75 union acpi_object *obj;
76
77 obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
78 if (obj && obj->type != type) {
79 ACPI_FREE(obj);
80 obj = NULL;
81 }
82
83 return obj;
84}
85
86#define ACPI_INIT_DSM_ARGV4(cnt, eles) \
87 { \
88 .package.type = ACPI_TYPE_PACKAGE, \
89 .package.count = (cnt), \
90 .package.elements = (eles) \
91 }
92
67#ifdef CONFIG_ACPI 93#ifdef CONFIG_ACPI
68 94
69#include <linux/proc_fs.h> 95#include <linux/proc_fs.h>