3 * Purpose: Provide PCI supports in ACPI
5 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
9 #include <linux/delay.h>
10 #include <linux/init.h>
11 #include <linux/pci.h>
12 #include <linux/module.h>
13 #include <acpi/acpi.h>
14 #include <acpi/acnamesp.h>
15 #include <acpi/acresrc.h>
16 #include <acpi/acpi_bus.h>
18 #include <linux/pci-acpi.h>
20 static u32 ctrlset_buf
[3] = {0, 0, 0};
21 static u32 global_ctrlsets
= 0;
22 static u8 OSC_UUID
[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
32 struct acpi_object_list input
;
33 union acpi_object in_params
[4];
34 struct acpi_buffer output
;
35 union acpi_object out_obj
;
38 /* Setting up output buffer */
39 output
.length
= sizeof(out_obj
) + 3*sizeof(u32
);
40 output
.pointer
= &out_obj
;
42 /* Setting up input parameters */
44 input
.pointer
= in_params
;
45 in_params
[0].type
= ACPI_TYPE_BUFFER
;
46 in_params
[0].buffer
.length
= 16;
47 in_params
[0].buffer
.pointer
= OSC_UUID
;
48 in_params
[1].type
= ACPI_TYPE_INTEGER
;
49 in_params
[1].integer
.value
= 1;
50 in_params
[2].type
= ACPI_TYPE_INTEGER
;
51 in_params
[2].integer
.value
= 3;
52 in_params
[3].type
= ACPI_TYPE_BUFFER
;
53 in_params
[3].buffer
.length
= 12;
54 in_params
[3].buffer
.pointer
= (u8
*)context
;
56 status
= acpi_evaluate_object(handle
, "_OSC", &input
, &output
);
57 if (ACPI_FAILURE (status
)) {
59 "Evaluate _OSC Set fails. Status = 0x%04x\n", status
);
62 if (out_obj
.type
!= ACPI_TYPE_BUFFER
) {
64 "Evaluate _OSC returns wrong type\n");
67 osc_dw0
= *((u32
*) out_obj
.buffer
.pointer
);
69 if (osc_dw0
& OSC_REQUEST_ERROR
)
70 printk(KERN_DEBUG
"_OSC request fails\n");
71 if (osc_dw0
& OSC_INVALID_UUID_ERROR
)
72 printk(KERN_DEBUG
"_OSC invalid UUID\n");
73 if (osc_dw0
& OSC_INVALID_REVISION_ERROR
)
74 printk(KERN_DEBUG
"_OSC invalid revision\n");
75 if (osc_dw0
& OSC_CAPABILITIES_MASK_ERROR
) {
76 /* Update Global Control Set */
77 global_ctrlsets
= *((u32
*)(out_obj
.buffer
.pointer
+8));
83 /* Update Global Control Set */
84 global_ctrlsets
= *((u32
*)(out_obj
.buffer
.pointer
+ 8));
97 struct acpi_object_list input
;
98 union acpi_object in_params
[4];
99 struct acpi_buffer output
;
100 union acpi_object out_obj
;
103 /* Setting up output buffer */
104 output
.length
= sizeof(out_obj
) + 3*sizeof(u32
);
105 output
.pointer
= &out_obj
;
107 /* Setting up input parameters */
109 input
.pointer
= in_params
;
110 in_params
[0].type
= ACPI_TYPE_BUFFER
;
111 in_params
[0].buffer
.length
= 16;
112 in_params
[0].buffer
.pointer
= OSC_UUID
;
113 in_params
[1].type
= ACPI_TYPE_INTEGER
;
114 in_params
[1].integer
.value
= 1;
115 in_params
[2].type
= ACPI_TYPE_INTEGER
;
116 in_params
[2].integer
.value
= 3;
117 in_params
[3].type
= ACPI_TYPE_BUFFER
;
118 in_params
[3].buffer
.length
= 12;
119 in_params
[3].buffer
.pointer
= (u8
*)context
;
121 status
= acpi_evaluate_object(handle
, "_OSC", &input
, &output
);
122 if (ACPI_FAILURE (status
)) {
124 "Evaluate _OSC Set fails. Status = 0x%04x\n", status
);
127 if (out_obj
.type
!= ACPI_TYPE_BUFFER
) {
129 "Evaluate _OSC returns wrong type\n");
132 osc_dw0
= *((u32
*) out_obj
.buffer
.pointer
);
134 if (osc_dw0
& OSC_REQUEST_ERROR
)
135 printk(KERN_DEBUG
"_OSC request fails\n");
136 if (osc_dw0
& OSC_INVALID_UUID_ERROR
)
137 printk(KERN_DEBUG
"_OSC invalid UUID\n");
138 if (osc_dw0
& OSC_INVALID_REVISION_ERROR
)
139 printk(KERN_DEBUG
"_OSC invalid revision\n");
140 if (osc_dw0
& OSC_CAPABILITIES_MASK_ERROR
) {
141 printk(KERN_DEBUG
"_OSC FW not grant req. control\n");
150 * pci_osc_support_set - register OS support to Firmware
151 * @flags: OS support bits
153 * Update OS support fields and doing a _OSC Query to obtain an update
154 * from Firmware on supported control bits.
156 acpi_status
pci_osc_support_set(u32 flags
)
160 if (!(flags
& OSC_SUPPORT_MASKS
)) {
163 ctrlset_buf
[OSC_SUPPORT_TYPE
] |= (flags
& OSC_SUPPORT_MASKS
);
165 /* do _OSC query for all possible controls */
166 temp
= ctrlset_buf
[OSC_CONTROL_TYPE
];
167 ctrlset_buf
[OSC_QUERY_TYPE
] = OSC_QUERY_ENABLE
;
168 ctrlset_buf
[OSC_CONTROL_TYPE
] = OSC_CONTROL_MASKS
;
169 acpi_get_devices ( PCI_ROOT_HID_STRING
,
173 ctrlset_buf
[OSC_QUERY_TYPE
] = !OSC_QUERY_ENABLE
;
174 ctrlset_buf
[OSC_CONTROL_TYPE
] = temp
;
177 EXPORT_SYMBOL(pci_osc_support_set
);
180 * pci_osc_control_set - commit requested control to Firmware
181 * @flags: driver's requested control bits
183 * Attempt to take control from Firmware on requested control bits.
185 acpi_status
pci_osc_control_set(u32 flags
)
190 ctrlset
= (flags
& OSC_CONTROL_MASKS
);
194 if (ctrlset_buf
[OSC_SUPPORT_TYPE
] &&
195 ((global_ctrlsets
& ctrlset
) != ctrlset
)) {
198 ctrlset_buf
[OSC_CONTROL_TYPE
] |= ctrlset
;
199 status
= acpi_get_devices ( PCI_ROOT_HID_STRING
,
203 if (ACPI_FAILURE (status
)) {
204 ctrlset_buf
[OSC_CONTROL_TYPE
] &= ~ctrlset
;
209 EXPORT_SYMBOL(pci_osc_control_set
);