diff options
Diffstat (limited to 'drivers/acpi')
190 files changed, 6249 insertions, 4091 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 3f3489c5ca8..3a17ca5fff6 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -7,7 +7,6 @@ menuconfig ACPI | |||
7 | depends on !IA64_HP_SIM | 7 | depends on !IA64_HP_SIM |
8 | depends on IA64 || X86 | 8 | depends on IA64 || X86 |
9 | depends on PCI | 9 | depends on PCI |
10 | depends on PM | ||
11 | select PNP | 10 | select PNP |
12 | default y | 11 | default y |
13 | help | 12 | help |
@@ -51,12 +50,7 @@ config ACPI_PROCFS | |||
51 | For backwards compatibility, this option allows | 50 | For backwards compatibility, this option allows |
52 | deprecated /proc/acpi/ files to exist, even when | 51 | deprecated /proc/acpi/ files to exist, even when |
53 | they have been replaced by functions in /sys. | 52 | they have been replaced by functions in /sys. |
54 | The deprecated files (and their replacements) include: | ||
55 | 53 | ||
56 | /proc/acpi/processor/*/throttling (/sys/class/thermal/ | ||
57 | cooling_device*/*) | ||
58 | /proc/acpi/video/*/brightness (/sys/class/backlight/) | ||
59 | /proc/acpi/thermal_zone/*/* (/sys/class/thermal/) | ||
60 | This option has no effect on /proc/acpi/ files | 54 | This option has no effect on /proc/acpi/ files |
61 | and functions which do not yet exist in /sys. | 55 | and functions which do not yet exist in /sys. |
62 | 56 | ||
@@ -74,6 +68,8 @@ config ACPI_PROCFS_POWER | |||
74 | /proc/acpi/ac_adapter/* (sys/class/power_supply/*) | 68 | /proc/acpi/ac_adapter/* (sys/class/power_supply/*) |
75 | This option has no effect on /proc/acpi/ directories | 69 | This option has no effect on /proc/acpi/ directories |
76 | and functions, which do not yet exist in /sys | 70 | and functions, which do not yet exist in /sys |
71 | This option, together with the proc directories, will be | ||
72 | deleted in 2.6.39. | ||
77 | 73 | ||
78 | Say N to delete power /proc/acpi/ directories that have moved to /sys/ | 74 | Say N to delete power /proc/acpi/ directories that have moved to /sys/ |
79 | 75 | ||
@@ -209,6 +205,17 @@ config ACPI_PROCESSOR | |||
209 | 205 | ||
210 | To compile this driver as a module, choose M here: | 206 | To compile this driver as a module, choose M here: |
211 | the module will be called processor. | 207 | the module will be called processor. |
208 | config ACPI_IPMI | ||
209 | tristate "IPMI" | ||
210 | depends on EXPERIMENTAL && IPMI_SI && IPMI_HANDLER | ||
211 | default n | ||
212 | help | ||
213 | This driver enables the ACPI to access the BMC controller. And it | ||
214 | uses the IPMI request/response message to communicate with BMC | ||
215 | controller, which can be found on on the server. | ||
216 | |||
217 | To compile this driver as a module, choose M here: | ||
218 | the module will be called as acpi_ipmi. | ||
212 | 219 | ||
213 | config ACPI_HOTPLUG_CPU | 220 | config ACPI_HOTPLUG_CPU |
214 | bool | 221 | bool |
@@ -310,7 +317,7 @@ config ACPI_PCI_SLOT | |||
310 | the module will be called pci_slot. | 317 | the module will be called pci_slot. |
311 | 318 | ||
312 | config X86_PM_TIMER | 319 | config X86_PM_TIMER |
313 | bool "Power Management Timer Support" if EMBEDDED | 320 | bool "Power Management Timer Support" if EXPERT |
314 | depends on X86 | 321 | depends on X86 |
315 | default y | 322 | default y |
316 | help | 323 | help |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 3d031d02e54..d113fa5100b 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -24,7 +24,7 @@ acpi-y += atomicio.o | |||
24 | # sleep related files | 24 | # sleep related files |
25 | acpi-y += wakeup.o | 25 | acpi-y += wakeup.o |
26 | acpi-y += sleep.o | 26 | acpi-y += sleep.o |
27 | acpi-$(CONFIG_ACPI_SLEEP) += proc.o | 27 | acpi-$(CONFIG_ACPI_SLEEP) += proc.o nvs.o |
28 | 28 | ||
29 | 29 | ||
30 | # | 30 | # |
@@ -69,5 +69,6 @@ processor-y += processor_idle.o processor_thermal.o | |||
69 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o | 69 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o |
70 | 70 | ||
71 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o | 71 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o |
72 | obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o | ||
72 | 73 | ||
73 | obj-$(CONFIG_ACPI_APEI) += apei/ | 74 | obj-$(CONFIG_ACPI_APEI) += apei/ |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index ba9afeaa23a..58c3f74bd84 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = { | |||
100 | .release = single_release, | 100 | .release = single_release, |
101 | }; | 101 | }; |
102 | #endif | 102 | #endif |
103 | static int get_ac_property(struct power_supply *psy, | ||
104 | enum power_supply_property psp, | ||
105 | union power_supply_propval *val) | ||
106 | { | ||
107 | struct acpi_ac *ac = to_acpi_ac(psy); | ||
108 | switch (psp) { | ||
109 | case POWER_SUPPLY_PROP_ONLINE: | ||
110 | val->intval = ac->state; | ||
111 | break; | ||
112 | default: | ||
113 | return -EINVAL; | ||
114 | } | ||
115 | return 0; | ||
116 | } | ||
117 | 103 | ||
118 | static enum power_supply_property ac_props[] = { | ||
119 | POWER_SUPPLY_PROP_ONLINE, | ||
120 | }; | ||
121 | /* -------------------------------------------------------------------------- | 104 | /* -------------------------------------------------------------------------- |
122 | AC Adapter Management | 105 | AC Adapter Management |
123 | -------------------------------------------------------------------------- */ | 106 | -------------------------------------------------------------------------- */ |
@@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac) | |||
140 | return 0; | 123 | return 0; |
141 | } | 124 | } |
142 | 125 | ||
126 | /* -------------------------------------------------------------------------- | ||
127 | sysfs I/F | ||
128 | -------------------------------------------------------------------------- */ | ||
129 | static int get_ac_property(struct power_supply *psy, | ||
130 | enum power_supply_property psp, | ||
131 | union power_supply_propval *val) | ||
132 | { | ||
133 | struct acpi_ac *ac = to_acpi_ac(psy); | ||
134 | |||
135 | if (!ac) | ||
136 | return -ENODEV; | ||
137 | |||
138 | if (acpi_ac_get_state(ac)) | ||
139 | return -ENODEV; | ||
140 | |||
141 | switch (psp) { | ||
142 | case POWER_SUPPLY_PROP_ONLINE: | ||
143 | val->intval = ac->state; | ||
144 | break; | ||
145 | default: | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static enum power_supply_property ac_props[] = { | ||
152 | POWER_SUPPLY_PROP_ONLINE, | ||
153 | }; | ||
154 | |||
143 | #ifdef CONFIG_ACPI_PROCFS_POWER | 155 | #ifdef CONFIG_ACPI_PROCFS_POWER |
144 | /* -------------------------------------------------------------------------- | 156 | /* -------------------------------------------------------------------------- |
145 | FS Interface (/proc) | 157 | FS Interface (/proc) |
@@ -185,7 +197,8 @@ static int acpi_ac_add_fs(struct acpi_device *device) | |||
185 | { | 197 | { |
186 | struct proc_dir_entry *entry = NULL; | 198 | struct proc_dir_entry *entry = NULL; |
187 | 199 | ||
188 | 200 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded," | |
201 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
189 | if (!acpi_device_dir(device)) { | 202 | if (!acpi_device_dir(device)) { |
190 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 203 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), |
191 | acpi_ac_dir); | 204 | acpi_ac_dir); |
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c new file mode 100644 index 00000000000..f40acef8026 --- /dev/null +++ b/drivers/acpi/acpi_ipmi.c | |||
@@ -0,0 +1,525 @@ | |||
1 | /* | ||
2 | * acpi_ipmi.c - ACPI IPMI opregion | ||
3 | * | ||
4 | * Copyright (C) 2010 Intel Corporation | ||
5 | * Copyright (C) 2010 Zhao Yakui <yakui.zhao@intel.com> | ||
6 | * | ||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or (at | ||
12 | * your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
22 | * | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/proc_fs.h> | ||
32 | #include <linux/seq_file.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/list.h> | ||
35 | #include <linux/spinlock.h> | ||
36 | #include <linux/io.h> | ||
37 | #include <acpi/acpi_bus.h> | ||
38 | #include <acpi/acpi_drivers.h> | ||
39 | #include <linux/ipmi.h> | ||
40 | #include <linux/device.h> | ||
41 | #include <linux/pnp.h> | ||
42 | |||
43 | MODULE_AUTHOR("Zhao Yakui"); | ||
44 | MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); | ||
45 | MODULE_LICENSE("GPL"); | ||
46 | |||
47 | #define IPMI_FLAGS_HANDLER_INSTALL 0 | ||
48 | |||
49 | #define ACPI_IPMI_OK 0 | ||
50 | #define ACPI_IPMI_TIMEOUT 0x10 | ||
51 | #define ACPI_IPMI_UNKNOWN 0x07 | ||
52 | /* the IPMI timeout is 5s */ | ||
53 | #define IPMI_TIMEOUT (5 * HZ) | ||
54 | |||
55 | struct acpi_ipmi_device { | ||
56 | /* the device list attached to driver_data.ipmi_devices */ | ||
57 | struct list_head head; | ||
58 | /* the IPMI request message list */ | ||
59 | struct list_head tx_msg_list; | ||
60 | struct mutex tx_msg_lock; | ||
61 | acpi_handle handle; | ||
62 | struct pnp_dev *pnp_dev; | ||
63 | ipmi_user_t user_interface; | ||
64 | int ipmi_ifnum; /* IPMI interface number */ | ||
65 | long curr_msgid; | ||
66 | unsigned long flags; | ||
67 | struct ipmi_smi_info smi_data; | ||
68 | }; | ||
69 | |||
70 | struct ipmi_driver_data { | ||
71 | struct list_head ipmi_devices; | ||
72 | struct ipmi_smi_watcher bmc_events; | ||
73 | struct ipmi_user_hndl ipmi_hndlrs; | ||
74 | struct mutex ipmi_lock; | ||
75 | }; | ||
76 | |||
77 | struct acpi_ipmi_msg { | ||
78 | struct list_head head; | ||
79 | /* | ||
80 | * General speaking the addr type should be SI_ADDR_TYPE. And | ||
81 | * the addr channel should be BMC. | ||
82 | * In fact it can also be IPMB type. But we will have to | ||
83 | * parse it from the Netfn command buffer. It is so complex | ||
84 | * that it is skipped. | ||
85 | */ | ||
86 | struct ipmi_addr addr; | ||
87 | long tx_msgid; | ||
88 | /* it is used to track whether the IPMI message is finished */ | ||
89 | struct completion tx_complete; | ||
90 | struct kernel_ipmi_msg tx_message; | ||
91 | int msg_done; | ||
92 | /* tx data . And copy it from ACPI object buffer */ | ||
93 | u8 tx_data[64]; | ||
94 | int tx_len; | ||
95 | u8 rx_data[64]; | ||
96 | int rx_len; | ||
97 | struct acpi_ipmi_device *device; | ||
98 | }; | ||
99 | |||
100 | /* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */ | ||
101 | struct acpi_ipmi_buffer { | ||
102 | u8 status; | ||
103 | u8 length; | ||
104 | u8 data[64]; | ||
105 | }; | ||
106 | |||
107 | static void ipmi_register_bmc(int iface, struct device *dev); | ||
108 | static void ipmi_bmc_gone(int iface); | ||
109 | static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); | ||
110 | static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device); | ||
111 | static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device); | ||
112 | |||
113 | static struct ipmi_driver_data driver_data = { | ||
114 | .ipmi_devices = LIST_HEAD_INIT(driver_data.ipmi_devices), | ||
115 | .bmc_events = { | ||
116 | .owner = THIS_MODULE, | ||
117 | .new_smi = ipmi_register_bmc, | ||
118 | .smi_gone = ipmi_bmc_gone, | ||
119 | }, | ||
120 | .ipmi_hndlrs = { | ||
121 | .ipmi_recv_hndl = ipmi_msg_handler, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | static struct acpi_ipmi_msg *acpi_alloc_ipmi_msg(struct acpi_ipmi_device *ipmi) | ||
126 | { | ||
127 | struct acpi_ipmi_msg *ipmi_msg; | ||
128 | struct pnp_dev *pnp_dev = ipmi->pnp_dev; | ||
129 | |||
130 | ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL); | ||
131 | if (!ipmi_msg) { | ||
132 | dev_warn(&pnp_dev->dev, "Can't allocate memory for ipmi_msg\n"); | ||
133 | return NULL; | ||
134 | } | ||
135 | init_completion(&ipmi_msg->tx_complete); | ||
136 | INIT_LIST_HEAD(&ipmi_msg->head); | ||
137 | ipmi_msg->device = ipmi; | ||
138 | return ipmi_msg; | ||
139 | } | ||
140 | |||
141 | #define IPMI_OP_RGN_NETFN(offset) ((offset >> 8) & 0xff) | ||
142 | #define IPMI_OP_RGN_CMD(offset) (offset & 0xff) | ||
143 | static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, | ||
144 | acpi_physical_address address, | ||
145 | acpi_integer *value) | ||
146 | { | ||
147 | struct kernel_ipmi_msg *msg; | ||
148 | struct acpi_ipmi_buffer *buffer; | ||
149 | struct acpi_ipmi_device *device; | ||
150 | |||
151 | msg = &tx_msg->tx_message; | ||
152 | /* | ||
153 | * IPMI network function and command are encoded in the address | ||
154 | * within the IPMI OpRegion; see ACPI 4.0, sec 5.5.2.4.3. | ||
155 | */ | ||
156 | msg->netfn = IPMI_OP_RGN_NETFN(address); | ||
157 | msg->cmd = IPMI_OP_RGN_CMD(address); | ||
158 | msg->data = tx_msg->tx_data; | ||
159 | /* | ||
160 | * value is the parameter passed by the IPMI opregion space handler. | ||
161 | * It points to the IPMI request message buffer | ||
162 | */ | ||
163 | buffer = (struct acpi_ipmi_buffer *)value; | ||
164 | /* copy the tx message data */ | ||
165 | msg->data_len = buffer->length; | ||
166 | memcpy(tx_msg->tx_data, buffer->data, msg->data_len); | ||
167 | /* | ||
168 | * now the default type is SYSTEM_INTERFACE and channel type is BMC. | ||
169 | * If the netfn is APP_REQUEST and the cmd is SEND_MESSAGE, | ||
170 | * the addr type should be changed to IPMB. Then we will have to parse | ||
171 | * the IPMI request message buffer to get the IPMB address. | ||
172 | * If so, please fix me. | ||
173 | */ | ||
174 | tx_msg->addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
175 | tx_msg->addr.channel = IPMI_BMC_CHANNEL; | ||
176 | tx_msg->addr.data[0] = 0; | ||
177 | |||
178 | /* Get the msgid */ | ||
179 | device = tx_msg->device; | ||
180 | mutex_lock(&device->tx_msg_lock); | ||
181 | device->curr_msgid++; | ||
182 | tx_msg->tx_msgid = device->curr_msgid; | ||
183 | mutex_unlock(&device->tx_msg_lock); | ||
184 | } | ||
185 | |||
186 | static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, | ||
187 | acpi_integer *value, int rem_time) | ||
188 | { | ||
189 | struct acpi_ipmi_buffer *buffer; | ||
190 | |||
191 | /* | ||
192 | * value is also used as output parameter. It represents the response | ||
193 | * IPMI message returned by IPMI command. | ||
194 | */ | ||
195 | buffer = (struct acpi_ipmi_buffer *)value; | ||
196 | if (!rem_time && !msg->msg_done) { | ||
197 | buffer->status = ACPI_IPMI_TIMEOUT; | ||
198 | return; | ||
199 | } | ||
200 | /* | ||
201 | * If the flag of msg_done is not set or the recv length is zero, it | ||
202 | * means that the IPMI command is not executed correctly. | ||
203 | * The status code will be ACPI_IPMI_UNKNOWN. | ||
204 | */ | ||
205 | if (!msg->msg_done || !msg->rx_len) { | ||
206 | buffer->status = ACPI_IPMI_UNKNOWN; | ||
207 | return; | ||
208 | } | ||
209 | /* | ||
210 | * If the IPMI response message is obtained correctly, the status code | ||
211 | * will be ACPI_IPMI_OK | ||
212 | */ | ||
213 | buffer->status = ACPI_IPMI_OK; | ||
214 | buffer->length = msg->rx_len; | ||
215 | memcpy(buffer->data, msg->rx_data, msg->rx_len); | ||
216 | } | ||
217 | |||
218 | static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi) | ||
219 | { | ||
220 | struct acpi_ipmi_msg *tx_msg, *temp; | ||
221 | int count = HZ / 10; | ||
222 | struct pnp_dev *pnp_dev = ipmi->pnp_dev; | ||
223 | |||
224 | list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) { | ||
225 | /* wake up the sleep thread on the Tx msg */ | ||
226 | complete(&tx_msg->tx_complete); | ||
227 | } | ||
228 | |||
229 | /* wait for about 100ms to flush the tx message list */ | ||
230 | while (count--) { | ||
231 | if (list_empty(&ipmi->tx_msg_list)) | ||
232 | break; | ||
233 | schedule_timeout(1); | ||
234 | } | ||
235 | if (!list_empty(&ipmi->tx_msg_list)) | ||
236 | dev_warn(&pnp_dev->dev, "tx msg list is not NULL\n"); | ||
237 | } | ||
238 | |||
239 | static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | ||
240 | { | ||
241 | struct acpi_ipmi_device *ipmi_device = user_msg_data; | ||
242 | int msg_found = 0; | ||
243 | struct acpi_ipmi_msg *tx_msg; | ||
244 | struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; | ||
245 | |||
246 | if (msg->user != ipmi_device->user_interface) { | ||
247 | dev_warn(&pnp_dev->dev, "Unexpected response is returned. " | ||
248 | "returned user %p, expected user %p\n", | ||
249 | msg->user, ipmi_device->user_interface); | ||
250 | ipmi_free_recv_msg(msg); | ||
251 | return; | ||
252 | } | ||
253 | mutex_lock(&ipmi_device->tx_msg_lock); | ||
254 | list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { | ||
255 | if (msg->msgid == tx_msg->tx_msgid) { | ||
256 | msg_found = 1; | ||
257 | break; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | mutex_unlock(&ipmi_device->tx_msg_lock); | ||
262 | if (!msg_found) { | ||
263 | dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " | ||
264 | "returned.\n", msg->msgid); | ||
265 | ipmi_free_recv_msg(msg); | ||
266 | return; | ||
267 | } | ||
268 | |||
269 | if (msg->msg.data_len) { | ||
270 | /* copy the response data to Rx_data buffer */ | ||
271 | memcpy(tx_msg->rx_data, msg->msg_data, msg->msg.data_len); | ||
272 | tx_msg->rx_len = msg->msg.data_len; | ||
273 | tx_msg->msg_done = 1; | ||
274 | } | ||
275 | complete(&tx_msg->tx_complete); | ||
276 | ipmi_free_recv_msg(msg); | ||
277 | }; | ||
278 | |||
279 | static void ipmi_register_bmc(int iface, struct device *dev) | ||
280 | { | ||
281 | struct acpi_ipmi_device *ipmi_device, *temp; | ||
282 | struct pnp_dev *pnp_dev; | ||
283 | ipmi_user_t user; | ||
284 | int err; | ||
285 | struct ipmi_smi_info smi_data; | ||
286 | acpi_handle handle; | ||
287 | |||
288 | err = ipmi_get_smi_info(iface, &smi_data); | ||
289 | |||
290 | if (err) | ||
291 | return; | ||
292 | |||
293 | if (smi_data.addr_src != SI_ACPI) { | ||
294 | put_device(smi_data.dev); | ||
295 | return; | ||
296 | } | ||
297 | |||
298 | handle = smi_data.addr_info.acpi_info.acpi_handle; | ||
299 | |||
300 | mutex_lock(&driver_data.ipmi_lock); | ||
301 | list_for_each_entry(temp, &driver_data.ipmi_devices, head) { | ||
302 | /* | ||
303 | * if the corresponding ACPI handle is already added | ||
304 | * to the device list, don't add it again. | ||
305 | */ | ||
306 | if (temp->handle == handle) | ||
307 | goto out; | ||
308 | } | ||
309 | |||
310 | ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL); | ||
311 | |||
312 | if (!ipmi_device) | ||
313 | goto out; | ||
314 | |||
315 | pnp_dev = to_pnp_dev(smi_data.dev); | ||
316 | ipmi_device->handle = handle; | ||
317 | ipmi_device->pnp_dev = pnp_dev; | ||
318 | |||
319 | err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs, | ||
320 | ipmi_device, &user); | ||
321 | if (err) { | ||
322 | dev_warn(&pnp_dev->dev, "Can't create IPMI user interface\n"); | ||
323 | kfree(ipmi_device); | ||
324 | goto out; | ||
325 | } | ||
326 | acpi_add_ipmi_device(ipmi_device); | ||
327 | ipmi_device->user_interface = user; | ||
328 | ipmi_device->ipmi_ifnum = iface; | ||
329 | mutex_unlock(&driver_data.ipmi_lock); | ||
330 | memcpy(&ipmi_device->smi_data, &smi_data, sizeof(struct ipmi_smi_info)); | ||
331 | return; | ||
332 | |||
333 | out: | ||
334 | mutex_unlock(&driver_data.ipmi_lock); | ||
335 | put_device(smi_data.dev); | ||
336 | return; | ||
337 | } | ||
338 | |||
339 | static void ipmi_bmc_gone(int iface) | ||
340 | { | ||
341 | struct acpi_ipmi_device *ipmi_device, *temp; | ||
342 | |||
343 | mutex_lock(&driver_data.ipmi_lock); | ||
344 | list_for_each_entry_safe(ipmi_device, temp, | ||
345 | &driver_data.ipmi_devices, head) { | ||
346 | if (ipmi_device->ipmi_ifnum != iface) | ||
347 | continue; | ||
348 | |||
349 | acpi_remove_ipmi_device(ipmi_device); | ||
350 | put_device(ipmi_device->smi_data.dev); | ||
351 | kfree(ipmi_device); | ||
352 | break; | ||
353 | } | ||
354 | mutex_unlock(&driver_data.ipmi_lock); | ||
355 | } | ||
356 | /* -------------------------------------------------------------------------- | ||
357 | * Address Space Management | ||
358 | * -------------------------------------------------------------------------- */ | ||
359 | /* | ||
360 | * This is the IPMI opregion space handler. | ||
361 | * @function: indicates the read/write. In fact as the IPMI message is driven | ||
362 | * by command, only write is meaningful. | ||
363 | * @address: This contains the netfn/command of IPMI request message. | ||
364 | * @bits : not used. | ||
365 | * @value : it is an in/out parameter. It points to the IPMI message buffer. | ||
366 | * Before the IPMI message is sent, it represents the actual request | ||
367 | * IPMI message. After the IPMI message is finished, it represents | ||
368 | * the response IPMI message returned by IPMI command. | ||
369 | * @handler_context: IPMI device context. | ||
370 | */ | ||
371 | |||
372 | static acpi_status | ||
373 | acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | ||
374 | u32 bits, acpi_integer *value, | ||
375 | void *handler_context, void *region_context) | ||
376 | { | ||
377 | struct acpi_ipmi_msg *tx_msg; | ||
378 | struct acpi_ipmi_device *ipmi_device = handler_context; | ||
379 | int err, rem_time; | ||
380 | acpi_status status; | ||
381 | /* | ||
382 | * IPMI opregion message. | ||
383 | * IPMI message is firstly written to the BMC and system software | ||
384 | * can get the respsonse. So it is unmeaningful for the read access | ||
385 | * of IPMI opregion. | ||
386 | */ | ||
387 | if ((function & ACPI_IO_MASK) == ACPI_READ) | ||
388 | return AE_TYPE; | ||
389 | |||
390 | if (!ipmi_device->user_interface) | ||
391 | return AE_NOT_EXIST; | ||
392 | |||
393 | tx_msg = acpi_alloc_ipmi_msg(ipmi_device); | ||
394 | if (!tx_msg) | ||
395 | return AE_NO_MEMORY; | ||
396 | |||
397 | acpi_format_ipmi_msg(tx_msg, address, value); | ||
398 | mutex_lock(&ipmi_device->tx_msg_lock); | ||
399 | list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); | ||
400 | mutex_unlock(&ipmi_device->tx_msg_lock); | ||
401 | err = ipmi_request_settime(ipmi_device->user_interface, | ||
402 | &tx_msg->addr, | ||
403 | tx_msg->tx_msgid, | ||
404 | &tx_msg->tx_message, | ||
405 | NULL, 0, 0, 0); | ||
406 | if (err) { | ||
407 | status = AE_ERROR; | ||
408 | goto end_label; | ||
409 | } | ||
410 | rem_time = wait_for_completion_timeout(&tx_msg->tx_complete, | ||
411 | IPMI_TIMEOUT); | ||
412 | acpi_format_ipmi_response(tx_msg, value, rem_time); | ||
413 | status = AE_OK; | ||
414 | |||
415 | end_label: | ||
416 | mutex_lock(&ipmi_device->tx_msg_lock); | ||
417 | list_del(&tx_msg->head); | ||
418 | mutex_unlock(&ipmi_device->tx_msg_lock); | ||
419 | kfree(tx_msg); | ||
420 | return status; | ||
421 | } | ||
422 | |||
423 | static void ipmi_remove_space_handler(struct acpi_ipmi_device *ipmi) | ||
424 | { | ||
425 | if (!test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags)) | ||
426 | return; | ||
427 | |||
428 | acpi_remove_address_space_handler(ipmi->handle, | ||
429 | ACPI_ADR_SPACE_IPMI, &acpi_ipmi_space_handler); | ||
430 | |||
431 | clear_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags); | ||
432 | } | ||
433 | |||
434 | static int ipmi_install_space_handler(struct acpi_ipmi_device *ipmi) | ||
435 | { | ||
436 | acpi_status status; | ||
437 | |||
438 | if (test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags)) | ||
439 | return 0; | ||
440 | |||
441 | status = acpi_install_address_space_handler(ipmi->handle, | ||
442 | ACPI_ADR_SPACE_IPMI, | ||
443 | &acpi_ipmi_space_handler, | ||
444 | NULL, ipmi); | ||
445 | if (ACPI_FAILURE(status)) { | ||
446 | struct pnp_dev *pnp_dev = ipmi->pnp_dev; | ||
447 | dev_warn(&pnp_dev->dev, "Can't register IPMI opregion space " | ||
448 | "handle\n"); | ||
449 | return -EINVAL; | ||
450 | } | ||
451 | set_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags); | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) | ||
456 | { | ||
457 | |||
458 | INIT_LIST_HEAD(&ipmi_device->head); | ||
459 | |||
460 | mutex_init(&ipmi_device->tx_msg_lock); | ||
461 | INIT_LIST_HEAD(&ipmi_device->tx_msg_list); | ||
462 | ipmi_install_space_handler(ipmi_device); | ||
463 | |||
464 | list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices); | ||
465 | } | ||
466 | |||
467 | static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device) | ||
468 | { | ||
469 | /* | ||
470 | * If the IPMI user interface is created, it should be | ||
471 | * destroyed. | ||
472 | */ | ||
473 | if (ipmi_device->user_interface) { | ||
474 | ipmi_destroy_user(ipmi_device->user_interface); | ||
475 | ipmi_device->user_interface = NULL; | ||
476 | } | ||
477 | /* flush the Tx_msg list */ | ||
478 | if (!list_empty(&ipmi_device->tx_msg_list)) | ||
479 | ipmi_flush_tx_msg(ipmi_device); | ||
480 | |||
481 | list_del(&ipmi_device->head); | ||
482 | ipmi_remove_space_handler(ipmi_device); | ||
483 | } | ||
484 | |||
485 | static int __init acpi_ipmi_init(void) | ||
486 | { | ||
487 | int result = 0; | ||
488 | |||
489 | if (acpi_disabled) | ||
490 | return result; | ||
491 | |||
492 | mutex_init(&driver_data.ipmi_lock); | ||
493 | |||
494 | result = ipmi_smi_watcher_register(&driver_data.bmc_events); | ||
495 | |||
496 | return result; | ||
497 | } | ||
498 | |||
499 | static void __exit acpi_ipmi_exit(void) | ||
500 | { | ||
501 | struct acpi_ipmi_device *ipmi_device, *temp; | ||
502 | |||
503 | if (acpi_disabled) | ||
504 | return; | ||
505 | |||
506 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); | ||
507 | |||
508 | /* | ||
509 | * When one smi_watcher is unregistered, it is only deleted | ||
510 | * from the smi_watcher list. But the smi_gone callback function | ||
511 | * is not called. So explicitly uninstall the ACPI IPMI oregion | ||
512 | * handler and free it. | ||
513 | */ | ||
514 | mutex_lock(&driver_data.ipmi_lock); | ||
515 | list_for_each_entry_safe(ipmi_device, temp, | ||
516 | &driver_data.ipmi_devices, head) { | ||
517 | acpi_remove_ipmi_device(ipmi_device); | ||
518 | put_device(ipmi_device->smi_data.dev); | ||
519 | kfree(ipmi_device); | ||
520 | } | ||
521 | mutex_unlock(&driver_data.ipmi_lock); | ||
522 | } | ||
523 | |||
524 | module_init(acpi_ipmi_init); | ||
525 | module_exit(acpi_ipmi_exit); | ||
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 6afceb3d403..a43fa1a57d5 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -298,7 +298,7 @@ static ssize_t acpi_pad_rrtime_store(struct device *dev, | |||
298 | static ssize_t acpi_pad_rrtime_show(struct device *dev, | 298 | static ssize_t acpi_pad_rrtime_show(struct device *dev, |
299 | struct device_attribute *attr, char *buf) | 299 | struct device_attribute *attr, char *buf) |
300 | { | 300 | { |
301 | return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time); | 301 | return scnprintf(buf, PAGE_SIZE, "%d\n", round_robin_time); |
302 | } | 302 | } |
303 | static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR, | 303 | static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR, |
304 | acpi_pad_rrtime_show, | 304 | acpi_pad_rrtime_show, |
@@ -321,7 +321,7 @@ static ssize_t acpi_pad_idlepct_store(struct device *dev, | |||
321 | static ssize_t acpi_pad_idlepct_show(struct device *dev, | 321 | static ssize_t acpi_pad_idlepct_show(struct device *dev, |
322 | struct device_attribute *attr, char *buf) | 322 | struct device_attribute *attr, char *buf) |
323 | { | 323 | { |
324 | return scnprintf(buf, PAGE_SIZE, "%d", idle_pct); | 324 | return scnprintf(buf, PAGE_SIZE, "%d\n", idle_pct); |
325 | } | 325 | } |
326 | static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR, | 326 | static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR, |
327 | acpi_pad_idlepct_show, | 327 | acpi_pad_idlepct_show, |
@@ -342,8 +342,11 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev, | |||
342 | static ssize_t acpi_pad_idlecpus_show(struct device *dev, | 342 | static ssize_t acpi_pad_idlecpus_show(struct device *dev, |
343 | struct device_attribute *attr, char *buf) | 343 | struct device_attribute *attr, char *buf) |
344 | { | 344 | { |
345 | return cpumask_scnprintf(buf, PAGE_SIZE, | 345 | int n = 0; |
346 | to_cpumask(pad_busy_cpus_bits)); | 346 | n = cpumask_scnprintf(buf, PAGE_SIZE-2, to_cpumask(pad_busy_cpus_bits)); |
347 | buf[n++] = '\n'; | ||
348 | buf[n] = '\0'; | ||
349 | return n; | ||
347 | } | 350 | } |
348 | static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, | 351 | static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, |
349 | acpi_pad_idlecpus_show, | 352 | acpi_pad_idlecpus_show, |
@@ -453,7 +456,7 @@ static void acpi_pad_notify(acpi_handle handle, u32 event, | |||
453 | dev_name(&device->dev), event, 0); | 456 | dev_name(&device->dev), event, 0); |
454 | break; | 457 | break; |
455 | default: | 458 | default: |
456 | printk(KERN_WARNING"Unsupported event [0x%x]\n", event); | 459 | printk(KERN_WARNING "Unsupported event [0x%x]\n", event); |
457 | break; | 460 | break; |
458 | } | 461 | } |
459 | } | 462 | } |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index a7e1d1aa410..a1224712fd0 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -10,11 +10,11 @@ obj-y += acpi.o | |||
10 | 10 | ||
11 | acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ | 11 | acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ |
12 | dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ | 12 | dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ |
13 | dsinit.o | 13 | dsinit.o dsargs.o dscontrol.o dswload2.o |
14 | 14 | ||
15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ | 15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ |
16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ | 16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ |
17 | evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o | 17 | evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o |
18 | 18 | ||
19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ | 19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ |
20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ | 20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ |
@@ -45,4 +45,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o | |||
45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | 45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ |
46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ | 46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ |
47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \ | 47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \ |
48 | utosi.o utxferror.o | 48 | utosi.o utxferror.o utdecode.o |
diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 3e50c74ed4a..e0ba17f0a7c 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index b17d8de9f6f..ab87396c2c0 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 72e9d5eb083..eb0b1f8dee6 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index 894a0ff2a94..2d1b7ffa377 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -48,7 +48,7 @@ | |||
48 | #define NAMEOF_ARG_NTE "__A0" | 48 | #define NAMEOF_ARG_NTE "__A0" |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * dsopcode - support for late evaluation | 51 | * dsargs - execution of dynamic arguments for static objects |
52 | */ | 52 | */ |
53 | acpi_status | 53 | acpi_status |
54 | acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc); | 54 | acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc); |
@@ -62,6 +62,20 @@ acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc); | |||
62 | 62 | ||
63 | acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc); | 63 | acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc); |
64 | 64 | ||
65 | /* | ||
66 | * dscontrol - support for execution control opcodes | ||
67 | */ | ||
68 | acpi_status | ||
69 | acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, | ||
70 | union acpi_parse_object *op); | ||
71 | |||
72 | acpi_status | ||
73 | acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state, | ||
74 | union acpi_parse_object *op); | ||
75 | |||
76 | /* | ||
77 | * dsopcode - support for late operand evaluation | ||
78 | */ | ||
65 | acpi_status | 79 | acpi_status |
66 | acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, | 80 | acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, |
67 | union acpi_parse_object *op); | 81 | union acpi_parse_object *op); |
@@ -86,17 +100,6 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, | |||
86 | acpi_status acpi_ds_initialize_region(acpi_handle obj_handle); | 100 | acpi_status acpi_ds_initialize_region(acpi_handle obj_handle); |
87 | 101 | ||
88 | /* | 102 | /* |
89 | * dsctrl - Parser/Interpreter interface, control stack routines | ||
90 | */ | ||
91 | acpi_status | ||
92 | acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, | ||
93 | union acpi_parse_object *op); | ||
94 | |||
95 | acpi_status | ||
96 | acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state, | ||
97 | union acpi_parse_object *op); | ||
98 | |||
99 | /* | ||
100 | * dsexec - Parser/Interpreter interface, method execution callbacks | 103 | * dsexec - Parser/Interpreter interface, method execution callbacks |
101 | */ | 104 | */ |
102 | acpi_status | 105 | acpi_status |
@@ -136,23 +139,26 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
136 | struct acpi_walk_state *walk_state); | 139 | struct acpi_walk_state *walk_state); |
137 | 140 | ||
138 | /* | 141 | /* |
139 | * dsload - Parser/Interpreter interface, namespace load callbacks | 142 | * dsload - Parser/Interpreter interface, pass 1 namespace load callbacks |
140 | */ | 143 | */ |
141 | acpi_status | 144 | acpi_status |
145 | acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number); | ||
146 | |||
147 | acpi_status | ||
142 | acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state, | 148 | acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state, |
143 | union acpi_parse_object **out_op); | 149 | union acpi_parse_object **out_op); |
144 | 150 | ||
145 | acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state); | 151 | acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state); |
146 | 152 | ||
153 | /* | ||
154 | * dsload - Parser/Interpreter interface, pass 2 namespace load callbacks | ||
155 | */ | ||
147 | acpi_status | 156 | acpi_status |
148 | acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | 157 | acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, |
149 | union acpi_parse_object **out_op); | 158 | union acpi_parse_object **out_op); |
150 | 159 | ||
151 | acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state); | 160 | acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state); |
152 | 161 | ||
153 | acpi_status | ||
154 | acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number); | ||
155 | |||
156 | /* | 162 | /* |
157 | * dsmthdat - method data (locals/args) | 163 | * dsmthdat - method data (locals/args) |
158 | */ | 164 | */ |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index a6f99cc37a1..41d247daf46 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -51,8 +51,6 @@ acpi_status acpi_ev_initialize_events(void); | |||
51 | 51 | ||
52 | acpi_status acpi_ev_install_xrupt_handlers(void); | 52 | acpi_status acpi_ev_install_xrupt_handlers(void); |
53 | 53 | ||
54 | acpi_status acpi_ev_install_fadt_gpes(void); | ||
55 | |||
56 | u32 acpi_ev_fixed_event_detect(void); | 54 | u32 acpi_ev_fixed_event_detect(void); |
57 | 55 | ||
58 | /* | 56 | /* |
@@ -82,9 +80,9 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); | |||
82 | 80 | ||
83 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 81 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
84 | 82 | ||
85 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 83 | acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); |
86 | 84 | ||
87 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 85 | acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); |
88 | 86 | ||
89 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, | 87 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, |
90 | u32 gpe_number); | 88 | u32 gpe_number); |
@@ -93,6 +91,8 @@ struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number, | |||
93 | struct acpi_gpe_block_info | 91 | struct acpi_gpe_block_info |
94 | *gpe_block); | 92 | *gpe_block); |
95 | 93 | ||
94 | acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info); | ||
95 | |||
96 | /* | 96 | /* |
97 | * evgpeblk - Upper-level GPE block support | 97 | * evgpeblk - Upper-level GPE block support |
98 | */ | 98 | */ |
@@ -107,12 +107,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
107 | acpi_status | 107 | acpi_status |
108 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 108 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
109 | struct acpi_gpe_block_info *gpe_block, | 109 | struct acpi_gpe_block_info *gpe_block, |
110 | void *ignored); | 110 | void *context); |
111 | 111 | ||
112 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); | 112 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); |
113 | 113 | ||
114 | u32 | 114 | u32 |
115 | acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, | 115 | acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, |
116 | struct acpi_gpe_event_info *gpe_event_info, | ||
116 | u32 gpe_number); | 117 | u32 gpe_number); |
117 | 118 | ||
118 | /* | 119 | /* |
@@ -126,10 +127,6 @@ acpi_status | |||
126 | acpi_ev_match_gpe_method(acpi_handle obj_handle, | 127 | acpi_ev_match_gpe_method(acpi_handle obj_handle, |
127 | u32 level, void *context, void **return_value); | 128 | u32 level, void *context, void **return_value); |
128 | 129 | ||
129 | acpi_status | ||
130 | acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, | ||
131 | u32 level, void *context, void **return_value); | ||
132 | |||
133 | /* | 130 | /* |
134 | * evgpeutil - GPE utilities | 131 | * evgpeutil - GPE utilities |
135 | */ | 132 | */ |
@@ -138,6 +135,10 @@ acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context); | |||
138 | 135 | ||
139 | u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info); | 136 | u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info); |
140 | 137 | ||
138 | acpi_status | ||
139 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
140 | struct acpi_gpe_block_info *gpe_block, void *context); | ||
141 | |||
141 | struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number); | 142 | struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number); |
142 | 143 | ||
143 | acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt); | 144 | acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt); |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index ad88fcae4eb..d69750b83b3 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -146,6 +146,9 @@ u8 acpi_gbl_system_awake_and_running; | |||
146 | 146 | ||
147 | extern u32 acpi_gbl_nesting_level; | 147 | extern u32 acpi_gbl_nesting_level; |
148 | 148 | ||
149 | ACPI_EXTERN u32 acpi_gpe_count; | ||
150 | ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]; | ||
151 | |||
149 | /* Support for dynamic control method tracing mechanism */ | 152 | /* Support for dynamic control method tracing mechanism */ |
150 | 153 | ||
151 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; | 154 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; |
@@ -225,8 +228,10 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_present; | |||
225 | */ | 228 | */ |
226 | ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock; /* For GPE data structs and registers */ | 229 | ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock; /* For GPE data structs and registers */ |
227 | ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ | 230 | ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ |
231 | ACPI_EXTERN spinlock_t _acpi_ev_global_lock_pending_lock; /* For global lock */ | ||
228 | #define acpi_gbl_gpe_lock &_acpi_gbl_gpe_lock | 232 | #define acpi_gbl_gpe_lock &_acpi_gbl_gpe_lock |
229 | #define acpi_gbl_hardware_lock &_acpi_gbl_hardware_lock | 233 | #define acpi_gbl_hardware_lock &_acpi_gbl_hardware_lock |
234 | #define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock | ||
230 | 235 | ||
231 | /***************************************************************************** | 236 | /***************************************************************************** |
232 | * | 237 | * |
@@ -268,6 +273,10 @@ ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS]; | |||
268 | ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; | 273 | ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; |
269 | ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; | 274 | ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; |
270 | 275 | ||
276 | /* Initialization sequencing */ | ||
277 | |||
278 | ACPI_EXTERN u8 acpi_gbl_reg_methods_executed; | ||
279 | |||
271 | /* Misc */ | 280 | /* Misc */ |
272 | 281 | ||
273 | ACPI_EXTERN u32 acpi_gbl_original_mode; | 282 | ACPI_EXTERN u32 acpi_gbl_original_mode; |
@@ -370,7 +379,9 @@ ACPI_EXTERN struct acpi_fixed_event_handler | |||
370 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; | 379 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; |
371 | ACPI_EXTERN struct acpi_gpe_block_info | 380 | ACPI_EXTERN struct acpi_gpe_block_info |
372 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; | 381 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; |
373 | ACPI_EXTERN u8 acpi_all_gpes_initialized; | 382 | ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; |
383 | ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler; | ||
384 | ACPI_EXTERN void *acpi_gbl_global_event_handler_context; | ||
374 | 385 | ||
375 | /***************************************************************************** | 386 | /***************************************************************************** |
376 | * | 387 | * |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 167470ad2d2..e7213beaafc 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -94,7 +94,7 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, | |||
94 | struct acpi_gpe_register_info *gpe_register_info); | 94 | struct acpi_gpe_register_info *gpe_register_info); |
95 | 95 | ||
96 | acpi_status | 96 | acpi_status |
97 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action); | 97 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action); |
98 | 98 | ||
99 | acpi_status | 99 | acpi_status |
100 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 100 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 049e203bd62..3731e1c34b8 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 2ceb0c05b2d..c7f743ca395 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -89,25 +89,6 @@ union acpi_parse_object; | |||
89 | #define ACPI_MAX_MUTEX 7 | 89 | #define ACPI_MAX_MUTEX 7 |
90 | #define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1 | 90 | #define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1 |
91 | 91 | ||
92 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
93 | #ifdef DEFINE_ACPI_GLOBALS | ||
94 | |||
95 | /* Debug names for the mutexes above */ | ||
96 | |||
97 | static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = { | ||
98 | "ACPI_MTX_Interpreter", | ||
99 | "ACPI_MTX_Namespace", | ||
100 | "ACPI_MTX_Tables", | ||
101 | "ACPI_MTX_Events", | ||
102 | "ACPI_MTX_Caches", | ||
103 | "ACPI_MTX_Memory", | ||
104 | "ACPI_MTX_CommandComplete", | ||
105 | "ACPI_MTX_CommandReady" | ||
106 | }; | ||
107 | |||
108 | #endif | ||
109 | #endif | ||
110 | |||
111 | /* Lock structure for reader/writer interfaces */ | 92 | /* Lock structure for reader/writer interfaces */ |
112 | 93 | ||
113 | struct acpi_rw_lock { | 94 | struct acpi_rw_lock { |
@@ -408,17 +389,23 @@ struct acpi_predefined_data { | |||
408 | 389 | ||
409 | /* Dispatch info for each GPE -- either a method or handler, cannot be both */ | 390 | /* Dispatch info for each GPE -- either a method or handler, cannot be both */ |
410 | 391 | ||
411 | struct acpi_handler_info { | 392 | struct acpi_gpe_handler_info { |
412 | acpi_event_handler address; /* Address of handler, if any */ | 393 | acpi_gpe_handler address; /* Address of handler, if any */ |
413 | void *context; /* Context to be passed to handler */ | 394 | void *context; /* Context to be passed to handler */ |
414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ | 395 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ |
415 | u8 orig_flags; /* Original misc info about this GPE */ | 396 | u8 original_flags; /* Original (pre-handler) GPE info */ |
416 | u8 orig_enabled; /* Set if the GPE was originally enabled */ | 397 | u8 originally_enabled; /* True if GPE was originally enabled */ |
398 | }; | ||
399 | |||
400 | struct acpi_gpe_notify_object { | ||
401 | struct acpi_namespace_node *node; | ||
402 | struct acpi_gpe_notify_object *next; | ||
417 | }; | 403 | }; |
418 | 404 | ||
419 | union acpi_gpe_dispatch_info { | 405 | union acpi_gpe_dispatch_info { |
420 | struct acpi_namespace_node *method_node; /* Method node for this GPE level */ | 406 | struct acpi_namespace_node *method_node; /* Method node for this GPE level */ |
421 | struct acpi_handler_info *handler; | 407 | struct acpi_gpe_handler_info *handler; /* Installed GPE handler */ |
408 | struct acpi_gpe_notify_object device; /* List of _PRW devices for implicit notify */ | ||
422 | }; | 409 | }; |
423 | 410 | ||
424 | /* | 411 | /* |
@@ -458,7 +445,7 @@ struct acpi_gpe_block_info { | |||
458 | u32 register_count; /* Number of register pairs in block */ | 445 | u32 register_count; /* Number of register pairs in block */ |
459 | u16 gpe_count; /* Number of individual GPEs in block */ | 446 | u16 gpe_count; /* Number of individual GPEs in block */ |
460 | u8 block_base_number; /* Base GPE number for this block */ | 447 | u8 block_base_number; /* Base GPE number for this block */ |
461 | u8 initialized; /* If set, the GPE block has been initialized */ | 448 | u8 initialized; /* TRUE if this block is initialized */ |
462 | }; | 449 | }; |
463 | 450 | ||
464 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ | 451 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ |
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 8d5c9e0a495..b7491ee1fba 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index d44d3bc5b84..79a598c67fe 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index bdbfaf22bd1..1055769f2f0 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -93,12 +93,10 @@ | |||
93 | 93 | ||
94 | #define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */ | 94 | #define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */ |
95 | #define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */ | 95 | #define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */ |
96 | #define AOPOBJ_DATA_VALID 0x04 /* Object is intialized and data is valid */ | 96 | #define AOPOBJ_DATA_VALID 0x04 /* Object is initialized and data is valid */ |
97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */ | 97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */ |
98 | #define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */ | 98 | #define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */ |
99 | #define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */ | 99 | #define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */ |
100 | #define AOPOBJ_MODULE_LEVEL 0x40 /* Method is actually module-level code */ | ||
101 | #define AOPOBJ_MODIFIED_NAMESPACE 0x80 /* Method modified the namespace */ | ||
102 | 100 | ||
103 | /****************************************************************************** | 101 | /****************************************************************************** |
104 | * | 102 | * |
@@ -175,7 +173,7 @@ struct acpi_object_region { | |||
175 | }; | 173 | }; |
176 | 174 | ||
177 | struct acpi_object_method { | 175 | struct acpi_object_method { |
178 | ACPI_OBJECT_COMMON_HEADER u8 method_flags; | 176 | ACPI_OBJECT_COMMON_HEADER u8 info_flags; |
179 | u8 param_count; | 177 | u8 param_count; |
180 | u8 sync_level; | 178 | u8 sync_level; |
181 | union acpi_operand_object *mutex; | 179 | union acpi_operand_object *mutex; |
@@ -183,13 +181,21 @@ struct acpi_object_method { | |||
183 | union { | 181 | union { |
184 | ACPI_INTERNAL_METHOD implementation; | 182 | ACPI_INTERNAL_METHOD implementation; |
185 | union acpi_operand_object *handler; | 183 | union acpi_operand_object *handler; |
186 | } extra; | 184 | } dispatch; |
187 | 185 | ||
188 | u32 aml_length; | 186 | u32 aml_length; |
189 | u8 thread_count; | 187 | u8 thread_count; |
190 | acpi_owner_id owner_id; | 188 | acpi_owner_id owner_id; |
191 | }; | 189 | }; |
192 | 190 | ||
191 | /* Flags for info_flags field above */ | ||
192 | |||
193 | #define ACPI_METHOD_MODULE_LEVEL 0x01 /* Method is actually module-level code */ | ||
194 | #define ACPI_METHOD_INTERNAL_ONLY 0x02 /* Method is implemented internally (_OSI) */ | ||
195 | #define ACPI_METHOD_SERIALIZED 0x04 /* Method is serialized */ | ||
196 | #define ACPI_METHOD_SERIALIZED_PENDING 0x08 /* Method is to be marked serialized */ | ||
197 | #define ACPI_METHOD_MODIFIED_NAMESPACE 0x10 /* Method modified the namespace */ | ||
198 | |||
193 | /****************************************************************************** | 199 | /****************************************************************************** |
194 | * | 200 | * |
195 | * Objects that can be notified. All share a common notify_info area. | 201 | * Objects that can be notified. All share a common notify_info area. |
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index 8c15ff43f42..bb2ccfad737 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index d0bb0fd3e57..5ea1e06afa2 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 10998d369ad..94e73c97cf8 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index 528bcbaf4ce..f08b55b7f3a 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 6e5dd97949f..1623b245dde 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 62a576e3436..967f08124eb 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 72e4183c193..99c140d8e34 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 1f484ba228f..f4f0998d396 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
@@ -7,7 +7,7 @@ | |||
7 | *****************************************************************************/ | 7 | *****************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2010, Intel Corp. | 10 | * Copyright (C) 2000 - 2011, Intel Corp. |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
@@ -480,16 +480,10 @@ typedef enum { | |||
480 | AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D | 480 | AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D |
481 | } AML_ACCESS_ATTRIBUTE; | 481 | } AML_ACCESS_ATTRIBUTE; |
482 | 482 | ||
483 | /* Bit fields in method_flags byte */ | 483 | /* Bit fields in the AML method_flags byte */ |
484 | 484 | ||
485 | #define AML_METHOD_ARG_COUNT 0x07 | 485 | #define AML_METHOD_ARG_COUNT 0x07 |
486 | #define AML_METHOD_SERIALIZED 0x08 | 486 | #define AML_METHOD_SERIALIZED 0x08 |
487 | #define AML_METHOD_SYNC_LEVEL 0xF0 | 487 | #define AML_METHOD_SYNC_LEVEL 0xF0 |
488 | 488 | ||
489 | /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ | ||
490 | |||
491 | #define AML_METHOD_INTERNAL_ONLY 0x01 | ||
492 | #define AML_METHOD_RESERVED1 0x02 | ||
493 | #define AML_METHOD_RESERVED2 0x04 | ||
494 | |||
495 | #endif /* __AMLCODE_H__ */ | 489 | #endif /* __AMLCODE_H__ */ |
diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index 0e5798fcbb1..59122cde247 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c new file mode 100644 index 00000000000..8c7b99728aa --- /dev/null +++ b/drivers/acpi/acpica/dsargs.c | |||
@@ -0,0 +1,391 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: dsargs - Support for execution of dynamic arguments for static | ||
4 | * objects (regions, fields, buffer fields, etc.) | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2011, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include "accommon.h" | ||
47 | #include "acparser.h" | ||
48 | #include "amlcode.h" | ||
49 | #include "acdispat.h" | ||
50 | #include "acnamesp.h" | ||
51 | |||
52 | #define _COMPONENT ACPI_DISPATCHER | ||
53 | ACPI_MODULE_NAME("dsargs") | ||
54 | |||
55 | /* Local prototypes */ | ||
56 | static acpi_status | ||
57 | acpi_ds_execute_arguments(struct acpi_namespace_node *node, | ||
58 | struct acpi_namespace_node *scope_node, | ||
59 | u32 aml_length, u8 *aml_start); | ||
60 | |||
61 | /******************************************************************************* | ||
62 | * | ||
63 | * FUNCTION: acpi_ds_execute_arguments | ||
64 | * | ||
65 | * PARAMETERS: Node - Object NS node | ||
66 | * scope_node - Parent NS node | ||
67 | * aml_length - Length of executable AML | ||
68 | * aml_start - Pointer to the AML | ||
69 | * | ||
70 | * RETURN: Status. | ||
71 | * | ||
72 | * DESCRIPTION: Late (deferred) execution of region or field arguments | ||
73 | * | ||
74 | ******************************************************************************/ | ||
75 | |||
76 | static acpi_status | ||
77 | acpi_ds_execute_arguments(struct acpi_namespace_node *node, | ||
78 | struct acpi_namespace_node *scope_node, | ||
79 | u32 aml_length, u8 *aml_start) | ||
80 | { | ||
81 | acpi_status status; | ||
82 | union acpi_parse_object *op; | ||
83 | struct acpi_walk_state *walk_state; | ||
84 | |||
85 | ACPI_FUNCTION_TRACE(ds_execute_arguments); | ||
86 | |||
87 | /* Allocate a new parser op to be the root of the parsed tree */ | ||
88 | |||
89 | op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); | ||
90 | if (!op) { | ||
91 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
92 | } | ||
93 | |||
94 | /* Save the Node for use in acpi_ps_parse_aml */ | ||
95 | |||
96 | op->common.node = scope_node; | ||
97 | |||
98 | /* Create and initialize a new parser state */ | ||
99 | |||
100 | walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); | ||
101 | if (!walk_state) { | ||
102 | status = AE_NO_MEMORY; | ||
103 | goto cleanup; | ||
104 | } | ||
105 | |||
106 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, | ||
107 | aml_length, NULL, ACPI_IMODE_LOAD_PASS1); | ||
108 | if (ACPI_FAILURE(status)) { | ||
109 | acpi_ds_delete_walk_state(walk_state); | ||
110 | goto cleanup; | ||
111 | } | ||
112 | |||
113 | /* Mark this parse as a deferred opcode */ | ||
114 | |||
115 | walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; | ||
116 | walk_state->deferred_node = node; | ||
117 | |||
118 | /* Pass1: Parse the entire declaration */ | ||
119 | |||
120 | status = acpi_ps_parse_aml(walk_state); | ||
121 | if (ACPI_FAILURE(status)) { | ||
122 | goto cleanup; | ||
123 | } | ||
124 | |||
125 | /* Get and init the Op created above */ | ||
126 | |||
127 | op->common.node = node; | ||
128 | acpi_ps_delete_parse_tree(op); | ||
129 | |||
130 | /* Evaluate the deferred arguments */ | ||
131 | |||
132 | op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); | ||
133 | if (!op) { | ||
134 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
135 | } | ||
136 | |||
137 | op->common.node = scope_node; | ||
138 | |||
139 | /* Create and initialize a new parser state */ | ||
140 | |||
141 | walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); | ||
142 | if (!walk_state) { | ||
143 | status = AE_NO_MEMORY; | ||
144 | goto cleanup; | ||
145 | } | ||
146 | |||
147 | /* Execute the opcode and arguments */ | ||
148 | |||
149 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, | ||
150 | aml_length, NULL, ACPI_IMODE_EXECUTE); | ||
151 | if (ACPI_FAILURE(status)) { | ||
152 | acpi_ds_delete_walk_state(walk_state); | ||
153 | goto cleanup; | ||
154 | } | ||
155 | |||
156 | /* Mark this execution as a deferred opcode */ | ||
157 | |||
158 | walk_state->deferred_node = node; | ||
159 | status = acpi_ps_parse_aml(walk_state); | ||
160 | |||
161 | cleanup: | ||
162 | acpi_ps_delete_parse_tree(op); | ||
163 | return_ACPI_STATUS(status); | ||
164 | } | ||
165 | |||
166 | /******************************************************************************* | ||
167 | * | ||
168 | * FUNCTION: acpi_ds_get_buffer_field_arguments | ||
169 | * | ||
170 | * PARAMETERS: obj_desc - A valid buffer_field object | ||
171 | * | ||
172 | * RETURN: Status. | ||
173 | * | ||
174 | * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late | ||
175 | * evaluation of these field attributes. | ||
176 | * | ||
177 | ******************************************************************************/ | ||
178 | |||
179 | acpi_status | ||
180 | acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) | ||
181 | { | ||
182 | union acpi_operand_object *extra_desc; | ||
183 | struct acpi_namespace_node *node; | ||
184 | acpi_status status; | ||
185 | |||
186 | ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc); | ||
187 | |||
188 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
189 | return_ACPI_STATUS(AE_OK); | ||
190 | } | ||
191 | |||
192 | /* Get the AML pointer (method object) and buffer_field node */ | ||
193 | |||
194 | extra_desc = acpi_ns_get_secondary_object(obj_desc); | ||
195 | node = obj_desc->buffer_field.node; | ||
196 | |||
197 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_BUFFER_FIELD, | ||
198 | node, NULL)); | ||
199 | |||
200 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", | ||
201 | acpi_ut_get_node_name(node))); | ||
202 | |||
203 | /* Execute the AML code for the term_arg arguments */ | ||
204 | |||
205 | status = acpi_ds_execute_arguments(node, node->parent, | ||
206 | extra_desc->extra.aml_length, | ||
207 | extra_desc->extra.aml_start); | ||
208 | return_ACPI_STATUS(status); | ||
209 | } | ||
210 | |||
211 | /******************************************************************************* | ||
212 | * | ||
213 | * FUNCTION: acpi_ds_get_bank_field_arguments | ||
214 | * | ||
215 | * PARAMETERS: obj_desc - A valid bank_field object | ||
216 | * | ||
217 | * RETURN: Status. | ||
218 | * | ||
219 | * DESCRIPTION: Get bank_field bank_value. This implements the late | ||
220 | * evaluation of these field attributes. | ||
221 | * | ||
222 | ******************************************************************************/ | ||
223 | |||
224 | acpi_status | ||
225 | acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) | ||
226 | { | ||
227 | union acpi_operand_object *extra_desc; | ||
228 | struct acpi_namespace_node *node; | ||
229 | acpi_status status; | ||
230 | |||
231 | ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc); | ||
232 | |||
233 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
234 | return_ACPI_STATUS(AE_OK); | ||
235 | } | ||
236 | |||
237 | /* Get the AML pointer (method object) and bank_field node */ | ||
238 | |||
239 | extra_desc = acpi_ns_get_secondary_object(obj_desc); | ||
240 | node = obj_desc->bank_field.node; | ||
241 | |||
242 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
243 | (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL)); | ||
244 | |||
245 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", | ||
246 | acpi_ut_get_node_name(node))); | ||
247 | |||
248 | /* Execute the AML code for the term_arg arguments */ | ||
249 | |||
250 | status = acpi_ds_execute_arguments(node, node->parent, | ||
251 | extra_desc->extra.aml_length, | ||
252 | extra_desc->extra.aml_start); | ||
253 | return_ACPI_STATUS(status); | ||
254 | } | ||
255 | |||
256 | /******************************************************************************* | ||
257 | * | ||
258 | * FUNCTION: acpi_ds_get_buffer_arguments | ||
259 | * | ||
260 | * PARAMETERS: obj_desc - A valid Buffer object | ||
261 | * | ||
262 | * RETURN: Status. | ||
263 | * | ||
264 | * DESCRIPTION: Get Buffer length and initializer byte list. This implements | ||
265 | * the late evaluation of these attributes. | ||
266 | * | ||
267 | ******************************************************************************/ | ||
268 | |||
269 | acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc) | ||
270 | { | ||
271 | struct acpi_namespace_node *node; | ||
272 | acpi_status status; | ||
273 | |||
274 | ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc); | ||
275 | |||
276 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
277 | return_ACPI_STATUS(AE_OK); | ||
278 | } | ||
279 | |||
280 | /* Get the Buffer node */ | ||
281 | |||
282 | node = obj_desc->buffer.node; | ||
283 | if (!node) { | ||
284 | ACPI_ERROR((AE_INFO, | ||
285 | "No pointer back to namespace node in buffer object %p", | ||
286 | obj_desc)); | ||
287 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
288 | } | ||
289 | |||
290 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n")); | ||
291 | |||
292 | /* Execute the AML code for the term_arg arguments */ | ||
293 | |||
294 | status = acpi_ds_execute_arguments(node, node, | ||
295 | obj_desc->buffer.aml_length, | ||
296 | obj_desc->buffer.aml_start); | ||
297 | return_ACPI_STATUS(status); | ||
298 | } | ||
299 | |||
300 | /******************************************************************************* | ||
301 | * | ||
302 | * FUNCTION: acpi_ds_get_package_arguments | ||
303 | * | ||
304 | * PARAMETERS: obj_desc - A valid Package object | ||
305 | * | ||
306 | * RETURN: Status. | ||
307 | * | ||
308 | * DESCRIPTION: Get Package length and initializer byte list. This implements | ||
309 | * the late evaluation of these attributes. | ||
310 | * | ||
311 | ******************************************************************************/ | ||
312 | |||
313 | acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc) | ||
314 | { | ||
315 | struct acpi_namespace_node *node; | ||
316 | acpi_status status; | ||
317 | |||
318 | ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc); | ||
319 | |||
320 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
321 | return_ACPI_STATUS(AE_OK); | ||
322 | } | ||
323 | |||
324 | /* Get the Package node */ | ||
325 | |||
326 | node = obj_desc->package.node; | ||
327 | if (!node) { | ||
328 | ACPI_ERROR((AE_INFO, | ||
329 | "No pointer back to namespace node in package %p", | ||
330 | obj_desc)); | ||
331 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
332 | } | ||
333 | |||
334 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n")); | ||
335 | |||
336 | /* Execute the AML code for the term_arg arguments */ | ||
337 | |||
338 | status = acpi_ds_execute_arguments(node, node, | ||
339 | obj_desc->package.aml_length, | ||
340 | obj_desc->package.aml_start); | ||
341 | return_ACPI_STATUS(status); | ||
342 | } | ||
343 | |||
344 | /******************************************************************************* | ||
345 | * | ||
346 | * FUNCTION: acpi_ds_get_region_arguments | ||
347 | * | ||
348 | * PARAMETERS: obj_desc - A valid region object | ||
349 | * | ||
350 | * RETURN: Status. | ||
351 | * | ||
352 | * DESCRIPTION: Get region address and length. This implements the late | ||
353 | * evaluation of these region attributes. | ||
354 | * | ||
355 | ******************************************************************************/ | ||
356 | |||
357 | acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) | ||
358 | { | ||
359 | struct acpi_namespace_node *node; | ||
360 | acpi_status status; | ||
361 | union acpi_operand_object *extra_desc; | ||
362 | |||
363 | ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc); | ||
364 | |||
365 | if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { | ||
366 | return_ACPI_STATUS(AE_OK); | ||
367 | } | ||
368 | |||
369 | extra_desc = acpi_ns_get_secondary_object(obj_desc); | ||
370 | if (!extra_desc) { | ||
371 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
372 | } | ||
373 | |||
374 | /* Get the Region node */ | ||
375 | |||
376 | node = obj_desc->region.node; | ||
377 | |||
378 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
379 | (ACPI_TYPE_REGION, node, NULL)); | ||
380 | |||
381 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", | ||
382 | acpi_ut_get_node_name(node), | ||
383 | extra_desc->extra.aml_start)); | ||
384 | |||
385 | /* Execute the argument AML */ | ||
386 | |||
387 | status = acpi_ds_execute_arguments(node, node->parent, | ||
388 | extra_desc->extra.aml_length, | ||
389 | extra_desc->extra.aml_start); | ||
390 | return_ACPI_STATUS(status); | ||
391 | } | ||
diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c new file mode 100644 index 00000000000..26c49fff58d --- /dev/null +++ b/drivers/acpi/acpica/dscontrol.c | |||
@@ -0,0 +1,410 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: dscontrol - Support for execution control opcodes - | ||
4 | * if/else/while/return | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2011, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include "accommon.h" | ||
47 | #include "amlcode.h" | ||
48 | #include "acdispat.h" | ||
49 | #include "acinterp.h" | ||
50 | |||
51 | #define _COMPONENT ACPI_DISPATCHER | ||
52 | ACPI_MODULE_NAME("dscontrol") | ||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_ds_exec_begin_control_op | ||
57 | * | ||
58 | * PARAMETERS: walk_list - The list that owns the walk stack | ||
59 | * Op - The control Op | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Handles all control ops encountered during control method | ||
64 | * execution. | ||
65 | * | ||
66 | ******************************************************************************/ | ||
67 | acpi_status | ||
68 | acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, | ||
69 | union acpi_parse_object *op) | ||
70 | { | ||
71 | acpi_status status = AE_OK; | ||
72 | union acpi_generic_state *control_state; | ||
73 | |||
74 | ACPI_FUNCTION_NAME(ds_exec_begin_control_op); | ||
75 | |||
76 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", | ||
77 | op, op->common.aml_opcode, walk_state)); | ||
78 | |||
79 | switch (op->common.aml_opcode) { | ||
80 | case AML_WHILE_OP: | ||
81 | |||
82 | /* | ||
83 | * If this is an additional iteration of a while loop, continue. | ||
84 | * There is no need to allocate a new control state. | ||
85 | */ | ||
86 | if (walk_state->control_state) { | ||
87 | if (walk_state->control_state->control. | ||
88 | aml_predicate_start == | ||
89 | (walk_state->parser_state.aml - 1)) { | ||
90 | |||
91 | /* Reset the state to start-of-loop */ | ||
92 | |||
93 | walk_state->control_state->common.state = | ||
94 | ACPI_CONTROL_CONDITIONAL_EXECUTING; | ||
95 | break; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /*lint -fallthrough */ | ||
100 | |||
101 | case AML_IF_OP: | ||
102 | |||
103 | /* | ||
104 | * IF/WHILE: Create a new control state to manage these | ||
105 | * constructs. We need to manage these as a stack, in order | ||
106 | * to handle nesting. | ||
107 | */ | ||
108 | control_state = acpi_ut_create_control_state(); | ||
109 | if (!control_state) { | ||
110 | status = AE_NO_MEMORY; | ||
111 | break; | ||
112 | } | ||
113 | /* | ||
114 | * Save a pointer to the predicate for multiple executions | ||
115 | * of a loop | ||
116 | */ | ||
117 | control_state->control.aml_predicate_start = | ||
118 | walk_state->parser_state.aml - 1; | ||
119 | control_state->control.package_end = | ||
120 | walk_state->parser_state.pkg_end; | ||
121 | control_state->control.opcode = op->common.aml_opcode; | ||
122 | |||
123 | /* Push the control state on this walk's control stack */ | ||
124 | |||
125 | acpi_ut_push_generic_state(&walk_state->control_state, | ||
126 | control_state); | ||
127 | break; | ||
128 | |||
129 | case AML_ELSE_OP: | ||
130 | |||
131 | /* Predicate is in the state object */ | ||
132 | /* If predicate is true, the IF was executed, ignore ELSE part */ | ||
133 | |||
134 | if (walk_state->last_predicate) { | ||
135 | status = AE_CTRL_TRUE; | ||
136 | } | ||
137 | |||
138 | break; | ||
139 | |||
140 | case AML_RETURN_OP: | ||
141 | |||
142 | break; | ||
143 | |||
144 | default: | ||
145 | break; | ||
146 | } | ||
147 | |||
148 | return (status); | ||
149 | } | ||
150 | |||
151 | /******************************************************************************* | ||
152 | * | ||
153 | * FUNCTION: acpi_ds_exec_end_control_op | ||
154 | * | ||
155 | * PARAMETERS: walk_list - The list that owns the walk stack | ||
156 | * Op - The control Op | ||
157 | * | ||
158 | * RETURN: Status | ||
159 | * | ||
160 | * DESCRIPTION: Handles all control ops encountered during control method | ||
161 | * execution. | ||
162 | * | ||
163 | ******************************************************************************/ | ||
164 | |||
165 | acpi_status | ||
166 | acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | ||
167 | union acpi_parse_object * op) | ||
168 | { | ||
169 | acpi_status status = AE_OK; | ||
170 | union acpi_generic_state *control_state; | ||
171 | |||
172 | ACPI_FUNCTION_NAME(ds_exec_end_control_op); | ||
173 | |||
174 | switch (op->common.aml_opcode) { | ||
175 | case AML_IF_OP: | ||
176 | |||
177 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op)); | ||
178 | |||
179 | /* | ||
180 | * Save the result of the predicate in case there is an | ||
181 | * ELSE to come | ||
182 | */ | ||
183 | walk_state->last_predicate = | ||
184 | (u8)walk_state->control_state->common.value; | ||
185 | |||
186 | /* | ||
187 | * Pop the control state that was created at the start | ||
188 | * of the IF and free it | ||
189 | */ | ||
190 | control_state = | ||
191 | acpi_ut_pop_generic_state(&walk_state->control_state); | ||
192 | acpi_ut_delete_generic_state(control_state); | ||
193 | break; | ||
194 | |||
195 | case AML_ELSE_OP: | ||
196 | |||
197 | break; | ||
198 | |||
199 | case AML_WHILE_OP: | ||
200 | |||
201 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op)); | ||
202 | |||
203 | control_state = walk_state->control_state; | ||
204 | if (control_state->common.value) { | ||
205 | |||
206 | /* Predicate was true, the body of the loop was just executed */ | ||
207 | |||
208 | /* | ||
209 | * This loop counter mechanism allows the interpreter to escape | ||
210 | * possibly infinite loops. This can occur in poorly written AML | ||
211 | * when the hardware does not respond within a while loop and the | ||
212 | * loop does not implement a timeout. | ||
213 | */ | ||
214 | control_state->control.loop_count++; | ||
215 | if (control_state->control.loop_count > | ||
216 | ACPI_MAX_LOOP_ITERATIONS) { | ||
217 | status = AE_AML_INFINITE_LOOP; | ||
218 | break; | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * Go back and evaluate the predicate and maybe execute the loop | ||
223 | * another time | ||
224 | */ | ||
225 | status = AE_CTRL_PENDING; | ||
226 | walk_state->aml_last_while = | ||
227 | control_state->control.aml_predicate_start; | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | /* Predicate was false, terminate this while loop */ | ||
232 | |||
233 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
234 | "[WHILE_OP] termination! Op=%p\n", op)); | ||
235 | |||
236 | /* Pop this control state and free it */ | ||
237 | |||
238 | control_state = | ||
239 | acpi_ut_pop_generic_state(&walk_state->control_state); | ||
240 | acpi_ut_delete_generic_state(control_state); | ||
241 | break; | ||
242 | |||
243 | case AML_RETURN_OP: | ||
244 | |||
245 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
246 | "[RETURN_OP] Op=%p Arg=%p\n", op, | ||
247 | op->common.value.arg)); | ||
248 | |||
249 | /* | ||
250 | * One optional operand -- the return value | ||
251 | * It can be either an immediate operand or a result that | ||
252 | * has been bubbled up the tree | ||
253 | */ | ||
254 | if (op->common.value.arg) { | ||
255 | |||
256 | /* Since we have a real Return(), delete any implicit return */ | ||
257 | |||
258 | acpi_ds_clear_implicit_return(walk_state); | ||
259 | |||
260 | /* Return statement has an immediate operand */ | ||
261 | |||
262 | status = | ||
263 | acpi_ds_create_operands(walk_state, | ||
264 | op->common.value.arg); | ||
265 | if (ACPI_FAILURE(status)) { | ||
266 | return (status); | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * If value being returned is a Reference (such as | ||
271 | * an arg or local), resolve it now because it may | ||
272 | * cease to exist at the end of the method. | ||
273 | */ | ||
274 | status = | ||
275 | acpi_ex_resolve_to_value(&walk_state->operands[0], | ||
276 | walk_state); | ||
277 | if (ACPI_FAILURE(status)) { | ||
278 | return (status); | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Get the return value and save as the last result | ||
283 | * value. This is the only place where walk_state->return_desc | ||
284 | * is set to anything other than zero! | ||
285 | */ | ||
286 | walk_state->return_desc = walk_state->operands[0]; | ||
287 | } else if (walk_state->result_count) { | ||
288 | |||
289 | /* Since we have a real Return(), delete any implicit return */ | ||
290 | |||
291 | acpi_ds_clear_implicit_return(walk_state); | ||
292 | |||
293 | /* | ||
294 | * The return value has come from a previous calculation. | ||
295 | * | ||
296 | * If value being returned is a Reference (such as | ||
297 | * an arg or local), resolve it now because it may | ||
298 | * cease to exist at the end of the method. | ||
299 | * | ||
300 | * Allow references created by the Index operator to return | ||
301 | * unchanged. | ||
302 | */ | ||
303 | if ((ACPI_GET_DESCRIPTOR_TYPE | ||
304 | (walk_state->results->results.obj_desc[0]) == | ||
305 | ACPI_DESC_TYPE_OPERAND) | ||
306 | && ((walk_state->results->results.obj_desc[0])-> | ||
307 | common.type == ACPI_TYPE_LOCAL_REFERENCE) | ||
308 | && ((walk_state->results->results.obj_desc[0])-> | ||
309 | reference.class != ACPI_REFCLASS_INDEX)) { | ||
310 | status = | ||
311 | acpi_ex_resolve_to_value(&walk_state-> | ||
312 | results->results. | ||
313 | obj_desc[0], | ||
314 | walk_state); | ||
315 | if (ACPI_FAILURE(status)) { | ||
316 | return (status); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | walk_state->return_desc = | ||
321 | walk_state->results->results.obj_desc[0]; | ||
322 | } else { | ||
323 | /* No return operand */ | ||
324 | |||
325 | if (walk_state->num_operands) { | ||
326 | acpi_ut_remove_reference(walk_state-> | ||
327 | operands[0]); | ||
328 | } | ||
329 | |||
330 | walk_state->operands[0] = NULL; | ||
331 | walk_state->num_operands = 0; | ||
332 | walk_state->return_desc = NULL; | ||
333 | } | ||
334 | |||
335 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
336 | "Completed RETURN_OP State=%p, RetVal=%p\n", | ||
337 | walk_state, walk_state->return_desc)); | ||
338 | |||
339 | /* End the control method execution right now */ | ||
340 | |||
341 | status = AE_CTRL_TERMINATE; | ||
342 | break; | ||
343 | |||
344 | case AML_NOOP_OP: | ||
345 | |||
346 | /* Just do nothing! */ | ||
347 | break; | ||
348 | |||
349 | case AML_BREAK_POINT_OP: | ||
350 | |||
351 | /* | ||
352 | * Set the single-step flag. This will cause the debugger (if present) | ||
353 | * to break to the console within the AML debugger at the start of the | ||
354 | * next AML instruction. | ||
355 | */ | ||
356 | ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE); | ||
357 | ACPI_DEBUGGER_EXEC(acpi_os_printf | ||
358 | ("**break** Executed AML BreakPoint opcode\n")); | ||
359 | |||
360 | /* Call to the OSL in case OS wants a piece of the action */ | ||
361 | |||
362 | status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, | ||
363 | "Executed AML Breakpoint opcode"); | ||
364 | break; | ||
365 | |||
366 | case AML_BREAK_OP: | ||
367 | case AML_CONTINUE_OP: /* ACPI 2.0 */ | ||
368 | |||
369 | /* Pop and delete control states until we find a while */ | ||
370 | |||
371 | while (walk_state->control_state && | ||
372 | (walk_state->control_state->control.opcode != | ||
373 | AML_WHILE_OP)) { | ||
374 | control_state = | ||
375 | acpi_ut_pop_generic_state(&walk_state-> | ||
376 | control_state); | ||
377 | acpi_ut_delete_generic_state(control_state); | ||
378 | } | ||
379 | |||
380 | /* No while found? */ | ||
381 | |||
382 | if (!walk_state->control_state) { | ||
383 | return (AE_AML_NO_WHILE); | ||
384 | } | ||
385 | |||
386 | /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */ | ||
387 | |||
388 | walk_state->aml_last_while = | ||
389 | walk_state->control_state->control.package_end; | ||
390 | |||
391 | /* Return status depending on opcode */ | ||
392 | |||
393 | if (op->common.aml_opcode == AML_BREAK_OP) { | ||
394 | status = AE_CTRL_BREAK; | ||
395 | } else { | ||
396 | status = AE_CTRL_CONTINUE; | ||
397 | } | ||
398 | break; | ||
399 | |||
400 | default: | ||
401 | |||
402 | ACPI_ERROR((AE_INFO, "Unknown control opcode=0x%X Op=%p", | ||
403 | op->common.aml_opcode, op)); | ||
404 | |||
405 | status = AE_AML_BAD_OPCODE; | ||
406 | break; | ||
407 | } | ||
408 | |||
409 | return (status); | ||
410 | } | ||
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 347bee1726f..34be60c0e44 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index cc4a38c5755..a7718bf2b9a 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index d94dd8974b5..5d797751e20 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "amlcode.h" | ||
47 | #include "acdispat.h" | 46 | #include "acdispat.h" |
48 | #include "acinterp.h" | 47 | #include "acinterp.h" |
49 | #include "acnamesp.h" | 48 | #include "acnamesp.h" |
@@ -201,7 +200,7 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, | |||
201 | /* | 200 | /* |
202 | * If this method is serialized, we need to acquire the method mutex. | 201 | * If this method is serialized, we need to acquire the method mutex. |
203 | */ | 202 | */ |
204 | if (obj_desc->method.method_flags & AML_METHOD_SERIALIZED) { | 203 | if (obj_desc->method.info_flags & ACPI_METHOD_SERIALIZED) { |
205 | /* | 204 | /* |
206 | * Create a mutex for the method if it is defined to be Serialized | 205 | * Create a mutex for the method if it is defined to be Serialized |
207 | * and a mutex has not already been created. We defer the mutex creation | 206 | * and a mutex has not already been created. We defer the mutex creation |
@@ -413,8 +412,9 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
413 | 412 | ||
414 | /* Invoke an internal method if necessary */ | 413 | /* Invoke an internal method if necessary */ |
415 | 414 | ||
416 | if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { | 415 | if (obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) { |
417 | status = obj_desc->method.extra.implementation(next_walk_state); | 416 | status = |
417 | obj_desc->method.dispatch.implementation(next_walk_state); | ||
418 | if (status == AE_OK) { | 418 | if (status == AE_OK) { |
419 | status = AE_CTRL_TERMINATE; | 419 | status = AE_CTRL_TERMINATE; |
420 | } | 420 | } |
@@ -579,11 +579,14 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
579 | 579 | ||
580 | /* | 580 | /* |
581 | * Delete any namespace objects created anywhere within the | 581 | * Delete any namespace objects created anywhere within the |
582 | * namespace by the execution of this method. Unless this method | 582 | * namespace by the execution of this method. Unless: |
583 | * is a module-level executable code method, in which case we | 583 | * 1) This method is a module-level executable code method, in which |
584 | * want make the objects permanent. | 584 | * case we want make the objects permanent. |
585 | * 2) There are other threads executing the method, in which case we | ||
586 | * will wait until the last thread has completed. | ||
585 | */ | 587 | */ |
586 | if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { | 588 | if (!(method_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) |
589 | && (method_desc->method.thread_count == 1)) { | ||
587 | 590 | ||
588 | /* Delete any direct children of (created by) this method */ | 591 | /* Delete any direct children of (created by) this method */ |
589 | 592 | ||
@@ -593,12 +596,17 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
593 | /* | 596 | /* |
594 | * Delete any objects that were created by this method | 597 | * Delete any objects that were created by this method |
595 | * elsewhere in the namespace (if any were created). | 598 | * elsewhere in the namespace (if any were created). |
599 | * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the | ||
600 | * deletion such that we don't have to perform an entire | ||
601 | * namespace walk for every control method execution. | ||
596 | */ | 602 | */ |
597 | if (method_desc->method. | 603 | if (method_desc->method. |
598 | flags & AOPOBJ_MODIFIED_NAMESPACE) { | 604 | info_flags & ACPI_METHOD_MODIFIED_NAMESPACE) { |
599 | acpi_ns_delete_namespace_by_owner(method_desc-> | 605 | acpi_ns_delete_namespace_by_owner(method_desc-> |
600 | method. | 606 | method. |
601 | owner_id); | 607 | owner_id); |
608 | method_desc->method.info_flags &= | ||
609 | ~ACPI_METHOD_MODIFIED_NAMESPACE; | ||
602 | } | 610 | } |
603 | } | 611 | } |
604 | } | 612 | } |
@@ -629,19 +637,43 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
629 | * Serialized if it appears that the method is incorrectly written and | 637 | * Serialized if it appears that the method is incorrectly written and |
630 | * does not support multiple thread execution. The best example of this | 638 | * does not support multiple thread execution. The best example of this |
631 | * is if such a method creates namespace objects and blocks. A second | 639 | * is if such a method creates namespace objects and blocks. A second |
632 | * thread will fail with an AE_ALREADY_EXISTS exception | 640 | * thread will fail with an AE_ALREADY_EXISTS exception. |
633 | * | 641 | * |
634 | * This code is here because we must wait until the last thread exits | 642 | * This code is here because we must wait until the last thread exits |
635 | * before creating the synchronization semaphore. | 643 | * before marking the method as serialized. |
636 | */ | 644 | */ |
637 | if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) | 645 | if (method_desc->method. |
638 | && (!method_desc->method.mutex)) { | 646 | info_flags & ACPI_METHOD_SERIALIZED_PENDING) { |
639 | (void)acpi_ds_create_method_mutex(method_desc); | 647 | if (walk_state) { |
648 | ACPI_INFO((AE_INFO, | ||
649 | "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error", | ||
650 | walk_state->method_node->name. | ||
651 | ascii)); | ||
652 | } | ||
653 | |||
654 | /* | ||
655 | * Method tried to create an object twice and was marked as | ||
656 | * "pending serialized". The probable cause is that the method | ||
657 | * cannot handle reentrancy. | ||
658 | * | ||
659 | * The method was created as not_serialized, but it tried to create | ||
660 | * a named object and then blocked, causing the second thread | ||
661 | * entrance to begin and then fail. Workaround this problem by | ||
662 | * marking the method permanently as Serialized when the last | ||
663 | * thread exits here. | ||
664 | */ | ||
665 | method_desc->method.info_flags &= | ||
666 | ~ACPI_METHOD_SERIALIZED_PENDING; | ||
667 | method_desc->method.info_flags |= | ||
668 | ACPI_METHOD_SERIALIZED; | ||
669 | method_desc->method.sync_level = 0; | ||
640 | } | 670 | } |
641 | 671 | ||
642 | /* No more threads, we can free the owner_id */ | 672 | /* No more threads, we can free the owner_id */ |
643 | 673 | ||
644 | if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { | 674 | if (! |
675 | (method_desc->method. | ||
676 | info_flags & ACPI_METHOD_MODULE_LEVEL)) { | ||
645 | acpi_ut_release_owner_id(&method_desc->method.owner_id); | 677 | acpi_ut_release_owner_id(&method_desc->method.owner_id); |
646 | } | 678 | } |
647 | } | 679 | } |
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 8095306fcd8..905ce29a92e 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 8e85f54a8e0..f42e17e5c25 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 7c0e7422717..c627a288e02 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c | |||
@@ -1,12 +1,11 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Module Name: dsopcode - Dispatcher Op Region support and handling of | 3 | * Module Name: dsopcode - Dispatcher suport for regions and fields |
4 | * "control" opcodes | ||
5 | * | 4 | * |
6 | *****************************************************************************/ | 5 | *****************************************************************************/ |
7 | 6 | ||
8 | /* | 7 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 9 | * All rights reserved. |
11 | * | 10 | * |
12 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -57,11 +56,6 @@ ACPI_MODULE_NAME("dsopcode") | |||
57 | 56 | ||
58 | /* Local prototypes */ | 57 | /* Local prototypes */ |
59 | static acpi_status | 58 | static acpi_status |
60 | acpi_ds_execute_arguments(struct acpi_namespace_node *node, | ||
61 | struct acpi_namespace_node *scope_node, | ||
62 | u32 aml_length, u8 * aml_start); | ||
63 | |||
64 | static acpi_status | ||
65 | acpi_ds_init_buffer_field(u16 aml_opcode, | 59 | acpi_ds_init_buffer_field(u16 aml_opcode, |
66 | union acpi_operand_object *obj_desc, | 60 | union acpi_operand_object *obj_desc, |
67 | union acpi_operand_object *buffer_desc, | 61 | union acpi_operand_object *buffer_desc, |
@@ -71,361 +65,6 @@ acpi_ds_init_buffer_field(u16 aml_opcode, | |||
71 | 65 | ||
72 | /******************************************************************************* | 66 | /******************************************************************************* |
73 | * | 67 | * |
74 | * FUNCTION: acpi_ds_execute_arguments | ||
75 | * | ||
76 | * PARAMETERS: Node - Object NS node | ||
77 | * scope_node - Parent NS node | ||
78 | * aml_length - Length of executable AML | ||
79 | * aml_start - Pointer to the AML | ||
80 | * | ||
81 | * RETURN: Status. | ||
82 | * | ||
83 | * DESCRIPTION: Late (deferred) execution of region or field arguments | ||
84 | * | ||
85 | ******************************************************************************/ | ||
86 | |||
87 | static acpi_status | ||
88 | acpi_ds_execute_arguments(struct acpi_namespace_node *node, | ||
89 | struct acpi_namespace_node *scope_node, | ||
90 | u32 aml_length, u8 * aml_start) | ||
91 | { | ||
92 | acpi_status status; | ||
93 | union acpi_parse_object *op; | ||
94 | struct acpi_walk_state *walk_state; | ||
95 | |||
96 | ACPI_FUNCTION_TRACE(ds_execute_arguments); | ||
97 | |||
98 | /* | ||
99 | * Allocate a new parser op to be the root of the parsed tree | ||
100 | */ | ||
101 | op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); | ||
102 | if (!op) { | ||
103 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
104 | } | ||
105 | |||
106 | /* Save the Node for use in acpi_ps_parse_aml */ | ||
107 | |||
108 | op->common.node = scope_node; | ||
109 | |||
110 | /* Create and initialize a new parser state */ | ||
111 | |||
112 | walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); | ||
113 | if (!walk_state) { | ||
114 | status = AE_NO_MEMORY; | ||
115 | goto cleanup; | ||
116 | } | ||
117 | |||
118 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, | ||
119 | aml_length, NULL, ACPI_IMODE_LOAD_PASS1); | ||
120 | if (ACPI_FAILURE(status)) { | ||
121 | acpi_ds_delete_walk_state(walk_state); | ||
122 | goto cleanup; | ||
123 | } | ||
124 | |||
125 | /* Mark this parse as a deferred opcode */ | ||
126 | |||
127 | walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; | ||
128 | walk_state->deferred_node = node; | ||
129 | |||
130 | /* Pass1: Parse the entire declaration */ | ||
131 | |||
132 | status = acpi_ps_parse_aml(walk_state); | ||
133 | if (ACPI_FAILURE(status)) { | ||
134 | goto cleanup; | ||
135 | } | ||
136 | |||
137 | /* Get and init the Op created above */ | ||
138 | |||
139 | op->common.node = node; | ||
140 | acpi_ps_delete_parse_tree(op); | ||
141 | |||
142 | /* Evaluate the deferred arguments */ | ||
143 | |||
144 | op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); | ||
145 | if (!op) { | ||
146 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
147 | } | ||
148 | |||
149 | op->common.node = scope_node; | ||
150 | |||
151 | /* Create and initialize a new parser state */ | ||
152 | |||
153 | walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); | ||
154 | if (!walk_state) { | ||
155 | status = AE_NO_MEMORY; | ||
156 | goto cleanup; | ||
157 | } | ||
158 | |||
159 | /* Execute the opcode and arguments */ | ||
160 | |||
161 | status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, | ||
162 | aml_length, NULL, ACPI_IMODE_EXECUTE); | ||
163 | if (ACPI_FAILURE(status)) { | ||
164 | acpi_ds_delete_walk_state(walk_state); | ||
165 | goto cleanup; | ||
166 | } | ||
167 | |||
168 | /* Mark this execution as a deferred opcode */ | ||
169 | |||
170 | walk_state->deferred_node = node; | ||
171 | status = acpi_ps_parse_aml(walk_state); | ||
172 | |||
173 | cleanup: | ||
174 | acpi_ps_delete_parse_tree(op); | ||
175 | return_ACPI_STATUS(status); | ||
176 | } | ||
177 | |||
178 | /******************************************************************************* | ||
179 | * | ||
180 | * FUNCTION: acpi_ds_get_buffer_field_arguments | ||
181 | * | ||
182 | * PARAMETERS: obj_desc - A valid buffer_field object | ||
183 | * | ||
184 | * RETURN: Status. | ||
185 | * | ||
186 | * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late | ||
187 | * evaluation of these field attributes. | ||
188 | * | ||
189 | ******************************************************************************/ | ||
190 | |||
191 | acpi_status | ||
192 | acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) | ||
193 | { | ||
194 | union acpi_operand_object *extra_desc; | ||
195 | struct acpi_namespace_node *node; | ||
196 | acpi_status status; | ||
197 | |||
198 | ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc); | ||
199 | |||
200 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
201 | return_ACPI_STATUS(AE_OK); | ||
202 | } | ||
203 | |||
204 | /* Get the AML pointer (method object) and buffer_field node */ | ||
205 | |||
206 | extra_desc = acpi_ns_get_secondary_object(obj_desc); | ||
207 | node = obj_desc->buffer_field.node; | ||
208 | |||
209 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
210 | (ACPI_TYPE_BUFFER_FIELD, node, NULL)); | ||
211 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", | ||
212 | acpi_ut_get_node_name(node))); | ||
213 | |||
214 | /* Execute the AML code for the term_arg arguments */ | ||
215 | |||
216 | status = acpi_ds_execute_arguments(node, node->parent, | ||
217 | extra_desc->extra.aml_length, | ||
218 | extra_desc->extra.aml_start); | ||
219 | return_ACPI_STATUS(status); | ||
220 | } | ||
221 | |||
222 | /******************************************************************************* | ||
223 | * | ||
224 | * FUNCTION: acpi_ds_get_bank_field_arguments | ||
225 | * | ||
226 | * PARAMETERS: obj_desc - A valid bank_field object | ||
227 | * | ||
228 | * RETURN: Status. | ||
229 | * | ||
230 | * DESCRIPTION: Get bank_field bank_value. This implements the late | ||
231 | * evaluation of these field attributes. | ||
232 | * | ||
233 | ******************************************************************************/ | ||
234 | |||
235 | acpi_status | ||
236 | acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) | ||
237 | { | ||
238 | union acpi_operand_object *extra_desc; | ||
239 | struct acpi_namespace_node *node; | ||
240 | acpi_status status; | ||
241 | |||
242 | ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc); | ||
243 | |||
244 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
245 | return_ACPI_STATUS(AE_OK); | ||
246 | } | ||
247 | |||
248 | /* Get the AML pointer (method object) and bank_field node */ | ||
249 | |||
250 | extra_desc = acpi_ns_get_secondary_object(obj_desc); | ||
251 | node = obj_desc->bank_field.node; | ||
252 | |||
253 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
254 | (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL)); | ||
255 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", | ||
256 | acpi_ut_get_node_name(node))); | ||
257 | |||
258 | /* Execute the AML code for the term_arg arguments */ | ||
259 | |||
260 | status = acpi_ds_execute_arguments(node, node->parent, | ||
261 | extra_desc->extra.aml_length, | ||
262 | extra_desc->extra.aml_start); | ||
263 | return_ACPI_STATUS(status); | ||
264 | } | ||
265 | |||
266 | /******************************************************************************* | ||
267 | * | ||
268 | * FUNCTION: acpi_ds_get_buffer_arguments | ||
269 | * | ||
270 | * PARAMETERS: obj_desc - A valid Buffer object | ||
271 | * | ||
272 | * RETURN: Status. | ||
273 | * | ||
274 | * DESCRIPTION: Get Buffer length and initializer byte list. This implements | ||
275 | * the late evaluation of these attributes. | ||
276 | * | ||
277 | ******************************************************************************/ | ||
278 | |||
279 | acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc) | ||
280 | { | ||
281 | struct acpi_namespace_node *node; | ||
282 | acpi_status status; | ||
283 | |||
284 | ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc); | ||
285 | |||
286 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
287 | return_ACPI_STATUS(AE_OK); | ||
288 | } | ||
289 | |||
290 | /* Get the Buffer node */ | ||
291 | |||
292 | node = obj_desc->buffer.node; | ||
293 | if (!node) { | ||
294 | ACPI_ERROR((AE_INFO, | ||
295 | "No pointer back to namespace node in buffer object %p", | ||
296 | obj_desc)); | ||
297 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
298 | } | ||
299 | |||
300 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n")); | ||
301 | |||
302 | /* Execute the AML code for the term_arg arguments */ | ||
303 | |||
304 | status = acpi_ds_execute_arguments(node, node, | ||
305 | obj_desc->buffer.aml_length, | ||
306 | obj_desc->buffer.aml_start); | ||
307 | return_ACPI_STATUS(status); | ||
308 | } | ||
309 | |||
310 | /******************************************************************************* | ||
311 | * | ||
312 | * FUNCTION: acpi_ds_get_package_arguments | ||
313 | * | ||
314 | * PARAMETERS: obj_desc - A valid Package object | ||
315 | * | ||
316 | * RETURN: Status. | ||
317 | * | ||
318 | * DESCRIPTION: Get Package length and initializer byte list. This implements | ||
319 | * the late evaluation of these attributes. | ||
320 | * | ||
321 | ******************************************************************************/ | ||
322 | |||
323 | acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc) | ||
324 | { | ||
325 | struct acpi_namespace_node *node; | ||
326 | acpi_status status; | ||
327 | |||
328 | ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc); | ||
329 | |||
330 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
331 | return_ACPI_STATUS(AE_OK); | ||
332 | } | ||
333 | |||
334 | /* Get the Package node */ | ||
335 | |||
336 | node = obj_desc->package.node; | ||
337 | if (!node) { | ||
338 | ACPI_ERROR((AE_INFO, | ||
339 | "No pointer back to namespace node in package %p", | ||
340 | obj_desc)); | ||
341 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
342 | } | ||
343 | |||
344 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n")); | ||
345 | |||
346 | /* Execute the AML code for the term_arg arguments */ | ||
347 | |||
348 | status = acpi_ds_execute_arguments(node, node, | ||
349 | obj_desc->package.aml_length, | ||
350 | obj_desc->package.aml_start); | ||
351 | return_ACPI_STATUS(status); | ||
352 | } | ||
353 | |||
354 | /***************************************************************************** | ||
355 | * | ||
356 | * FUNCTION: acpi_ds_get_region_arguments | ||
357 | * | ||
358 | * PARAMETERS: obj_desc - A valid region object | ||
359 | * | ||
360 | * RETURN: Status. | ||
361 | * | ||
362 | * DESCRIPTION: Get region address and length. This implements the late | ||
363 | * evaluation of these region attributes. | ||
364 | * | ||
365 | ****************************************************************************/ | ||
366 | |||
367 | acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) | ||
368 | { | ||
369 | struct acpi_namespace_node *node; | ||
370 | acpi_status status; | ||
371 | union acpi_operand_object *extra_desc; | ||
372 | |||
373 | ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc); | ||
374 | |||
375 | if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { | ||
376 | return_ACPI_STATUS(AE_OK); | ||
377 | } | ||
378 | |||
379 | extra_desc = acpi_ns_get_secondary_object(obj_desc); | ||
380 | if (!extra_desc) { | ||
381 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
382 | } | ||
383 | |||
384 | /* Get the Region node */ | ||
385 | |||
386 | node = obj_desc->region.node; | ||
387 | |||
388 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
389 | (ACPI_TYPE_REGION, node, NULL)); | ||
390 | |||
391 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", | ||
392 | acpi_ut_get_node_name(node), | ||
393 | extra_desc->extra.aml_start)); | ||
394 | |||
395 | /* Execute the argument AML */ | ||
396 | |||
397 | status = acpi_ds_execute_arguments(node, node->parent, | ||
398 | extra_desc->extra.aml_length, | ||
399 | extra_desc->extra.aml_start); | ||
400 | if (ACPI_FAILURE(status)) { | ||
401 | return_ACPI_STATUS(status); | ||
402 | } | ||
403 | |||
404 | /* Validate the region address/length via the host OS */ | ||
405 | |||
406 | status = acpi_os_validate_address(obj_desc->region.space_id, | ||
407 | obj_desc->region.address, | ||
408 | (acpi_size) obj_desc->region.length, | ||
409 | acpi_ut_get_node_name(node)); | ||
410 | |||
411 | if (ACPI_FAILURE(status)) { | ||
412 | /* | ||
413 | * Invalid address/length. We will emit an error message and mark | ||
414 | * the region as invalid, so that it will cause an additional error if | ||
415 | * it is ever used. Then return AE_OK. | ||
416 | */ | ||
417 | ACPI_EXCEPTION((AE_INFO, status, | ||
418 | "During address validation of OpRegion [%4.4s]", | ||
419 | node->name.ascii)); | ||
420 | obj_desc->common.flags |= AOPOBJ_INVALID; | ||
421 | status = AE_OK; | ||
422 | } | ||
423 | |||
424 | return_ACPI_STATUS(status); | ||
425 | } | ||
426 | |||
427 | /******************************************************************************* | ||
428 | * | ||
429 | * FUNCTION: acpi_ds_initialize_region | 68 | * FUNCTION: acpi_ds_initialize_region |
430 | * | 69 | * |
431 | * PARAMETERS: obj_handle - Region namespace node | 70 | * PARAMETERS: obj_handle - Region namespace node |
@@ -826,8 +465,9 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, | |||
826 | * | 465 | * |
827 | * RETURN: Status | 466 | * RETURN: Status |
828 | * | 467 | * |
829 | * DESCRIPTION: Get region address and length | 468 | * DESCRIPTION: Get region address and length. |
830 | * Called from acpi_ds_exec_end_op during data_table_region parse tree walk | 469 | * Called from acpi_ds_exec_end_op during data_table_region parse |
470 | * tree walk. | ||
831 | * | 471 | * |
832 | ******************************************************************************/ | 472 | ******************************************************************************/ |
833 | 473 | ||
@@ -1114,360 +754,3 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, | |||
1114 | acpi_ut_remove_reference(operand_desc); | 754 | acpi_ut_remove_reference(operand_desc); |
1115 | return_ACPI_STATUS(status); | 755 | return_ACPI_STATUS(status); |
1116 | } | 756 | } |
1117 | |||
1118 | /******************************************************************************* | ||
1119 | * | ||
1120 | * FUNCTION: acpi_ds_exec_begin_control_op | ||
1121 | * | ||
1122 | * PARAMETERS: walk_list - The list that owns the walk stack | ||
1123 | * Op - The control Op | ||
1124 | * | ||
1125 | * RETURN: Status | ||
1126 | * | ||
1127 | * DESCRIPTION: Handles all control ops encountered during control method | ||
1128 | * execution. | ||
1129 | * | ||
1130 | ******************************************************************************/ | ||
1131 | |||
1132 | acpi_status | ||
1133 | acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, | ||
1134 | union acpi_parse_object *op) | ||
1135 | { | ||
1136 | acpi_status status = AE_OK; | ||
1137 | union acpi_generic_state *control_state; | ||
1138 | |||
1139 | ACPI_FUNCTION_NAME(ds_exec_begin_control_op); | ||
1140 | |||
1141 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op, | ||
1142 | op->common.aml_opcode, walk_state)); | ||
1143 | |||
1144 | switch (op->common.aml_opcode) { | ||
1145 | case AML_WHILE_OP: | ||
1146 | |||
1147 | /* | ||
1148 | * If this is an additional iteration of a while loop, continue. | ||
1149 | * There is no need to allocate a new control state. | ||
1150 | */ | ||
1151 | if (walk_state->control_state) { | ||
1152 | if (walk_state->control_state->control.aml_predicate_start | ||
1153 | == (walk_state->parser_state.aml - 1)) { | ||
1154 | |||
1155 | /* Reset the state to start-of-loop */ | ||
1156 | |||
1157 | walk_state->control_state->common.state = | ||
1158 | ACPI_CONTROL_CONDITIONAL_EXECUTING; | ||
1159 | break; | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | /*lint -fallthrough */ | ||
1164 | |||
1165 | case AML_IF_OP: | ||
1166 | |||
1167 | /* | ||
1168 | * IF/WHILE: Create a new control state to manage these | ||
1169 | * constructs. We need to manage these as a stack, in order | ||
1170 | * to handle nesting. | ||
1171 | */ | ||
1172 | control_state = acpi_ut_create_control_state(); | ||
1173 | if (!control_state) { | ||
1174 | status = AE_NO_MEMORY; | ||
1175 | break; | ||
1176 | } | ||
1177 | /* | ||
1178 | * Save a pointer to the predicate for multiple executions | ||
1179 | * of a loop | ||
1180 | */ | ||
1181 | control_state->control.aml_predicate_start = | ||
1182 | walk_state->parser_state.aml - 1; | ||
1183 | control_state->control.package_end = | ||
1184 | walk_state->parser_state.pkg_end; | ||
1185 | control_state->control.opcode = op->common.aml_opcode; | ||
1186 | |||
1187 | /* Push the control state on this walk's control stack */ | ||
1188 | |||
1189 | acpi_ut_push_generic_state(&walk_state->control_state, | ||
1190 | control_state); | ||
1191 | break; | ||
1192 | |||
1193 | case AML_ELSE_OP: | ||
1194 | |||
1195 | /* Predicate is in the state object */ | ||
1196 | /* If predicate is true, the IF was executed, ignore ELSE part */ | ||
1197 | |||
1198 | if (walk_state->last_predicate) { | ||
1199 | status = AE_CTRL_TRUE; | ||
1200 | } | ||
1201 | |||
1202 | break; | ||
1203 | |||
1204 | case AML_RETURN_OP: | ||
1205 | |||
1206 | break; | ||
1207 | |||
1208 | default: | ||
1209 | break; | ||
1210 | } | ||
1211 | |||
1212 | return (status); | ||
1213 | } | ||
1214 | |||
1215 | /******************************************************************************* | ||
1216 | * | ||
1217 | * FUNCTION: acpi_ds_exec_end_control_op | ||
1218 | * | ||
1219 | * PARAMETERS: walk_list - The list that owns the walk stack | ||
1220 | * Op - The control Op | ||
1221 | * | ||
1222 | * RETURN: Status | ||
1223 | * | ||
1224 | * DESCRIPTION: Handles all control ops encountered during control method | ||
1225 | * execution. | ||
1226 | * | ||
1227 | ******************************************************************************/ | ||
1228 | |||
1229 | acpi_status | ||
1230 | acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | ||
1231 | union acpi_parse_object * op) | ||
1232 | { | ||
1233 | acpi_status status = AE_OK; | ||
1234 | union acpi_generic_state *control_state; | ||
1235 | |||
1236 | ACPI_FUNCTION_NAME(ds_exec_end_control_op); | ||
1237 | |||
1238 | switch (op->common.aml_opcode) { | ||
1239 | case AML_IF_OP: | ||
1240 | |||
1241 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op)); | ||
1242 | |||
1243 | /* | ||
1244 | * Save the result of the predicate in case there is an | ||
1245 | * ELSE to come | ||
1246 | */ | ||
1247 | walk_state->last_predicate = | ||
1248 | (u8) walk_state->control_state->common.value; | ||
1249 | |||
1250 | /* | ||
1251 | * Pop the control state that was created at the start | ||
1252 | * of the IF and free it | ||
1253 | */ | ||
1254 | control_state = | ||
1255 | acpi_ut_pop_generic_state(&walk_state->control_state); | ||
1256 | acpi_ut_delete_generic_state(control_state); | ||
1257 | break; | ||
1258 | |||
1259 | case AML_ELSE_OP: | ||
1260 | |||
1261 | break; | ||
1262 | |||
1263 | case AML_WHILE_OP: | ||
1264 | |||
1265 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op)); | ||
1266 | |||
1267 | control_state = walk_state->control_state; | ||
1268 | if (control_state->common.value) { | ||
1269 | |||
1270 | /* Predicate was true, the body of the loop was just executed */ | ||
1271 | |||
1272 | /* | ||
1273 | * This loop counter mechanism allows the interpreter to escape | ||
1274 | * possibly infinite loops. This can occur in poorly written AML | ||
1275 | * when the hardware does not respond within a while loop and the | ||
1276 | * loop does not implement a timeout. | ||
1277 | */ | ||
1278 | control_state->control.loop_count++; | ||
1279 | if (control_state->control.loop_count > | ||
1280 | ACPI_MAX_LOOP_ITERATIONS) { | ||
1281 | status = AE_AML_INFINITE_LOOP; | ||
1282 | break; | ||
1283 | } | ||
1284 | |||
1285 | /* | ||
1286 | * Go back and evaluate the predicate and maybe execute the loop | ||
1287 | * another time | ||
1288 | */ | ||
1289 | status = AE_CTRL_PENDING; | ||
1290 | walk_state->aml_last_while = | ||
1291 | control_state->control.aml_predicate_start; | ||
1292 | break; | ||
1293 | } | ||
1294 | |||
1295 | /* Predicate was false, terminate this while loop */ | ||
1296 | |||
1297 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
1298 | "[WHILE_OP] termination! Op=%p\n", op)); | ||
1299 | |||
1300 | /* Pop this control state and free it */ | ||
1301 | |||
1302 | control_state = | ||
1303 | acpi_ut_pop_generic_state(&walk_state->control_state); | ||
1304 | acpi_ut_delete_generic_state(control_state); | ||
1305 | break; | ||
1306 | |||
1307 | case AML_RETURN_OP: | ||
1308 | |||
1309 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
1310 | "[RETURN_OP] Op=%p Arg=%p\n", op, | ||
1311 | op->common.value.arg)); | ||
1312 | |||
1313 | /* | ||
1314 | * One optional operand -- the return value | ||
1315 | * It can be either an immediate operand or a result that | ||
1316 | * has been bubbled up the tree | ||
1317 | */ | ||
1318 | if (op->common.value.arg) { | ||
1319 | |||
1320 | /* Since we have a real Return(), delete any implicit return */ | ||
1321 | |||
1322 | acpi_ds_clear_implicit_return(walk_state); | ||
1323 | |||
1324 | /* Return statement has an immediate operand */ | ||
1325 | |||
1326 | status = | ||
1327 | acpi_ds_create_operands(walk_state, | ||
1328 | op->common.value.arg); | ||
1329 | if (ACPI_FAILURE(status)) { | ||
1330 | return (status); | ||
1331 | } | ||
1332 | |||
1333 | /* | ||
1334 | * If value being returned is a Reference (such as | ||
1335 | * an arg or local), resolve it now because it may | ||
1336 | * cease to exist at the end of the method. | ||
1337 | */ | ||
1338 | status = | ||
1339 | acpi_ex_resolve_to_value(&walk_state->operands[0], | ||
1340 | walk_state); | ||
1341 | if (ACPI_FAILURE(status)) { | ||
1342 | return (status); | ||
1343 | } | ||
1344 | |||
1345 | /* | ||
1346 | * Get the return value and save as the last result | ||
1347 | * value. This is the only place where walk_state->return_desc | ||
1348 | * is set to anything other than zero! | ||
1349 | */ | ||
1350 | walk_state->return_desc = walk_state->operands[0]; | ||
1351 | } else if (walk_state->result_count) { | ||
1352 | |||
1353 | /* Since we have a real Return(), delete any implicit return */ | ||
1354 | |||
1355 | acpi_ds_clear_implicit_return(walk_state); | ||
1356 | |||
1357 | /* | ||
1358 | * The return value has come from a previous calculation. | ||
1359 | * | ||
1360 | * If value being returned is a Reference (such as | ||
1361 | * an arg or local), resolve it now because it may | ||
1362 | * cease to exist at the end of the method. | ||
1363 | * | ||
1364 | * Allow references created by the Index operator to return unchanged. | ||
1365 | */ | ||
1366 | if ((ACPI_GET_DESCRIPTOR_TYPE | ||
1367 | (walk_state->results->results.obj_desc[0]) == | ||
1368 | ACPI_DESC_TYPE_OPERAND) | ||
1369 | && ((walk_state->results->results.obj_desc[0])-> | ||
1370 | common.type == ACPI_TYPE_LOCAL_REFERENCE) | ||
1371 | && ((walk_state->results->results.obj_desc[0])-> | ||
1372 | reference.class != ACPI_REFCLASS_INDEX)) { | ||
1373 | status = | ||
1374 | acpi_ex_resolve_to_value(&walk_state-> | ||
1375 | results->results. | ||
1376 | obj_desc[0], | ||
1377 | walk_state); | ||
1378 | if (ACPI_FAILURE(status)) { | ||
1379 | return (status); | ||
1380 | } | ||
1381 | } | ||
1382 | |||
1383 | walk_state->return_desc = | ||
1384 | walk_state->results->results.obj_desc[0]; | ||
1385 | } else { | ||
1386 | /* No return operand */ | ||
1387 | |||
1388 | if (walk_state->num_operands) { | ||
1389 | acpi_ut_remove_reference(walk_state-> | ||
1390 | operands[0]); | ||
1391 | } | ||
1392 | |||
1393 | walk_state->operands[0] = NULL; | ||
1394 | walk_state->num_operands = 0; | ||
1395 | walk_state->return_desc = NULL; | ||
1396 | } | ||
1397 | |||
1398 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
1399 | "Completed RETURN_OP State=%p, RetVal=%p\n", | ||
1400 | walk_state, walk_state->return_desc)); | ||
1401 | |||
1402 | /* End the control method execution right now */ | ||
1403 | |||
1404 | status = AE_CTRL_TERMINATE; | ||
1405 | break; | ||
1406 | |||
1407 | case AML_NOOP_OP: | ||
1408 | |||
1409 | /* Just do nothing! */ | ||
1410 | break; | ||
1411 | |||
1412 | case AML_BREAK_POINT_OP: | ||
1413 | |||
1414 | /* | ||
1415 | * Set the single-step flag. This will cause the debugger (if present) | ||
1416 | * to break to the console within the AML debugger at the start of the | ||
1417 | * next AML instruction. | ||
1418 | */ | ||
1419 | ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE); | ||
1420 | ACPI_DEBUGGER_EXEC(acpi_os_printf | ||
1421 | ("**break** Executed AML BreakPoint opcode\n")); | ||
1422 | |||
1423 | /* Call to the OSL in case OS wants a piece of the action */ | ||
1424 | |||
1425 | status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, | ||
1426 | "Executed AML Breakpoint opcode"); | ||
1427 | break; | ||
1428 | |||
1429 | case AML_BREAK_OP: | ||
1430 | case AML_CONTINUE_OP: /* ACPI 2.0 */ | ||
1431 | |||
1432 | /* Pop and delete control states until we find a while */ | ||
1433 | |||
1434 | while (walk_state->control_state && | ||
1435 | (walk_state->control_state->control.opcode != | ||
1436 | AML_WHILE_OP)) { | ||
1437 | control_state = | ||
1438 | acpi_ut_pop_generic_state(&walk_state-> | ||
1439 | control_state); | ||
1440 | acpi_ut_delete_generic_state(control_state); | ||
1441 | } | ||
1442 | |||
1443 | /* No while found? */ | ||
1444 | |||
1445 | if (!walk_state->control_state) { | ||
1446 | return (AE_AML_NO_WHILE); | ||
1447 | } | ||
1448 | |||
1449 | /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */ | ||
1450 | |||
1451 | walk_state->aml_last_while = | ||
1452 | walk_state->control_state->control.package_end; | ||
1453 | |||
1454 | /* Return status depending on opcode */ | ||
1455 | |||
1456 | if (op->common.aml_opcode == AML_BREAK_OP) { | ||
1457 | status = AE_CTRL_BREAK; | ||
1458 | } else { | ||
1459 | status = AE_CTRL_CONTINUE; | ||
1460 | } | ||
1461 | break; | ||
1462 | |||
1463 | default: | ||
1464 | |||
1465 | ACPI_ERROR((AE_INFO, "Unknown control opcode=0x%X Op=%p", | ||
1466 | op->common.aml_opcode, op)); | ||
1467 | |||
1468 | status = AE_AML_BAD_OPCODE; | ||
1469 | break; | ||
1470 | } | ||
1471 | |||
1472 | return (status); | ||
1473 | } | ||
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 15135c25aa9..2c477ce172f 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 6b0b5d08d97..fe40e4c6554 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 140a9d00295..23a3b1ab20c 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c | |||
@@ -1,11 +1,11 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Module Name: dswload - Dispatcher namespace load callbacks | 3 | * Module Name: dswload - Dispatcher first pass namespace load callbacks |
4 | * | 4 | * |
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -48,7 +48,6 @@ | |||
48 | #include "acdispat.h" | 48 | #include "acdispat.h" |
49 | #include "acinterp.h" | 49 | #include "acinterp.h" |
50 | #include "acnamesp.h" | 50 | #include "acnamesp.h" |
51 | #include "acevents.h" | ||
52 | 51 | ||
53 | #ifdef ACPI_ASL_COMPILER | 52 | #ifdef ACPI_ASL_COMPILER |
54 | #include <acpi/acdisasm.h> | 53 | #include <acpi/acdisasm.h> |
@@ -537,670 +536,3 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) | |||
537 | 536 | ||
538 | return_ACPI_STATUS(status); | 537 | return_ACPI_STATUS(status); |
539 | } | 538 | } |
540 | |||
541 | /******************************************************************************* | ||
542 | * | ||
543 | * FUNCTION: acpi_ds_load2_begin_op | ||
544 | * | ||
545 | * PARAMETERS: walk_state - Current state of the parse tree walk | ||
546 | * out_op - Wher to return op if a new one is created | ||
547 | * | ||
548 | * RETURN: Status | ||
549 | * | ||
550 | * DESCRIPTION: Descending callback used during the loading of ACPI tables. | ||
551 | * | ||
552 | ******************************************************************************/ | ||
553 | |||
554 | acpi_status | ||
555 | acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | ||
556 | union acpi_parse_object **out_op) | ||
557 | { | ||
558 | union acpi_parse_object *op; | ||
559 | struct acpi_namespace_node *node; | ||
560 | acpi_status status; | ||
561 | acpi_object_type object_type; | ||
562 | char *buffer_ptr; | ||
563 | u32 flags; | ||
564 | |||
565 | ACPI_FUNCTION_TRACE(ds_load2_begin_op); | ||
566 | |||
567 | op = walk_state->op; | ||
568 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, | ||
569 | walk_state)); | ||
570 | |||
571 | if (op) { | ||
572 | if ((walk_state->control_state) && | ||
573 | (walk_state->control_state->common.state == | ||
574 | ACPI_CONTROL_CONDITIONAL_EXECUTING)) { | ||
575 | |||
576 | /* We are executing a while loop outside of a method */ | ||
577 | |||
578 | status = acpi_ds_exec_begin_op(walk_state, out_op); | ||
579 | return_ACPI_STATUS(status); | ||
580 | } | ||
581 | |||
582 | /* We only care about Namespace opcodes here */ | ||
583 | |||
584 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && | ||
585 | (walk_state->opcode != AML_INT_NAMEPATH_OP)) || | ||
586 | (!(walk_state->op_info->flags & AML_NAMED))) { | ||
587 | return_ACPI_STATUS(AE_OK); | ||
588 | } | ||
589 | |||
590 | /* Get the name we are going to enter or lookup in the namespace */ | ||
591 | |||
592 | if (walk_state->opcode == AML_INT_NAMEPATH_OP) { | ||
593 | |||
594 | /* For Namepath op, get the path string */ | ||
595 | |||
596 | buffer_ptr = op->common.value.string; | ||
597 | if (!buffer_ptr) { | ||
598 | |||
599 | /* No name, just exit */ | ||
600 | |||
601 | return_ACPI_STATUS(AE_OK); | ||
602 | } | ||
603 | } else { | ||
604 | /* Get name from the op */ | ||
605 | |||
606 | buffer_ptr = ACPI_CAST_PTR(char, &op->named.name); | ||
607 | } | ||
608 | } else { | ||
609 | /* Get the namestring from the raw AML */ | ||
610 | |||
611 | buffer_ptr = | ||
612 | acpi_ps_get_next_namestring(&walk_state->parser_state); | ||
613 | } | ||
614 | |||
615 | /* Map the opcode into an internal object type */ | ||
616 | |||
617 | object_type = walk_state->op_info->object_type; | ||
618 | |||
619 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
620 | "State=%p Op=%p Type=%X\n", walk_state, op, | ||
621 | object_type)); | ||
622 | |||
623 | switch (walk_state->opcode) { | ||
624 | case AML_FIELD_OP: | ||
625 | case AML_BANK_FIELD_OP: | ||
626 | case AML_INDEX_FIELD_OP: | ||
627 | |||
628 | node = NULL; | ||
629 | status = AE_OK; | ||
630 | break; | ||
631 | |||
632 | case AML_INT_NAMEPATH_OP: | ||
633 | /* | ||
634 | * The name_path is an object reference to an existing object. | ||
635 | * Don't enter the name into the namespace, but look it up | ||
636 | * for use later. | ||
637 | */ | ||
638 | status = | ||
639 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | ||
640 | object_type, ACPI_IMODE_EXECUTE, | ||
641 | ACPI_NS_SEARCH_PARENT, walk_state, &(node)); | ||
642 | break; | ||
643 | |||
644 | case AML_SCOPE_OP: | ||
645 | |||
646 | /* Special case for Scope(\) -> refers to the Root node */ | ||
647 | |||
648 | if (op && (op->named.node == acpi_gbl_root_node)) { | ||
649 | node = op->named.node; | ||
650 | |||
651 | status = | ||
652 | acpi_ds_scope_stack_push(node, object_type, | ||
653 | walk_state); | ||
654 | if (ACPI_FAILURE(status)) { | ||
655 | return_ACPI_STATUS(status); | ||
656 | } | ||
657 | } else { | ||
658 | /* | ||
659 | * The Path is an object reference to an existing object. | ||
660 | * Don't enter the name into the namespace, but look it up | ||
661 | * for use later. | ||
662 | */ | ||
663 | status = | ||
664 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | ||
665 | object_type, ACPI_IMODE_EXECUTE, | ||
666 | ACPI_NS_SEARCH_PARENT, walk_state, | ||
667 | &(node)); | ||
668 | if (ACPI_FAILURE(status)) { | ||
669 | #ifdef ACPI_ASL_COMPILER | ||
670 | if (status == AE_NOT_FOUND) { | ||
671 | status = AE_OK; | ||
672 | } else { | ||
673 | ACPI_ERROR_NAMESPACE(buffer_ptr, | ||
674 | status); | ||
675 | } | ||
676 | #else | ||
677 | ACPI_ERROR_NAMESPACE(buffer_ptr, status); | ||
678 | #endif | ||
679 | return_ACPI_STATUS(status); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | /* | ||
684 | * We must check to make sure that the target is | ||
685 | * one of the opcodes that actually opens a scope | ||
686 | */ | ||
687 | switch (node->type) { | ||
688 | case ACPI_TYPE_ANY: | ||
689 | case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ | ||
690 | case ACPI_TYPE_DEVICE: | ||
691 | case ACPI_TYPE_POWER: | ||
692 | case ACPI_TYPE_PROCESSOR: | ||
693 | case ACPI_TYPE_THERMAL: | ||
694 | |||
695 | /* These are acceptable types */ | ||
696 | break; | ||
697 | |||
698 | case ACPI_TYPE_INTEGER: | ||
699 | case ACPI_TYPE_STRING: | ||
700 | case ACPI_TYPE_BUFFER: | ||
701 | |||
702 | /* | ||
703 | * These types we will allow, but we will change the type. | ||
704 | * This enables some existing code of the form: | ||
705 | * | ||
706 | * Name (DEB, 0) | ||
707 | * Scope (DEB) { ... } | ||
708 | */ | ||
709 | ACPI_WARNING((AE_INFO, | ||
710 | "Type override - [%4.4s] had invalid type (%s) " | ||
711 | "for Scope operator, changed to type ANY\n", | ||
712 | acpi_ut_get_node_name(node), | ||
713 | acpi_ut_get_type_name(node->type))); | ||
714 | |||
715 | node->type = ACPI_TYPE_ANY; | ||
716 | walk_state->scope_info->common.value = ACPI_TYPE_ANY; | ||
717 | break; | ||
718 | |||
719 | default: | ||
720 | |||
721 | /* All other types are an error */ | ||
722 | |||
723 | ACPI_ERROR((AE_INFO, | ||
724 | "Invalid type (%s) for target of " | ||
725 | "Scope operator [%4.4s] (Cannot override)", | ||
726 | acpi_ut_get_type_name(node->type), | ||
727 | acpi_ut_get_node_name(node))); | ||
728 | |||
729 | return (AE_AML_OPERAND_TYPE); | ||
730 | } | ||
731 | break; | ||
732 | |||
733 | default: | ||
734 | |||
735 | /* All other opcodes */ | ||
736 | |||
737 | if (op && op->common.node) { | ||
738 | |||
739 | /* This op/node was previously entered into the namespace */ | ||
740 | |||
741 | node = op->common.node; | ||
742 | |||
743 | if (acpi_ns_opens_scope(object_type)) { | ||
744 | status = | ||
745 | acpi_ds_scope_stack_push(node, object_type, | ||
746 | walk_state); | ||
747 | if (ACPI_FAILURE(status)) { | ||
748 | return_ACPI_STATUS(status); | ||
749 | } | ||
750 | } | ||
751 | |||
752 | return_ACPI_STATUS(AE_OK); | ||
753 | } | ||
754 | |||
755 | /* | ||
756 | * Enter the named type into the internal namespace. We enter the name | ||
757 | * as we go downward in the parse tree. Any necessary subobjects that | ||
758 | * involve arguments to the opcode must be created as we go back up the | ||
759 | * parse tree later. | ||
760 | * | ||
761 | * Note: Name may already exist if we are executing a deferred opcode. | ||
762 | */ | ||
763 | if (walk_state->deferred_node) { | ||
764 | |||
765 | /* This name is already in the namespace, get the node */ | ||
766 | |||
767 | node = walk_state->deferred_node; | ||
768 | status = AE_OK; | ||
769 | break; | ||
770 | } | ||
771 | |||
772 | flags = ACPI_NS_NO_UPSEARCH; | ||
773 | if (walk_state->pass_number == ACPI_IMODE_EXECUTE) { | ||
774 | |||
775 | /* Execution mode, node cannot already exist, node is temporary */ | ||
776 | |||
777 | flags |= ACPI_NS_ERROR_IF_FOUND; | ||
778 | |||
779 | if (! | ||
780 | (walk_state-> | ||
781 | parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
782 | flags |= ACPI_NS_TEMPORARY; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | /* Add new entry or lookup existing entry */ | ||
787 | |||
788 | status = | ||
789 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | ||
790 | object_type, ACPI_IMODE_LOAD_PASS2, flags, | ||
791 | walk_state, &node); | ||
792 | |||
793 | if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) { | ||
794 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
795 | "***New Node [%4.4s] %p is temporary\n", | ||
796 | acpi_ut_get_node_name(node), node)); | ||
797 | } | ||
798 | break; | ||
799 | } | ||
800 | |||
801 | if (ACPI_FAILURE(status)) { | ||
802 | ACPI_ERROR_NAMESPACE(buffer_ptr, status); | ||
803 | return_ACPI_STATUS(status); | ||
804 | } | ||
805 | |||
806 | if (!op) { | ||
807 | |||
808 | /* Create a new op */ | ||
809 | |||
810 | op = acpi_ps_alloc_op(walk_state->opcode); | ||
811 | if (!op) { | ||
812 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
813 | } | ||
814 | |||
815 | /* Initialize the new op */ | ||
816 | |||
817 | if (node) { | ||
818 | op->named.name = node->name.integer; | ||
819 | } | ||
820 | *out_op = op; | ||
821 | } | ||
822 | |||
823 | /* | ||
824 | * Put the Node in the "op" object that the parser uses, so we | ||
825 | * can get it again quickly when this scope is closed | ||
826 | */ | ||
827 | op->common.node = node; | ||
828 | return_ACPI_STATUS(status); | ||
829 | } | ||
830 | |||
831 | /******************************************************************************* | ||
832 | * | ||
833 | * FUNCTION: acpi_ds_load2_end_op | ||
834 | * | ||
835 | * PARAMETERS: walk_state - Current state of the parse tree walk | ||
836 | * | ||
837 | * RETURN: Status | ||
838 | * | ||
839 | * DESCRIPTION: Ascending callback used during the loading of the namespace, | ||
840 | * both control methods and everything else. | ||
841 | * | ||
842 | ******************************************************************************/ | ||
843 | |||
844 | acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | ||
845 | { | ||
846 | union acpi_parse_object *op; | ||
847 | acpi_status status = AE_OK; | ||
848 | acpi_object_type object_type; | ||
849 | struct acpi_namespace_node *node; | ||
850 | union acpi_parse_object *arg; | ||
851 | struct acpi_namespace_node *new_node; | ||
852 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
853 | u32 i; | ||
854 | u8 region_space; | ||
855 | #endif | ||
856 | |||
857 | ACPI_FUNCTION_TRACE(ds_load2_end_op); | ||
858 | |||
859 | op = walk_state->op; | ||
860 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", | ||
861 | walk_state->op_info->name, op, walk_state)); | ||
862 | |||
863 | /* Check if opcode had an associated namespace object */ | ||
864 | |||
865 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { | ||
866 | return_ACPI_STATUS(AE_OK); | ||
867 | } | ||
868 | |||
869 | if (op->common.aml_opcode == AML_SCOPE_OP) { | ||
870 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
871 | "Ending scope Op=%p State=%p\n", op, | ||
872 | walk_state)); | ||
873 | } | ||
874 | |||
875 | object_type = walk_state->op_info->object_type; | ||
876 | |||
877 | /* | ||
878 | * Get the Node/name from the earlier lookup | ||
879 | * (It was saved in the *op structure) | ||
880 | */ | ||
881 | node = op->common.node; | ||
882 | |||
883 | /* | ||
884 | * Put the Node on the object stack (Contains the ACPI Name of | ||
885 | * this object) | ||
886 | */ | ||
887 | walk_state->operands[0] = (void *)node; | ||
888 | walk_state->num_operands = 1; | ||
889 | |||
890 | /* Pop the scope stack */ | ||
891 | |||
892 | if (acpi_ns_opens_scope(object_type) && | ||
893 | (op->common.aml_opcode != AML_INT_METHODCALL_OP)) { | ||
894 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
895 | "(%s) Popping scope for Op %p\n", | ||
896 | acpi_ut_get_type_name(object_type), op)); | ||
897 | |||
898 | status = acpi_ds_scope_stack_pop(walk_state); | ||
899 | if (ACPI_FAILURE(status)) { | ||
900 | goto cleanup; | ||
901 | } | ||
902 | } | ||
903 | |||
904 | /* | ||
905 | * Named operations are as follows: | ||
906 | * | ||
907 | * AML_ALIAS | ||
908 | * AML_BANKFIELD | ||
909 | * AML_CREATEBITFIELD | ||
910 | * AML_CREATEBYTEFIELD | ||
911 | * AML_CREATEDWORDFIELD | ||
912 | * AML_CREATEFIELD | ||
913 | * AML_CREATEQWORDFIELD | ||
914 | * AML_CREATEWORDFIELD | ||
915 | * AML_DATA_REGION | ||
916 | * AML_DEVICE | ||
917 | * AML_EVENT | ||
918 | * AML_FIELD | ||
919 | * AML_INDEXFIELD | ||
920 | * AML_METHOD | ||
921 | * AML_METHODCALL | ||
922 | * AML_MUTEX | ||
923 | * AML_NAME | ||
924 | * AML_NAMEDFIELD | ||
925 | * AML_OPREGION | ||
926 | * AML_POWERRES | ||
927 | * AML_PROCESSOR | ||
928 | * AML_SCOPE | ||
929 | * AML_THERMALZONE | ||
930 | */ | ||
931 | |||
932 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
933 | "Create-Load [%s] State=%p Op=%p NamedObj=%p\n", | ||
934 | acpi_ps_get_opcode_name(op->common.aml_opcode), | ||
935 | walk_state, op, node)); | ||
936 | |||
937 | /* Decode the opcode */ | ||
938 | |||
939 | arg = op->common.value.arg; | ||
940 | |||
941 | switch (walk_state->op_info->type) { | ||
942 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
943 | |||
944 | case AML_TYPE_CREATE_FIELD: | ||
945 | /* | ||
946 | * Create the field object, but the field buffer and index must | ||
947 | * be evaluated later during the execution phase | ||
948 | */ | ||
949 | status = acpi_ds_create_buffer_field(op, walk_state); | ||
950 | break; | ||
951 | |||
952 | case AML_TYPE_NAMED_FIELD: | ||
953 | /* | ||
954 | * If we are executing a method, initialize the field | ||
955 | */ | ||
956 | if (walk_state->method_node) { | ||
957 | status = acpi_ds_init_field_objects(op, walk_state); | ||
958 | } | ||
959 | |||
960 | switch (op->common.aml_opcode) { | ||
961 | case AML_INDEX_FIELD_OP: | ||
962 | |||
963 | status = | ||
964 | acpi_ds_create_index_field(op, | ||
965 | (acpi_handle) arg-> | ||
966 | common.node, walk_state); | ||
967 | break; | ||
968 | |||
969 | case AML_BANK_FIELD_OP: | ||
970 | |||
971 | status = | ||
972 | acpi_ds_create_bank_field(op, arg->common.node, | ||
973 | walk_state); | ||
974 | break; | ||
975 | |||
976 | case AML_FIELD_OP: | ||
977 | |||
978 | status = | ||
979 | acpi_ds_create_field(op, arg->common.node, | ||
980 | walk_state); | ||
981 | break; | ||
982 | |||
983 | default: | ||
984 | /* All NAMED_FIELD opcodes must be handled above */ | ||
985 | break; | ||
986 | } | ||
987 | break; | ||
988 | |||
989 | case AML_TYPE_NAMED_SIMPLE: | ||
990 | |||
991 | status = acpi_ds_create_operands(walk_state, arg); | ||
992 | if (ACPI_FAILURE(status)) { | ||
993 | goto cleanup; | ||
994 | } | ||
995 | |||
996 | switch (op->common.aml_opcode) { | ||
997 | case AML_PROCESSOR_OP: | ||
998 | |||
999 | status = acpi_ex_create_processor(walk_state); | ||
1000 | break; | ||
1001 | |||
1002 | case AML_POWER_RES_OP: | ||
1003 | |||
1004 | status = acpi_ex_create_power_resource(walk_state); | ||
1005 | break; | ||
1006 | |||
1007 | case AML_MUTEX_OP: | ||
1008 | |||
1009 | status = acpi_ex_create_mutex(walk_state); | ||
1010 | break; | ||
1011 | |||
1012 | case AML_EVENT_OP: | ||
1013 | |||
1014 | status = acpi_ex_create_event(walk_state); | ||
1015 | break; | ||
1016 | |||
1017 | case AML_ALIAS_OP: | ||
1018 | |||
1019 | status = acpi_ex_create_alias(walk_state); | ||
1020 | break; | ||
1021 | |||
1022 | default: | ||
1023 | /* Unknown opcode */ | ||
1024 | |||
1025 | status = AE_OK; | ||
1026 | goto cleanup; | ||
1027 | } | ||
1028 | |||
1029 | /* Delete operands */ | ||
1030 | |||
1031 | for (i = 1; i < walk_state->num_operands; i++) { | ||
1032 | acpi_ut_remove_reference(walk_state->operands[i]); | ||
1033 | walk_state->operands[i] = NULL; | ||
1034 | } | ||
1035 | |||
1036 | break; | ||
1037 | #endif /* ACPI_NO_METHOD_EXECUTION */ | ||
1038 | |||
1039 | case AML_TYPE_NAMED_COMPLEX: | ||
1040 | |||
1041 | switch (op->common.aml_opcode) { | ||
1042 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
1043 | case AML_REGION_OP: | ||
1044 | case AML_DATA_REGION_OP: | ||
1045 | |||
1046 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
1047 | region_space = (acpi_adr_space_type) | ||
1048 | ((op->common.value.arg)->common.value. | ||
1049 | integer); | ||
1050 | } else { | ||
1051 | region_space = REGION_DATA_TABLE; | ||
1052 | } | ||
1053 | |||
1054 | /* | ||
1055 | * The op_region is not fully parsed at this time. The only valid | ||
1056 | * argument is the space_id. (We must save the address of the | ||
1057 | * AML of the address and length operands) | ||
1058 | * | ||
1059 | * If we have a valid region, initialize it. The namespace is | ||
1060 | * unlocked at this point. | ||
1061 | * | ||
1062 | * Need to unlock interpreter if it is locked (if we are running | ||
1063 | * a control method), in order to allow _REG methods to be run | ||
1064 | * during acpi_ev_initialize_region. | ||
1065 | */ | ||
1066 | if (walk_state->method_node) { | ||
1067 | /* | ||
1068 | * Executing a method: initialize the region and unlock | ||
1069 | * the interpreter | ||
1070 | */ | ||
1071 | status = | ||
1072 | acpi_ex_create_region(op->named.data, | ||
1073 | op->named.length, | ||
1074 | region_space, | ||
1075 | walk_state); | ||
1076 | if (ACPI_FAILURE(status)) { | ||
1077 | return (status); | ||
1078 | } | ||
1079 | |||
1080 | acpi_ex_exit_interpreter(); | ||
1081 | } | ||
1082 | |||
1083 | status = | ||
1084 | acpi_ev_initialize_region | ||
1085 | (acpi_ns_get_attached_object(node), FALSE); | ||
1086 | if (walk_state->method_node) { | ||
1087 | acpi_ex_enter_interpreter(); | ||
1088 | } | ||
1089 | |||
1090 | if (ACPI_FAILURE(status)) { | ||
1091 | /* | ||
1092 | * If AE_NOT_EXIST is returned, it is not fatal | ||
1093 | * because many regions get created before a handler | ||
1094 | * is installed for said region. | ||
1095 | */ | ||
1096 | if (AE_NOT_EXIST == status) { | ||
1097 | status = AE_OK; | ||
1098 | } | ||
1099 | } | ||
1100 | break; | ||
1101 | |||
1102 | case AML_NAME_OP: | ||
1103 | |||
1104 | status = acpi_ds_create_node(walk_state, node, op); | ||
1105 | break; | ||
1106 | |||
1107 | case AML_METHOD_OP: | ||
1108 | /* | ||
1109 | * method_op pkg_length name_string method_flags term_list | ||
1110 | * | ||
1111 | * Note: We must create the method node/object pair as soon as we | ||
1112 | * see the method declaration. This allows later pass1 parsing | ||
1113 | * of invocations of the method (need to know the number of | ||
1114 | * arguments.) | ||
1115 | */ | ||
1116 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
1117 | "LOADING-Method: State=%p Op=%p NamedObj=%p\n", | ||
1118 | walk_state, op, op->named.node)); | ||
1119 | |||
1120 | if (!acpi_ns_get_attached_object(op->named.node)) { | ||
1121 | walk_state->operands[0] = | ||
1122 | ACPI_CAST_PTR(void, op->named.node); | ||
1123 | walk_state->num_operands = 1; | ||
1124 | |||
1125 | status = | ||
1126 | acpi_ds_create_operands(walk_state, | ||
1127 | op->common.value. | ||
1128 | arg); | ||
1129 | if (ACPI_SUCCESS(status)) { | ||
1130 | status = | ||
1131 | acpi_ex_create_method(op->named. | ||
1132 | data, | ||
1133 | op->named. | ||
1134 | length, | ||
1135 | walk_state); | ||
1136 | } | ||
1137 | walk_state->operands[0] = NULL; | ||
1138 | walk_state->num_operands = 0; | ||
1139 | |||
1140 | if (ACPI_FAILURE(status)) { | ||
1141 | return_ACPI_STATUS(status); | ||
1142 | } | ||
1143 | } | ||
1144 | break; | ||
1145 | |||
1146 | #endif /* ACPI_NO_METHOD_EXECUTION */ | ||
1147 | |||
1148 | default: | ||
1149 | /* All NAMED_COMPLEX opcodes must be handled above */ | ||
1150 | break; | ||
1151 | } | ||
1152 | break; | ||
1153 | |||
1154 | case AML_CLASS_INTERNAL: | ||
1155 | |||
1156 | /* case AML_INT_NAMEPATH_OP: */ | ||
1157 | break; | ||
1158 | |||
1159 | case AML_CLASS_METHOD_CALL: | ||
1160 | |||
1161 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
1162 | "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n", | ||
1163 | walk_state, op, node)); | ||
1164 | |||
1165 | /* | ||
1166 | * Lookup the method name and save the Node | ||
1167 | */ | ||
1168 | status = | ||
1169 | acpi_ns_lookup(walk_state->scope_info, | ||
1170 | arg->common.value.string, ACPI_TYPE_ANY, | ||
1171 | ACPI_IMODE_LOAD_PASS2, | ||
1172 | ACPI_NS_SEARCH_PARENT | | ||
1173 | ACPI_NS_DONT_OPEN_SCOPE, walk_state, | ||
1174 | &(new_node)); | ||
1175 | if (ACPI_SUCCESS(status)) { | ||
1176 | /* | ||
1177 | * Make sure that what we found is indeed a method | ||
1178 | * We didn't search for a method on purpose, to see if the name | ||
1179 | * would resolve | ||
1180 | */ | ||
1181 | if (new_node->type != ACPI_TYPE_METHOD) { | ||
1182 | status = AE_AML_OPERAND_TYPE; | ||
1183 | } | ||
1184 | |||
1185 | /* We could put the returned object (Node) on the object stack for | ||
1186 | * later, but for now, we will put it in the "op" object that the | ||
1187 | * parser uses, so we can get it again at the end of this scope | ||
1188 | */ | ||
1189 | op->common.node = new_node; | ||
1190 | } else { | ||
1191 | ACPI_ERROR_NAMESPACE(arg->common.value.string, status); | ||
1192 | } | ||
1193 | break; | ||
1194 | |||
1195 | default: | ||
1196 | break; | ||
1197 | } | ||
1198 | |||
1199 | cleanup: | ||
1200 | |||
1201 | /* Remove the Node pushed at the very beginning */ | ||
1202 | |||
1203 | walk_state->operands[0] = NULL; | ||
1204 | walk_state->num_operands = 0; | ||
1205 | return_ACPI_STATUS(status); | ||
1206 | } | ||
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c new file mode 100644 index 00000000000..4be4e921dfe --- /dev/null +++ b/drivers/acpi/acpica/dswload2.c | |||
@@ -0,0 +1,720 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: dswload2 - Dispatcher second pass namespace load callbacks | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2011, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acparser.h" | ||
47 | #include "amlcode.h" | ||
48 | #include "acdispat.h" | ||
49 | #include "acinterp.h" | ||
50 | #include "acnamesp.h" | ||
51 | #include "acevents.h" | ||
52 | |||
53 | #define _COMPONENT ACPI_DISPATCHER | ||
54 | ACPI_MODULE_NAME("dswload2") | ||
55 | |||
56 | /******************************************************************************* | ||
57 | * | ||
58 | * FUNCTION: acpi_ds_load2_begin_op | ||
59 | * | ||
60 | * PARAMETERS: walk_state - Current state of the parse tree walk | ||
61 | * out_op - Wher to return op if a new one is created | ||
62 | * | ||
63 | * RETURN: Status | ||
64 | * | ||
65 | * DESCRIPTION: Descending callback used during the loading of ACPI tables. | ||
66 | * | ||
67 | ******************************************************************************/ | ||
68 | acpi_status | ||
69 | acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | ||
70 | union acpi_parse_object **out_op) | ||
71 | { | ||
72 | union acpi_parse_object *op; | ||
73 | struct acpi_namespace_node *node; | ||
74 | acpi_status status; | ||
75 | acpi_object_type object_type; | ||
76 | char *buffer_ptr; | ||
77 | u32 flags; | ||
78 | |||
79 | ACPI_FUNCTION_TRACE(ds_load2_begin_op); | ||
80 | |||
81 | op = walk_state->op; | ||
82 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, | ||
83 | walk_state)); | ||
84 | |||
85 | if (op) { | ||
86 | if ((walk_state->control_state) && | ||
87 | (walk_state->control_state->common.state == | ||
88 | ACPI_CONTROL_CONDITIONAL_EXECUTING)) { | ||
89 | |||
90 | /* We are executing a while loop outside of a method */ | ||
91 | |||
92 | status = acpi_ds_exec_begin_op(walk_state, out_op); | ||
93 | return_ACPI_STATUS(status); | ||
94 | } | ||
95 | |||
96 | /* We only care about Namespace opcodes here */ | ||
97 | |||
98 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && | ||
99 | (walk_state->opcode != AML_INT_NAMEPATH_OP)) || | ||
100 | (!(walk_state->op_info->flags & AML_NAMED))) { | ||
101 | return_ACPI_STATUS(AE_OK); | ||
102 | } | ||
103 | |||
104 | /* Get the name we are going to enter or lookup in the namespace */ | ||
105 | |||
106 | if (walk_state->opcode == AML_INT_NAMEPATH_OP) { | ||
107 | |||
108 | /* For Namepath op, get the path string */ | ||
109 | |||
110 | buffer_ptr = op->common.value.string; | ||
111 | if (!buffer_ptr) { | ||
112 | |||
113 | /* No name, just exit */ | ||
114 | |||
115 | return_ACPI_STATUS(AE_OK); | ||
116 | } | ||
117 | } else { | ||
118 | /* Get name from the op */ | ||
119 | |||
120 | buffer_ptr = ACPI_CAST_PTR(char, &op->named.name); | ||
121 | } | ||
122 | } else { | ||
123 | /* Get the namestring from the raw AML */ | ||
124 | |||
125 | buffer_ptr = | ||
126 | acpi_ps_get_next_namestring(&walk_state->parser_state); | ||
127 | } | ||
128 | |||
129 | /* Map the opcode into an internal object type */ | ||
130 | |||
131 | object_type = walk_state->op_info->object_type; | ||
132 | |||
133 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
134 | "State=%p Op=%p Type=%X\n", walk_state, op, | ||
135 | object_type)); | ||
136 | |||
137 | switch (walk_state->opcode) { | ||
138 | case AML_FIELD_OP: | ||
139 | case AML_BANK_FIELD_OP: | ||
140 | case AML_INDEX_FIELD_OP: | ||
141 | |||
142 | node = NULL; | ||
143 | status = AE_OK; | ||
144 | break; | ||
145 | |||
146 | case AML_INT_NAMEPATH_OP: | ||
147 | /* | ||
148 | * The name_path is an object reference to an existing object. | ||
149 | * Don't enter the name into the namespace, but look it up | ||
150 | * for use later. | ||
151 | */ | ||
152 | status = | ||
153 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | ||
154 | object_type, ACPI_IMODE_EXECUTE, | ||
155 | ACPI_NS_SEARCH_PARENT, walk_state, &(node)); | ||
156 | break; | ||
157 | |||
158 | case AML_SCOPE_OP: | ||
159 | |||
160 | /* Special case for Scope(\) -> refers to the Root node */ | ||
161 | |||
162 | if (op && (op->named.node == acpi_gbl_root_node)) { | ||
163 | node = op->named.node; | ||
164 | |||
165 | status = | ||
166 | acpi_ds_scope_stack_push(node, object_type, | ||
167 | walk_state); | ||
168 | if (ACPI_FAILURE(status)) { | ||
169 | return_ACPI_STATUS(status); | ||
170 | } | ||
171 | } else { | ||
172 | /* | ||
173 | * The Path is an object reference to an existing object. | ||
174 | * Don't enter the name into the namespace, but look it up | ||
175 | * for use later. | ||
176 | */ | ||
177 | status = | ||
178 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | ||
179 | object_type, ACPI_IMODE_EXECUTE, | ||
180 | ACPI_NS_SEARCH_PARENT, walk_state, | ||
181 | &(node)); | ||
182 | if (ACPI_FAILURE(status)) { | ||
183 | #ifdef ACPI_ASL_COMPILER | ||
184 | if (status == AE_NOT_FOUND) { | ||
185 | status = AE_OK; | ||
186 | } else { | ||
187 | ACPI_ERROR_NAMESPACE(buffer_ptr, | ||
188 | status); | ||
189 | } | ||
190 | #else | ||
191 | ACPI_ERROR_NAMESPACE(buffer_ptr, status); | ||
192 | #endif | ||
193 | return_ACPI_STATUS(status); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * We must check to make sure that the target is | ||
199 | * one of the opcodes that actually opens a scope | ||
200 | */ | ||
201 | switch (node->type) { | ||
202 | case ACPI_TYPE_ANY: | ||
203 | case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ | ||
204 | case ACPI_TYPE_DEVICE: | ||
205 | case ACPI_TYPE_POWER: | ||
206 | case ACPI_TYPE_PROCESSOR: | ||
207 | case ACPI_TYPE_THERMAL: | ||
208 | |||
209 | /* These are acceptable types */ | ||
210 | break; | ||
211 | |||
212 | case ACPI_TYPE_INTEGER: | ||
213 | case ACPI_TYPE_STRING: | ||
214 | case ACPI_TYPE_BUFFER: | ||
215 | |||
216 | /* | ||
217 | * These types we will allow, but we will change the type. | ||
218 | * This enables some existing code of the form: | ||
219 | * | ||
220 | * Name (DEB, 0) | ||
221 | * Scope (DEB) { ... } | ||
222 | */ | ||
223 | ACPI_WARNING((AE_INFO, | ||
224 | "Type override - [%4.4s] had invalid type (%s) " | ||
225 | "for Scope operator, changed to type ANY\n", | ||
226 | acpi_ut_get_node_name(node), | ||
227 | acpi_ut_get_type_name(node->type))); | ||
228 | |||
229 | node->type = ACPI_TYPE_ANY; | ||
230 | walk_state->scope_info->common.value = ACPI_TYPE_ANY; | ||
231 | break; | ||
232 | |||
233 | default: | ||
234 | |||
235 | /* All other types are an error */ | ||
236 | |||
237 | ACPI_ERROR((AE_INFO, | ||
238 | "Invalid type (%s) for target of " | ||
239 | "Scope operator [%4.4s] (Cannot override)", | ||
240 | acpi_ut_get_type_name(node->type), | ||
241 | acpi_ut_get_node_name(node))); | ||
242 | |||
243 | return (AE_AML_OPERAND_TYPE); | ||
244 | } | ||
245 | break; | ||
246 | |||
247 | default: | ||
248 | |||
249 | /* All other opcodes */ | ||
250 | |||
251 | if (op && op->common.node) { | ||
252 | |||
253 | /* This op/node was previously entered into the namespace */ | ||
254 | |||
255 | node = op->common.node; | ||
256 | |||
257 | if (acpi_ns_opens_scope(object_type)) { | ||
258 | status = | ||
259 | acpi_ds_scope_stack_push(node, object_type, | ||
260 | walk_state); | ||
261 | if (ACPI_FAILURE(status)) { | ||
262 | return_ACPI_STATUS(status); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | return_ACPI_STATUS(AE_OK); | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * Enter the named type into the internal namespace. We enter the name | ||
271 | * as we go downward in the parse tree. Any necessary subobjects that | ||
272 | * involve arguments to the opcode must be created as we go back up the | ||
273 | * parse tree later. | ||
274 | * | ||
275 | * Note: Name may already exist if we are executing a deferred opcode. | ||
276 | */ | ||
277 | if (walk_state->deferred_node) { | ||
278 | |||
279 | /* This name is already in the namespace, get the node */ | ||
280 | |||
281 | node = walk_state->deferred_node; | ||
282 | status = AE_OK; | ||
283 | break; | ||
284 | } | ||
285 | |||
286 | flags = ACPI_NS_NO_UPSEARCH; | ||
287 | if (walk_state->pass_number == ACPI_IMODE_EXECUTE) { | ||
288 | |||
289 | /* Execution mode, node cannot already exist, node is temporary */ | ||
290 | |||
291 | flags |= ACPI_NS_ERROR_IF_FOUND; | ||
292 | |||
293 | if (! | ||
294 | (walk_state-> | ||
295 | parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
296 | flags |= ACPI_NS_TEMPORARY; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | /* Add new entry or lookup existing entry */ | ||
301 | |||
302 | status = | ||
303 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | ||
304 | object_type, ACPI_IMODE_LOAD_PASS2, flags, | ||
305 | walk_state, &node); | ||
306 | |||
307 | if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) { | ||
308 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
309 | "***New Node [%4.4s] %p is temporary\n", | ||
310 | acpi_ut_get_node_name(node), node)); | ||
311 | } | ||
312 | break; | ||
313 | } | ||
314 | |||
315 | if (ACPI_FAILURE(status)) { | ||
316 | ACPI_ERROR_NAMESPACE(buffer_ptr, status); | ||
317 | return_ACPI_STATUS(status); | ||
318 | } | ||
319 | |||
320 | if (!op) { | ||
321 | |||
322 | /* Create a new op */ | ||
323 | |||
324 | op = acpi_ps_alloc_op(walk_state->opcode); | ||
325 | if (!op) { | ||
326 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
327 | } | ||
328 | |||
329 | /* Initialize the new op */ | ||
330 | |||
331 | if (node) { | ||
332 | op->named.name = node->name.integer; | ||
333 | } | ||
334 | *out_op = op; | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * Put the Node in the "op" object that the parser uses, so we | ||
339 | * can get it again quickly when this scope is closed | ||
340 | */ | ||
341 | op->common.node = node; | ||
342 | return_ACPI_STATUS(status); | ||
343 | } | ||
344 | |||
345 | /******************************************************************************* | ||
346 | * | ||
347 | * FUNCTION: acpi_ds_load2_end_op | ||
348 | * | ||
349 | * PARAMETERS: walk_state - Current state of the parse tree walk | ||
350 | * | ||
351 | * RETURN: Status | ||
352 | * | ||
353 | * DESCRIPTION: Ascending callback used during the loading of the namespace, | ||
354 | * both control methods and everything else. | ||
355 | * | ||
356 | ******************************************************************************/ | ||
357 | |||
358 | acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | ||
359 | { | ||
360 | union acpi_parse_object *op; | ||
361 | acpi_status status = AE_OK; | ||
362 | acpi_object_type object_type; | ||
363 | struct acpi_namespace_node *node; | ||
364 | union acpi_parse_object *arg; | ||
365 | struct acpi_namespace_node *new_node; | ||
366 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
367 | u32 i; | ||
368 | u8 region_space; | ||
369 | #endif | ||
370 | |||
371 | ACPI_FUNCTION_TRACE(ds_load2_end_op); | ||
372 | |||
373 | op = walk_state->op; | ||
374 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", | ||
375 | walk_state->op_info->name, op, walk_state)); | ||
376 | |||
377 | /* Check if opcode had an associated namespace object */ | ||
378 | |||
379 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { | ||
380 | return_ACPI_STATUS(AE_OK); | ||
381 | } | ||
382 | |||
383 | if (op->common.aml_opcode == AML_SCOPE_OP) { | ||
384 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
385 | "Ending scope Op=%p State=%p\n", op, | ||
386 | walk_state)); | ||
387 | } | ||
388 | |||
389 | object_type = walk_state->op_info->object_type; | ||
390 | |||
391 | /* | ||
392 | * Get the Node/name from the earlier lookup | ||
393 | * (It was saved in the *op structure) | ||
394 | */ | ||
395 | node = op->common.node; | ||
396 | |||
397 | /* | ||
398 | * Put the Node on the object stack (Contains the ACPI Name of | ||
399 | * this object) | ||
400 | */ | ||
401 | walk_state->operands[0] = (void *)node; | ||
402 | walk_state->num_operands = 1; | ||
403 | |||
404 | /* Pop the scope stack */ | ||
405 | |||
406 | if (acpi_ns_opens_scope(object_type) && | ||
407 | (op->common.aml_opcode != AML_INT_METHODCALL_OP)) { | ||
408 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
409 | "(%s) Popping scope for Op %p\n", | ||
410 | acpi_ut_get_type_name(object_type), op)); | ||
411 | |||
412 | status = acpi_ds_scope_stack_pop(walk_state); | ||
413 | if (ACPI_FAILURE(status)) { | ||
414 | goto cleanup; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * Named operations are as follows: | ||
420 | * | ||
421 | * AML_ALIAS | ||
422 | * AML_BANKFIELD | ||
423 | * AML_CREATEBITFIELD | ||
424 | * AML_CREATEBYTEFIELD | ||
425 | * AML_CREATEDWORDFIELD | ||
426 | * AML_CREATEFIELD | ||
427 | * AML_CREATEQWORDFIELD | ||
428 | * AML_CREATEWORDFIELD | ||
429 | * AML_DATA_REGION | ||
430 | * AML_DEVICE | ||
431 | * AML_EVENT | ||
432 | * AML_FIELD | ||
433 | * AML_INDEXFIELD | ||
434 | * AML_METHOD | ||
435 | * AML_METHODCALL | ||
436 | * AML_MUTEX | ||
437 | * AML_NAME | ||
438 | * AML_NAMEDFIELD | ||
439 | * AML_OPREGION | ||
440 | * AML_POWERRES | ||
441 | * AML_PROCESSOR | ||
442 | * AML_SCOPE | ||
443 | * AML_THERMALZONE | ||
444 | */ | ||
445 | |||
446 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
447 | "Create-Load [%s] State=%p Op=%p NamedObj=%p\n", | ||
448 | acpi_ps_get_opcode_name(op->common.aml_opcode), | ||
449 | walk_state, op, node)); | ||
450 | |||
451 | /* Decode the opcode */ | ||
452 | |||
453 | arg = op->common.value.arg; | ||
454 | |||
455 | switch (walk_state->op_info->type) { | ||
456 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
457 | |||
458 | case AML_TYPE_CREATE_FIELD: | ||
459 | /* | ||
460 | * Create the field object, but the field buffer and index must | ||
461 | * be evaluated later during the execution phase | ||
462 | */ | ||
463 | status = acpi_ds_create_buffer_field(op, walk_state); | ||
464 | break; | ||
465 | |||
466 | case AML_TYPE_NAMED_FIELD: | ||
467 | /* | ||
468 | * If we are executing a method, initialize the field | ||
469 | */ | ||
470 | if (walk_state->method_node) { | ||
471 | status = acpi_ds_init_field_objects(op, walk_state); | ||
472 | } | ||
473 | |||
474 | switch (op->common.aml_opcode) { | ||
475 | case AML_INDEX_FIELD_OP: | ||
476 | |||
477 | status = | ||
478 | acpi_ds_create_index_field(op, | ||
479 | (acpi_handle) arg-> | ||
480 | common.node, walk_state); | ||
481 | break; | ||
482 | |||
483 | case AML_BANK_FIELD_OP: | ||
484 | |||
485 | status = | ||
486 | acpi_ds_create_bank_field(op, arg->common.node, | ||
487 | walk_state); | ||
488 | break; | ||
489 | |||
490 | case AML_FIELD_OP: | ||
491 | |||
492 | status = | ||
493 | acpi_ds_create_field(op, arg->common.node, | ||
494 | walk_state); | ||
495 | break; | ||
496 | |||
497 | default: | ||
498 | /* All NAMED_FIELD opcodes must be handled above */ | ||
499 | break; | ||
500 | } | ||
501 | break; | ||
502 | |||
503 | case AML_TYPE_NAMED_SIMPLE: | ||
504 | |||
505 | status = acpi_ds_create_operands(walk_state, arg); | ||
506 | if (ACPI_FAILURE(status)) { | ||
507 | goto cleanup; | ||
508 | } | ||
509 | |||
510 | switch (op->common.aml_opcode) { | ||
511 | case AML_PROCESSOR_OP: | ||
512 | |||
513 | status = acpi_ex_create_processor(walk_state); | ||
514 | break; | ||
515 | |||
516 | case AML_POWER_RES_OP: | ||
517 | |||
518 | status = acpi_ex_create_power_resource(walk_state); | ||
519 | break; | ||
520 | |||
521 | case AML_MUTEX_OP: | ||
522 | |||
523 | status = acpi_ex_create_mutex(walk_state); | ||
524 | break; | ||
525 | |||
526 | case AML_EVENT_OP: | ||
527 | |||
528 | status = acpi_ex_create_event(walk_state); | ||
529 | break; | ||
530 | |||
531 | case AML_ALIAS_OP: | ||
532 | |||
533 | status = acpi_ex_create_alias(walk_state); | ||
534 | break; | ||
535 | |||
536 | default: | ||
537 | /* Unknown opcode */ | ||
538 | |||
539 | status = AE_OK; | ||
540 | goto cleanup; | ||
541 | } | ||
542 | |||
543 | /* Delete operands */ | ||
544 | |||
545 | for (i = 1; i < walk_state->num_operands; i++) { | ||
546 | acpi_ut_remove_reference(walk_state->operands[i]); | ||
547 | walk_state->operands[i] = NULL; | ||
548 | } | ||
549 | |||
550 | break; | ||
551 | #endif /* ACPI_NO_METHOD_EXECUTION */ | ||
552 | |||
553 | case AML_TYPE_NAMED_COMPLEX: | ||
554 | |||
555 | switch (op->common.aml_opcode) { | ||
556 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
557 | case AML_REGION_OP: | ||
558 | case AML_DATA_REGION_OP: | ||
559 | |||
560 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
561 | region_space = (acpi_adr_space_type) | ||
562 | ((op->common.value.arg)->common.value. | ||
563 | integer); | ||
564 | } else { | ||
565 | region_space = REGION_DATA_TABLE; | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | * The op_region is not fully parsed at this time. The only valid | ||
570 | * argument is the space_id. (We must save the address of the | ||
571 | * AML of the address and length operands) | ||
572 | * | ||
573 | * If we have a valid region, initialize it. The namespace is | ||
574 | * unlocked at this point. | ||
575 | * | ||
576 | * Need to unlock interpreter if it is locked (if we are running | ||
577 | * a control method), in order to allow _REG methods to be run | ||
578 | * during acpi_ev_initialize_region. | ||
579 | */ | ||
580 | if (walk_state->method_node) { | ||
581 | /* | ||
582 | * Executing a method: initialize the region and unlock | ||
583 | * the interpreter | ||
584 | */ | ||
585 | status = | ||
586 | acpi_ex_create_region(op->named.data, | ||
587 | op->named.length, | ||
588 | region_space, | ||
589 | walk_state); | ||
590 | if (ACPI_FAILURE(status)) { | ||
591 | return (status); | ||
592 | } | ||
593 | |||
594 | acpi_ex_exit_interpreter(); | ||
595 | } | ||
596 | |||
597 | status = | ||
598 | acpi_ev_initialize_region | ||
599 | (acpi_ns_get_attached_object(node), FALSE); | ||
600 | if (walk_state->method_node) { | ||
601 | acpi_ex_enter_interpreter(); | ||
602 | } | ||
603 | |||
604 | if (ACPI_FAILURE(status)) { | ||
605 | /* | ||
606 | * If AE_NOT_EXIST is returned, it is not fatal | ||
607 | * because many regions get created before a handler | ||
608 | * is installed for said region. | ||
609 | */ | ||
610 | if (AE_NOT_EXIST == status) { | ||
611 | status = AE_OK; | ||
612 | } | ||
613 | } | ||
614 | break; | ||
615 | |||
616 | case AML_NAME_OP: | ||
617 | |||
618 | status = acpi_ds_create_node(walk_state, node, op); | ||
619 | break; | ||
620 | |||
621 | case AML_METHOD_OP: | ||
622 | /* | ||
623 | * method_op pkg_length name_string method_flags term_list | ||
624 | * | ||
625 | * Note: We must create the method node/object pair as soon as we | ||
626 | * see the method declaration. This allows later pass1 parsing | ||
627 | * of invocations of the method (need to know the number of | ||
628 | * arguments.) | ||
629 | */ | ||
630 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
631 | "LOADING-Method: State=%p Op=%p NamedObj=%p\n", | ||
632 | walk_state, op, op->named.node)); | ||
633 | |||
634 | if (!acpi_ns_get_attached_object(op->named.node)) { | ||
635 | walk_state->operands[0] = | ||
636 | ACPI_CAST_PTR(void, op->named.node); | ||
637 | walk_state->num_operands = 1; | ||
638 | |||
639 | status = | ||
640 | acpi_ds_create_operands(walk_state, | ||
641 | op->common.value. | ||
642 | arg); | ||
643 | if (ACPI_SUCCESS(status)) { | ||
644 | status = | ||
645 | acpi_ex_create_method(op->named. | ||
646 | data, | ||
647 | op->named. | ||
648 | length, | ||
649 | walk_state); | ||
650 | } | ||
651 | walk_state->operands[0] = NULL; | ||
652 | walk_state->num_operands = 0; | ||
653 | |||
654 | if (ACPI_FAILURE(status)) { | ||
655 | return_ACPI_STATUS(status); | ||
656 | } | ||
657 | } | ||
658 | break; | ||
659 | |||
660 | #endif /* ACPI_NO_METHOD_EXECUTION */ | ||
661 | |||
662 | default: | ||
663 | /* All NAMED_COMPLEX opcodes must be handled above */ | ||
664 | break; | ||
665 | } | ||
666 | break; | ||
667 | |||
668 | case AML_CLASS_INTERNAL: | ||
669 | |||
670 | /* case AML_INT_NAMEPATH_OP: */ | ||
671 | break; | ||
672 | |||
673 | case AML_CLASS_METHOD_CALL: | ||
674 | |||
675 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
676 | "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n", | ||
677 | walk_state, op, node)); | ||
678 | |||
679 | /* | ||
680 | * Lookup the method name and save the Node | ||
681 | */ | ||
682 | status = | ||
683 | acpi_ns_lookup(walk_state->scope_info, | ||
684 | arg->common.value.string, ACPI_TYPE_ANY, | ||
685 | ACPI_IMODE_LOAD_PASS2, | ||
686 | ACPI_NS_SEARCH_PARENT | | ||
687 | ACPI_NS_DONT_OPEN_SCOPE, walk_state, | ||
688 | &(new_node)); | ||
689 | if (ACPI_SUCCESS(status)) { | ||
690 | /* | ||
691 | * Make sure that what we found is indeed a method | ||
692 | * We didn't search for a method on purpose, to see if the name | ||
693 | * would resolve | ||
694 | */ | ||
695 | if (new_node->type != ACPI_TYPE_METHOD) { | ||
696 | status = AE_AML_OPERAND_TYPE; | ||
697 | } | ||
698 | |||
699 | /* We could put the returned object (Node) on the object stack for | ||
700 | * later, but for now, we will put it in the "op" object that the | ||
701 | * parser uses, so we can get it again at the end of this scope | ||
702 | */ | ||
703 | op->common.node = new_node; | ||
704 | } else { | ||
705 | ACPI_ERROR_NAMESPACE(arg->common.value.string, status); | ||
706 | } | ||
707 | break; | ||
708 | |||
709 | default: | ||
710 | break; | ||
711 | } | ||
712 | |||
713 | cleanup: | ||
714 | |||
715 | /* Remove the Node pushed at the very beginning */ | ||
716 | |||
717 | walk_state->operands[0] = NULL; | ||
718 | walk_state->num_operands = 0; | ||
719 | return_ACPI_STATUS(status); | ||
720 | } | ||
diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index d1e701709da..76a661fc1e0 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 83155dd8671..a6c374ef991 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index c61c3039c31..d458b041e65 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -217,9 +217,17 @@ u32 acpi_ev_fixed_event_detect(void) | |||
217 | status_bit_mask) | 217 | status_bit_mask) |
218 | && (fixed_enable & acpi_gbl_fixed_event_info[i]. | 218 | && (fixed_enable & acpi_gbl_fixed_event_info[i]. |
219 | enable_bit_mask)) { | 219 | enable_bit_mask)) { |
220 | /* | ||
221 | * Found an active (signalled) event. Invoke global event | ||
222 | * handler if present. | ||
223 | */ | ||
224 | acpi_fixed_event_count[i]++; | ||
225 | if (acpi_gbl_global_event_handler) { | ||
226 | acpi_gbl_global_event_handler | ||
227 | (ACPI_EVENT_TYPE_FIXED, NULL, i, | ||
228 | acpi_gbl_global_event_handler_context); | ||
229 | } | ||
220 | 230 | ||
221 | /* Found an active (signalled) event */ | ||
222 | acpi_os_fixed_event_count(i); | ||
223 | int_status |= acpi_ev_fixed_event_dispatch(i); | 231 | int_status |= acpi_ev_fixed_event_dispatch(i); |
224 | } | 232 | } |
225 | } | 233 | } |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index f226eac314d..65c79add3b1 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("evgpe") | |||
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); | 53 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); |
54 | 54 | ||
55 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context); | ||
56 | |||
55 | /******************************************************************************* | 57 | /******************************************************************************* |
56 | * | 58 | * |
57 | * FUNCTION: acpi_ev_update_gpe_enable_mask | 59 | * FUNCTION: acpi_ev_update_gpe_enable_mask |
@@ -102,7 +104,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) | |||
102 | * | 104 | * |
103 | * RETURN: Status | 105 | * RETURN: Status |
104 | * | 106 | * |
105 | * DESCRIPTION: Clear the given GPE from stale events and enable it. | 107 | * DESCRIPTION: Clear a GPE of stale events and enable it. |
106 | * | 108 | * |
107 | ******************************************************************************/ | 109 | ******************************************************************************/ |
108 | acpi_status | 110 | acpi_status |
@@ -113,12 +115,13 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
113 | ACPI_FUNCTION_TRACE(ev_enable_gpe); | 115 | ACPI_FUNCTION_TRACE(ev_enable_gpe); |
114 | 116 | ||
115 | /* | 117 | /* |
116 | * We will only allow a GPE to be enabled if it has either an | 118 | * We will only allow a GPE to be enabled if it has either an associated |
117 | * associated method (_Lxx/_Exx) or a handler. Otherwise, the | 119 | * method (_Lxx/_Exx) or a handler, or is using the implicit notify |
118 | * GPE will be immediately disabled by acpi_ev_gpe_dispatch the | 120 | * feature. Otherwise, the GPE will be immediately disabled by |
119 | * first time it fires. | 121 | * acpi_ev_gpe_dispatch the first time it fires. |
120 | */ | 122 | */ |
121 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { | 123 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == |
124 | ACPI_GPE_DISPATCH_NONE) { | ||
122 | return_ACPI_STATUS(AE_NO_HANDLER); | 125 | return_ACPI_STATUS(AE_NO_HANDLER); |
123 | } | 126 | } |
124 | 127 | ||
@@ -137,9 +140,9 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
137 | 140 | ||
138 | /******************************************************************************* | 141 | /******************************************************************************* |
139 | * | 142 | * |
140 | * FUNCTION: acpi_raw_enable_gpe | 143 | * FUNCTION: acpi_ev_add_gpe_reference |
141 | * | 144 | * |
142 | * PARAMETERS: gpe_event_info - GPE to enable | 145 | * PARAMETERS: gpe_event_info - Add a reference to this GPE |
143 | * | 146 | * |
144 | * RETURN: Status | 147 | * RETURN: Status |
145 | * | 148 | * |
@@ -148,16 +151,21 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
148 | * | 151 | * |
149 | ******************************************************************************/ | 152 | ******************************************************************************/ |
150 | 153 | ||
151 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | 154 | acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) |
152 | { | 155 | { |
153 | acpi_status status = AE_OK; | 156 | acpi_status status = AE_OK; |
154 | 157 | ||
158 | ACPI_FUNCTION_TRACE(ev_add_gpe_reference); | ||
159 | |||
155 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { | 160 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { |
156 | return_ACPI_STATUS(AE_LIMIT); | 161 | return_ACPI_STATUS(AE_LIMIT); |
157 | } | 162 | } |
158 | 163 | ||
159 | gpe_event_info->runtime_count++; | 164 | gpe_event_info->runtime_count++; |
160 | if (gpe_event_info->runtime_count == 1) { | 165 | if (gpe_event_info->runtime_count == 1) { |
166 | |||
167 | /* Enable on first reference */ | ||
168 | |||
161 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | 169 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); |
162 | if (ACPI_SUCCESS(status)) { | 170 | if (ACPI_SUCCESS(status)) { |
163 | status = acpi_ev_enable_gpe(gpe_event_info); | 171 | status = acpi_ev_enable_gpe(gpe_event_info); |
@@ -173,9 +181,9 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
173 | 181 | ||
174 | /******************************************************************************* | 182 | /******************************************************************************* |
175 | * | 183 | * |
176 | * FUNCTION: acpi_raw_disable_gpe | 184 | * FUNCTION: acpi_ev_remove_gpe_reference |
177 | * | 185 | * |
178 | * PARAMETERS: gpe_event_info - GPE to disable | 186 | * PARAMETERS: gpe_event_info - Remove a reference to this GPE |
179 | * | 187 | * |
180 | * RETURN: Status | 188 | * RETURN: Status |
181 | * | 189 | * |
@@ -184,16 +192,21 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
184 | * | 192 | * |
185 | ******************************************************************************/ | 193 | ******************************************************************************/ |
186 | 194 | ||
187 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | 195 | acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) |
188 | { | 196 | { |
189 | acpi_status status = AE_OK; | 197 | acpi_status status = AE_OK; |
190 | 198 | ||
199 | ACPI_FUNCTION_TRACE(ev_remove_gpe_reference); | ||
200 | |||
191 | if (!gpe_event_info->runtime_count) { | 201 | if (!gpe_event_info->runtime_count) { |
192 | return_ACPI_STATUS(AE_LIMIT); | 202 | return_ACPI_STATUS(AE_LIMIT); |
193 | } | 203 | } |
194 | 204 | ||
195 | gpe_event_info->runtime_count--; | 205 | gpe_event_info->runtime_count--; |
196 | if (!gpe_event_info->runtime_count) { | 206 | if (!gpe_event_info->runtime_count) { |
207 | |||
208 | /* Disable on last reference */ | ||
209 | |||
197 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | 210 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); |
198 | if (ACPI_SUCCESS(status)) { | 211 | if (ACPI_SUCCESS(status)) { |
199 | status = acpi_hw_low_set_gpe(gpe_event_info, | 212 | status = acpi_hw_low_set_gpe(gpe_event_info, |
@@ -360,6 +373,15 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
360 | 373 | ||
361 | gpe_register_info = &gpe_block->register_info[i]; | 374 | gpe_register_info = &gpe_block->register_info[i]; |
362 | 375 | ||
376 | /* | ||
377 | * Optimization: If there are no GPEs enabled within this | ||
378 | * register, we can safely ignore the entire register. | ||
379 | */ | ||
380 | if (!(gpe_register_info->enable_for_run | | ||
381 | gpe_register_info->enable_for_wake)) { | ||
382 | continue; | ||
383 | } | ||
384 | |||
363 | /* Read the Status Register */ | 385 | /* Read the Status Register */ |
364 | 386 | ||
365 | status = | 387 | status = |
@@ -379,7 +401,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
379 | } | 401 | } |
380 | 402 | ||
381 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | 403 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, |
382 | "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", | 404 | "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n", |
383 | gpe_register_info->base_gpe_number, | 405 | gpe_register_info->base_gpe_number, |
384 | status_reg, enable_reg)); | 406 | status_reg, enable_reg)); |
385 | 407 | ||
@@ -405,7 +427,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
405 | * or method. | 427 | * or method. |
406 | */ | 428 | */ |
407 | int_status |= | 429 | int_status |= |
408 | acpi_ev_gpe_dispatch(&gpe_block-> | 430 | acpi_ev_gpe_dispatch(gpe_block-> |
431 | node, | ||
432 | &gpe_block-> | ||
409 | event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); | 433 | event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); |
410 | } | 434 | } |
411 | } | 435 | } |
@@ -435,19 +459,29 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
435 | * an interrupt handler. | 459 | * an interrupt handler. |
436 | * | 460 | * |
437 | ******************************************************************************/ | 461 | ******************************************************************************/ |
438 | static void acpi_ev_asynch_enable_gpe(void *context); | ||
439 | 462 | ||
440 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | 463 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) |
441 | { | 464 | { |
442 | struct acpi_gpe_event_info *gpe_event_info = (void *)context; | 465 | struct acpi_gpe_event_info *gpe_event_info = context; |
443 | acpi_status status; | 466 | acpi_status status; |
444 | struct acpi_gpe_event_info local_gpe_event_info; | 467 | struct acpi_gpe_event_info *local_gpe_event_info; |
445 | struct acpi_evaluate_info *info; | 468 | struct acpi_evaluate_info *info; |
469 | struct acpi_gpe_notify_object *notify_object; | ||
446 | 470 | ||
447 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); | 471 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); |
448 | 472 | ||
473 | /* Allocate a local GPE block */ | ||
474 | |||
475 | local_gpe_event_info = | ||
476 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info)); | ||
477 | if (!local_gpe_event_info) { | ||
478 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE")); | ||
479 | return_VOID; | ||
480 | } | ||
481 | |||
449 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | 482 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
450 | if (ACPI_FAILURE(status)) { | 483 | if (ACPI_FAILURE(status)) { |
484 | ACPI_FREE(local_gpe_event_info); | ||
451 | return_VOID; | 485 | return_VOID; |
452 | } | 486 | } |
453 | 487 | ||
@@ -455,6 +489,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
455 | 489 | ||
456 | if (!acpi_ev_valid_gpe_event(gpe_event_info)) { | 490 | if (!acpi_ev_valid_gpe_event(gpe_event_info)) { |
457 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 491 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
492 | ACPI_FREE(local_gpe_event_info); | ||
458 | return_VOID; | 493 | return_VOID; |
459 | } | 494 | } |
460 | 495 | ||
@@ -462,7 +497,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
462 | * Take a snapshot of the GPE info for this level - we copy the info to | 497 | * Take a snapshot of the GPE info for this level - we copy the info to |
463 | * prevent a race condition with remove_handler/remove_block. | 498 | * prevent a race condition with remove_handler/remove_block. |
464 | */ | 499 | */ |
465 | ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info, | 500 | ACPI_MEMCPY(local_gpe_event_info, gpe_event_info, |
466 | sizeof(struct acpi_gpe_event_info)); | 501 | sizeof(struct acpi_gpe_event_info)); |
467 | 502 | ||
468 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 503 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
@@ -470,12 +505,34 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
470 | return_VOID; | 505 | return_VOID; |
471 | } | 506 | } |
472 | 507 | ||
473 | /* | 508 | /* Do the correct dispatch - normal method or implicit notify */ |
474 | * Must check for control method type dispatch one more time to avoid a | 509 | |
475 | * race with ev_gpe_install_handler | 510 | switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { |
476 | */ | 511 | case ACPI_GPE_DISPATCH_NOTIFY: |
477 | if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == | 512 | |
478 | ACPI_GPE_DISPATCH_METHOD) { | 513 | /* |
514 | * Implicit notify. | ||
515 | * Dispatch a DEVICE_WAKE notify to the appropriate handler. | ||
516 | * NOTE: the request is queued for execution after this method | ||
517 | * completes. The notify handlers are NOT invoked synchronously | ||
518 | * from this thread -- because handlers may in turn run other | ||
519 | * control methods. | ||
520 | */ | ||
521 | status = acpi_ev_queue_notify_request( | ||
522 | local_gpe_event_info->dispatch.device.node, | ||
523 | ACPI_NOTIFY_DEVICE_WAKE); | ||
524 | |||
525 | notify_object = local_gpe_event_info->dispatch.device.next; | ||
526 | while (ACPI_SUCCESS(status) && notify_object) { | ||
527 | status = acpi_ev_queue_notify_request( | ||
528 | notify_object->node, | ||
529 | ACPI_NOTIFY_DEVICE_WAKE); | ||
530 | notify_object = notify_object->next; | ||
531 | } | ||
532 | |||
533 | break; | ||
534 | |||
535 | case ACPI_GPE_DISPATCH_METHOD: | ||
479 | 536 | ||
480 | /* Allocate the evaluation information block */ | 537 | /* Allocate the evaluation information block */ |
481 | 538 | ||
@@ -488,7 +545,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
488 | * control method that corresponds to this GPE | 545 | * control method that corresponds to this GPE |
489 | */ | 546 | */ |
490 | info->prefix_node = | 547 | info->prefix_node = |
491 | local_gpe_event_info.dispatch.method_node; | 548 | local_gpe_event_info->dispatch.method_node; |
492 | info->flags = ACPI_IGNORE_RETURN_VALUE; | 549 | info->flags = ACPI_IGNORE_RETURN_VALUE; |
493 | 550 | ||
494 | status = acpi_ns_evaluate(info); | 551 | status = acpi_ns_evaluate(info); |
@@ -499,46 +556,98 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
499 | ACPI_EXCEPTION((AE_INFO, status, | 556 | ACPI_EXCEPTION((AE_INFO, status, |
500 | "while evaluating GPE method [%4.4s]", | 557 | "while evaluating GPE method [%4.4s]", |
501 | acpi_ut_get_node_name | 558 | acpi_ut_get_node_name |
502 | (local_gpe_event_info.dispatch. | 559 | (local_gpe_event_info->dispatch. |
503 | method_node))); | 560 | method_node))); |
504 | } | 561 | } |
562 | |||
563 | break; | ||
564 | |||
565 | default: | ||
566 | return_VOID; /* Should never happen */ | ||
505 | } | 567 | } |
568 | |||
506 | /* Defer enabling of GPE until all notify handlers are done */ | 569 | /* Defer enabling of GPE until all notify handlers are done */ |
507 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe, | 570 | |
508 | gpe_event_info); | 571 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, |
572 | acpi_ev_asynch_enable_gpe, | ||
573 | local_gpe_event_info); | ||
574 | if (ACPI_FAILURE(status)) { | ||
575 | ACPI_FREE(local_gpe_event_info); | ||
576 | } | ||
509 | return_VOID; | 577 | return_VOID; |
510 | } | 578 | } |
511 | 579 | ||
512 | static void acpi_ev_asynch_enable_gpe(void *context) | 580 | |
581 | /******************************************************************************* | ||
582 | * | ||
583 | * FUNCTION: acpi_ev_asynch_enable_gpe | ||
584 | * | ||
585 | * PARAMETERS: Context (gpe_event_info) - Info for this GPE | ||
586 | * Callback from acpi_os_execute | ||
587 | * | ||
588 | * RETURN: None | ||
589 | * | ||
590 | * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to | ||
591 | * complete (i.e., finish execution of Notify) | ||
592 | * | ||
593 | ******************************************************************************/ | ||
594 | |||
595 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context) | ||
513 | { | 596 | { |
514 | struct acpi_gpe_event_info *gpe_event_info = context; | 597 | struct acpi_gpe_event_info *gpe_event_info = context; |
598 | |||
599 | (void)acpi_ev_finish_gpe(gpe_event_info); | ||
600 | |||
601 | ACPI_FREE(gpe_event_info); | ||
602 | return; | ||
603 | } | ||
604 | |||
605 | |||
606 | /******************************************************************************* | ||
607 | * | ||
608 | * FUNCTION: acpi_ev_finish_gpe | ||
609 | * | ||
610 | * PARAMETERS: gpe_event_info - Info for this GPE | ||
611 | * | ||
612 | * RETURN: Status | ||
613 | * | ||
614 | * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution | ||
615 | * of a GPE method or a synchronous or asynchronous GPE handler. | ||
616 | * | ||
617 | ******************************************************************************/ | ||
618 | |||
619 | acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
620 | { | ||
515 | acpi_status status; | 621 | acpi_status status; |
622 | |||
516 | if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == | 623 | if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == |
517 | ACPI_GPE_LEVEL_TRIGGERED) { | 624 | ACPI_GPE_LEVEL_TRIGGERED) { |
518 | /* | 625 | /* |
519 | * GPE is level-triggered, we clear the GPE status bit after handling | 626 | * GPE is level-triggered, we clear the GPE status bit after |
520 | * the event. | 627 | * handling the event. |
521 | */ | 628 | */ |
522 | status = acpi_hw_clear_gpe(gpe_event_info); | 629 | status = acpi_hw_clear_gpe(gpe_event_info); |
523 | if (ACPI_FAILURE(status)) { | 630 | if (ACPI_FAILURE(status)) { |
524 | return_VOID; | 631 | return (status); |
525 | } | 632 | } |
526 | } | 633 | } |
527 | 634 | ||
528 | /* | 635 | /* |
529 | * Enable this GPE, conditionally. This means that the GPE will only be | 636 | * Enable this GPE, conditionally. This means that the GPE will |
530 | * physically enabled if the enable_for_run bit is set in the event_info | 637 | * only be physically enabled if the enable_for_run bit is set |
638 | * in the event_info. | ||
531 | */ | 639 | */ |
532 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); | 640 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE); |
533 | 641 | return (AE_OK); | |
534 | return_VOID; | ||
535 | } | 642 | } |
536 | 643 | ||
644 | |||
537 | /******************************************************************************* | 645 | /******************************************************************************* |
538 | * | 646 | * |
539 | * FUNCTION: acpi_ev_gpe_dispatch | 647 | * FUNCTION: acpi_ev_gpe_dispatch |
540 | * | 648 | * |
541 | * PARAMETERS: gpe_event_info - Info for this GPE | 649 | * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1 |
650 | * gpe_event_info - Info for this GPE | ||
542 | * gpe_number - Number relative to the parent GPE block | 651 | * gpe_number - Number relative to the parent GPE block |
543 | * | 652 | * |
544 | * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED | 653 | * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED |
@@ -551,13 +660,22 @@ static void acpi_ev_asynch_enable_gpe(void *context) | |||
551 | ******************************************************************************/ | 660 | ******************************************************************************/ |
552 | 661 | ||
553 | u32 | 662 | u32 |
554 | acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | 663 | acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, |
664 | struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | ||
555 | { | 665 | { |
556 | acpi_status status; | 666 | acpi_status status; |
667 | u32 return_value; | ||
557 | 668 | ||
558 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); | 669 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); |
559 | 670 | ||
560 | acpi_os_gpe_count(gpe_number); | 671 | /* Invoke global event handler if present */ |
672 | |||
673 | acpi_gpe_count++; | ||
674 | if (acpi_gbl_global_event_handler) { | ||
675 | acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device, | ||
676 | gpe_number, | ||
677 | acpi_gbl_global_event_handler_context); | ||
678 | } | ||
561 | 679 | ||
562 | /* | 680 | /* |
563 | * If edge-triggered, clear the GPE status bit now. Note that | 681 | * If edge-triggered, clear the GPE status bit now. Note that |
@@ -568,59 +686,55 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
568 | status = acpi_hw_clear_gpe(gpe_event_info); | 686 | status = acpi_hw_clear_gpe(gpe_event_info); |
569 | if (ACPI_FAILURE(status)) { | 687 | if (ACPI_FAILURE(status)) { |
570 | ACPI_EXCEPTION((AE_INFO, status, | 688 | ACPI_EXCEPTION((AE_INFO, status, |
571 | "Unable to clear GPE[0x%2X]", | 689 | "Unable to clear GPE%02X", gpe_number)); |
572 | gpe_number)); | ||
573 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | 690 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); |
574 | } | 691 | } |
575 | } | 692 | } |
576 | 693 | ||
577 | /* | 694 | /* |
578 | * Dispatch the GPE to either an installed handler, or the control method | 695 | * Always disable the GPE so that it does not keep firing before |
579 | * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke | 696 | * any asynchronous activity completes (either from the execution |
580 | * it and do not attempt to run the method. If there is neither a handler | 697 | * of a GPE method or an asynchronous GPE handler.) |
581 | * nor a method, we disable this GPE to prevent further such pointless | 698 | * |
582 | * events from firing. | 699 | * If there is no handler or method to run, just disable the |
700 | * GPE and leave it disabled permanently to prevent further such | ||
701 | * pointless events from firing. | ||
702 | */ | ||
703 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
704 | if (ACPI_FAILURE(status)) { | ||
705 | ACPI_EXCEPTION((AE_INFO, status, | ||
706 | "Unable to disable GPE%02X", gpe_number)); | ||
707 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | ||
708 | } | ||
709 | |||
710 | /* | ||
711 | * Dispatch the GPE to either an installed handler or the control | ||
712 | * method associated with this GPE (_Lxx or _Exx). If a handler | ||
713 | * exists, we invoke it and do not attempt to run the method. | ||
714 | * If there is neither a handler nor a method, leave the GPE | ||
715 | * disabled. | ||
583 | */ | 716 | */ |
584 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { | 717 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { |
585 | case ACPI_GPE_DISPATCH_HANDLER: | 718 | case ACPI_GPE_DISPATCH_HANDLER: |
586 | 719 | ||
587 | /* | 720 | /* Invoke the installed handler (at interrupt level) */ |
588 | * Invoke the installed handler (at interrupt level) | ||
589 | * Ignore return status for now. | ||
590 | * TBD: leave GPE disabled on error? | ||
591 | */ | ||
592 | (void)gpe_event_info->dispatch.handler->address(gpe_event_info-> | ||
593 | dispatch. | ||
594 | handler-> | ||
595 | context); | ||
596 | 721 | ||
597 | /* It is now safe to clear level-triggered events. */ | 722 | return_value = |
723 | gpe_event_info->dispatch.handler->address(gpe_device, | ||
724 | gpe_number, | ||
725 | gpe_event_info-> | ||
726 | dispatch.handler-> | ||
727 | context); | ||
598 | 728 | ||
599 | if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == | 729 | /* If requested, clear (if level-triggered) and reenable the GPE */ |
600 | ACPI_GPE_LEVEL_TRIGGERED) { | 730 | |
601 | status = acpi_hw_clear_gpe(gpe_event_info); | 731 | if (return_value & ACPI_REENABLE_GPE) { |
602 | if (ACPI_FAILURE(status)) { | 732 | (void)acpi_ev_finish_gpe(gpe_event_info); |
603 | ACPI_EXCEPTION((AE_INFO, status, | ||
604 | "Unable to clear GPE[0x%2X]", | ||
605 | gpe_number)); | ||
606 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | ||
607 | } | ||
608 | } | 733 | } |
609 | break; | 734 | break; |
610 | 735 | ||
611 | case ACPI_GPE_DISPATCH_METHOD: | 736 | case ACPI_GPE_DISPATCH_METHOD: |
612 | 737 | case ACPI_GPE_DISPATCH_NOTIFY: | |
613 | /* | ||
614 | * Disable the GPE, so it doesn't keep firing before the method has a | ||
615 | * chance to run (it runs asynchronously with interrupts enabled). | ||
616 | */ | ||
617 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
618 | if (ACPI_FAILURE(status)) { | ||
619 | ACPI_EXCEPTION((AE_INFO, status, | ||
620 | "Unable to disable GPE[0x%2X]", | ||
621 | gpe_number)); | ||
622 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | ||
623 | } | ||
624 | 738 | ||
625 | /* | 739 | /* |
626 | * Execute the method associated with the GPE | 740 | * Execute the method associated with the GPE |
@@ -631,7 +745,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
631 | gpe_event_info); | 745 | gpe_event_info); |
632 | if (ACPI_FAILURE(status)) { | 746 | if (ACPI_FAILURE(status)) { |
633 | ACPI_EXCEPTION((AE_INFO, status, | 747 | ACPI_EXCEPTION((AE_INFO, status, |
634 | "Unable to queue handler for GPE[0x%2X] - event disabled", | 748 | "Unable to queue handler for GPE%2X - event disabled", |
635 | gpe_number)); | 749 | gpe_number)); |
636 | } | 750 | } |
637 | break; | 751 | break; |
@@ -644,20 +758,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
644 | * a GPE to be enabled if it has no handler or method. | 758 | * a GPE to be enabled if it has no handler or method. |
645 | */ | 759 | */ |
646 | ACPI_ERROR((AE_INFO, | 760 | ACPI_ERROR((AE_INFO, |
647 | "No handler or method for GPE[0x%2X], disabling event", | 761 | "No handler or method for GPE%02X, disabling event", |
648 | gpe_number)); | 762 | gpe_number)); |
649 | 763 | ||
650 | /* | ||
651 | * Disable the GPE. The GPE will remain disabled a handler | ||
652 | * is installed or ACPICA is restarted. | ||
653 | */ | ||
654 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
655 | if (ACPI_FAILURE(status)) { | ||
656 | ACPI_EXCEPTION((AE_INFO, status, | ||
657 | "Unable to disable GPE[0x%2X]", | ||
658 | gpe_number)); | ||
659 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | ||
660 | } | ||
661 | break; | 764 | break; |
662 | } | 765 | } |
663 | 766 | ||
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 020add3eee1..ca2c41a5331 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -361,9 +361,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
361 | 361 | ||
362 | gpe_block->node = gpe_device; | 362 | gpe_block->node = gpe_device; |
363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); | 363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); |
364 | gpe_block->initialized = FALSE; | ||
364 | gpe_block->register_count = register_count; | 365 | gpe_block->register_count = register_count; |
365 | gpe_block->block_base_number = gpe_block_base_number; | 366 | gpe_block->block_base_number = gpe_block_base_number; |
366 | gpe_block->initialized = FALSE; | ||
367 | 367 | ||
368 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, | 368 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, |
369 | sizeof(struct acpi_generic_address)); | 369 | sizeof(struct acpi_generic_address)); |
@@ -386,7 +386,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
386 | return_ACPI_STATUS(status); | 386 | return_ACPI_STATUS(status); |
387 | } | 387 | } |
388 | 388 | ||
389 | acpi_all_gpes_initialized = FALSE; | 389 | acpi_gbl_all_gpes_initialized = FALSE; |
390 | 390 | ||
391 | /* Find all GPE methods (_Lxx or_Exx) for this block */ | 391 | /* Find all GPE methods (_Lxx or_Exx) for this block */ |
392 | 392 | ||
@@ -423,14 +423,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
423 | * | 423 | * |
424 | * FUNCTION: acpi_ev_initialize_gpe_block | 424 | * FUNCTION: acpi_ev_initialize_gpe_block |
425 | * | 425 | * |
426 | * PARAMETERS: gpe_device - Handle to the parent GPE block | 426 | * PARAMETERS: acpi_gpe_callback |
427 | * gpe_block - Gpe Block info | ||
428 | * | 427 | * |
429 | * RETURN: Status | 428 | * RETURN: Status |
430 | * | 429 | * |
431 | * DESCRIPTION: Initialize and enable a GPE block. First find and run any | 430 | * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have |
432 | * _PRT methods associated with the block, then enable the | 431 | * associated methods. |
433 | * appropriate GPEs. | ||
434 | * Note: Assumes namespace is locked. | 432 | * Note: Assumes namespace is locked. |
435 | * | 433 | * |
436 | ******************************************************************************/ | 434 | ******************************************************************************/ |
@@ -450,8 +448,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
450 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); | 448 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); |
451 | 449 | ||
452 | /* | 450 | /* |
453 | * Ignore a null GPE block (e.g., if no GPE block 1 exists) and | 451 | * Ignore a null GPE block (e.g., if no GPE block 1 exists), and |
454 | * GPE blocks that have been initialized already. | 452 | * any GPE blocks that have been initialized already. |
455 | */ | 453 | */ |
456 | if (!gpe_block || gpe_block->initialized) { | 454 | if (!gpe_block || gpe_block->initialized) { |
457 | return_ACPI_STATUS(AE_OK); | 455 | return_ACPI_STATUS(AE_OK); |
@@ -459,8 +457,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
459 | 457 | ||
460 | /* | 458 | /* |
461 | * Enable all GPEs that have a corresponding method and have the | 459 | * Enable all GPEs that have a corresponding method and have the |
462 | * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must | 460 | * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block |
463 | * be enabled via the acpi_enable_gpe() interface. | 461 | * must be enabled via the acpi_enable_gpe() interface. |
464 | */ | 462 | */ |
465 | gpe_enabled_count = 0; | 463 | gpe_enabled_count = 0; |
466 | 464 | ||
@@ -472,14 +470,19 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
472 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; | 470 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; |
473 | gpe_event_info = &gpe_block->event_info[gpe_index]; | 471 | gpe_event_info = &gpe_block->event_info[gpe_index]; |
474 | 472 | ||
475 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ | 473 | /* |
476 | 474 | * Ignore GPEs that have no corresponding _Lxx/_Exx method | |
477 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) | 475 | * and GPEs that are used to wake the system |
476 | */ | ||
477 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | ||
478 | ACPI_GPE_DISPATCH_NONE) | ||
479 | || ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | ||
480 | == ACPI_GPE_DISPATCH_HANDLER) | ||
478 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | 481 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { |
479 | continue; | 482 | continue; |
480 | } | 483 | } |
481 | 484 | ||
482 | status = acpi_raw_enable_gpe(gpe_event_info); | 485 | status = acpi_ev_add_gpe_reference(gpe_event_info); |
483 | if (ACPI_FAILURE(status)) { | 486 | if (ACPI_FAILURE(status)) { |
484 | ACPI_EXCEPTION((AE_INFO, status, | 487 | ACPI_EXCEPTION((AE_INFO, status, |
485 | "Could not enable GPE 0x%02X", | 488 | "Could not enable GPE 0x%02X", |
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 2c7def95f72..ce9aa9f9a97 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -45,11 +45,27 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acevents.h" | 46 | #include "acevents.h" |
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "acinterp.h" | ||
49 | 48 | ||
50 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
51 | ACPI_MODULE_NAME("evgpeinit") | 50 | ACPI_MODULE_NAME("evgpeinit") |
52 | 51 | ||
52 | /* | ||
53 | * Note: History of _PRW support in ACPICA | ||
54 | * | ||
55 | * Originally (2000 - 2010), the GPE initialization code performed a walk of | ||
56 | * the entire namespace to execute the _PRW methods and detect all GPEs | ||
57 | * capable of waking the system. | ||
58 | * | ||
59 | * As of 10/2010, the _PRW method execution has been removed since it is | ||
60 | * actually unnecessary. The host OS must in fact execute all _PRW methods | ||
61 | * in order to identify the device/power-resource dependencies. We now put | ||
62 | * the onus on the host OS to identify the wake GPEs as part of this process | ||
63 | * and to inform ACPICA of these GPEs via the acpi_setup_gpe_for_wake interface. This | ||
64 | * not only reduces the complexity of the ACPICA initialization code, but in | ||
65 | * some cases (on systems with very large namespaces) it should reduce the | ||
66 | * kernel boot time as well. | ||
67 | */ | ||
68 | |||
53 | /******************************************************************************* | 69 | /******************************************************************************* |
54 | * | 70 | * |
55 | * FUNCTION: acpi_ev_gpe_initialize | 71 | * FUNCTION: acpi_ev_gpe_initialize |
@@ -222,7 +238,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
222 | acpi_status status = AE_OK; | 238 | acpi_status status = AE_OK; |
223 | 239 | ||
224 | /* | 240 | /* |
225 | * 2) Find any _Lxx/_Exx GPE methods that have just been loaded. | 241 | * Find any _Lxx/_Exx GPE methods that have just been loaded. |
226 | * | 242 | * |
227 | * Any GPEs that correspond to new _Lxx/_Exx methods are immediately | 243 | * Any GPEs that correspond to new _Lxx/_Exx methods are immediately |
228 | * enabled. | 244 | * enabled. |
@@ -235,9 +251,9 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
235 | return; | 251 | return; |
236 | } | 252 | } |
237 | 253 | ||
254 | walk_info.count = 0; | ||
238 | walk_info.owner_id = table_owner_id; | 255 | walk_info.owner_id = table_owner_id; |
239 | walk_info.execute_by_owner_id = TRUE; | 256 | walk_info.execute_by_owner_id = TRUE; |
240 | walk_info.count = 0; | ||
241 | 257 | ||
242 | /* Walk the interrupt level descriptor list */ | 258 | /* Walk the interrupt level descriptor list */ |
243 | 259 | ||
@@ -298,7 +314,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
298 | * xx - is the GPE number [in HEX] | 314 | * xx - is the GPE number [in HEX] |
299 | * | 315 | * |
300 | * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods | 316 | * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods |
301 | * with that owner. | 317 | * with that owner. |
302 | * | 318 | * |
303 | ******************************************************************************/ | 319 | ******************************************************************************/ |
304 | 320 | ||
@@ -408,10 +424,14 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
408 | return_ACPI_STATUS(AE_OK); | 424 | return_ACPI_STATUS(AE_OK); |
409 | } | 425 | } |
410 | 426 | ||
427 | /* Disable the GPE in case it's been enabled already. */ | ||
428 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
429 | |||
411 | /* | 430 | /* |
412 | * Add the GPE information from above to the gpe_event_info block for | 431 | * Add the GPE information from above to the gpe_event_info block for |
413 | * use during dispatch of this GPE. | 432 | * use during dispatch of this GPE. |
414 | */ | 433 | */ |
434 | gpe_event_info->flags &= ~(ACPI_GPE_DISPATCH_MASK); | ||
415 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); | 435 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); |
416 | gpe_event_info->dispatch.method_node = method_node; | 436 | gpe_event_info->dispatch.method_node = method_node; |
417 | 437 | ||
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index 19a0e513ea4..80a81d0c4a8 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -154,6 +154,45 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) | |||
154 | 154 | ||
155 | /******************************************************************************* | 155 | /******************************************************************************* |
156 | * | 156 | * |
157 | * FUNCTION: acpi_ev_get_gpe_device | ||
158 | * | ||
159 | * PARAMETERS: GPE_WALK_CALLBACK | ||
160 | * | ||
161 | * RETURN: Status | ||
162 | * | ||
163 | * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE | ||
164 | * block device. NULL if the GPE is one of the FADT-defined GPEs. | ||
165 | * | ||
166 | ******************************************************************************/ | ||
167 | |||
168 | acpi_status | ||
169 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
170 | struct acpi_gpe_block_info *gpe_block, void *context) | ||
171 | { | ||
172 | struct acpi_gpe_device_info *info = context; | ||
173 | |||
174 | /* Increment Index by the number of GPEs in this block */ | ||
175 | |||
176 | info->next_block_base_index += gpe_block->gpe_count; | ||
177 | |||
178 | if (info->index < info->next_block_base_index) { | ||
179 | /* | ||
180 | * The GPE index is within this block, get the node. Leave the node | ||
181 | * NULL for the FADT-defined GPEs | ||
182 | */ | ||
183 | if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { | ||
184 | info->gpe_device = gpe_block->node; | ||
185 | } | ||
186 | |||
187 | info->status = AE_OK; | ||
188 | return (AE_CTRL_END); | ||
189 | } | ||
190 | |||
191 | return (AE_OK); | ||
192 | } | ||
193 | |||
194 | /******************************************************************************* | ||
195 | * | ||
157 | * FUNCTION: acpi_ev_get_gpe_xrupt_block | 196 | * FUNCTION: acpi_ev_get_gpe_xrupt_block |
158 | * | 197 | * |
159 | * PARAMETERS: interrupt_number - Interrupt for a GPE block | 198 | * PARAMETERS: interrupt_number - Interrupt for a GPE block |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index fcaed9fb44f..7dc80946f7b 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -284,41 +284,39 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
284 | * RETURN: ACPI_INTERRUPT_HANDLED | 284 | * RETURN: ACPI_INTERRUPT_HANDLED |
285 | * | 285 | * |
286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | 286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock |
287 | * release interrupt occurs. Attempt to acquire the global lock, | 287 | * release interrupt occurs. If there's a thread waiting for |
288 | * if successful, signal the thread waiting for the lock. | 288 | * the global lock, signal it. |
289 | * | 289 | * |
290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If | 290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If |
291 | * this is not possible for some reason, a separate thread will have to be | 291 | * this is not possible for some reason, a separate thread will have to be |
292 | * scheduled to do this. | 292 | * scheduled to do this. |
293 | * | 293 | * |
294 | ******************************************************************************/ | 294 | ******************************************************************************/ |
295 | static u8 acpi_ev_global_lock_pending; | ||
295 | 296 | ||
296 | static u32 acpi_ev_global_lock_handler(void *context) | 297 | static u32 acpi_ev_global_lock_handler(void *context) |
297 | { | 298 | { |
298 | u8 acquired = FALSE; | 299 | acpi_status status; |
300 | acpi_cpu_flags flags; | ||
299 | 301 | ||
300 | /* | 302 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
301 | * Attempt to get the lock. | ||
302 | * | ||
303 | * If we don't get it now, it will be marked pending and we will | ||
304 | * take another interrupt when it becomes free. | ||
305 | */ | ||
306 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
307 | if (acquired) { | ||
308 | 303 | ||
309 | /* Got the lock, now wake all threads waiting for it */ | 304 | if (!acpi_ev_global_lock_pending) { |
305 | goto out; | ||
306 | } | ||
310 | 307 | ||
311 | acpi_gbl_global_lock_acquired = TRUE; | 308 | /* Send a unit to the semaphore */ |
312 | /* Send a unit to the semaphore */ | ||
313 | 309 | ||
314 | if (ACPI_FAILURE | 310 | status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); |
315 | (acpi_os_signal_semaphore | 311 | if (ACPI_FAILURE(status)) { |
316 | (acpi_gbl_global_lock_semaphore, 1))) { | 312 | ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); |
317 | ACPI_ERROR((AE_INFO, | ||
318 | "Could not signal Global Lock semaphore")); | ||
319 | } | ||
320 | } | 313 | } |
321 | 314 | ||
315 | acpi_ev_global_lock_pending = FALSE; | ||
316 | |||
317 | out: | ||
318 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
319 | |||
322 | return (ACPI_INTERRUPT_HANDLED); | 320 | return (ACPI_INTERRUPT_HANDLED); |
323 | } | 321 | } |
324 | 322 | ||
@@ -415,6 +413,7 @@ static int acpi_ev_global_lock_acquired; | |||
415 | 413 | ||
416 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | 414 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) |
417 | { | 415 | { |
416 | acpi_cpu_flags flags; | ||
418 | acpi_status status = AE_OK; | 417 | acpi_status status = AE_OK; |
419 | u8 acquired = FALSE; | 418 | u8 acquired = FALSE; |
420 | 419 | ||
@@ -467,32 +466,47 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
467 | return_ACPI_STATUS(AE_OK); | 466 | return_ACPI_STATUS(AE_OK); |
468 | } | 467 | } |
469 | 468 | ||
470 | /* Attempt to acquire the actual hardware lock */ | 469 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
470 | |||
471 | do { | ||
472 | |||
473 | /* Attempt to acquire the actual hardware lock */ | ||
474 | |||
475 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
476 | if (acquired) { | ||
477 | acpi_gbl_global_lock_acquired = TRUE; | ||
478 | |||
479 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
480 | "Acquired hardware Global Lock\n")); | ||
481 | break; | ||
482 | } | ||
471 | 483 | ||
472 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | 484 | acpi_ev_global_lock_pending = TRUE; |
473 | if (acquired) { | ||
474 | 485 | ||
475 | /* We got the lock */ | 486 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); |
476 | 487 | ||
488 | /* | ||
489 | * Did not get the lock. The pending bit was set above, and we | ||
490 | * must wait until we get the global lock released interrupt. | ||
491 | */ | ||
477 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 492 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
478 | "Acquired hardware Global Lock\n")); | 493 | "Waiting for hardware Global Lock\n")); |
479 | 494 | ||
480 | acpi_gbl_global_lock_acquired = TRUE; | 495 | /* |
481 | return_ACPI_STATUS(AE_OK); | 496 | * Wait for handshake with the global lock interrupt handler. |
482 | } | 497 | * This interface releases the interpreter if we must wait. |
498 | */ | ||
499 | status = acpi_ex_system_wait_semaphore( | ||
500 | acpi_gbl_global_lock_semaphore, | ||
501 | ACPI_WAIT_FOREVER); | ||
483 | 502 | ||
484 | /* | 503 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
485 | * Did not get the lock. The pending bit was set above, and we must now | ||
486 | * wait until we get the global lock released interrupt. | ||
487 | */ | ||
488 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); | ||
489 | 504 | ||
490 | /* | 505 | } while (ACPI_SUCCESS(status)); |
491 | * Wait for handshake with the global lock interrupt handler. | 506 | |
492 | * This interface releases the interpreter if we must wait. | 507 | acpi_ev_global_lock_pending = FALSE; |
493 | */ | 508 | |
494 | status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, | 509 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); |
495 | ACPI_WAIT_FOREVER); | ||
496 | 510 | ||
497 | return_ACPI_STATUS(status); | 511 | return_ACPI_STATUS(status); |
498 | } | 512 | } |
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 98fd210e87b..bea7223d7a7 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -231,6 +231,8 @@ acpi_status acpi_ev_initialize_op_regions(void) | |||
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | acpi_gbl_reg_methods_executed = TRUE; | ||
235 | |||
234 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 236 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
235 | return_ACPI_STATUS(status); | 237 | return_ACPI_STATUS(status); |
236 | } | 238 | } |
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 0b47a6dc929..9659cee6093 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -590,9 +590,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
590 | * See acpi_ns_exec_module_code | 590 | * See acpi_ns_exec_module_code |
591 | */ | 591 | */ |
592 | if (obj_desc->method. | 592 | if (obj_desc->method. |
593 | flags & AOPOBJ_MODULE_LEVEL) { | 593 | info_flags & ACPI_METHOD_MODULE_LEVEL) { |
594 | handler_obj = | 594 | handler_obj = |
595 | obj_desc->method.extra.handler; | 595 | obj_desc->method.dispatch.handler; |
596 | } | 596 | } |
597 | break; | 597 | break; |
598 | 598 | ||
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 8dfbaa96e42..2ebd40e1a3e 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 36af222cac6..e1141402dbe 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -92,6 +92,57 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler) | |||
92 | 92 | ||
93 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) | 93 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) |
94 | #endif /* ACPI_FUTURE_USAGE */ | 94 | #endif /* ACPI_FUTURE_USAGE */ |
95 | |||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * FUNCTION: acpi_install_global_event_handler | ||
99 | * | ||
100 | * PARAMETERS: Handler - Pointer to the global event handler function | ||
101 | * Context - Value passed to the handler on each event | ||
102 | * | ||
103 | * RETURN: Status | ||
104 | * | ||
105 | * DESCRIPTION: Saves the pointer to the handler function. The global handler | ||
106 | * is invoked upon each incoming GPE and Fixed Event. It is | ||
107 | * invoked at interrupt level at the time of the event dispatch. | ||
108 | * Can be used to update event counters, etc. | ||
109 | * | ||
110 | ******************************************************************************/ | ||
111 | acpi_status | ||
112 | acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context) | ||
113 | { | ||
114 | acpi_status status; | ||
115 | |||
116 | ACPI_FUNCTION_TRACE(acpi_install_global_event_handler); | ||
117 | |||
118 | /* Parameter validation */ | ||
119 | |||
120 | if (!handler) { | ||
121 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
122 | } | ||
123 | |||
124 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
125 | if (ACPI_FAILURE(status)) { | ||
126 | return_ACPI_STATUS(status); | ||
127 | } | ||
128 | |||
129 | /* Don't allow two handlers. */ | ||
130 | |||
131 | if (acpi_gbl_global_event_handler) { | ||
132 | status = AE_ALREADY_EXISTS; | ||
133 | goto cleanup; | ||
134 | } | ||
135 | |||
136 | acpi_gbl_global_event_handler = handler; | ||
137 | acpi_gbl_global_event_handler_context = context; | ||
138 | |||
139 | cleanup: | ||
140 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
141 | return_ACPI_STATUS(status); | ||
142 | } | ||
143 | |||
144 | ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler) | ||
145 | |||
95 | /******************************************************************************* | 146 | /******************************************************************************* |
96 | * | 147 | * |
97 | * FUNCTION: acpi_install_fixed_event_handler | 148 | * FUNCTION: acpi_install_fixed_event_handler |
@@ -671,10 +722,10 @@ ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler) | |||
671 | acpi_status | 722 | acpi_status |
672 | acpi_install_gpe_handler(acpi_handle gpe_device, | 723 | acpi_install_gpe_handler(acpi_handle gpe_device, |
673 | u32 gpe_number, | 724 | u32 gpe_number, |
674 | u32 type, acpi_event_handler address, void *context) | 725 | u32 type, acpi_gpe_handler address, void *context) |
675 | { | 726 | { |
676 | struct acpi_gpe_event_info *gpe_event_info; | 727 | struct acpi_gpe_event_info *gpe_event_info; |
677 | struct acpi_handler_info *handler; | 728 | struct acpi_gpe_handler_info *handler; |
678 | acpi_status status; | 729 | acpi_status status; |
679 | acpi_cpu_flags flags; | 730 | acpi_cpu_flags flags; |
680 | 731 | ||
@@ -693,7 +744,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
693 | 744 | ||
694 | /* Allocate memory for the handler object */ | 745 | /* Allocate memory for the handler object */ |
695 | 746 | ||
696 | handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); | 747 | handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info)); |
697 | if (!handler) { | 748 | if (!handler) { |
698 | status = AE_NO_MEMORY; | 749 | status = AE_NO_MEMORY; |
699 | goto unlock_and_exit; | 750 | goto unlock_and_exit; |
@@ -722,7 +773,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
722 | handler->address = address; | 773 | handler->address = address; |
723 | handler->context = context; | 774 | handler->context = context; |
724 | handler->method_node = gpe_event_info->dispatch.method_node; | 775 | handler->method_node = gpe_event_info->dispatch.method_node; |
725 | handler->orig_flags = gpe_event_info->flags & | 776 | handler->original_flags = gpe_event_info->flags & |
726 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | 777 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
727 | 778 | ||
728 | /* | 779 | /* |
@@ -731,10 +782,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
731 | * disabled now to avoid spurious execution of the handler. | 782 | * disabled now to avoid spurious execution of the handler. |
732 | */ | 783 | */ |
733 | 784 | ||
734 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | 785 | if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) |
735 | && gpe_event_info->runtime_count) { | 786 | && gpe_event_info->runtime_count) { |
736 | handler->orig_enabled = 1; | 787 | handler->originally_enabled = 1; |
737 | (void)acpi_raw_disable_gpe(gpe_event_info); | 788 | (void)acpi_ev_remove_gpe_reference(gpe_event_info); |
738 | } | 789 | } |
739 | 790 | ||
740 | /* Install the handler */ | 791 | /* Install the handler */ |
@@ -777,10 +828,10 @@ ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) | |||
777 | ******************************************************************************/ | 828 | ******************************************************************************/ |
778 | acpi_status | 829 | acpi_status |
779 | acpi_remove_gpe_handler(acpi_handle gpe_device, | 830 | acpi_remove_gpe_handler(acpi_handle gpe_device, |
780 | u32 gpe_number, acpi_event_handler address) | 831 | u32 gpe_number, acpi_gpe_handler address) |
781 | { | 832 | { |
782 | struct acpi_gpe_event_info *gpe_event_info; | 833 | struct acpi_gpe_event_info *gpe_event_info; |
783 | struct acpi_handler_info *handler; | 834 | struct acpi_gpe_handler_info *handler; |
784 | acpi_status status; | 835 | acpi_status status; |
785 | acpi_cpu_flags flags; | 836 | acpi_cpu_flags flags; |
786 | 837 | ||
@@ -835,7 +886,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
835 | gpe_event_info->dispatch.method_node = handler->method_node; | 886 | gpe_event_info->dispatch.method_node = handler->method_node; |
836 | gpe_event_info->flags &= | 887 | gpe_event_info->flags &= |
837 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | 888 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
838 | gpe_event_info->flags |= handler->orig_flags; | 889 | gpe_event_info->flags |= handler->original_flags; |
839 | 890 | ||
840 | /* | 891 | /* |
841 | * If the GPE was previously associated with a method and it was | 892 | * If the GPE was previously associated with a method and it was |
@@ -843,9 +894,9 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
843 | * post-initialization configuration. | 894 | * post-initialization configuration. |
844 | */ | 895 | */ |
845 | 896 | ||
846 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | 897 | if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) |
847 | && handler->orig_enabled) | 898 | && handler->originally_enabled) |
848 | (void)acpi_raw_enable_gpe(gpe_event_info); | 899 | (void)acpi_ev_add_gpe_reference(gpe_event_info); |
849 | 900 | ||
850 | /* Now we can free the handler object */ | 901 | /* Now we can free the handler object */ |
851 | 902 | ||
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index a1dabe3fd8a..c57b5c707a7 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -43,18 +43,11 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acevents.h" | ||
47 | #include "acnamesp.h" | ||
48 | #include "actables.h" | 46 | #include "actables.h" |
49 | 47 | ||
50 | #define _COMPONENT ACPI_EVENTS | 48 | #define _COMPONENT ACPI_EVENTS |
51 | ACPI_MODULE_NAME("evxfevnt") | 49 | ACPI_MODULE_NAME("evxfevnt") |
52 | 50 | ||
53 | /* Local prototypes */ | ||
54 | static acpi_status | ||
55 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
56 | struct acpi_gpe_block_info *gpe_block, void *context); | ||
57 | |||
58 | /******************************************************************************* | 51 | /******************************************************************************* |
59 | * | 52 | * |
60 | * FUNCTION: acpi_enable | 53 | * FUNCTION: acpi_enable |
@@ -213,185 +206,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) | |||
213 | 206 | ||
214 | /******************************************************************************* | 207 | /******************************************************************************* |
215 | * | 208 | * |
216 | * FUNCTION: acpi_gpe_wakeup | ||
217 | * | ||
218 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
219 | * gpe_number - GPE level within the GPE block | ||
220 | * Action - Enable or Disable | ||
221 | * | ||
222 | * RETURN: Status | ||
223 | * | ||
224 | * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. | ||
225 | * | ||
226 | ******************************************************************************/ | ||
227 | acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) | ||
228 | { | ||
229 | acpi_status status = AE_OK; | ||
230 | struct acpi_gpe_event_info *gpe_event_info; | ||
231 | struct acpi_gpe_register_info *gpe_register_info; | ||
232 | acpi_cpu_flags flags; | ||
233 | u32 register_bit; | ||
234 | |||
235 | ACPI_FUNCTION_TRACE(acpi_gpe_wakeup); | ||
236 | |||
237 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
238 | |||
239 | /* Ensure that we have a valid GPE number */ | ||
240 | |||
241 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
242 | if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
243 | status = AE_BAD_PARAMETER; | ||
244 | goto unlock_and_exit; | ||
245 | } | ||
246 | |||
247 | gpe_register_info = gpe_event_info->register_info; | ||
248 | if (!gpe_register_info) { | ||
249 | status = AE_NOT_EXIST; | ||
250 | goto unlock_and_exit; | ||
251 | } | ||
252 | |||
253 | register_bit = | ||
254 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
255 | |||
256 | /* Perform the action */ | ||
257 | |||
258 | switch (action) { | ||
259 | case ACPI_GPE_ENABLE: | ||
260 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, | ||
261 | (u8)register_bit); | ||
262 | break; | ||
263 | |||
264 | case ACPI_GPE_DISABLE: | ||
265 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, | ||
266 | (u8)register_bit); | ||
267 | break; | ||
268 | |||
269 | default: | ||
270 | ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); | ||
271 | status = AE_BAD_PARAMETER; | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | unlock_and_exit: | ||
276 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
277 | return_ACPI_STATUS(status); | ||
278 | } | ||
279 | |||
280 | ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) | ||
281 | |||
282 | /******************************************************************************* | ||
283 | * | ||
284 | * FUNCTION: acpi_enable_gpe | ||
285 | * | ||
286 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
287 | * gpe_number - GPE level within the GPE block | ||
288 | * | ||
289 | * RETURN: Status | ||
290 | * | ||
291 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is | ||
292 | * hardware-enabled. | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
296 | { | ||
297 | acpi_status status = AE_BAD_PARAMETER; | ||
298 | struct acpi_gpe_event_info *gpe_event_info; | ||
299 | acpi_cpu_flags flags; | ||
300 | |||
301 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); | ||
302 | |||
303 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
304 | |||
305 | /* Ensure that we have a valid GPE number */ | ||
306 | |||
307 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
308 | if (gpe_event_info) { | ||
309 | status = acpi_raw_enable_gpe(gpe_event_info); | ||
310 | } | ||
311 | |||
312 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
313 | return_ACPI_STATUS(status); | ||
314 | } | ||
315 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | ||
316 | |||
317 | /******************************************************************************* | ||
318 | * | ||
319 | * FUNCTION: acpi_disable_gpe | ||
320 | * | ||
321 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
322 | * gpe_number - GPE level within the GPE block | ||
323 | * | ||
324 | * RETURN: Status | ||
325 | * | ||
326 | * DESCRIPTION: Remove a reference to a GPE. When the last reference is | ||
327 | * removed, only then is the GPE disabled (for runtime GPEs), or | ||
328 | * the GPE mask bit disabled (for wake GPEs) | ||
329 | * | ||
330 | ******************************************************************************/ | ||
331 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
332 | { | ||
333 | acpi_status status = AE_BAD_PARAMETER; | ||
334 | struct acpi_gpe_event_info *gpe_event_info; | ||
335 | acpi_cpu_flags flags; | ||
336 | |||
337 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); | ||
338 | |||
339 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
340 | |||
341 | /* Ensure that we have a valid GPE number */ | ||
342 | |||
343 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
344 | if (gpe_event_info) { | ||
345 | status = acpi_raw_disable_gpe(gpe_event_info) ; | ||
346 | } | ||
347 | |||
348 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
349 | return_ACPI_STATUS(status); | ||
350 | } | ||
351 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | ||
352 | |||
353 | /******************************************************************************* | ||
354 | * | ||
355 | * FUNCTION: acpi_gpe_can_wake | ||
356 | * | ||
357 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
358 | * gpe_number - GPE level within the GPE block | ||
359 | * | ||
360 | * RETURN: Status | ||
361 | * | ||
362 | * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE | ||
363 | * has a corresponding method and is currently enabled, disable it | ||
364 | * (GPEs with corresponding methods are enabled unconditionally | ||
365 | * during initialization, but GPEs that can wake up are expected | ||
366 | * to be initially disabled). | ||
367 | * | ||
368 | ******************************************************************************/ | ||
369 | acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) | ||
370 | { | ||
371 | acpi_status status = AE_OK; | ||
372 | struct acpi_gpe_event_info *gpe_event_info; | ||
373 | acpi_cpu_flags flags; | ||
374 | |||
375 | ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); | ||
376 | |||
377 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
378 | |||
379 | /* Ensure that we have a valid GPE number */ | ||
380 | |||
381 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
382 | if (gpe_event_info) { | ||
383 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
384 | } else { | ||
385 | status = AE_BAD_PARAMETER; | ||
386 | } | ||
387 | |||
388 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
389 | return_ACPI_STATUS(status); | ||
390 | } | ||
391 | ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) | ||
392 | |||
393 | /******************************************************************************* | ||
394 | * | ||
395 | * FUNCTION: acpi_disable_event | 209 | * FUNCTION: acpi_disable_event |
396 | * | 210 | * |
397 | * PARAMETERS: Event - The fixed eventto be enabled | 211 | * PARAMETERS: Event - The fixed eventto be enabled |
@@ -483,44 +297,6 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event) | |||
483 | 297 | ||
484 | /******************************************************************************* | 298 | /******************************************************************************* |
485 | * | 299 | * |
486 | * FUNCTION: acpi_clear_gpe | ||
487 | * | ||
488 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
489 | * gpe_number - GPE level within the GPE block | ||
490 | * | ||
491 | * RETURN: Status | ||
492 | * | ||
493 | * DESCRIPTION: Clear an ACPI event (general purpose) | ||
494 | * | ||
495 | ******************************************************************************/ | ||
496 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
497 | { | ||
498 | acpi_status status = AE_OK; | ||
499 | struct acpi_gpe_event_info *gpe_event_info; | ||
500 | acpi_cpu_flags flags; | ||
501 | |||
502 | ACPI_FUNCTION_TRACE(acpi_clear_gpe); | ||
503 | |||
504 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
505 | |||
506 | /* Ensure that we have a valid GPE number */ | ||
507 | |||
508 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
509 | if (!gpe_event_info) { | ||
510 | status = AE_BAD_PARAMETER; | ||
511 | goto unlock_and_exit; | ||
512 | } | ||
513 | |||
514 | status = acpi_hw_clear_gpe(gpe_event_info); | ||
515 | |||
516 | unlock_and_exit: | ||
517 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
518 | return_ACPI_STATUS(status); | ||
519 | } | ||
520 | |||
521 | ACPI_EXPORT_SYMBOL(acpi_clear_gpe) | ||
522 | /******************************************************************************* | ||
523 | * | ||
524 | * FUNCTION: acpi_get_event_status | 300 | * FUNCTION: acpi_get_event_status |
525 | * | 301 | * |
526 | * PARAMETERS: Event - The fixed event | 302 | * PARAMETERS: Event - The fixed event |
@@ -575,379 +351,3 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) | |||
575 | } | 351 | } |
576 | 352 | ||
577 | ACPI_EXPORT_SYMBOL(acpi_get_event_status) | 353 | ACPI_EXPORT_SYMBOL(acpi_get_event_status) |
578 | |||
579 | /******************************************************************************* | ||
580 | * | ||
581 | * FUNCTION: acpi_get_gpe_status | ||
582 | * | ||
583 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
584 | * gpe_number - GPE level within the GPE block | ||
585 | * event_status - Where the current status of the event will | ||
586 | * be returned | ||
587 | * | ||
588 | * RETURN: Status | ||
589 | * | ||
590 | * DESCRIPTION: Get status of an event (general purpose) | ||
591 | * | ||
592 | ******************************************************************************/ | ||
593 | acpi_status | ||
594 | acpi_get_gpe_status(acpi_handle gpe_device, | ||
595 | u32 gpe_number, acpi_event_status *event_status) | ||
596 | { | ||
597 | acpi_status status = AE_OK; | ||
598 | struct acpi_gpe_event_info *gpe_event_info; | ||
599 | acpi_cpu_flags flags; | ||
600 | |||
601 | ACPI_FUNCTION_TRACE(acpi_get_gpe_status); | ||
602 | |||
603 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
604 | |||
605 | /* Ensure that we have a valid GPE number */ | ||
606 | |||
607 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
608 | if (!gpe_event_info) { | ||
609 | status = AE_BAD_PARAMETER; | ||
610 | goto unlock_and_exit; | ||
611 | } | ||
612 | |||
613 | /* Obtain status on the requested GPE number */ | ||
614 | |||
615 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); | ||
616 | |||
617 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | ||
618 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | ||
619 | |||
620 | unlock_and_exit: | ||
621 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
622 | return_ACPI_STATUS(status); | ||
623 | } | ||
624 | |||
625 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) | ||
626 | /******************************************************************************* | ||
627 | * | ||
628 | * FUNCTION: acpi_install_gpe_block | ||
629 | * | ||
630 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | ||
631 | * gpe_block_address - Address and space_iD | ||
632 | * register_count - Number of GPE register pairs in the block | ||
633 | * interrupt_number - H/W interrupt for the block | ||
634 | * | ||
635 | * RETURN: Status | ||
636 | * | ||
637 | * DESCRIPTION: Create and Install a block of GPE registers | ||
638 | * | ||
639 | ******************************************************************************/ | ||
640 | acpi_status | ||
641 | acpi_install_gpe_block(acpi_handle gpe_device, | ||
642 | struct acpi_generic_address *gpe_block_address, | ||
643 | u32 register_count, u32 interrupt_number) | ||
644 | { | ||
645 | acpi_status status = AE_OK; | ||
646 | union acpi_operand_object *obj_desc; | ||
647 | struct acpi_namespace_node *node; | ||
648 | struct acpi_gpe_block_info *gpe_block; | ||
649 | |||
650 | ACPI_FUNCTION_TRACE(acpi_install_gpe_block); | ||
651 | |||
652 | if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { | ||
653 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
654 | } | ||
655 | |||
656 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
657 | if (ACPI_FAILURE(status)) { | ||
658 | return (status); | ||
659 | } | ||
660 | |||
661 | node = acpi_ns_validate_handle(gpe_device); | ||
662 | if (!node) { | ||
663 | status = AE_BAD_PARAMETER; | ||
664 | goto unlock_and_exit; | ||
665 | } | ||
666 | |||
667 | /* | ||
668 | * For user-installed GPE Block Devices, the gpe_block_base_number | ||
669 | * is always zero | ||
670 | */ | ||
671 | status = | ||
672 | acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, | ||
673 | interrupt_number, &gpe_block); | ||
674 | if (ACPI_FAILURE(status)) { | ||
675 | goto unlock_and_exit; | ||
676 | } | ||
677 | |||
678 | /* Install block in the device_object attached to the node */ | ||
679 | |||
680 | obj_desc = acpi_ns_get_attached_object(node); | ||
681 | if (!obj_desc) { | ||
682 | |||
683 | /* | ||
684 | * No object, create a new one (Device nodes do not always have | ||
685 | * an attached object) | ||
686 | */ | ||
687 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); | ||
688 | if (!obj_desc) { | ||
689 | status = AE_NO_MEMORY; | ||
690 | goto unlock_and_exit; | ||
691 | } | ||
692 | |||
693 | status = | ||
694 | acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); | ||
695 | |||
696 | /* Remove local reference to the object */ | ||
697 | |||
698 | acpi_ut_remove_reference(obj_desc); | ||
699 | |||
700 | if (ACPI_FAILURE(status)) { | ||
701 | goto unlock_and_exit; | ||
702 | } | ||
703 | } | ||
704 | |||
705 | /* Now install the GPE block in the device_object */ | ||
706 | |||
707 | obj_desc->device.gpe_block = gpe_block; | ||
708 | |||
709 | unlock_and_exit: | ||
710 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
711 | return_ACPI_STATUS(status); | ||
712 | } | ||
713 | |||
714 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) | ||
715 | |||
716 | /******************************************************************************* | ||
717 | * | ||
718 | * FUNCTION: acpi_remove_gpe_block | ||
719 | * | ||
720 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | ||
721 | * | ||
722 | * RETURN: Status | ||
723 | * | ||
724 | * DESCRIPTION: Remove a previously installed block of GPE registers | ||
725 | * | ||
726 | ******************************************************************************/ | ||
727 | acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) | ||
728 | { | ||
729 | union acpi_operand_object *obj_desc; | ||
730 | acpi_status status; | ||
731 | struct acpi_namespace_node *node; | ||
732 | |||
733 | ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); | ||
734 | |||
735 | if (!gpe_device) { | ||
736 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
737 | } | ||
738 | |||
739 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
740 | if (ACPI_FAILURE(status)) { | ||
741 | return (status); | ||
742 | } | ||
743 | |||
744 | node = acpi_ns_validate_handle(gpe_device); | ||
745 | if (!node) { | ||
746 | status = AE_BAD_PARAMETER; | ||
747 | goto unlock_and_exit; | ||
748 | } | ||
749 | |||
750 | /* Get the device_object attached to the node */ | ||
751 | |||
752 | obj_desc = acpi_ns_get_attached_object(node); | ||
753 | if (!obj_desc || !obj_desc->device.gpe_block) { | ||
754 | return_ACPI_STATUS(AE_NULL_OBJECT); | ||
755 | } | ||
756 | |||
757 | /* Delete the GPE block (but not the device_object) */ | ||
758 | |||
759 | status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); | ||
760 | if (ACPI_SUCCESS(status)) { | ||
761 | obj_desc->device.gpe_block = NULL; | ||
762 | } | ||
763 | |||
764 | unlock_and_exit: | ||
765 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
766 | return_ACPI_STATUS(status); | ||
767 | } | ||
768 | |||
769 | ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) | ||
770 | |||
771 | /******************************************************************************* | ||
772 | * | ||
773 | * FUNCTION: acpi_get_gpe_device | ||
774 | * | ||
775 | * PARAMETERS: Index - System GPE index (0-current_gpe_count) | ||
776 | * gpe_device - Where the parent GPE Device is returned | ||
777 | * | ||
778 | * RETURN: Status | ||
779 | * | ||
780 | * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL | ||
781 | * gpe device indicates that the gpe number is contained in one of | ||
782 | * the FADT-defined gpe blocks. Otherwise, the GPE block device. | ||
783 | * | ||
784 | ******************************************************************************/ | ||
785 | acpi_status | ||
786 | acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) | ||
787 | { | ||
788 | struct acpi_gpe_device_info info; | ||
789 | acpi_status status; | ||
790 | |||
791 | ACPI_FUNCTION_TRACE(acpi_get_gpe_device); | ||
792 | |||
793 | if (!gpe_device) { | ||
794 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
795 | } | ||
796 | |||
797 | if (index >= acpi_current_gpe_count) { | ||
798 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
799 | } | ||
800 | |||
801 | /* Setup and walk the GPE list */ | ||
802 | |||
803 | info.index = index; | ||
804 | info.status = AE_NOT_EXIST; | ||
805 | info.gpe_device = NULL; | ||
806 | info.next_block_base_index = 0; | ||
807 | |||
808 | status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); | ||
809 | if (ACPI_FAILURE(status)) { | ||
810 | return_ACPI_STATUS(status); | ||
811 | } | ||
812 | |||
813 | *gpe_device = info.gpe_device; | ||
814 | return_ACPI_STATUS(info.status); | ||
815 | } | ||
816 | |||
817 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | ||
818 | |||
819 | /******************************************************************************* | ||
820 | * | ||
821 | * FUNCTION: acpi_ev_get_gpe_device | ||
822 | * | ||
823 | * PARAMETERS: GPE_WALK_CALLBACK | ||
824 | * | ||
825 | * RETURN: Status | ||
826 | * | ||
827 | * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE | ||
828 | * block device. NULL if the GPE is one of the FADT-defined GPEs. | ||
829 | * | ||
830 | ******************************************************************************/ | ||
831 | static acpi_status | ||
832 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
833 | struct acpi_gpe_block_info *gpe_block, void *context) | ||
834 | { | ||
835 | struct acpi_gpe_device_info *info = context; | ||
836 | |||
837 | /* Increment Index by the number of GPEs in this block */ | ||
838 | |||
839 | info->next_block_base_index += gpe_block->gpe_count; | ||
840 | |||
841 | if (info->index < info->next_block_base_index) { | ||
842 | /* | ||
843 | * The GPE index is within this block, get the node. Leave the node | ||
844 | * NULL for the FADT-defined GPEs | ||
845 | */ | ||
846 | if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { | ||
847 | info->gpe_device = gpe_block->node; | ||
848 | } | ||
849 | |||
850 | info->status = AE_OK; | ||
851 | return (AE_CTRL_END); | ||
852 | } | ||
853 | |||
854 | return (AE_OK); | ||
855 | } | ||
856 | |||
857 | /****************************************************************************** | ||
858 | * | ||
859 | * FUNCTION: acpi_disable_all_gpes | ||
860 | * | ||
861 | * PARAMETERS: None | ||
862 | * | ||
863 | * RETURN: Status | ||
864 | * | ||
865 | * DESCRIPTION: Disable and clear all GPEs in all GPE blocks | ||
866 | * | ||
867 | ******************************************************************************/ | ||
868 | |||
869 | acpi_status acpi_disable_all_gpes(void) | ||
870 | { | ||
871 | acpi_status status; | ||
872 | |||
873 | ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); | ||
874 | |||
875 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
876 | if (ACPI_FAILURE(status)) { | ||
877 | return_ACPI_STATUS(status); | ||
878 | } | ||
879 | |||
880 | status = acpi_hw_disable_all_gpes(); | ||
881 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
882 | |||
883 | return_ACPI_STATUS(status); | ||
884 | } | ||
885 | |||
886 | /****************************************************************************** | ||
887 | * | ||
888 | * FUNCTION: acpi_enable_all_runtime_gpes | ||
889 | * | ||
890 | * PARAMETERS: None | ||
891 | * | ||
892 | * RETURN: Status | ||
893 | * | ||
894 | * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks | ||
895 | * | ||
896 | ******************************************************************************/ | ||
897 | |||
898 | acpi_status acpi_enable_all_runtime_gpes(void) | ||
899 | { | ||
900 | acpi_status status; | ||
901 | |||
902 | ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); | ||
903 | |||
904 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
905 | if (ACPI_FAILURE(status)) { | ||
906 | return_ACPI_STATUS(status); | ||
907 | } | ||
908 | |||
909 | status = acpi_hw_enable_all_runtime_gpes(); | ||
910 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
911 | |||
912 | return_ACPI_STATUS(status); | ||
913 | } | ||
914 | |||
915 | /****************************************************************************** | ||
916 | * | ||
917 | * FUNCTION: acpi_update_gpes | ||
918 | * | ||
919 | * PARAMETERS: None | ||
920 | * | ||
921 | * RETURN: None | ||
922 | * | ||
923 | * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and | ||
924 | * are not pointed to by any device _PRW methods indicating that | ||
925 | * these GPEs are generally intended for system or device wakeup | ||
926 | * (such GPEs have to be enabled directly when the devices whose | ||
927 | * _PRW methods point to them are set up for wakeup signaling). | ||
928 | * | ||
929 | ******************************************************************************/ | ||
930 | |||
931 | acpi_status acpi_update_gpes(void) | ||
932 | { | ||
933 | acpi_status status; | ||
934 | |||
935 | ACPI_FUNCTION_TRACE(acpi_update_gpes); | ||
936 | |||
937 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
938 | if (ACPI_FAILURE(status)) { | ||
939 | return_ACPI_STATUS(status); | ||
940 | } else if (acpi_all_gpes_initialized) { | ||
941 | goto unlock; | ||
942 | } | ||
943 | |||
944 | status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); | ||
945 | if (ACPI_SUCCESS(status)) { | ||
946 | acpi_all_gpes_initialized = TRUE; | ||
947 | } | ||
948 | |||
949 | unlock: | ||
950 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
951 | |||
952 | return_ACPI_STATUS(status); | ||
953 | } | ||
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c new file mode 100644 index 00000000000..52aaff3df56 --- /dev/null +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -0,0 +1,696 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2011, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acevents.h" | ||
47 | #include "acnamesp.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_EVENTS | ||
50 | ACPI_MODULE_NAME("evxfgpe") | ||
51 | |||
52 | /****************************************************************************** | ||
53 | * | ||
54 | * FUNCTION: acpi_update_all_gpes | ||
55 | * | ||
56 | * PARAMETERS: None | ||
57 | * | ||
58 | * RETURN: Status | ||
59 | * | ||
60 | * DESCRIPTION: Complete GPE initialization and enable all GPEs that have | ||
61 | * associated _Lxx or _Exx methods and are not pointed to by any | ||
62 | * device _PRW methods (this indicates that these GPEs are | ||
63 | * generally intended for system or device wakeup. Such GPEs | ||
64 | * have to be enabled directly when the devices whose _PRW | ||
65 | * methods point to them are set up for wakeup signaling.) | ||
66 | * | ||
67 | * NOTE: Should be called after any GPEs are added to the system. Primarily, | ||
68 | * after the system _PRW methods have been run, but also after a GPE Block | ||
69 | * Device has been added or if any new GPE methods have been added via a | ||
70 | * dynamic table load. | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | acpi_status acpi_update_all_gpes(void) | ||
75 | { | ||
76 | acpi_status status; | ||
77 | |||
78 | ACPI_FUNCTION_TRACE(acpi_update_all_gpes); | ||
79 | |||
80 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
81 | if (ACPI_FAILURE(status)) { | ||
82 | return_ACPI_STATUS(status); | ||
83 | } | ||
84 | |||
85 | if (acpi_gbl_all_gpes_initialized) { | ||
86 | goto unlock_and_exit; | ||
87 | } | ||
88 | |||
89 | status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); | ||
90 | if (ACPI_SUCCESS(status)) { | ||
91 | acpi_gbl_all_gpes_initialized = TRUE; | ||
92 | } | ||
93 | |||
94 | unlock_and_exit: | ||
95 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
96 | |||
97 | return_ACPI_STATUS(status); | ||
98 | } | ||
99 | |||
100 | ACPI_EXPORT_SYMBOL(acpi_update_all_gpes) | ||
101 | |||
102 | /******************************************************************************* | ||
103 | * | ||
104 | * FUNCTION: acpi_enable_gpe | ||
105 | * | ||
106 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
107 | * gpe_number - GPE level within the GPE block | ||
108 | * | ||
109 | * RETURN: Status | ||
110 | * | ||
111 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is | ||
112 | * hardware-enabled. | ||
113 | * | ||
114 | ******************************************************************************/ | ||
115 | |||
116 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
117 | { | ||
118 | acpi_status status = AE_BAD_PARAMETER; | ||
119 | struct acpi_gpe_event_info *gpe_event_info; | ||
120 | acpi_cpu_flags flags; | ||
121 | |||
122 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); | ||
123 | |||
124 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
125 | |||
126 | /* Ensure that we have a valid GPE number */ | ||
127 | |||
128 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
129 | if (gpe_event_info) { | ||
130 | status = acpi_ev_add_gpe_reference(gpe_event_info); | ||
131 | } | ||
132 | |||
133 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
134 | return_ACPI_STATUS(status); | ||
135 | } | ||
136 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | ||
137 | |||
138 | /******************************************************************************* | ||
139 | * | ||
140 | * FUNCTION: acpi_disable_gpe | ||
141 | * | ||
142 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
143 | * gpe_number - GPE level within the GPE block | ||
144 | * | ||
145 | * RETURN: Status | ||
146 | * | ||
147 | * DESCRIPTION: Remove a reference to a GPE. When the last reference is | ||
148 | * removed, only then is the GPE disabled (for runtime GPEs), or | ||
149 | * the GPE mask bit disabled (for wake GPEs) | ||
150 | * | ||
151 | ******************************************************************************/ | ||
152 | |||
153 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
154 | { | ||
155 | acpi_status status = AE_BAD_PARAMETER; | ||
156 | struct acpi_gpe_event_info *gpe_event_info; | ||
157 | acpi_cpu_flags flags; | ||
158 | |||
159 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); | ||
160 | |||
161 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
162 | |||
163 | /* Ensure that we have a valid GPE number */ | ||
164 | |||
165 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
166 | if (gpe_event_info) { | ||
167 | status = acpi_ev_remove_gpe_reference(gpe_event_info) ; | ||
168 | } | ||
169 | |||
170 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
171 | return_ACPI_STATUS(status); | ||
172 | } | ||
173 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | ||
174 | |||
175 | |||
176 | /******************************************************************************* | ||
177 | * | ||
178 | * FUNCTION: acpi_setup_gpe_for_wake | ||
179 | * | ||
180 | * PARAMETERS: wake_device - Device associated with the GPE (via _PRW) | ||
181 | * gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
182 | * gpe_number - GPE level within the GPE block | ||
183 | * | ||
184 | * RETURN: Status | ||
185 | * | ||
186 | * DESCRIPTION: Mark a GPE as having the ability to wake the system. This | ||
187 | * interface is intended to be used as the host executes the | ||
188 | * _PRW methods (Power Resources for Wake) in the system tables. | ||
189 | * Each _PRW appears under a Device Object (The wake_device), and | ||
190 | * contains the info for the wake GPE associated with the | ||
191 | * wake_device. | ||
192 | * | ||
193 | ******************************************************************************/ | ||
194 | acpi_status | ||
195 | acpi_setup_gpe_for_wake(acpi_handle wake_device, | ||
196 | acpi_handle gpe_device, u32 gpe_number) | ||
197 | { | ||
198 | acpi_status status = AE_BAD_PARAMETER; | ||
199 | struct acpi_gpe_event_info *gpe_event_info; | ||
200 | struct acpi_namespace_node *device_node; | ||
201 | struct acpi_gpe_notify_object *notify_object; | ||
202 | acpi_cpu_flags flags; | ||
203 | u8 gpe_dispatch_mask; | ||
204 | |||
205 | ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); | ||
206 | |||
207 | /* Parameter Validation */ | ||
208 | |||
209 | if (!wake_device) { | ||
210 | /* | ||
211 | * By forcing wake_device to be valid, we automatically enable the | ||
212 | * implicit notify feature on all hosts. | ||
213 | */ | ||
214 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
215 | } | ||
216 | |||
217 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
218 | |||
219 | /* Ensure that we have a valid GPE number */ | ||
220 | |||
221 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
222 | if (!gpe_event_info) { | ||
223 | goto unlock_and_exit; | ||
224 | } | ||
225 | |||
226 | if (wake_device == ACPI_ROOT_OBJECT) { | ||
227 | goto out; | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * If there is no method or handler for this GPE, then the | ||
232 | * wake_device will be notified whenever this GPE fires (aka | ||
233 | * "implicit notify") Note: The GPE is assumed to be | ||
234 | * level-triggered (for windows compatibility). | ||
235 | */ | ||
236 | gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK; | ||
237 | if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE | ||
238 | && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) { | ||
239 | goto out; | ||
240 | } | ||
241 | |||
242 | /* Validate wake_device is of type Device */ | ||
243 | |||
244 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); | ||
245 | if (device_node->type != ACPI_TYPE_DEVICE) { | ||
246 | goto unlock_and_exit; | ||
247 | } | ||
248 | |||
249 | if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) { | ||
250 | gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | | ||
251 | ACPI_GPE_LEVEL_TRIGGERED); | ||
252 | gpe_event_info->dispatch.device.node = device_node; | ||
253 | gpe_event_info->dispatch.device.next = NULL; | ||
254 | } else { | ||
255 | /* There are multiple devices to notify implicitly. */ | ||
256 | |||
257 | notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object)); | ||
258 | if (!notify_object) { | ||
259 | status = AE_NO_MEMORY; | ||
260 | goto unlock_and_exit; | ||
261 | } | ||
262 | |||
263 | notify_object->node = device_node; | ||
264 | notify_object->next = gpe_event_info->dispatch.device.next; | ||
265 | gpe_event_info->dispatch.device.next = notify_object; | ||
266 | } | ||
267 | |||
268 | out: | ||
269 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
270 | status = AE_OK; | ||
271 | |||
272 | unlock_and_exit: | ||
273 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
274 | return_ACPI_STATUS(status); | ||
275 | } | ||
276 | ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake) | ||
277 | |||
278 | /******************************************************************************* | ||
279 | * | ||
280 | * FUNCTION: acpi_set_gpe_wake_mask | ||
281 | * | ||
282 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
283 | * gpe_number - GPE level within the GPE block | ||
284 | * Action - Enable or Disable | ||
285 | * | ||
286 | * RETURN: Status | ||
287 | * | ||
288 | * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must | ||
289 | * already be marked as a WAKE GPE. | ||
290 | * | ||
291 | ******************************************************************************/ | ||
292 | |||
293 | acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action) | ||
294 | { | ||
295 | acpi_status status = AE_OK; | ||
296 | struct acpi_gpe_event_info *gpe_event_info; | ||
297 | struct acpi_gpe_register_info *gpe_register_info; | ||
298 | acpi_cpu_flags flags; | ||
299 | u32 register_bit; | ||
300 | |||
301 | ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask); | ||
302 | |||
303 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
304 | |||
305 | /* | ||
306 | * Ensure that we have a valid GPE number and that this GPE is in | ||
307 | * fact a wake GPE | ||
308 | */ | ||
309 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
310 | if (!gpe_event_info) { | ||
311 | status = AE_BAD_PARAMETER; | ||
312 | goto unlock_and_exit; | ||
313 | } | ||
314 | |||
315 | if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
316 | status = AE_TYPE; | ||
317 | goto unlock_and_exit; | ||
318 | } | ||
319 | |||
320 | gpe_register_info = gpe_event_info->register_info; | ||
321 | if (!gpe_register_info) { | ||
322 | status = AE_NOT_EXIST; | ||
323 | goto unlock_and_exit; | ||
324 | } | ||
325 | |||
326 | register_bit = | ||
327 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
328 | |||
329 | /* Perform the action */ | ||
330 | |||
331 | switch (action) { | ||
332 | case ACPI_GPE_ENABLE: | ||
333 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, | ||
334 | (u8)register_bit); | ||
335 | break; | ||
336 | |||
337 | case ACPI_GPE_DISABLE: | ||
338 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, | ||
339 | (u8)register_bit); | ||
340 | break; | ||
341 | |||
342 | default: | ||
343 | ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); | ||
344 | status = AE_BAD_PARAMETER; | ||
345 | break; | ||
346 | } | ||
347 | |||
348 | unlock_and_exit: | ||
349 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
350 | return_ACPI_STATUS(status); | ||
351 | } | ||
352 | |||
353 | ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask) | ||
354 | |||
355 | /******************************************************************************* | ||
356 | * | ||
357 | * FUNCTION: acpi_clear_gpe | ||
358 | * | ||
359 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
360 | * gpe_number - GPE level within the GPE block | ||
361 | * | ||
362 | * RETURN: Status | ||
363 | * | ||
364 | * DESCRIPTION: Clear an ACPI event (general purpose) | ||
365 | * | ||
366 | ******************************************************************************/ | ||
367 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
368 | { | ||
369 | acpi_status status = AE_OK; | ||
370 | struct acpi_gpe_event_info *gpe_event_info; | ||
371 | acpi_cpu_flags flags; | ||
372 | |||
373 | ACPI_FUNCTION_TRACE(acpi_clear_gpe); | ||
374 | |||
375 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
376 | |||
377 | /* Ensure that we have a valid GPE number */ | ||
378 | |||
379 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
380 | if (!gpe_event_info) { | ||
381 | status = AE_BAD_PARAMETER; | ||
382 | goto unlock_and_exit; | ||
383 | } | ||
384 | |||
385 | status = acpi_hw_clear_gpe(gpe_event_info); | ||
386 | |||
387 | unlock_and_exit: | ||
388 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
389 | return_ACPI_STATUS(status); | ||
390 | } | ||
391 | |||
392 | ACPI_EXPORT_SYMBOL(acpi_clear_gpe) | ||
393 | |||
394 | /******************************************************************************* | ||
395 | * | ||
396 | * FUNCTION: acpi_get_gpe_status | ||
397 | * | ||
398 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
399 | * gpe_number - GPE level within the GPE block | ||
400 | * event_status - Where the current status of the event will | ||
401 | * be returned | ||
402 | * | ||
403 | * RETURN: Status | ||
404 | * | ||
405 | * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) | ||
406 | * | ||
407 | ******************************************************************************/ | ||
408 | acpi_status | ||
409 | acpi_get_gpe_status(acpi_handle gpe_device, | ||
410 | u32 gpe_number, acpi_event_status *event_status) | ||
411 | { | ||
412 | acpi_status status = AE_OK; | ||
413 | struct acpi_gpe_event_info *gpe_event_info; | ||
414 | acpi_cpu_flags flags; | ||
415 | |||
416 | ACPI_FUNCTION_TRACE(acpi_get_gpe_status); | ||
417 | |||
418 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
419 | |||
420 | /* Ensure that we have a valid GPE number */ | ||
421 | |||
422 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
423 | if (!gpe_event_info) { | ||
424 | status = AE_BAD_PARAMETER; | ||
425 | goto unlock_and_exit; | ||
426 | } | ||
427 | |||
428 | /* Obtain status on the requested GPE number */ | ||
429 | |||
430 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); | ||
431 | |||
432 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | ||
433 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | ||
434 | |||
435 | unlock_and_exit: | ||
436 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
437 | return_ACPI_STATUS(status); | ||
438 | } | ||
439 | |||
440 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) | ||
441 | |||
442 | /****************************************************************************** | ||
443 | * | ||
444 | * FUNCTION: acpi_disable_all_gpes | ||
445 | * | ||
446 | * PARAMETERS: None | ||
447 | * | ||
448 | * RETURN: Status | ||
449 | * | ||
450 | * DESCRIPTION: Disable and clear all GPEs in all GPE blocks | ||
451 | * | ||
452 | ******************************************************************************/ | ||
453 | |||
454 | acpi_status acpi_disable_all_gpes(void) | ||
455 | { | ||
456 | acpi_status status; | ||
457 | |||
458 | ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); | ||
459 | |||
460 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
461 | if (ACPI_FAILURE(status)) { | ||
462 | return_ACPI_STATUS(status); | ||
463 | } | ||
464 | |||
465 | status = acpi_hw_disable_all_gpes(); | ||
466 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
467 | |||
468 | return_ACPI_STATUS(status); | ||
469 | } | ||
470 | |||
471 | ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes) | ||
472 | |||
473 | /****************************************************************************** | ||
474 | * | ||
475 | * FUNCTION: acpi_enable_all_runtime_gpes | ||
476 | * | ||
477 | * PARAMETERS: None | ||
478 | * | ||
479 | * RETURN: Status | ||
480 | * | ||
481 | * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks | ||
482 | * | ||
483 | ******************************************************************************/ | ||
484 | |||
485 | acpi_status acpi_enable_all_runtime_gpes(void) | ||
486 | { | ||
487 | acpi_status status; | ||
488 | |||
489 | ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); | ||
490 | |||
491 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
492 | if (ACPI_FAILURE(status)) { | ||
493 | return_ACPI_STATUS(status); | ||
494 | } | ||
495 | |||
496 | status = acpi_hw_enable_all_runtime_gpes(); | ||
497 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
498 | |||
499 | return_ACPI_STATUS(status); | ||
500 | } | ||
501 | |||
502 | ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes) | ||
503 | |||
504 | /******************************************************************************* | ||
505 | * | ||
506 | * FUNCTION: acpi_install_gpe_block | ||
507 | * | ||
508 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | ||
509 | * gpe_block_address - Address and space_iD | ||
510 | * register_count - Number of GPE register pairs in the block | ||
511 | * interrupt_number - H/W interrupt for the block | ||
512 | * | ||
513 | * RETURN: Status | ||
514 | * | ||
515 | * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not | ||
516 | * enabled here. | ||
517 | * | ||
518 | ******************************************************************************/ | ||
519 | acpi_status | ||
520 | acpi_install_gpe_block(acpi_handle gpe_device, | ||
521 | struct acpi_generic_address *gpe_block_address, | ||
522 | u32 register_count, u32 interrupt_number) | ||
523 | { | ||
524 | acpi_status status; | ||
525 | union acpi_operand_object *obj_desc; | ||
526 | struct acpi_namespace_node *node; | ||
527 | struct acpi_gpe_block_info *gpe_block; | ||
528 | |||
529 | ACPI_FUNCTION_TRACE(acpi_install_gpe_block); | ||
530 | |||
531 | if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { | ||
532 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
533 | } | ||
534 | |||
535 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
536 | if (ACPI_FAILURE(status)) { | ||
537 | return (status); | ||
538 | } | ||
539 | |||
540 | node = acpi_ns_validate_handle(gpe_device); | ||
541 | if (!node) { | ||
542 | status = AE_BAD_PARAMETER; | ||
543 | goto unlock_and_exit; | ||
544 | } | ||
545 | |||
546 | /* | ||
547 | * For user-installed GPE Block Devices, the gpe_block_base_number | ||
548 | * is always zero | ||
549 | */ | ||
550 | status = | ||
551 | acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, | ||
552 | interrupt_number, &gpe_block); | ||
553 | if (ACPI_FAILURE(status)) { | ||
554 | goto unlock_and_exit; | ||
555 | } | ||
556 | |||
557 | /* Install block in the device_object attached to the node */ | ||
558 | |||
559 | obj_desc = acpi_ns_get_attached_object(node); | ||
560 | if (!obj_desc) { | ||
561 | |||
562 | /* | ||
563 | * No object, create a new one (Device nodes do not always have | ||
564 | * an attached object) | ||
565 | */ | ||
566 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); | ||
567 | if (!obj_desc) { | ||
568 | status = AE_NO_MEMORY; | ||
569 | goto unlock_and_exit; | ||
570 | } | ||
571 | |||
572 | status = | ||
573 | acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); | ||
574 | |||
575 | /* Remove local reference to the object */ | ||
576 | |||
577 | acpi_ut_remove_reference(obj_desc); | ||
578 | |||
579 | if (ACPI_FAILURE(status)) { | ||
580 | goto unlock_and_exit; | ||
581 | } | ||
582 | } | ||
583 | |||
584 | /* Now install the GPE block in the device_object */ | ||
585 | |||
586 | obj_desc->device.gpe_block = gpe_block; | ||
587 | |||
588 | unlock_and_exit: | ||
589 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
590 | return_ACPI_STATUS(status); | ||
591 | } | ||
592 | |||
593 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) | ||
594 | |||
595 | /******************************************************************************* | ||
596 | * | ||
597 | * FUNCTION: acpi_remove_gpe_block | ||
598 | * | ||
599 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | ||
600 | * | ||
601 | * RETURN: Status | ||
602 | * | ||
603 | * DESCRIPTION: Remove a previously installed block of GPE registers | ||
604 | * | ||
605 | ******************************************************************************/ | ||
606 | acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) | ||
607 | { | ||
608 | union acpi_operand_object *obj_desc; | ||
609 | acpi_status status; | ||
610 | struct acpi_namespace_node *node; | ||
611 | |||
612 | ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); | ||
613 | |||
614 | if (!gpe_device) { | ||
615 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
616 | } | ||
617 | |||
618 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
619 | if (ACPI_FAILURE(status)) { | ||
620 | return (status); | ||
621 | } | ||
622 | |||
623 | node = acpi_ns_validate_handle(gpe_device); | ||
624 | if (!node) { | ||
625 | status = AE_BAD_PARAMETER; | ||
626 | goto unlock_and_exit; | ||
627 | } | ||
628 | |||
629 | /* Get the device_object attached to the node */ | ||
630 | |||
631 | obj_desc = acpi_ns_get_attached_object(node); | ||
632 | if (!obj_desc || !obj_desc->device.gpe_block) { | ||
633 | return_ACPI_STATUS(AE_NULL_OBJECT); | ||
634 | } | ||
635 | |||
636 | /* Delete the GPE block (but not the device_object) */ | ||
637 | |||
638 | status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); | ||
639 | if (ACPI_SUCCESS(status)) { | ||
640 | obj_desc->device.gpe_block = NULL; | ||
641 | } | ||
642 | |||
643 | unlock_and_exit: | ||
644 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
645 | return_ACPI_STATUS(status); | ||
646 | } | ||
647 | |||
648 | ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) | ||
649 | |||
650 | /******************************************************************************* | ||
651 | * | ||
652 | * FUNCTION: acpi_get_gpe_device | ||
653 | * | ||
654 | * PARAMETERS: Index - System GPE index (0-current_gpe_count) | ||
655 | * gpe_device - Where the parent GPE Device is returned | ||
656 | * | ||
657 | * RETURN: Status | ||
658 | * | ||
659 | * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL | ||
660 | * gpe device indicates that the gpe number is contained in one of | ||
661 | * the FADT-defined gpe blocks. Otherwise, the GPE block device. | ||
662 | * | ||
663 | ******************************************************************************/ | ||
664 | acpi_status | ||
665 | acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) | ||
666 | { | ||
667 | struct acpi_gpe_device_info info; | ||
668 | acpi_status status; | ||
669 | |||
670 | ACPI_FUNCTION_TRACE(acpi_get_gpe_device); | ||
671 | |||
672 | if (!gpe_device) { | ||
673 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
674 | } | ||
675 | |||
676 | if (index >= acpi_current_gpe_count) { | ||
677 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
678 | } | ||
679 | |||
680 | /* Setup and walk the GPE list */ | ||
681 | |||
682 | info.index = index; | ||
683 | info.status = AE_NOT_EXIST; | ||
684 | info.gpe_device = NULL; | ||
685 | info.next_block_base_index = 0; | ||
686 | |||
687 | status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); | ||
688 | if (ACPI_FAILURE(status)) { | ||
689 | return_ACPI_STATUS(status); | ||
690 | } | ||
691 | |||
692 | *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device); | ||
693 | return_ACPI_STATUS(info.status); | ||
694 | } | ||
695 | |||
696 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | ||
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index ce9314f7945..c85c8c45599 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -110,9 +110,39 @@ acpi_install_address_space_handler(acpi_handle device, | |||
110 | goto unlock_and_exit; | 110 | goto unlock_and_exit; |
111 | } | 111 | } |
112 | 112 | ||
113 | /* Run all _REG methods for this address space */ | 113 | /* |
114 | * For the default space_iDs, (the IDs for which there are default region handlers | ||
115 | * installed) Only execute the _REG methods if the global initialization _REG | ||
116 | * methods have already been run (via acpi_initialize_objects). In other words, | ||
117 | * we will defer the execution of the _REG methods for these space_iDs until | ||
118 | * execution of acpi_initialize_objects. This is done because we need the handlers | ||
119 | * for the default spaces (mem/io/pci/table) to be installed before we can run | ||
120 | * any control methods (or _REG methods). There is known BIOS code that depends | ||
121 | * on this. | ||
122 | * | ||
123 | * For all other space_iDs, we can safely execute the _REG methods immediately. | ||
124 | * This means that for IDs like embedded_controller, this function should be called | ||
125 | * only after acpi_enable_subsystem has been called. | ||
126 | */ | ||
127 | switch (space_id) { | ||
128 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
129 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
130 | case ACPI_ADR_SPACE_PCI_CONFIG: | ||
131 | case ACPI_ADR_SPACE_DATA_TABLE: | ||
132 | |||
133 | if (acpi_gbl_reg_methods_executed) { | ||
134 | |||
135 | /* Run all _REG methods for this address space */ | ||
136 | |||
137 | status = acpi_ev_execute_reg_methods(node, space_id); | ||
138 | } | ||
139 | break; | ||
140 | |||
141 | default: | ||
114 | 142 | ||
115 | status = acpi_ev_execute_reg_methods(node, space_id); | 143 | status = acpi_ev_execute_reg_methods(node, space_id); |
144 | break; | ||
145 | } | ||
116 | 146 | ||
117 | unlock_and_exit: | 147 | unlock_and_exit: |
118 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 148 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 18832205b63..745a42b401f 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index b73bc50c5b7..74162a11817 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 3c61b48c73f..e7b372d1766 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -482,13 +482,11 @@ acpi_ex_create_method(u8 * aml_start, | |||
482 | obj_desc->method.aml_length = aml_length; | 482 | obj_desc->method.aml_length = aml_length; |
483 | 483 | ||
484 | /* | 484 | /* |
485 | * Disassemble the method flags. Split off the Arg Count | 485 | * Disassemble the method flags. Split off the arg_count, Serialized |
486 | * for efficiency | 486 | * flag, and sync_level for efficiency. |
487 | */ | 487 | */ |
488 | method_flags = (u8) operand[1]->integer.value; | 488 | method_flags = (u8) operand[1]->integer.value; |
489 | 489 | ||
490 | obj_desc->method.method_flags = | ||
491 | (u8) (method_flags & ~AML_METHOD_ARG_COUNT); | ||
492 | obj_desc->method.param_count = | 490 | obj_desc->method.param_count = |
493 | (u8) (method_flags & AML_METHOD_ARG_COUNT); | 491 | (u8) (method_flags & AML_METHOD_ARG_COUNT); |
494 | 492 | ||
@@ -497,6 +495,8 @@ acpi_ex_create_method(u8 * aml_start, | |||
497 | * created for this method when it is parsed. | 495 | * created for this method when it is parsed. |
498 | */ | 496 | */ |
499 | if (method_flags & AML_METHOD_SERIALIZED) { | 497 | if (method_flags & AML_METHOD_SERIALIZED) { |
498 | obj_desc->method.info_flags = ACPI_METHOD_SERIALIZED; | ||
499 | |||
500 | /* | 500 | /* |
501 | * ACPI 1.0: sync_level = 0 | 501 | * ACPI 1.0: sync_level = 0 |
502 | * ACPI 2.0: sync_level = sync_level in method declaration | 502 | * ACPI 2.0: sync_level = sync_level in method declaration |
diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index be8c98b480d..c7a2f1edd28 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index f067bbb0d96..61b8c0e8b74 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -122,7 +122,7 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = { | |||
122 | 122 | ||
123 | static struct acpi_exdump_info acpi_ex_dump_method[9] = { | 123 | static struct acpi_exdump_info acpi_ex_dump_method[9] = { |
124 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, | 124 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, |
125 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"}, | 125 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.info_flags), "Info Flags"}, |
126 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), | 126 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), |
127 | "Parameter Count"}, | 127 | "Parameter Count"}, |
128 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, | 128 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, |
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index f17d2ff0031..0bde2230c02 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 38293fd3e08..f915a7f3f92 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -280,13 +280,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
280 | if (ACPI_FAILURE(status)) { | 280 | if (ACPI_FAILURE(status)) { |
281 | if (status == AE_NOT_IMPLEMENTED) { | 281 | if (status == AE_NOT_IMPLEMENTED) { |
282 | ACPI_ERROR((AE_INFO, | 282 | ACPI_ERROR((AE_INFO, |
283 | "Region %s(0x%X) not implemented", | 283 | "Region %s (ID=%u) not implemented", |
284 | acpi_ut_get_region_name(rgn_desc->region. | 284 | acpi_ut_get_region_name(rgn_desc->region. |
285 | space_id), | 285 | space_id), |
286 | rgn_desc->region.space_id)); | 286 | rgn_desc->region.space_id)); |
287 | } else if (status == AE_NOT_EXIST) { | 287 | } else if (status == AE_NOT_EXIST) { |
288 | ACPI_ERROR((AE_INFO, | 288 | ACPI_ERROR((AE_INFO, |
289 | "Region %s(0x%X) has no handler", | 289 | "Region %s (ID=%u) has no handler", |
290 | acpi_ut_get_region_name(rgn_desc->region. | 290 | acpi_ut_get_region_name(rgn_desc->region. |
291 | space_id), | 291 | space_id), |
292 | rgn_desc->region.space_id)); | 292 | rgn_desc->region.space_id)); |
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 95db4be0877..703d88ed0b3 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 6af14e43f83..be1c56ead65 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index d11e539ef76..49ec049c157 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 84e4d185aa2..236ead14b7f 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index 10e104cf0fb..2571b4a310f 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 7a08d23befc..1b48d9d28c9 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 4b50730cf9a..f4a2787e8e9 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 7aae29f73d3..cc95e200040 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index de17e10da0e..f0d5e14f1f2 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index 1fa4289a687..55997e46948 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index 7ca35ea8ace..db502cd7d93 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 8c97cfd6a0f..e3bb00ccdff 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 1624436ba4c..c0c8842dd34 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index d4af684620c..a979017d56b 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c | |||
@@ -7,7 +7,7 @@ | |||
7 | *****************************************************************************/ | 7 | *****************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2010, Intel Corp. | 10 | * Copyright (C) 2000 - 2011, Intel Corp. |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index e972b667b09..dc665cc554d 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 675aaa91a77..df66e7b686b 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 4093522eed4..8ad93146dd3 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index b44274a0b62..fc380d3d45a 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 14750db2a1b..f610d88a66b 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -62,10 +62,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
62 | * PARAMETERS: gpe_event_info - Info block for the GPE | 62 | * PARAMETERS: gpe_event_info - Info block for the GPE |
63 | * gpe_register_info - Info block for the GPE register | 63 | * gpe_register_info - Info block for the GPE register |
64 | * | 64 | * |
65 | * RETURN: Status | 65 | * RETURN: Register mask with a one in the GPE bit position |
66 | * | 66 | * |
67 | * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given | 67 | * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the |
68 | * GPE set. | 68 | * correct position for the input GPE. |
69 | * | 69 | * |
70 | ******************************************************************************/ | 70 | ******************************************************************************/ |
71 | 71 | ||
@@ -85,12 +85,12 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, | |||
85 | * | 85 | * |
86 | * RETURN: Status | 86 | * RETURN: Status |
87 | * | 87 | * |
88 | * DESCRIPTION: Enable or disable a single GPE in its enable register. | 88 | * DESCRIPTION: Enable or disable a single GPE in the parent enable register. |
89 | * | 89 | * |
90 | ******************************************************************************/ | 90 | ******************************************************************************/ |
91 | 91 | ||
92 | acpi_status | 92 | acpi_status |
93 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) | 93 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) |
94 | { | 94 | { |
95 | struct acpi_gpe_register_info *gpe_register_info; | 95 | struct acpi_gpe_register_info *gpe_register_info; |
96 | acpi_status status; | 96 | acpi_status status; |
@@ -113,14 +113,20 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) | |||
113 | return (status); | 113 | return (status); |
114 | } | 114 | } |
115 | 115 | ||
116 | /* Set ot clear just the bit that corresponds to this GPE */ | 116 | /* Set or clear just the bit that corresponds to this GPE */ |
117 | 117 | ||
118 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, | 118 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, |
119 | gpe_register_info); | 119 | gpe_register_info); |
120 | switch (action) { | 120 | switch (action) { |
121 | case ACPI_GPE_COND_ENABLE: | 121 | case ACPI_GPE_CONDITIONAL_ENABLE: |
122 | if (!(register_bit & gpe_register_info->enable_for_run)) | 122 | |
123 | /* Only enable if the enable_for_run bit is set */ | ||
124 | |||
125 | if (!(register_bit & gpe_register_info->enable_for_run)) { | ||
123 | return (AE_BAD_PARAMETER); | 126 | return (AE_BAD_PARAMETER); |
127 | } | ||
128 | |||
129 | /*lint -fallthrough */ | ||
124 | 130 | ||
125 | case ACPI_GPE_ENABLE: | 131 | case ACPI_GPE_ENABLE: |
126 | ACPI_SET_BIT(enable_mask, register_bit); | 132 | ACPI_SET_BIT(enable_mask, register_bit); |
@@ -131,7 +137,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) | |||
131 | break; | 137 | break; |
132 | 138 | ||
133 | default: | 139 | default: |
134 | ACPI_ERROR((AE_INFO, "Invalid action\n")); | 140 | ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action)); |
135 | return (AE_BAD_PARAMETER); | 141 | return (AE_BAD_PARAMETER); |
136 | } | 142 | } |
137 | 143 | ||
@@ -168,13 +174,13 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | |||
168 | return (AE_NOT_EXIST); | 174 | return (AE_NOT_EXIST); |
169 | } | 175 | } |
170 | 176 | ||
171 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, | ||
172 | gpe_register_info); | ||
173 | |||
174 | /* | 177 | /* |
175 | * Write a one to the appropriate bit in the status register to | 178 | * Write a one to the appropriate bit in the status register to |
176 | * clear this GPE. | 179 | * clear this GPE. |
177 | */ | 180 | */ |
181 | register_bit = | ||
182 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
183 | |||
178 | status = acpi_hw_write(register_bit, | 184 | status = acpi_hw_write(register_bit, |
179 | &gpe_register_info->status_address); | 185 | &gpe_register_info->status_address); |
180 | 186 | ||
@@ -201,8 +207,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
201 | u32 in_byte; | 207 | u32 in_byte; |
202 | u32 register_bit; | 208 | u32 register_bit; |
203 | struct acpi_gpe_register_info *gpe_register_info; | 209 | struct acpi_gpe_register_info *gpe_register_info; |
204 | acpi_status status; | ||
205 | acpi_event_status local_event_status = 0; | 210 | acpi_event_status local_event_status = 0; |
211 | acpi_status status; | ||
206 | 212 | ||
207 | ACPI_FUNCTION_ENTRY(); | 213 | ACPI_FUNCTION_ENTRY(); |
208 | 214 | ||
diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c index ad21c7d8bf4..050fd227951 100644 --- a/drivers/acpi/acpica/hwpci.c +++ b/drivers/acpi/acpica/hwpci.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 5d1273b660a..55accb7018b 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -7,7 +7,7 @@ | |||
7 | ******************************************************************************/ | 7 | ******************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2010, Intel Corp. | 10 | * Copyright (C) 2000 - 2011, Intel Corp. |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 3796811276a..2ac28bbe882 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 1ef8e0bb250..9c8eb71a12f 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index e1d9c777b21..5f160587465 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 50cc3be7772..f75f81ad15c 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -80,14 +80,14 @@ acpi_status acpi_reset(void) | |||
80 | 80 | ||
81 | if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { | 81 | if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
82 | /* | 82 | /* |
83 | * For I/O space, write directly to the OSL. This bypasses the port | 83 | * For I/O space, write directly to the OSL. This |
84 | * validation mechanism, which may block a valid write to the reset | 84 | * bypasses the port validation mechanism, which may |
85 | * register. | 85 | * block a valid write to the reset register. Spec |
86 | * section 4.7.3.6 requires register width to be 8. | ||
86 | */ | 87 | */ |
87 | status = | 88 | status = |
88 | acpi_os_write_port((acpi_io_address) reset_reg->address, | 89 | acpi_os_write_port((acpi_io_address) reset_reg->address, |
89 | acpi_gbl_FADT.reset_value, | 90 | acpi_gbl_FADT.reset_value, 8); |
90 | reset_reg->bit_width); | ||
91 | } else { | 91 | } else { |
92 | /* Write the reset value to the reset register */ | 92 | /* Write the reset value to the reset register */ |
93 | 93 | ||
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 0cd925be5fc..d93172fd15a 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -163,9 +163,9 @@ acpi_status acpi_ns_root_initialize(void) | |||
163 | #else | 163 | #else |
164 | /* Mark this as a very SPECIAL method */ | 164 | /* Mark this as a very SPECIAL method */ |
165 | 165 | ||
166 | obj_desc->method.method_flags = | 166 | obj_desc->method.info_flags = |
167 | AML_METHOD_INTERNAL_ONLY; | 167 | ACPI_METHOD_INTERNAL_ONLY; |
168 | obj_desc->method.extra.implementation = | 168 | obj_desc->method.dispatch.implementation = |
169 | acpi_ut_osi_implementation; | 169 | acpi_ut_osi_implementation; |
170 | #endif | 170 | #endif |
171 | break; | 171 | break; |
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 1e5ff803d9a..1d0ef15d158 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -234,8 +234,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp | |||
234 | * modified the namespace. This is used for cleanup when the | 234 | * modified the namespace. This is used for cleanup when the |
235 | * method exits. | 235 | * method exits. |
236 | */ | 236 | */ |
237 | walk_state->method_desc->method.flags |= | 237 | walk_state->method_desc->method.info_flags |= |
238 | AOPOBJ_MODIFIED_NAMESPACE; | 238 | ACPI_METHOD_MODIFIED_NAMESPACE; |
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | ||
@@ -341,6 +341,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
341 | { | 341 | { |
342 | struct acpi_namespace_node *child_node = NULL; | 342 | struct acpi_namespace_node *child_node = NULL; |
343 | u32 level = 1; | 343 | u32 level = 1; |
344 | acpi_status status; | ||
344 | 345 | ||
345 | ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree); | 346 | ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree); |
346 | 347 | ||
@@ -348,6 +349,13 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
348 | return_VOID; | 349 | return_VOID; |
349 | } | 350 | } |
350 | 351 | ||
352 | /* Lock namespace for possible update */ | ||
353 | |||
354 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
355 | if (ACPI_FAILURE(status)) { | ||
356 | return_VOID; | ||
357 | } | ||
358 | |||
351 | /* | 359 | /* |
352 | * Traverse the tree of objects until we bubble back up | 360 | * Traverse the tree of objects until we bubble back up |
353 | * to where we started. | 361 | * to where we started. |
@@ -397,6 +405,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
397 | } | 405 | } |
398 | } | 406 | } |
399 | 407 | ||
408 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
400 | return_VOID; | 409 | return_VOID; |
401 | } | 410 | } |
402 | 411 | ||
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index a54dc39e304..b683cc2ff9d 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -624,9 +624,22 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
624 | acpi_owner_id owner_id, acpi_handle start_handle) | 624 | acpi_owner_id owner_id, acpi_handle start_handle) |
625 | { | 625 | { |
626 | struct acpi_walk_info info; | 626 | struct acpi_walk_info info; |
627 | acpi_status status; | ||
627 | 628 | ||
628 | ACPI_FUNCTION_ENTRY(); | 629 | ACPI_FUNCTION_ENTRY(); |
629 | 630 | ||
631 | /* | ||
632 | * Just lock the entire namespace for the duration of the dump. | ||
633 | * We don't want any changes to the namespace during this time, | ||
634 | * especially the temporary nodes since we are going to display | ||
635 | * them also. | ||
636 | */ | ||
637 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
638 | if (ACPI_FAILURE(status)) { | ||
639 | acpi_os_printf("Could not acquire namespace mutex\n"); | ||
640 | return; | ||
641 | } | ||
642 | |||
630 | info.debug_level = ACPI_LV_TABLES; | 643 | info.debug_level = ACPI_LV_TABLES; |
631 | info.owner_id = owner_id; | 644 | info.owner_id = owner_id; |
632 | info.display_type = display_type; | 645 | info.display_type = display_type; |
@@ -636,6 +649,8 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
636 | ACPI_NS_WALK_TEMP_NODES, | 649 | ACPI_NS_WALK_TEMP_NODES, |
637 | acpi_ns_dump_one_object, NULL, | 650 | acpi_ns_dump_one_object, NULL, |
638 | (void *)&info, NULL); | 651 | (void *)&info, NULL); |
652 | |||
653 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
639 | } | 654 | } |
640 | #endif /* ACPI_FUTURE_USAGE */ | 655 | #endif /* ACPI_FUTURE_USAGE */ |
641 | 656 | ||
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index d2a97921e24..2ed294b7a4d 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index f52829cc294..c1bd02b1a05 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -389,7 +389,7 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | |||
389 | * acpi_gbl_root_node->Object is NULL at PASS1. | 389 | * acpi_gbl_root_node->Object is NULL at PASS1. |
390 | */ | 390 | */ |
391 | if ((type == ACPI_TYPE_DEVICE) && parent_node->object) { | 391 | if ((type == ACPI_TYPE_DEVICE) && parent_node->object) { |
392 | method_obj->method.extra.handler = | 392 | method_obj->method.dispatch.handler = |
393 | parent_node->object->device.handler; | 393 | parent_node->object->device.handler; |
394 | } | 394 | } |
395 | 395 | ||
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 660a2728908..fd7c6380e29 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -577,9 +577,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle, | |||
577 | * as possible (without an NMI being received in the middle of | 577 | * as possible (without an NMI being received in the middle of |
578 | * this) - so disable NMIs and initialize the device: | 578 | * this) - so disable NMIs and initialize the device: |
579 | */ | 579 | */ |
580 | acpi_nmi_disable(); | ||
581 | status = acpi_ns_evaluate(info); | 580 | status = acpi_ns_evaluate(info); |
582 | acpi_nmi_enable(); | ||
583 | 581 | ||
584 | if (ACPI_SUCCESS(status)) { | 582 | if (ACPI_SUCCESS(status)) { |
585 | walk_info->num_INI++; | 583 | walk_info->num_INI++; |
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index df18be94fef..5f7dc691c18 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index d3104af57e1..d5fa520c3de 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 41a9213dd5a..3bb8bf105ea 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 5808c89e9fa..b3234fa795b 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 7096bcda0c7..9fb03fa8ffd 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index d1c13669266..1d76ac85b5e 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 4ef9f43ea92..973883babee 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 41102a84272..28b0d7a62b9 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index a7d6ad9c111..cb1b104a69a 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 2cd5be8fe10..345f0c3c6ad 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index ebef8a7fd70..c53f0040e49 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index b01e45a415e..3fd4526f3db 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -603,10 +603,9 @@ acpi_status acpi_install_method(u8 *buffer) | |||
603 | method_obj->method.param_count = (u8) | 603 | method_obj->method.param_count = (u8) |
604 | (method_flags & AML_METHOD_ARG_COUNT); | 604 | (method_flags & AML_METHOD_ARG_COUNT); |
605 | 605 | ||
606 | method_obj->method.method_flags = (u8) | ||
607 | (method_flags & ~AML_METHOD_ARG_COUNT); | ||
608 | |||
609 | if (method_flags & AML_METHOD_SERIALIZED) { | 606 | if (method_flags & AML_METHOD_SERIALIZED) { |
607 | method_obj->method.info_flags = ACPI_METHOD_SERIALIZED; | ||
608 | |||
610 | method_obj->method.sync_level = (u8) | 609 | method_obj->method.sync_level = (u8) |
611 | ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); | 610 | ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); |
612 | } | 611 | } |
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index a1f04e9b803..db7660f8b86 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 7df1a4c9527..e1fad0ee013 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 2f2e7760938..01dd70d1de5 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -655,7 +655,7 @@ acpi_ps_link_module_code(union acpi_parse_object *parent_op, | |||
655 | method_obj->method.aml_start = aml_start; | 655 | method_obj->method.aml_start = aml_start; |
656 | method_obj->method.aml_length = aml_length; | 656 | method_obj->method.aml_length = aml_length; |
657 | method_obj->method.owner_id = owner_id; | 657 | method_obj->method.owner_id = owner_id; |
658 | method_obj->method.flags |= AOPOBJ_MODULE_LEVEL; | 658 | method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL; |
659 | 659 | ||
660 | /* | 660 | /* |
661 | * Save the parent node in next_object. This is cheating, but we | 661 | * Save the parent node in next_object. This is cheating, but we |
diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index 2b0c3be2b1b..bed08de7528 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 8d81542194d..9bb0cbd37b5 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -55,7 +55,6 @@ | |||
55 | #include "acparser.h" | 55 | #include "acparser.h" |
56 | #include "acdispat.h" | 56 | #include "acdispat.h" |
57 | #include "amlcode.h" | 57 | #include "amlcode.h" |
58 | #include "acnamesp.h" | ||
59 | #include "acinterp.h" | 58 | #include "acinterp.h" |
60 | 59 | ||
61 | #define _COMPONENT ACPI_PARSER | 60 | #define _COMPONENT ACPI_PARSER |
@@ -539,24 +538,16 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
539 | /* Check for possible multi-thread reentrancy problem */ | 538 | /* Check for possible multi-thread reentrancy problem */ |
540 | 539 | ||
541 | if ((status == AE_ALREADY_EXISTS) && | 540 | if ((status == AE_ALREADY_EXISTS) && |
542 | (!walk_state->method_desc->method.mutex)) { | 541 | (!(walk_state->method_desc->method. |
543 | ACPI_INFO((AE_INFO, | 542 | info_flags & ACPI_METHOD_SERIALIZED))) { |
544 | "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error", | ||
545 | walk_state->method_node->name. | ||
546 | ascii)); | ||
547 | |||
548 | /* | 543 | /* |
549 | * Method tried to create an object twice. The probable cause is | 544 | * Method is not serialized and tried to create an object |
550 | * that the method cannot handle reentrancy. | 545 | * twice. The probable cause is that the method cannot |
551 | * | 546 | * handle reentrancy. Mark as "pending serialized" now, and |
552 | * The method is marked not_serialized, but it tried to create | 547 | * then mark "serialized" when the last thread exits. |
553 | * a named object, causing the second thread entrance to fail. | ||
554 | * Workaround this problem by marking the method permanently | ||
555 | * as Serialized. | ||
556 | */ | 548 | */ |
557 | walk_state->method_desc->method.method_flags |= | 549 | walk_state->method_desc->method.info_flags |= |
558 | AML_METHOD_SERIALIZED; | 550 | ACPI_METHOD_SERIALIZED_PENDING; |
559 | walk_state->method_desc->method.sync_level = 0; | ||
560 | } | 551 | } |
561 | } | 552 | } |
562 | 553 | ||
diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c index 40e2b279ea1..a5faa1323a0 100644 --- a/drivers/acpi/acpica/psscope.c +++ b/drivers/acpi/acpica/psscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c index d4b970c3630..f1464c03aa4 100644 --- a/drivers/acpi/acpica/pstree.c +++ b/drivers/acpi/acpica/pstree.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index fe29eee5adb..7eda7850342 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c index 8abb9629443..3312d6368bf 100644 --- a/drivers/acpi/acpica/pswalk.c +++ b/drivers/acpi/acpica/pswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index c42f067cff9..8086805d449 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -47,7 +47,6 @@ | |||
47 | #include "acdispat.h" | 47 | #include "acdispat.h" |
48 | #include "acinterp.h" | 48 | #include "acinterp.h" |
49 | #include "actables.h" | 49 | #include "actables.h" |
50 | #include "amlcode.h" | ||
51 | 50 | ||
52 | #define _COMPONENT ACPI_PARSER | 51 | #define _COMPONENT ACPI_PARSER |
53 | ACPI_MODULE_NAME("psxface") | 52 | ACPI_MODULE_NAME("psxface") |
@@ -285,15 +284,15 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) | |||
285 | goto cleanup; | 284 | goto cleanup; |
286 | } | 285 | } |
287 | 286 | ||
288 | if (info->obj_desc->method.flags & AOPOBJ_MODULE_LEVEL) { | 287 | if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) { |
289 | walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL; | 288 | walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL; |
290 | } | 289 | } |
291 | 290 | ||
292 | /* Invoke an internal method if necessary */ | 291 | /* Invoke an internal method if necessary */ |
293 | 292 | ||
294 | if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { | 293 | if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) { |
295 | status = | 294 | status = |
296 | info->obj_desc->method.extra.implementation(walk_state); | 295 | info->obj_desc->method.dispatch.implementation(walk_state); |
297 | info->return_object = walk_state->return_desc; | 296 | info->return_object = walk_state->return_desc; |
298 | 297 | ||
299 | /* Cleanup states */ | 298 | /* Cleanup states */ |
diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c index 226c806ae98..9e66f907842 100644 --- a/drivers/acpi/acpica/rsaddr.c +++ b/drivers/acpi/acpica/rsaddr.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index d6ebf7ec622..3a8a89ec2ca 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index c80a2eea3a0..4ce6e1147e8 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index f859b0386fe..33db7520c74 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c index 1fd868b964f..f9ea60872aa 100644 --- a/drivers/acpi/acpica/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c index 33bff17c0bb..0c7efef008b 100644 --- a/drivers/acpi/acpica/rsio.c +++ b/drivers/acpi/acpica/rsio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c index 545da40d7fa..50b8ad21116 100644 --- a/drivers/acpi/acpica/rsirq.c +++ b/drivers/acpi/acpica/rsirq.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index 7335f22aac2..1bfcef736c5 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c index 887b8ba8c43..7cc6d8625f1 100644 --- a/drivers/acpi/acpica/rsmemory.c +++ b/drivers/acpi/acpica/rsmemory.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index f8cd9e87d98..410264b22a2 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 491191e6cf6..231811e5693 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 9f6a6e7e1c8..2ff657a28f2 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index d2ff4325c42..6f5588e62c0 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -384,8 +384,11 @@ static void acpi_tb_convert_fadt(void) | |||
384 | * | 384 | * |
385 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at | 385 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at |
386 | * offset 45, 55, 95, and the word located at offset 109, 110. | 386 | * offset 45, 55, 95, and the word located at offset 109, 110. |
387 | * | ||
388 | * Note: The FADT revision value is unreliable. Only the length can be | ||
389 | * trusted. | ||
387 | */ | 390 | */ |
388 | if (acpi_gbl_FADT.header.revision < FADT2_REVISION_ID) { | 391 | if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) { |
389 | acpi_gbl_FADT.preferred_profile = 0; | 392 | acpi_gbl_FADT.preferred_profile = 0; |
390 | acpi_gbl_FADT.pstate_control = 0; | 393 | acpi_gbl_FADT.pstate_control = 0; |
391 | acpi_gbl_FADT.cst_control = 0; | 394 | acpi_gbl_FADT.cst_control = 0; |
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index 989d5c86786..a55cb2bb5ab 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 83d7af8d090..48db0944ce4 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 34f9c2bc5e1..0f2d395feab 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 4a8b9e6ea57..4b7085dfc68 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2010, Intel Corp. | 9 | * Copyright (C) 2000 - 2011, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index fd2c07d1d3a..7eb6c6cc1ed 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index 8f089628156..0a697351cf6 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 6fef83f04bc..aded299a2fa 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index f21c486929a..a9bcd816dc2 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c new file mode 100644 index 00000000000..136a814cec6 --- /dev/null +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -0,0 +1,548 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utdecode - Utility decoding routines (value-to-string) | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2011, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_UTILITIES | ||
49 | ACPI_MODULE_NAME("utdecode") | ||
50 | |||
51 | /******************************************************************************* | ||
52 | * | ||
53 | * FUNCTION: acpi_format_exception | ||
54 | * | ||
55 | * PARAMETERS: Status - The acpi_status code to be formatted | ||
56 | * | ||
57 | * RETURN: A string containing the exception text. A valid pointer is | ||
58 | * always returned. | ||
59 | * | ||
60 | * DESCRIPTION: This function translates an ACPI exception into an ASCII string | ||
61 | * It is here instead of utxface.c so it is always present. | ||
62 | * | ||
63 | ******************************************************************************/ | ||
64 | const char *acpi_format_exception(acpi_status status) | ||
65 | { | ||
66 | const char *exception = NULL; | ||
67 | |||
68 | ACPI_FUNCTION_ENTRY(); | ||
69 | |||
70 | exception = acpi_ut_validate_exception(status); | ||
71 | if (!exception) { | ||
72 | |||
73 | /* Exception code was not recognized */ | ||
74 | |||
75 | ACPI_ERROR((AE_INFO, | ||
76 | "Unknown exception code: 0x%8.8X", status)); | ||
77 | |||
78 | exception = "UNKNOWN_STATUS_CODE"; | ||
79 | } | ||
80 | |||
81 | return (ACPI_CAST_PTR(const char, exception)); | ||
82 | } | ||
83 | |||
84 | ACPI_EXPORT_SYMBOL(acpi_format_exception) | ||
85 | |||
86 | /* | ||
87 | * Properties of the ACPI Object Types, both internal and external. | ||
88 | * The table is indexed by values of acpi_object_type | ||
89 | */ | ||
90 | const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES] = { | ||
91 | ACPI_NS_NORMAL, /* 00 Any */ | ||
92 | ACPI_NS_NORMAL, /* 01 Number */ | ||
93 | ACPI_NS_NORMAL, /* 02 String */ | ||
94 | ACPI_NS_NORMAL, /* 03 Buffer */ | ||
95 | ACPI_NS_NORMAL, /* 04 Package */ | ||
96 | ACPI_NS_NORMAL, /* 05 field_unit */ | ||
97 | ACPI_NS_NEWSCOPE, /* 06 Device */ | ||
98 | ACPI_NS_NORMAL, /* 07 Event */ | ||
99 | ACPI_NS_NEWSCOPE, /* 08 Method */ | ||
100 | ACPI_NS_NORMAL, /* 09 Mutex */ | ||
101 | ACPI_NS_NORMAL, /* 10 Region */ | ||
102 | ACPI_NS_NEWSCOPE, /* 11 Power */ | ||
103 | ACPI_NS_NEWSCOPE, /* 12 Processor */ | ||
104 | ACPI_NS_NEWSCOPE, /* 13 Thermal */ | ||
105 | ACPI_NS_NORMAL, /* 14 buffer_field */ | ||
106 | ACPI_NS_NORMAL, /* 15 ddb_handle */ | ||
107 | ACPI_NS_NORMAL, /* 16 Debug Object */ | ||
108 | ACPI_NS_NORMAL, /* 17 def_field */ | ||
109 | ACPI_NS_NORMAL, /* 18 bank_field */ | ||
110 | ACPI_NS_NORMAL, /* 19 index_field */ | ||
111 | ACPI_NS_NORMAL, /* 20 Reference */ | ||
112 | ACPI_NS_NORMAL, /* 21 Alias */ | ||
113 | ACPI_NS_NORMAL, /* 22 method_alias */ | ||
114 | ACPI_NS_NORMAL, /* 23 Notify */ | ||
115 | ACPI_NS_NORMAL, /* 24 Address Handler */ | ||
116 | ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */ | ||
117 | ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */ | ||
118 | ACPI_NS_NEWSCOPE, /* 27 Scope */ | ||
119 | ACPI_NS_NORMAL, /* 28 Extra */ | ||
120 | ACPI_NS_NORMAL, /* 29 Data */ | ||
121 | ACPI_NS_NORMAL /* 30 Invalid */ | ||
122 | }; | ||
123 | |||
124 | /******************************************************************************* | ||
125 | * | ||
126 | * FUNCTION: acpi_ut_hex_to_ascii_char | ||
127 | * | ||
128 | * PARAMETERS: Integer - Contains the hex digit | ||
129 | * Position - bit position of the digit within the | ||
130 | * integer (multiple of 4) | ||
131 | * | ||
132 | * RETURN: The converted Ascii character | ||
133 | * | ||
134 | * DESCRIPTION: Convert a hex digit to an Ascii character | ||
135 | * | ||
136 | ******************************************************************************/ | ||
137 | |||
138 | /* Hex to ASCII conversion table */ | ||
139 | |||
140 | static const char acpi_gbl_hex_to_ascii[] = { | ||
141 | '0', '1', '2', '3', '4', '5', '6', '7', | ||
142 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' | ||
143 | }; | ||
144 | |||
145 | char acpi_ut_hex_to_ascii_char(u64 integer, u32 position) | ||
146 | { | ||
147 | |||
148 | return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); | ||
149 | } | ||
150 | |||
151 | /******************************************************************************* | ||
152 | * | ||
153 | * FUNCTION: acpi_ut_get_region_name | ||
154 | * | ||
155 | * PARAMETERS: Space ID - ID for the region | ||
156 | * | ||
157 | * RETURN: Decoded region space_id name | ||
158 | * | ||
159 | * DESCRIPTION: Translate a Space ID into a name string (Debug only) | ||
160 | * | ||
161 | ******************************************************************************/ | ||
162 | |||
163 | /* Region type decoding */ | ||
164 | |||
165 | const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { | ||
166 | "SystemMemory", | ||
167 | "SystemIO", | ||
168 | "PCI_Config", | ||
169 | "EmbeddedControl", | ||
170 | "SMBus", | ||
171 | "SystemCMOS", | ||
172 | "PCIBARTarget", | ||
173 | "IPMI", | ||
174 | "DataTable" | ||
175 | }; | ||
176 | |||
177 | char *acpi_ut_get_region_name(u8 space_id) | ||
178 | { | ||
179 | |||
180 | if (space_id >= ACPI_USER_REGION_BEGIN) { | ||
181 | return ("UserDefinedRegion"); | ||
182 | } else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { | ||
183 | return ("FunctionalFixedHW"); | ||
184 | } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { | ||
185 | return ("InvalidSpaceId"); | ||
186 | } | ||
187 | |||
188 | return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id])); | ||
189 | } | ||
190 | |||
191 | /******************************************************************************* | ||
192 | * | ||
193 | * FUNCTION: acpi_ut_get_event_name | ||
194 | * | ||
195 | * PARAMETERS: event_id - Fixed event ID | ||
196 | * | ||
197 | * RETURN: Decoded event ID name | ||
198 | * | ||
199 | * DESCRIPTION: Translate a Event ID into a name string (Debug only) | ||
200 | * | ||
201 | ******************************************************************************/ | ||
202 | |||
203 | /* Event type decoding */ | ||
204 | |||
205 | static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = { | ||
206 | "PM_Timer", | ||
207 | "GlobalLock", | ||
208 | "PowerButton", | ||
209 | "SleepButton", | ||
210 | "RealTimeClock", | ||
211 | }; | ||
212 | |||
213 | char *acpi_ut_get_event_name(u32 event_id) | ||
214 | { | ||
215 | |||
216 | if (event_id > ACPI_EVENT_MAX) { | ||
217 | return ("InvalidEventID"); | ||
218 | } | ||
219 | |||
220 | return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id])); | ||
221 | } | ||
222 | |||
223 | /******************************************************************************* | ||
224 | * | ||
225 | * FUNCTION: acpi_ut_get_type_name | ||
226 | * | ||
227 | * PARAMETERS: Type - An ACPI object type | ||
228 | * | ||
229 | * RETURN: Decoded ACPI object type name | ||
230 | * | ||
231 | * DESCRIPTION: Translate a Type ID into a name string (Debug only) | ||
232 | * | ||
233 | ******************************************************************************/ | ||
234 | |||
235 | /* | ||
236 | * Elements of acpi_gbl_ns_type_names below must match | ||
237 | * one-to-one with values of acpi_object_type | ||
238 | * | ||
239 | * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; | ||
240 | * when stored in a table it really means that we have thus far seen no | ||
241 | * evidence to indicate what type is actually going to be stored for this entry. | ||
242 | */ | ||
243 | static const char acpi_gbl_bad_type[] = "UNDEFINED"; | ||
244 | |||
245 | /* Printable names of the ACPI object types */ | ||
246 | |||
247 | static const char *acpi_gbl_ns_type_names[] = { | ||
248 | /* 00 */ "Untyped", | ||
249 | /* 01 */ "Integer", | ||
250 | /* 02 */ "String", | ||
251 | /* 03 */ "Buffer", | ||
252 | /* 04 */ "Package", | ||
253 | /* 05 */ "FieldUnit", | ||
254 | /* 06 */ "Device", | ||
255 | /* 07 */ "Event", | ||
256 | /* 08 */ "Method", | ||
257 | /* 09 */ "Mutex", | ||
258 | /* 10 */ "Region", | ||
259 | /* 11 */ "Power", | ||
260 | /* 12 */ "Processor", | ||
261 | /* 13 */ "Thermal", | ||
262 | /* 14 */ "BufferField", | ||
263 | /* 15 */ "DdbHandle", | ||
264 | /* 16 */ "DebugObject", | ||
265 | /* 17 */ "RegionField", | ||
266 | /* 18 */ "BankField", | ||
267 | /* 19 */ "IndexField", | ||
268 | /* 20 */ "Reference", | ||
269 | /* 21 */ "Alias", | ||
270 | /* 22 */ "MethodAlias", | ||
271 | /* 23 */ "Notify", | ||
272 | /* 24 */ "AddrHandler", | ||
273 | /* 25 */ "ResourceDesc", | ||
274 | /* 26 */ "ResourceFld", | ||
275 | /* 27 */ "Scope", | ||
276 | /* 28 */ "Extra", | ||
277 | /* 29 */ "Data", | ||
278 | /* 30 */ "Invalid" | ||
279 | }; | ||
280 | |||
281 | char *acpi_ut_get_type_name(acpi_object_type type) | ||
282 | { | ||
283 | |||
284 | if (type > ACPI_TYPE_INVALID) { | ||
285 | return (ACPI_CAST_PTR(char, acpi_gbl_bad_type)); | ||
286 | } | ||
287 | |||
288 | return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type])); | ||
289 | } | ||
290 | |||
291 | char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) | ||
292 | { | ||
293 | |||
294 | if (!obj_desc) { | ||
295 | return ("[NULL Object Descriptor]"); | ||
296 | } | ||
297 | |||
298 | return (acpi_ut_get_type_name(obj_desc->common.type)); | ||
299 | } | ||
300 | |||
301 | /******************************************************************************* | ||
302 | * | ||
303 | * FUNCTION: acpi_ut_get_node_name | ||
304 | * | ||
305 | * PARAMETERS: Object - A namespace node | ||
306 | * | ||
307 | * RETURN: ASCII name of the node | ||
308 | * | ||
309 | * DESCRIPTION: Validate the node and return the node's ACPI name. | ||
310 | * | ||
311 | ******************************************************************************/ | ||
312 | |||
313 | char *acpi_ut_get_node_name(void *object) | ||
314 | { | ||
315 | struct acpi_namespace_node *node = (struct acpi_namespace_node *)object; | ||
316 | |||
317 | /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */ | ||
318 | |||
319 | if (!object) { | ||
320 | return ("NULL"); | ||
321 | } | ||
322 | |||
323 | /* Check for Root node */ | ||
324 | |||
325 | if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) { | ||
326 | return ("\"\\\" "); | ||
327 | } | ||
328 | |||
329 | /* Descriptor must be a namespace node */ | ||
330 | |||
331 | if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { | ||
332 | return ("####"); | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Ensure name is valid. The name was validated/repaired when the node | ||
337 | * was created, but make sure it has not been corrupted. | ||
338 | */ | ||
339 | acpi_ut_repair_name(node->name.ascii); | ||
340 | |||
341 | /* Return the name */ | ||
342 | |||
343 | return (node->name.ascii); | ||
344 | } | ||
345 | |||
346 | /******************************************************************************* | ||
347 | * | ||
348 | * FUNCTION: acpi_ut_get_descriptor_name | ||
349 | * | ||
350 | * PARAMETERS: Object - An ACPI object | ||
351 | * | ||
352 | * RETURN: Decoded name of the descriptor type | ||
353 | * | ||
354 | * DESCRIPTION: Validate object and return the descriptor type | ||
355 | * | ||
356 | ******************************************************************************/ | ||
357 | |||
358 | /* Printable names of object descriptor types */ | ||
359 | |||
360 | static const char *acpi_gbl_desc_type_names[] = { | ||
361 | /* 00 */ "Not a Descriptor", | ||
362 | /* 01 */ "Cached", | ||
363 | /* 02 */ "State-Generic", | ||
364 | /* 03 */ "State-Update", | ||
365 | /* 04 */ "State-Package", | ||
366 | /* 05 */ "State-Control", | ||
367 | /* 06 */ "State-RootParseScope", | ||
368 | /* 07 */ "State-ParseScope", | ||
369 | /* 08 */ "State-WalkScope", | ||
370 | /* 09 */ "State-Result", | ||
371 | /* 10 */ "State-Notify", | ||
372 | /* 11 */ "State-Thread", | ||
373 | /* 12 */ "Walk", | ||
374 | /* 13 */ "Parser", | ||
375 | /* 14 */ "Operand", | ||
376 | /* 15 */ "Node" | ||
377 | }; | ||
378 | |||
379 | char *acpi_ut_get_descriptor_name(void *object) | ||
380 | { | ||
381 | |||
382 | if (!object) { | ||
383 | return ("NULL OBJECT"); | ||
384 | } | ||
385 | |||
386 | if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) { | ||
387 | return ("Not a Descriptor"); | ||
388 | } | ||
389 | |||
390 | return (ACPI_CAST_PTR(char, | ||
391 | acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE | ||
392 | (object)])); | ||
393 | |||
394 | } | ||
395 | |||
396 | /******************************************************************************* | ||
397 | * | ||
398 | * FUNCTION: acpi_ut_get_reference_name | ||
399 | * | ||
400 | * PARAMETERS: Object - An ACPI reference object | ||
401 | * | ||
402 | * RETURN: Decoded name of the type of reference | ||
403 | * | ||
404 | * DESCRIPTION: Decode a reference object sub-type to a string. | ||
405 | * | ||
406 | ******************************************************************************/ | ||
407 | |||
408 | /* Printable names of reference object sub-types */ | ||
409 | |||
410 | static const char *acpi_gbl_ref_class_names[] = { | ||
411 | /* 00 */ "Local", | ||
412 | /* 01 */ "Argument", | ||
413 | /* 02 */ "RefOf", | ||
414 | /* 03 */ "Index", | ||
415 | /* 04 */ "DdbHandle", | ||
416 | /* 05 */ "Named Object", | ||
417 | /* 06 */ "Debug" | ||
418 | }; | ||
419 | |||
420 | const char *acpi_ut_get_reference_name(union acpi_operand_object *object) | ||
421 | { | ||
422 | |||
423 | if (!object) { | ||
424 | return ("NULL Object"); | ||
425 | } | ||
426 | |||
427 | if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { | ||
428 | return ("Not an Operand object"); | ||
429 | } | ||
430 | |||
431 | if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE) { | ||
432 | return ("Not a Reference object"); | ||
433 | } | ||
434 | |||
435 | if (object->reference.class > ACPI_REFCLASS_MAX) { | ||
436 | return ("Unknown Reference class"); | ||
437 | } | ||
438 | |||
439 | return (acpi_gbl_ref_class_names[object->reference.class]); | ||
440 | } | ||
441 | |||
442 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
443 | /* | ||
444 | * Strings and procedures used for debug only | ||
445 | */ | ||
446 | |||
447 | /******************************************************************************* | ||
448 | * | ||
449 | * FUNCTION: acpi_ut_get_mutex_name | ||
450 | * | ||
451 | * PARAMETERS: mutex_id - The predefined ID for this mutex. | ||
452 | * | ||
453 | * RETURN: Decoded name of the internal mutex | ||
454 | * | ||
455 | * DESCRIPTION: Translate a mutex ID into a name string (Debug only) | ||
456 | * | ||
457 | ******************************************************************************/ | ||
458 | |||
459 | /* Names for internal mutex objects, used for debug output */ | ||
460 | |||
461 | static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = { | ||
462 | "ACPI_MTX_Interpreter", | ||
463 | "ACPI_MTX_Namespace", | ||
464 | "ACPI_MTX_Tables", | ||
465 | "ACPI_MTX_Events", | ||
466 | "ACPI_MTX_Caches", | ||
467 | "ACPI_MTX_Memory", | ||
468 | "ACPI_MTX_CommandComplete", | ||
469 | "ACPI_MTX_CommandReady" | ||
470 | }; | ||
471 | |||
472 | char *acpi_ut_get_mutex_name(u32 mutex_id) | ||
473 | { | ||
474 | |||
475 | if (mutex_id > ACPI_MAX_MUTEX) { | ||
476 | return ("Invalid Mutex ID"); | ||
477 | } | ||
478 | |||
479 | return (acpi_gbl_mutex_names[mutex_id]); | ||
480 | } | ||
481 | |||
482 | /******************************************************************************* | ||
483 | * | ||
484 | * FUNCTION: acpi_ut_get_notify_name | ||
485 | * | ||
486 | * PARAMETERS: notify_value - Value from the Notify() request | ||
487 | * | ||
488 | * RETURN: Decoded name for the notify value | ||
489 | * | ||
490 | * DESCRIPTION: Translate a Notify Value to a notify namestring. | ||
491 | * | ||
492 | ******************************************************************************/ | ||
493 | |||
494 | /* Names for Notify() values, used for debug output */ | ||
495 | |||
496 | static const char *acpi_gbl_notify_value_names[] = { | ||
497 | "Bus Check", | ||
498 | "Device Check", | ||
499 | "Device Wake", | ||
500 | "Eject Request", | ||
501 | "Device Check Light", | ||
502 | "Frequency Mismatch", | ||
503 | "Bus Mode Mismatch", | ||
504 | "Power Fault", | ||
505 | "Capabilities Check", | ||
506 | "Device PLD Check", | ||
507 | "Reserved", | ||
508 | "System Locality Update" | ||
509 | }; | ||
510 | |||
511 | const char *acpi_ut_get_notify_name(u32 notify_value) | ||
512 | { | ||
513 | |||
514 | if (notify_value <= ACPI_NOTIFY_MAX) { | ||
515 | return (acpi_gbl_notify_value_names[notify_value]); | ||
516 | } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | ||
517 | return ("Reserved"); | ||
518 | } else { /* Greater or equal to 0x80 */ | ||
519 | |||
520 | return ("**Device Specific**"); | ||
521 | } | ||
522 | } | ||
523 | #endif | ||
524 | |||
525 | /******************************************************************************* | ||
526 | * | ||
527 | * FUNCTION: acpi_ut_valid_object_type | ||
528 | * | ||
529 | * PARAMETERS: Type - Object type to be validated | ||
530 | * | ||
531 | * RETURN: TRUE if valid object type, FALSE otherwise | ||
532 | * | ||
533 | * DESCRIPTION: Validate an object type | ||
534 | * | ||
535 | ******************************************************************************/ | ||
536 | |||
537 | u8 acpi_ut_valid_object_type(acpi_object_type type) | ||
538 | { | ||
539 | |||
540 | if (type > ACPI_TYPE_LOCAL_MAX) { | ||
541 | |||
542 | /* Note: Assumes all TYPEs are contiguous (external/local) */ | ||
543 | |||
544 | return (FALSE); | ||
545 | } | ||
546 | |||
547 | return (TRUE); | ||
548 | } | ||
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index ed794cd033e..31f5a7832ef 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 22f59ef604e..18f73c9d10b 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index e87bc6760be..833a38a9c90 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -45,7 +45,6 @@ | |||
45 | 45 | ||
46 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
47 | #include "accommon.h" | 47 | #include "accommon.h" |
48 | #include "acnamesp.h" | ||
49 | 48 | ||
50 | #define _COMPONENT ACPI_UTILITIES | 49 | #define _COMPONENT ACPI_UTILITIES |
51 | ACPI_MODULE_NAME("utglobal") | 50 | ACPI_MODULE_NAME("utglobal") |
@@ -107,43 +106,6 @@ const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS] = { | |||
107 | 106 | ||
108 | /******************************************************************************* | 107 | /******************************************************************************* |
109 | * | 108 | * |
110 | * FUNCTION: acpi_format_exception | ||
111 | * | ||
112 | * PARAMETERS: Status - The acpi_status code to be formatted | ||
113 | * | ||
114 | * RETURN: A string containing the exception text. A valid pointer is | ||
115 | * always returned. | ||
116 | * | ||
117 | * DESCRIPTION: This function translates an ACPI exception into an ASCII string | ||
118 | * It is here instead of utxface.c so it is always present. | ||
119 | * | ||
120 | ******************************************************************************/ | ||
121 | |||
122 | const char *acpi_format_exception(acpi_status status) | ||
123 | { | ||
124 | const char *exception = NULL; | ||
125 | |||
126 | ACPI_FUNCTION_ENTRY(); | ||
127 | |||
128 | exception = acpi_ut_validate_exception(status); | ||
129 | if (!exception) { | ||
130 | |||
131 | /* Exception code was not recognized */ | ||
132 | |||
133 | ACPI_ERROR((AE_INFO, | ||
134 | "Unknown exception code: 0x%8.8X", status)); | ||
135 | |||
136 | exception = "UNKNOWN_STATUS_CODE"; | ||
137 | dump_stack(); | ||
138 | } | ||
139 | |||
140 | return (ACPI_CAST_PTR(const char, exception)); | ||
141 | } | ||
142 | |||
143 | ACPI_EXPORT_SYMBOL(acpi_format_exception) | ||
144 | |||
145 | /******************************************************************************* | ||
146 | * | ||
147 | * Namespace globals | 109 | * Namespace globals |
148 | * | 110 | * |
149 | ******************************************************************************/ | 111 | ******************************************************************************/ |
@@ -177,71 +139,6 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { | |||
177 | {NULL, ACPI_TYPE_ANY, NULL} | 139 | {NULL, ACPI_TYPE_ANY, NULL} |
178 | }; | 140 | }; |
179 | 141 | ||
180 | /* | ||
181 | * Properties of the ACPI Object Types, both internal and external. | ||
182 | * The table is indexed by values of acpi_object_type | ||
183 | */ | ||
184 | const u8 acpi_gbl_ns_properties[] = { | ||
185 | ACPI_NS_NORMAL, /* 00 Any */ | ||
186 | ACPI_NS_NORMAL, /* 01 Number */ | ||
187 | ACPI_NS_NORMAL, /* 02 String */ | ||
188 | ACPI_NS_NORMAL, /* 03 Buffer */ | ||
189 | ACPI_NS_NORMAL, /* 04 Package */ | ||
190 | ACPI_NS_NORMAL, /* 05 field_unit */ | ||
191 | ACPI_NS_NEWSCOPE, /* 06 Device */ | ||
192 | ACPI_NS_NORMAL, /* 07 Event */ | ||
193 | ACPI_NS_NEWSCOPE, /* 08 Method */ | ||
194 | ACPI_NS_NORMAL, /* 09 Mutex */ | ||
195 | ACPI_NS_NORMAL, /* 10 Region */ | ||
196 | ACPI_NS_NEWSCOPE, /* 11 Power */ | ||
197 | ACPI_NS_NEWSCOPE, /* 12 Processor */ | ||
198 | ACPI_NS_NEWSCOPE, /* 13 Thermal */ | ||
199 | ACPI_NS_NORMAL, /* 14 buffer_field */ | ||
200 | ACPI_NS_NORMAL, /* 15 ddb_handle */ | ||
201 | ACPI_NS_NORMAL, /* 16 Debug Object */ | ||
202 | ACPI_NS_NORMAL, /* 17 def_field */ | ||
203 | ACPI_NS_NORMAL, /* 18 bank_field */ | ||
204 | ACPI_NS_NORMAL, /* 19 index_field */ | ||
205 | ACPI_NS_NORMAL, /* 20 Reference */ | ||
206 | ACPI_NS_NORMAL, /* 21 Alias */ | ||
207 | ACPI_NS_NORMAL, /* 22 method_alias */ | ||
208 | ACPI_NS_NORMAL, /* 23 Notify */ | ||
209 | ACPI_NS_NORMAL, /* 24 Address Handler */ | ||
210 | ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */ | ||
211 | ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */ | ||
212 | ACPI_NS_NEWSCOPE, /* 27 Scope */ | ||
213 | ACPI_NS_NORMAL, /* 28 Extra */ | ||
214 | ACPI_NS_NORMAL, /* 29 Data */ | ||
215 | ACPI_NS_NORMAL /* 30 Invalid */ | ||
216 | }; | ||
217 | |||
218 | /* Hex to ASCII conversion table */ | ||
219 | |||
220 | static const char acpi_gbl_hex_to_ascii[] = { | ||
221 | '0', '1', '2', '3', '4', '5', '6', '7', | ||
222 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' | ||
223 | }; | ||
224 | |||
225 | /******************************************************************************* | ||
226 | * | ||
227 | * FUNCTION: acpi_ut_hex_to_ascii_char | ||
228 | * | ||
229 | * PARAMETERS: Integer - Contains the hex digit | ||
230 | * Position - bit position of the digit within the | ||
231 | * integer (multiple of 4) | ||
232 | * | ||
233 | * RETURN: The converted Ascii character | ||
234 | * | ||
235 | * DESCRIPTION: Convert a hex digit to an Ascii character | ||
236 | * | ||
237 | ******************************************************************************/ | ||
238 | |||
239 | char acpi_ut_hex_to_ascii_char(u64 integer, u32 position) | ||
240 | { | ||
241 | |||
242 | return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); | ||
243 | } | ||
244 | |||
245 | /****************************************************************************** | 142 | /****************************************************************************** |
246 | * | 143 | * |
247 | * Event and Hardware globals | 144 | * Event and Hardware globals |
@@ -341,386 +238,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = | |||
341 | 238 | ||
342 | /******************************************************************************* | 239 | /******************************************************************************* |
343 | * | 240 | * |
344 | * FUNCTION: acpi_ut_get_region_name | ||
345 | * | ||
346 | * PARAMETERS: None. | ||
347 | * | ||
348 | * RETURN: Status | ||
349 | * | ||
350 | * DESCRIPTION: Translate a Space ID into a name string (Debug only) | ||
351 | * | ||
352 | ******************************************************************************/ | ||
353 | |||
354 | /* Region type decoding */ | ||
355 | |||
356 | const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { | ||
357 | "SystemMemory", | ||
358 | "SystemIO", | ||
359 | "PCI_Config", | ||
360 | "EmbeddedControl", | ||
361 | "SMBus", | ||
362 | "SystemCMOS", | ||
363 | "PCIBARTarget", | ||
364 | "IPMI", | ||
365 | "DataTable" | ||
366 | }; | ||
367 | |||
368 | char *acpi_ut_get_region_name(u8 space_id) | ||
369 | { | ||
370 | |||
371 | if (space_id >= ACPI_USER_REGION_BEGIN) { | ||
372 | return ("UserDefinedRegion"); | ||
373 | } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { | ||
374 | return ("InvalidSpaceId"); | ||
375 | } | ||
376 | |||
377 | return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id])); | ||
378 | } | ||
379 | |||
380 | /******************************************************************************* | ||
381 | * | ||
382 | * FUNCTION: acpi_ut_get_event_name | ||
383 | * | ||
384 | * PARAMETERS: None. | ||
385 | * | ||
386 | * RETURN: Status | ||
387 | * | ||
388 | * DESCRIPTION: Translate a Event ID into a name string (Debug only) | ||
389 | * | ||
390 | ******************************************************************************/ | ||
391 | |||
392 | /* Event type decoding */ | ||
393 | |||
394 | static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = { | ||
395 | "PM_Timer", | ||
396 | "GlobalLock", | ||
397 | "PowerButton", | ||
398 | "SleepButton", | ||
399 | "RealTimeClock", | ||
400 | }; | ||
401 | |||
402 | char *acpi_ut_get_event_name(u32 event_id) | ||
403 | { | ||
404 | |||
405 | if (event_id > ACPI_EVENT_MAX) { | ||
406 | return ("InvalidEventID"); | ||
407 | } | ||
408 | |||
409 | return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id])); | ||
410 | } | ||
411 | |||
412 | /******************************************************************************* | ||
413 | * | ||
414 | * FUNCTION: acpi_ut_get_type_name | ||
415 | * | ||
416 | * PARAMETERS: None. | ||
417 | * | ||
418 | * RETURN: Status | ||
419 | * | ||
420 | * DESCRIPTION: Translate a Type ID into a name string (Debug only) | ||
421 | * | ||
422 | ******************************************************************************/ | ||
423 | |||
424 | /* | ||
425 | * Elements of acpi_gbl_ns_type_names below must match | ||
426 | * one-to-one with values of acpi_object_type | ||
427 | * | ||
428 | * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; | ||
429 | * when stored in a table it really means that we have thus far seen no | ||
430 | * evidence to indicate what type is actually going to be stored for this entry. | ||
431 | */ | ||
432 | static const char acpi_gbl_bad_type[] = "UNDEFINED"; | ||
433 | |||
434 | /* Printable names of the ACPI object types */ | ||
435 | |||
436 | static const char *acpi_gbl_ns_type_names[] = { | ||
437 | /* 00 */ "Untyped", | ||
438 | /* 01 */ "Integer", | ||
439 | /* 02 */ "String", | ||
440 | /* 03 */ "Buffer", | ||
441 | /* 04 */ "Package", | ||
442 | /* 05 */ "FieldUnit", | ||
443 | /* 06 */ "Device", | ||
444 | /* 07 */ "Event", | ||
445 | /* 08 */ "Method", | ||
446 | /* 09 */ "Mutex", | ||
447 | /* 10 */ "Region", | ||
448 | /* 11 */ "Power", | ||
449 | /* 12 */ "Processor", | ||
450 | /* 13 */ "Thermal", | ||
451 | /* 14 */ "BufferField", | ||
452 | /* 15 */ "DdbHandle", | ||
453 | /* 16 */ "DebugObject", | ||
454 | /* 17 */ "RegionField", | ||
455 | /* 18 */ "BankField", | ||
456 | /* 19 */ "IndexField", | ||
457 | /* 20 */ "Reference", | ||
458 | /* 21 */ "Alias", | ||
459 | /* 22 */ "MethodAlias", | ||
460 | /* 23 */ "Notify", | ||
461 | /* 24 */ "AddrHandler", | ||
462 | /* 25 */ "ResourceDesc", | ||
463 | /* 26 */ "ResourceFld", | ||
464 | /* 27 */ "Scope", | ||
465 | /* 28 */ "Extra", | ||
466 | /* 29 */ "Data", | ||
467 | /* 30 */ "Invalid" | ||
468 | }; | ||
469 | |||
470 | char *acpi_ut_get_type_name(acpi_object_type type) | ||
471 | { | ||
472 | |||
473 | if (type > ACPI_TYPE_INVALID) { | ||
474 | return (ACPI_CAST_PTR(char, acpi_gbl_bad_type)); | ||
475 | } | ||
476 | |||
477 | return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type])); | ||
478 | } | ||
479 | |||
480 | char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) | ||
481 | { | ||
482 | |||
483 | if (!obj_desc) { | ||
484 | return ("[NULL Object Descriptor]"); | ||
485 | } | ||
486 | |||
487 | return (acpi_ut_get_type_name(obj_desc->common.type)); | ||
488 | } | ||
489 | |||
490 | /******************************************************************************* | ||
491 | * | ||
492 | * FUNCTION: acpi_ut_get_node_name | ||
493 | * | ||
494 | * PARAMETERS: Object - A namespace node | ||
495 | * | ||
496 | * RETURN: Pointer to a string | ||
497 | * | ||
498 | * DESCRIPTION: Validate the node and return the node's ACPI name. | ||
499 | * | ||
500 | ******************************************************************************/ | ||
501 | |||
502 | char *acpi_ut_get_node_name(void *object) | ||
503 | { | ||
504 | struct acpi_namespace_node *node = (struct acpi_namespace_node *)object; | ||
505 | |||
506 | /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */ | ||
507 | |||
508 | if (!object) { | ||
509 | return ("NULL"); | ||
510 | } | ||
511 | |||
512 | /* Check for Root node */ | ||
513 | |||
514 | if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) { | ||
515 | return ("\"\\\" "); | ||
516 | } | ||
517 | |||
518 | /* Descriptor must be a namespace node */ | ||
519 | |||
520 | if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { | ||
521 | return ("####"); | ||
522 | } | ||
523 | |||
524 | /* Name must be a valid ACPI name */ | ||
525 | |||
526 | if (!acpi_ut_valid_acpi_name(node->name.integer)) { | ||
527 | node->name.integer = acpi_ut_repair_name(node->name.ascii); | ||
528 | } | ||
529 | |||
530 | /* Return the name */ | ||
531 | |||
532 | return (node->name.ascii); | ||
533 | } | ||
534 | |||
535 | /******************************************************************************* | ||
536 | * | ||
537 | * FUNCTION: acpi_ut_get_descriptor_name | ||
538 | * | ||
539 | * PARAMETERS: Object - An ACPI object | ||
540 | * | ||
541 | * RETURN: Pointer to a string | ||
542 | * | ||
543 | * DESCRIPTION: Validate object and return the descriptor type | ||
544 | * | ||
545 | ******************************************************************************/ | ||
546 | |||
547 | /* Printable names of object descriptor types */ | ||
548 | |||
549 | static const char *acpi_gbl_desc_type_names[] = { | ||
550 | /* 00 */ "Invalid", | ||
551 | /* 01 */ "Cached", | ||
552 | /* 02 */ "State-Generic", | ||
553 | /* 03 */ "State-Update", | ||
554 | /* 04 */ "State-Package", | ||
555 | /* 05 */ "State-Control", | ||
556 | /* 06 */ "State-RootParseScope", | ||
557 | /* 07 */ "State-ParseScope", | ||
558 | /* 08 */ "State-WalkScope", | ||
559 | /* 09 */ "State-Result", | ||
560 | /* 10 */ "State-Notify", | ||
561 | /* 11 */ "State-Thread", | ||
562 | /* 12 */ "Walk", | ||
563 | /* 13 */ "Parser", | ||
564 | /* 14 */ "Operand", | ||
565 | /* 15 */ "Node" | ||
566 | }; | ||
567 | |||
568 | char *acpi_ut_get_descriptor_name(void *object) | ||
569 | { | ||
570 | |||
571 | if (!object) { | ||
572 | return ("NULL OBJECT"); | ||
573 | } | ||
574 | |||
575 | if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) { | ||
576 | return (ACPI_CAST_PTR(char, acpi_gbl_bad_type)); | ||
577 | } | ||
578 | |||
579 | return (ACPI_CAST_PTR(char, | ||
580 | acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE | ||
581 | (object)])); | ||
582 | |||
583 | } | ||
584 | |||
585 | /******************************************************************************* | ||
586 | * | ||
587 | * FUNCTION: acpi_ut_get_reference_name | ||
588 | * | ||
589 | * PARAMETERS: Object - An ACPI reference object | ||
590 | * | ||
591 | * RETURN: Pointer to a string | ||
592 | * | ||
593 | * DESCRIPTION: Decode a reference object sub-type to a string. | ||
594 | * | ||
595 | ******************************************************************************/ | ||
596 | |||
597 | /* Printable names of reference object sub-types */ | ||
598 | |||
599 | static const char *acpi_gbl_ref_class_names[] = { | ||
600 | /* 00 */ "Local", | ||
601 | /* 01 */ "Argument", | ||
602 | /* 02 */ "RefOf", | ||
603 | /* 03 */ "Index", | ||
604 | /* 04 */ "DdbHandle", | ||
605 | /* 05 */ "Named Object", | ||
606 | /* 06 */ "Debug" | ||
607 | }; | ||
608 | |||
609 | const char *acpi_ut_get_reference_name(union acpi_operand_object *object) | ||
610 | { | ||
611 | if (!object) | ||
612 | return "NULL Object"; | ||
613 | |||
614 | if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) | ||
615 | return "Not an Operand object"; | ||
616 | |||
617 | if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE) | ||
618 | return "Not a Reference object"; | ||
619 | |||
620 | if (object->reference.class > ACPI_REFCLASS_MAX) | ||
621 | return "Unknown Reference class"; | ||
622 | |||
623 | return acpi_gbl_ref_class_names[object->reference.class]; | ||
624 | } | ||
625 | |||
626 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
627 | /* | ||
628 | * Strings and procedures used for debug only | ||
629 | */ | ||
630 | |||
631 | /******************************************************************************* | ||
632 | * | ||
633 | * FUNCTION: acpi_ut_get_mutex_name | ||
634 | * | ||
635 | * PARAMETERS: mutex_id - The predefined ID for this mutex. | ||
636 | * | ||
637 | * RETURN: String containing the name of the mutex. Always returns a valid | ||
638 | * pointer. | ||
639 | * | ||
640 | * DESCRIPTION: Translate a mutex ID into a name string (Debug only) | ||
641 | * | ||
642 | ******************************************************************************/ | ||
643 | |||
644 | char *acpi_ut_get_mutex_name(u32 mutex_id) | ||
645 | { | ||
646 | |||
647 | if (mutex_id > ACPI_MAX_MUTEX) { | ||
648 | return ("Invalid Mutex ID"); | ||
649 | } | ||
650 | |||
651 | return (acpi_gbl_mutex_names[mutex_id]); | ||
652 | } | ||
653 | |||
654 | /******************************************************************************* | ||
655 | * | ||
656 | * FUNCTION: acpi_ut_get_notify_name | ||
657 | * | ||
658 | * PARAMETERS: notify_value - Value from the Notify() request | ||
659 | * | ||
660 | * RETURN: String corresponding to the Notify Value. | ||
661 | * | ||
662 | * DESCRIPTION: Translate a Notify Value to a notify namestring. | ||
663 | * | ||
664 | ******************************************************************************/ | ||
665 | |||
666 | /* Names for Notify() values, used for debug output */ | ||
667 | |||
668 | static const char *acpi_gbl_notify_value_names[] = { | ||
669 | "Bus Check", | ||
670 | "Device Check", | ||
671 | "Device Wake", | ||
672 | "Eject Request", | ||
673 | "Device Check Light", | ||
674 | "Frequency Mismatch", | ||
675 | "Bus Mode Mismatch", | ||
676 | "Power Fault", | ||
677 | "Capabilities Check", | ||
678 | "Device PLD Check", | ||
679 | "Reserved", | ||
680 | "System Locality Update" | ||
681 | }; | ||
682 | |||
683 | const char *acpi_ut_get_notify_name(u32 notify_value) | ||
684 | { | ||
685 | |||
686 | if (notify_value <= ACPI_NOTIFY_MAX) { | ||
687 | return (acpi_gbl_notify_value_names[notify_value]); | ||
688 | } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | ||
689 | return ("Reserved"); | ||
690 | } else { /* Greater or equal to 0x80 */ | ||
691 | |||
692 | return ("**Device Specific**"); | ||
693 | } | ||
694 | } | ||
695 | #endif | ||
696 | |||
697 | /******************************************************************************* | ||
698 | * | ||
699 | * FUNCTION: acpi_ut_valid_object_type | ||
700 | * | ||
701 | * PARAMETERS: Type - Object type to be validated | ||
702 | * | ||
703 | * RETURN: TRUE if valid object type, FALSE otherwise | ||
704 | * | ||
705 | * DESCRIPTION: Validate an object type | ||
706 | * | ||
707 | ******************************************************************************/ | ||
708 | |||
709 | u8 acpi_ut_valid_object_type(acpi_object_type type) | ||
710 | { | ||
711 | |||
712 | if (type > ACPI_TYPE_LOCAL_MAX) { | ||
713 | |||
714 | /* Note: Assumes all TYPEs are contiguous (external/local) */ | ||
715 | |||
716 | return (FALSE); | ||
717 | } | ||
718 | |||
719 | return (TRUE); | ||
720 | } | ||
721 | |||
722 | /******************************************************************************* | ||
723 | * | ||
724 | * FUNCTION: acpi_ut_init_globals | 241 | * FUNCTION: acpi_ut_init_globals |
725 | * | 242 | * |
726 | * PARAMETERS: None | 243 | * PARAMETERS: None |
@@ -768,7 +285,7 @@ acpi_status acpi_ut_init_globals(void) | |||
768 | acpi_gbl_gpe_fadt_blocks[0] = NULL; | 285 | acpi_gbl_gpe_fadt_blocks[0] = NULL; |
769 | acpi_gbl_gpe_fadt_blocks[1] = NULL; | 286 | acpi_gbl_gpe_fadt_blocks[1] = NULL; |
770 | acpi_current_gpe_count = 0; | 287 | acpi_current_gpe_count = 0; |
771 | acpi_all_gpes_initialized = FALSE; | 288 | acpi_gbl_all_gpes_initialized = FALSE; |
772 | 289 | ||
773 | /* Global handlers */ | 290 | /* Global handlers */ |
774 | 291 | ||
@@ -778,6 +295,7 @@ acpi_status acpi_ut_init_globals(void) | |||
778 | acpi_gbl_init_handler = NULL; | 295 | acpi_gbl_init_handler = NULL; |
779 | acpi_gbl_table_handler = NULL; | 296 | acpi_gbl_table_handler = NULL; |
780 | acpi_gbl_interface_handler = NULL; | 297 | acpi_gbl_interface_handler = NULL; |
298 | acpi_gbl_global_event_handler = NULL; | ||
781 | 299 | ||
782 | /* Global Lock support */ | 300 | /* Global Lock support */ |
783 | 301 | ||
@@ -805,6 +323,7 @@ acpi_status acpi_ut_init_globals(void) | |||
805 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; | 323 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; |
806 | acpi_gbl_osi_data = 0; | 324 | acpi_gbl_osi_data = 0; |
807 | acpi_gbl_osi_mutex = NULL; | 325 | acpi_gbl_osi_mutex = NULL; |
326 | acpi_gbl_reg_methods_executed = FALSE; | ||
808 | 327 | ||
809 | /* Hardware oriented */ | 328 | /* Hardware oriented */ |
810 | 329 | ||
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index d2906328535..b679ea69354 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index c1b1c803ea9..191b6828cce 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c index b081cd46a15..f6bb75c6faf 100644 --- a/drivers/acpi/acpica/utlock.c +++ b/drivers/acpi/acpica/utlock.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index 49cf7b7fd81..ce481da9bb4 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index c7d0e05ef5a..c33a852d4f4 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index d9efa495b43..a946c689f03 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -85,6 +85,7 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
85 | 85 | ||
86 | spin_lock_init(acpi_gbl_gpe_lock); | 86 | spin_lock_init(acpi_gbl_gpe_lock); |
87 | spin_lock_init(acpi_gbl_hardware_lock); | 87 | spin_lock_init(acpi_gbl_hardware_lock); |
88 | spin_lock_init(acpi_ev_global_lock_pending_lock); | ||
88 | 89 | ||
89 | /* Mutex for _OSI support */ | 90 | /* Mutex for _OSI support */ |
90 | status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); | 91 | status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); |
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index fd1fa2749ea..188340a017b 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 18c59a85fdc..1fb10cb8f11 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 7965919000b..84e05184424 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index d35d109b8da..30c21e1a936 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 1f484c9a688..98ad125e14f 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index 6f12e314fba..916ae097c43 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index fca34ccfd29..66a03caa2ad 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config ACPI_APEI | 1 | config ACPI_APEI |
2 | bool "ACPI Platform Error Interface (APEI)" | 2 | bool "ACPI Platform Error Interface (APEI)" |
3 | select PSTORE | ||
3 | depends on X86 | 4 | depends on X86 |
4 | help | 5 | help |
5 | APEI allows to report errors (for example from the chipset) | 6 | APEI allows to report errors (for example from the chipset) |
@@ -21,6 +22,13 @@ config ACPI_APEI_GHES | |||
21 | by firmware to produce more valuable hardware error | 22 | by firmware to produce more valuable hardware error |
22 | information for Linux. | 23 | information for Linux. |
23 | 24 | ||
25 | config ACPI_APEI_PCIEAER | ||
26 | bool "APEI PCIe AER logging/recovering support" | ||
27 | depends on ACPI_APEI && PCIEAER | ||
28 | help | ||
29 | PCIe AER errors may be reported via APEI firmware first mode. | ||
30 | Turn on this option to enable the corresponding support. | ||
31 | |||
24 | config ACPI_APEI_EINJ | 32 | config ACPI_APEI_EINJ |
25 | tristate "APEI Error INJection (EINJ)" | 33 | tristate "APEI Error INJection (EINJ)" |
26 | depends on ACPI_APEI && DEBUG_FS | 34 | depends on ACPI_APEI && DEBUG_FS |
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index 18df1e94027..ef0581f2094 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h | |||
@@ -109,6 +109,8 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) | |||
109 | return sizeof(*estatus) + estatus->data_length; | 109 | return sizeof(*estatus) + estatus->data_length; |
110 | } | 110 | } |
111 | 111 | ||
112 | void apei_estatus_print(const char *pfx, | ||
113 | const struct acpi_hest_generic_status *estatus); | ||
112 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); | 114 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); |
113 | int apei_estatus_check(const struct acpi_hest_generic_status *estatus); | 115 | int apei_estatus_check(const struct acpi_hest_generic_status *estatus); |
114 | #endif | 116 | #endif |
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index f4cf2fc4c8c..5d4189464d6 100644 --- a/drivers/acpi/apei/cper.c +++ b/drivers/acpi/apei/cper.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/time.h> | 29 | #include <linux/time.h> |
30 | #include <linux/cper.h> | 30 | #include <linux/cper.h> |
31 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
32 | #include <linux/aer.h> | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * CPER record ID need to be unique even after reboot, because record | 35 | * CPER record ID need to be unique even after reboot, because record |
@@ -46,6 +47,326 @@ u64 cper_next_record_id(void) | |||
46 | } | 47 | } |
47 | EXPORT_SYMBOL_GPL(cper_next_record_id); | 48 | EXPORT_SYMBOL_GPL(cper_next_record_id); |
48 | 49 | ||
50 | static const char *cper_severity_strs[] = { | ||
51 | "recoverable", | ||
52 | "fatal", | ||
53 | "corrected", | ||
54 | "info", | ||
55 | }; | ||
56 | |||
57 | static const char *cper_severity_str(unsigned int severity) | ||
58 | { | ||
59 | return severity < ARRAY_SIZE(cper_severity_strs) ? | ||
60 | cper_severity_strs[severity] : "unknown"; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * cper_print_bits - print strings for set bits | ||
65 | * @pfx: prefix for each line, including log level and prefix string | ||
66 | * @bits: bit mask | ||
67 | * @strs: string array, indexed by bit position | ||
68 | * @strs_size: size of the string array: @strs | ||
69 | * | ||
70 | * For each set bit in @bits, print the corresponding string in @strs. | ||
71 | * If the output length is longer than 80, multiple line will be | ||
72 | * printed, with @pfx is printed at the beginning of each line. | ||
73 | */ | ||
74 | void cper_print_bits(const char *pfx, unsigned int bits, | ||
75 | const char *strs[], unsigned int strs_size) | ||
76 | { | ||
77 | int i, len = 0; | ||
78 | const char *str; | ||
79 | char buf[84]; | ||
80 | |||
81 | for (i = 0; i < strs_size; i++) { | ||
82 | if (!(bits & (1U << i))) | ||
83 | continue; | ||
84 | str = strs[i]; | ||
85 | if (!str) | ||
86 | continue; | ||
87 | if (len && len + strlen(str) + 2 > 80) { | ||
88 | printk("%s\n", buf); | ||
89 | len = 0; | ||
90 | } | ||
91 | if (!len) | ||
92 | len = snprintf(buf, sizeof(buf), "%s%s", pfx, str); | ||
93 | else | ||
94 | len += snprintf(buf+len, sizeof(buf)-len, ", %s", str); | ||
95 | } | ||
96 | if (len) | ||
97 | printk("%s\n", buf); | ||
98 | } | ||
99 | |||
100 | static const char *cper_proc_type_strs[] = { | ||
101 | "IA32/X64", | ||
102 | "IA64", | ||
103 | }; | ||
104 | |||
105 | static const char *cper_proc_isa_strs[] = { | ||
106 | "IA32", | ||
107 | "IA64", | ||
108 | "X64", | ||
109 | }; | ||
110 | |||
111 | static const char *cper_proc_error_type_strs[] = { | ||
112 | "cache error", | ||
113 | "TLB error", | ||
114 | "bus error", | ||
115 | "micro-architectural error", | ||
116 | }; | ||
117 | |||
118 | static const char *cper_proc_op_strs[] = { | ||
119 | "unknown or generic", | ||
120 | "data read", | ||
121 | "data write", | ||
122 | "instruction execution", | ||
123 | }; | ||
124 | |||
125 | static const char *cper_proc_flag_strs[] = { | ||
126 | "restartable", | ||
127 | "precise IP", | ||
128 | "overflow", | ||
129 | "corrected", | ||
130 | }; | ||
131 | |||
132 | static void cper_print_proc_generic(const char *pfx, | ||
133 | const struct cper_sec_proc_generic *proc) | ||
134 | { | ||
135 | if (proc->validation_bits & CPER_PROC_VALID_TYPE) | ||
136 | printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type, | ||
137 | proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ? | ||
138 | cper_proc_type_strs[proc->proc_type] : "unknown"); | ||
139 | if (proc->validation_bits & CPER_PROC_VALID_ISA) | ||
140 | printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa, | ||
141 | proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ? | ||
142 | cper_proc_isa_strs[proc->proc_isa] : "unknown"); | ||
143 | if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) { | ||
144 | printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type); | ||
145 | cper_print_bits(pfx, proc->proc_error_type, | ||
146 | cper_proc_error_type_strs, | ||
147 | ARRAY_SIZE(cper_proc_error_type_strs)); | ||
148 | } | ||
149 | if (proc->validation_bits & CPER_PROC_VALID_OPERATION) | ||
150 | printk("%s""operation: %d, %s\n", pfx, proc->operation, | ||
151 | proc->operation < ARRAY_SIZE(cper_proc_op_strs) ? | ||
152 | cper_proc_op_strs[proc->operation] : "unknown"); | ||
153 | if (proc->validation_bits & CPER_PROC_VALID_FLAGS) { | ||
154 | printk("%s""flags: 0x%02x\n", pfx, proc->flags); | ||
155 | cper_print_bits(pfx, proc->flags, cper_proc_flag_strs, | ||
156 | ARRAY_SIZE(cper_proc_flag_strs)); | ||
157 | } | ||
158 | if (proc->validation_bits & CPER_PROC_VALID_LEVEL) | ||
159 | printk("%s""level: %d\n", pfx, proc->level); | ||
160 | if (proc->validation_bits & CPER_PROC_VALID_VERSION) | ||
161 | printk("%s""version_info: 0x%016llx\n", pfx, proc->cpu_version); | ||
162 | if (proc->validation_bits & CPER_PROC_VALID_ID) | ||
163 | printk("%s""processor_id: 0x%016llx\n", pfx, proc->proc_id); | ||
164 | if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS) | ||
165 | printk("%s""target_address: 0x%016llx\n", | ||
166 | pfx, proc->target_addr); | ||
167 | if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID) | ||
168 | printk("%s""requestor_id: 0x%016llx\n", | ||
169 | pfx, proc->requestor_id); | ||
170 | if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID) | ||
171 | printk("%s""responder_id: 0x%016llx\n", | ||
172 | pfx, proc->responder_id); | ||
173 | if (proc->validation_bits & CPER_PROC_VALID_IP) | ||
174 | printk("%s""IP: 0x%016llx\n", pfx, proc->ip); | ||
175 | } | ||
176 | |||
177 | static const char *cper_mem_err_type_strs[] = { | ||
178 | "unknown", | ||
179 | "no error", | ||
180 | "single-bit ECC", | ||
181 | "multi-bit ECC", | ||
182 | "single-symbol chipkill ECC", | ||
183 | "multi-symbol chipkill ECC", | ||
184 | "master abort", | ||
185 | "target abort", | ||
186 | "parity error", | ||
187 | "watchdog timeout", | ||
188 | "invalid address", | ||
189 | "mirror Broken", | ||
190 | "memory sparing", | ||
191 | "scrub corrected error", | ||
192 | "scrub uncorrected error", | ||
193 | }; | ||
194 | |||
195 | static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem) | ||
196 | { | ||
197 | if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS) | ||
198 | printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status); | ||
199 | if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) | ||
200 | printk("%s""physical_address: 0x%016llx\n", | ||
201 | pfx, mem->physical_addr); | ||
202 | if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK) | ||
203 | printk("%s""physical_address_mask: 0x%016llx\n", | ||
204 | pfx, mem->physical_addr_mask); | ||
205 | if (mem->validation_bits & CPER_MEM_VALID_NODE) | ||
206 | printk("%s""node: %d\n", pfx, mem->node); | ||
207 | if (mem->validation_bits & CPER_MEM_VALID_CARD) | ||
208 | printk("%s""card: %d\n", pfx, mem->card); | ||
209 | if (mem->validation_bits & CPER_MEM_VALID_MODULE) | ||
210 | printk("%s""module: %d\n", pfx, mem->module); | ||
211 | if (mem->validation_bits & CPER_MEM_VALID_BANK) | ||
212 | printk("%s""bank: %d\n", pfx, mem->bank); | ||
213 | if (mem->validation_bits & CPER_MEM_VALID_DEVICE) | ||
214 | printk("%s""device: %d\n", pfx, mem->device); | ||
215 | if (mem->validation_bits & CPER_MEM_VALID_ROW) | ||
216 | printk("%s""row: %d\n", pfx, mem->row); | ||
217 | if (mem->validation_bits & CPER_MEM_VALID_COLUMN) | ||
218 | printk("%s""column: %d\n", pfx, mem->column); | ||
219 | if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION) | ||
220 | printk("%s""bit_position: %d\n", pfx, mem->bit_pos); | ||
221 | if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID) | ||
222 | printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id); | ||
223 | if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID) | ||
224 | printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id); | ||
225 | if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID) | ||
226 | printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id); | ||
227 | if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) { | ||
228 | u8 etype = mem->error_type; | ||
229 | printk("%s""error_type: %d, %s\n", pfx, etype, | ||
230 | etype < ARRAY_SIZE(cper_mem_err_type_strs) ? | ||
231 | cper_mem_err_type_strs[etype] : "unknown"); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | static const char *cper_pcie_port_type_strs[] = { | ||
236 | "PCIe end point", | ||
237 | "legacy PCI end point", | ||
238 | "unknown", | ||
239 | "unknown", | ||
240 | "root port", | ||
241 | "upstream switch port", | ||
242 | "downstream switch port", | ||
243 | "PCIe to PCI/PCI-X bridge", | ||
244 | "PCI/PCI-X to PCIe bridge", | ||
245 | "root complex integrated endpoint device", | ||
246 | "root complex event collector", | ||
247 | }; | ||
248 | |||
249 | static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, | ||
250 | const struct acpi_hest_generic_data *gdata) | ||
251 | { | ||
252 | if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) | ||
253 | printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, | ||
254 | pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ? | ||
255 | cper_pcie_port_type_strs[pcie->port_type] : "unknown"); | ||
256 | if (pcie->validation_bits & CPER_PCIE_VALID_VERSION) | ||
257 | printk("%s""version: %d.%d\n", pfx, | ||
258 | pcie->version.major, pcie->version.minor); | ||
259 | if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS) | ||
260 | printk("%s""command: 0x%04x, status: 0x%04x\n", pfx, | ||
261 | pcie->command, pcie->status); | ||
262 | if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) { | ||
263 | const __u8 *p; | ||
264 | printk("%s""device_id: %04x:%02x:%02x.%x\n", pfx, | ||
265 | pcie->device_id.segment, pcie->device_id.bus, | ||
266 | pcie->device_id.device, pcie->device_id.function); | ||
267 | printk("%s""slot: %d\n", pfx, | ||
268 | pcie->device_id.slot >> CPER_PCIE_SLOT_SHIFT); | ||
269 | printk("%s""secondary_bus: 0x%02x\n", pfx, | ||
270 | pcie->device_id.secondary_bus); | ||
271 | printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx, | ||
272 | pcie->device_id.vendor_id, pcie->device_id.device_id); | ||
273 | p = pcie->device_id.class_code; | ||
274 | printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]); | ||
275 | } | ||
276 | if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER) | ||
277 | printk("%s""serial number: 0x%04x, 0x%04x\n", pfx, | ||
278 | pcie->serial_number.lower, pcie->serial_number.upper); | ||
279 | if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS) | ||
280 | printk( | ||
281 | "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", | ||
282 | pfx, pcie->bridge.secondary_status, pcie->bridge.control); | ||
283 | #ifdef CONFIG_ACPI_APEI_PCIEAER | ||
284 | if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) { | ||
285 | struct aer_capability_regs *aer_regs = (void *)pcie->aer_info; | ||
286 | cper_print_aer(pfx, gdata->error_severity, aer_regs); | ||
287 | } | ||
288 | #endif | ||
289 | } | ||
290 | |||
291 | static const char *apei_estatus_section_flag_strs[] = { | ||
292 | "primary", | ||
293 | "containment warning", | ||
294 | "reset", | ||
295 | "threshold exceeded", | ||
296 | "resource not accessible", | ||
297 | "latent error", | ||
298 | }; | ||
299 | |||
300 | static void apei_estatus_print_section( | ||
301 | const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no) | ||
302 | { | ||
303 | uuid_le *sec_type = (uuid_le *)gdata->section_type; | ||
304 | __u16 severity; | ||
305 | |||
306 | severity = gdata->error_severity; | ||
307 | printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity, | ||
308 | cper_severity_str(severity)); | ||
309 | printk("%s""flags: 0x%02x\n", pfx, gdata->flags); | ||
310 | cper_print_bits(pfx, gdata->flags, apei_estatus_section_flag_strs, | ||
311 | ARRAY_SIZE(apei_estatus_section_flag_strs)); | ||
312 | if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) | ||
313 | printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id); | ||
314 | if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) | ||
315 | printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text); | ||
316 | |||
317 | if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) { | ||
318 | struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1); | ||
319 | printk("%s""section_type: general processor error\n", pfx); | ||
320 | if (gdata->error_data_length >= sizeof(*proc_err)) | ||
321 | cper_print_proc_generic(pfx, proc_err); | ||
322 | else | ||
323 | goto err_section_too_small; | ||
324 | } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) { | ||
325 | struct cper_sec_mem_err *mem_err = (void *)(gdata + 1); | ||
326 | printk("%s""section_type: memory error\n", pfx); | ||
327 | if (gdata->error_data_length >= sizeof(*mem_err)) | ||
328 | cper_print_mem(pfx, mem_err); | ||
329 | else | ||
330 | goto err_section_too_small; | ||
331 | } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) { | ||
332 | struct cper_sec_pcie *pcie = (void *)(gdata + 1); | ||
333 | printk("%s""section_type: PCIe error\n", pfx); | ||
334 | if (gdata->error_data_length >= sizeof(*pcie)) | ||
335 | cper_print_pcie(pfx, pcie, gdata); | ||
336 | else | ||
337 | goto err_section_too_small; | ||
338 | } else | ||
339 | printk("%s""section type: unknown, %pUl\n", pfx, sec_type); | ||
340 | |||
341 | return; | ||
342 | |||
343 | err_section_too_small: | ||
344 | pr_err(FW_WARN "error section length is too small\n"); | ||
345 | } | ||
346 | |||
347 | void apei_estatus_print(const char *pfx, | ||
348 | const struct acpi_hest_generic_status *estatus) | ||
349 | { | ||
350 | struct acpi_hest_generic_data *gdata; | ||
351 | unsigned int data_len, gedata_len; | ||
352 | int sec_no = 0; | ||
353 | __u16 severity; | ||
354 | |||
355 | printk("%s""APEI generic hardware error status\n", pfx); | ||
356 | severity = estatus->error_severity; | ||
357 | printk("%s""severity: %d, %s\n", pfx, severity, | ||
358 | cper_severity_str(severity)); | ||
359 | data_len = estatus->data_length; | ||
360 | gdata = (struct acpi_hest_generic_data *)(estatus + 1); | ||
361 | while (data_len > sizeof(*gdata)) { | ||
362 | gedata_len = gdata->error_data_length; | ||
363 | apei_estatus_print_section(pfx, gdata, sec_no); | ||
364 | data_len -= gedata_len + sizeof(*gdata); | ||
365 | sec_no++; | ||
366 | } | ||
367 | } | ||
368 | EXPORT_SYMBOL_GPL(apei_estatus_print); | ||
369 | |||
49 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) | 370 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) |
50 | { | 371 | { |
51 | if (estatus->data_length && | 372 | if (estatus->data_length && |
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index cf29df69380..096aebfe7f3 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #define EINJ_PFX "EINJ: " | 39 | #define EINJ_PFX "EINJ: " |
40 | 40 | ||
41 | #define SPIN_UNIT 100 /* 100ns */ | 41 | #define SPIN_UNIT 100 /* 100ns */ |
42 | /* Firmware should respond within 1 miliseconds */ | 42 | /* Firmware should respond within 1 milliseconds */ |
43 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) | 43 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) |
44 | 44 | ||
45 | /* | 45 | /* |
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index de73caf3ceb..a4cfb64c86a 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c | |||
@@ -43,12 +43,27 @@ static DEFINE_MUTEX(erst_dbg_mutex); | |||
43 | 43 | ||
44 | static int erst_dbg_open(struct inode *inode, struct file *file) | 44 | static int erst_dbg_open(struct inode *inode, struct file *file) |
45 | { | 45 | { |
46 | int rc, *pos; | ||
47 | |||
46 | if (erst_disable) | 48 | if (erst_disable) |
47 | return -ENODEV; | 49 | return -ENODEV; |
48 | 50 | ||
51 | pos = (int *)&file->private_data; | ||
52 | |||
53 | rc = erst_get_record_id_begin(pos); | ||
54 | if (rc) | ||
55 | return rc; | ||
56 | |||
49 | return nonseekable_open(inode, file); | 57 | return nonseekable_open(inode, file); |
50 | } | 58 | } |
51 | 59 | ||
60 | static int erst_dbg_release(struct inode *inode, struct file *file) | ||
61 | { | ||
62 | erst_get_record_id_end(); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
52 | static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | 67 | static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
53 | { | 68 | { |
54 | int rc; | 69 | int rc; |
@@ -79,18 +94,20 @@ static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
79 | static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, | 94 | static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, |
80 | size_t usize, loff_t *off) | 95 | size_t usize, loff_t *off) |
81 | { | 96 | { |
82 | int rc; | 97 | int rc, *pos; |
83 | ssize_t len = 0; | 98 | ssize_t len = 0; |
84 | u64 id; | 99 | u64 id; |
85 | 100 | ||
86 | if (*off != 0) | 101 | if (*off) |
87 | return -EINVAL; | 102 | return -EINVAL; |
88 | 103 | ||
89 | if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) | 104 | if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) |
90 | return -EINTR; | 105 | return -EINTR; |
91 | 106 | ||
107 | pos = (int *)&filp->private_data; | ||
108 | |||
92 | retry_next: | 109 | retry_next: |
93 | rc = erst_get_next_record_id(&id); | 110 | rc = erst_get_record_id_next(pos, &id); |
94 | if (rc) | 111 | if (rc) |
95 | goto out; | 112 | goto out; |
96 | /* no more record */ | 113 | /* no more record */ |
@@ -181,6 +198,7 @@ out: | |||
181 | static const struct file_operations erst_dbg_ops = { | 198 | static const struct file_operations erst_dbg_ops = { |
182 | .owner = THIS_MODULE, | 199 | .owner = THIS_MODULE, |
183 | .open = erst_dbg_open, | 200 | .open = erst_dbg_open, |
201 | .release = erst_dbg_release, | ||
184 | .read = erst_dbg_read, | 202 | .read = erst_dbg_read, |
185 | .write = erst_dbg_write, | 203 | .write = erst_dbg_write, |
186 | .unlocked_ioctl = erst_dbg_ioctl, | 204 | .unlocked_ioctl = erst_dbg_ioctl, |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 1211c03149e..d6cb0ff6988 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/cper.h> | 34 | #include <linux/cper.h> |
35 | #include <linux/nmi.h> | 35 | #include <linux/nmi.h> |
36 | #include <linux/hardirq.h> | 36 | #include <linux/hardirq.h> |
37 | #include <linux/pstore.h> | ||
37 | #include <acpi/apei.h> | 38 | #include <acpi/apei.h> |
38 | 39 | ||
39 | #include "apei-internal.h" | 40 | #include "apei-internal.h" |
@@ -53,7 +54,7 @@ | |||
53 | sizeof(struct acpi_table_erst))) | 54 | sizeof(struct acpi_table_erst))) |
54 | 55 | ||
55 | #define SPIN_UNIT 100 /* 100ns */ | 56 | #define SPIN_UNIT 100 /* 100ns */ |
56 | /* Firmware should respond within 1 miliseconds */ | 57 | /* Firmware should respond within 1 milliseconds */ |
57 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) | 58 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) |
58 | #define FIRMWARE_MAX_STALL 50 /* 50us */ | 59 | #define FIRMWARE_MAX_STALL 50 /* 50us */ |
59 | 60 | ||
@@ -86,7 +87,7 @@ static struct erst_erange { | |||
86 | * It is used to provide exclusive accessing for ERST Error Log | 87 | * It is used to provide exclusive accessing for ERST Error Log |
87 | * Address Range too. | 88 | * Address Range too. |
88 | */ | 89 | */ |
89 | static DEFINE_SPINLOCK(erst_lock); | 90 | static DEFINE_RAW_SPINLOCK(erst_lock); |
90 | 91 | ||
91 | static inline int erst_errno(int command_status) | 92 | static inline int erst_errno(int command_status) |
92 | { | 93 | { |
@@ -421,14 +422,30 @@ ssize_t erst_get_record_count(void) | |||
421 | if (erst_disable) | 422 | if (erst_disable) |
422 | return -ENODEV; | 423 | return -ENODEV; |
423 | 424 | ||
424 | spin_lock_irqsave(&erst_lock, flags); | 425 | raw_spin_lock_irqsave(&erst_lock, flags); |
425 | count = __erst_get_record_count(); | 426 | count = __erst_get_record_count(); |
426 | spin_unlock_irqrestore(&erst_lock, flags); | 427 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
427 | 428 | ||
428 | return count; | 429 | return count; |
429 | } | 430 | } |
430 | EXPORT_SYMBOL_GPL(erst_get_record_count); | 431 | EXPORT_SYMBOL_GPL(erst_get_record_count); |
431 | 432 | ||
433 | #define ERST_RECORD_ID_CACHE_SIZE_MIN 16 | ||
434 | #define ERST_RECORD_ID_CACHE_SIZE_MAX 1024 | ||
435 | |||
436 | struct erst_record_id_cache { | ||
437 | struct mutex lock; | ||
438 | u64 *entries; | ||
439 | int len; | ||
440 | int size; | ||
441 | int refcount; | ||
442 | }; | ||
443 | |||
444 | static struct erst_record_id_cache erst_record_id_cache = { | ||
445 | .lock = __MUTEX_INITIALIZER(erst_record_id_cache.lock), | ||
446 | .refcount = 0, | ||
447 | }; | ||
448 | |||
432 | static int __erst_get_next_record_id(u64 *record_id) | 449 | static int __erst_get_next_record_id(u64 *record_id) |
433 | { | 450 | { |
434 | struct apei_exec_context ctx; | 451 | struct apei_exec_context ctx; |
@@ -443,26 +460,179 @@ static int __erst_get_next_record_id(u64 *record_id) | |||
443 | return 0; | 460 | return 0; |
444 | } | 461 | } |
445 | 462 | ||
463 | int erst_get_record_id_begin(int *pos) | ||
464 | { | ||
465 | int rc; | ||
466 | |||
467 | if (erst_disable) | ||
468 | return -ENODEV; | ||
469 | |||
470 | rc = mutex_lock_interruptible(&erst_record_id_cache.lock); | ||
471 | if (rc) | ||
472 | return rc; | ||
473 | erst_record_id_cache.refcount++; | ||
474 | mutex_unlock(&erst_record_id_cache.lock); | ||
475 | |||
476 | *pos = 0; | ||
477 | |||
478 | return 0; | ||
479 | } | ||
480 | EXPORT_SYMBOL_GPL(erst_get_record_id_begin); | ||
481 | |||
482 | /* erst_record_id_cache.lock must be held by caller */ | ||
483 | static int __erst_record_id_cache_add_one(void) | ||
484 | { | ||
485 | u64 id, prev_id, first_id; | ||
486 | int i, rc; | ||
487 | u64 *entries; | ||
488 | unsigned long flags; | ||
489 | |||
490 | id = prev_id = first_id = APEI_ERST_INVALID_RECORD_ID; | ||
491 | retry: | ||
492 | raw_spin_lock_irqsave(&erst_lock, flags); | ||
493 | rc = __erst_get_next_record_id(&id); | ||
494 | raw_spin_unlock_irqrestore(&erst_lock, flags); | ||
495 | if (rc == -ENOENT) | ||
496 | return 0; | ||
497 | if (rc) | ||
498 | return rc; | ||
499 | if (id == APEI_ERST_INVALID_RECORD_ID) | ||
500 | return 0; | ||
501 | /* can not skip current ID, or loop back to first ID */ | ||
502 | if (id == prev_id || id == first_id) | ||
503 | return 0; | ||
504 | if (first_id == APEI_ERST_INVALID_RECORD_ID) | ||
505 | first_id = id; | ||
506 | prev_id = id; | ||
507 | |||
508 | entries = erst_record_id_cache.entries; | ||
509 | for (i = 0; i < erst_record_id_cache.len; i++) { | ||
510 | if (entries[i] == id) | ||
511 | break; | ||
512 | } | ||
513 | /* record id already in cache, try next */ | ||
514 | if (i < erst_record_id_cache.len) | ||
515 | goto retry; | ||
516 | if (erst_record_id_cache.len >= erst_record_id_cache.size) { | ||
517 | int new_size, alloc_size; | ||
518 | u64 *new_entries; | ||
519 | |||
520 | new_size = erst_record_id_cache.size * 2; | ||
521 | new_size = clamp_val(new_size, ERST_RECORD_ID_CACHE_SIZE_MIN, | ||
522 | ERST_RECORD_ID_CACHE_SIZE_MAX); | ||
523 | if (new_size <= erst_record_id_cache.size) { | ||
524 | if (printk_ratelimit()) | ||
525 | pr_warning(FW_WARN ERST_PFX | ||
526 | "too many record ID!\n"); | ||
527 | return 0; | ||
528 | } | ||
529 | alloc_size = new_size * sizeof(entries[0]); | ||
530 | if (alloc_size < PAGE_SIZE) | ||
531 | new_entries = kmalloc(alloc_size, GFP_KERNEL); | ||
532 | else | ||
533 | new_entries = vmalloc(alloc_size); | ||
534 | if (!new_entries) | ||
535 | return -ENOMEM; | ||
536 | memcpy(new_entries, entries, | ||
537 | erst_record_id_cache.len * sizeof(entries[0])); | ||
538 | if (erst_record_id_cache.size < PAGE_SIZE) | ||
539 | kfree(entries); | ||
540 | else | ||
541 | vfree(entries); | ||
542 | erst_record_id_cache.entries = entries = new_entries; | ||
543 | erst_record_id_cache.size = new_size; | ||
544 | } | ||
545 | entries[i] = id; | ||
546 | erst_record_id_cache.len++; | ||
547 | |||
548 | return 1; | ||
549 | } | ||
550 | |||
446 | /* | 551 | /* |
447 | * Get the record ID of an existing error record on the persistent | 552 | * Get the record ID of an existing error record on the persistent |
448 | * storage. If there is no error record on the persistent storage, the | 553 | * storage. If there is no error record on the persistent storage, the |
449 | * returned record_id is APEI_ERST_INVALID_RECORD_ID. | 554 | * returned record_id is APEI_ERST_INVALID_RECORD_ID. |
450 | */ | 555 | */ |
451 | int erst_get_next_record_id(u64 *record_id) | 556 | int erst_get_record_id_next(int *pos, u64 *record_id) |
452 | { | 557 | { |
453 | int rc; | 558 | int rc = 0; |
454 | unsigned long flags; | 559 | u64 *entries; |
455 | 560 | ||
456 | if (erst_disable) | 561 | if (erst_disable) |
457 | return -ENODEV; | 562 | return -ENODEV; |
458 | 563 | ||
459 | spin_lock_irqsave(&erst_lock, flags); | 564 | /* must be enclosed by erst_get_record_id_begin/end */ |
460 | rc = __erst_get_next_record_id(record_id); | 565 | BUG_ON(!erst_record_id_cache.refcount); |
461 | spin_unlock_irqrestore(&erst_lock, flags); | 566 | BUG_ON(*pos < 0 || *pos > erst_record_id_cache.len); |
567 | |||
568 | mutex_lock(&erst_record_id_cache.lock); | ||
569 | entries = erst_record_id_cache.entries; | ||
570 | for (; *pos < erst_record_id_cache.len; (*pos)++) | ||
571 | if (entries[*pos] != APEI_ERST_INVALID_RECORD_ID) | ||
572 | break; | ||
573 | /* found next record id in cache */ | ||
574 | if (*pos < erst_record_id_cache.len) { | ||
575 | *record_id = entries[*pos]; | ||
576 | (*pos)++; | ||
577 | goto out_unlock; | ||
578 | } | ||
579 | |||
580 | /* Try to add one more record ID to cache */ | ||
581 | rc = __erst_record_id_cache_add_one(); | ||
582 | if (rc < 0) | ||
583 | goto out_unlock; | ||
584 | /* successfully add one new ID */ | ||
585 | if (rc == 1) { | ||
586 | *record_id = erst_record_id_cache.entries[*pos]; | ||
587 | (*pos)++; | ||
588 | rc = 0; | ||
589 | } else { | ||
590 | *pos = -1; | ||
591 | *record_id = APEI_ERST_INVALID_RECORD_ID; | ||
592 | } | ||
593 | out_unlock: | ||
594 | mutex_unlock(&erst_record_id_cache.lock); | ||
462 | 595 | ||
463 | return rc; | 596 | return rc; |
464 | } | 597 | } |
465 | EXPORT_SYMBOL_GPL(erst_get_next_record_id); | 598 | EXPORT_SYMBOL_GPL(erst_get_record_id_next); |
599 | |||
600 | /* erst_record_id_cache.lock must be held by caller */ | ||
601 | static void __erst_record_id_cache_compact(void) | ||
602 | { | ||
603 | int i, wpos = 0; | ||
604 | u64 *entries; | ||
605 | |||
606 | if (erst_record_id_cache.refcount) | ||
607 | return; | ||
608 | |||
609 | entries = erst_record_id_cache.entries; | ||
610 | for (i = 0; i < erst_record_id_cache.len; i++) { | ||
611 | if (entries[i] == APEI_ERST_INVALID_RECORD_ID) | ||
612 | continue; | ||
613 | if (wpos != i) | ||
614 | memcpy(&entries[wpos], &entries[i], sizeof(entries[i])); | ||
615 | wpos++; | ||
616 | } | ||
617 | erst_record_id_cache.len = wpos; | ||
618 | } | ||
619 | |||
620 | void erst_get_record_id_end(void) | ||
621 | { | ||
622 | /* | ||
623 | * erst_disable != 0 should be detected by invoker via the | ||
624 | * return value of erst_get_record_id_begin/next, so this | ||
625 | * function should not be called for erst_disable != 0. | ||
626 | */ | ||
627 | BUG_ON(erst_disable); | ||
628 | |||
629 | mutex_lock(&erst_record_id_cache.lock); | ||
630 | erst_record_id_cache.refcount--; | ||
631 | BUG_ON(erst_record_id_cache.refcount < 0); | ||
632 | __erst_record_id_cache_compact(); | ||
633 | mutex_unlock(&erst_record_id_cache.lock); | ||
634 | } | ||
635 | EXPORT_SYMBOL_GPL(erst_get_record_id_end); | ||
466 | 636 | ||
467 | static int __erst_write_to_storage(u64 offset) | 637 | static int __erst_write_to_storage(u64 offset) |
468 | { | 638 | { |
@@ -624,17 +794,17 @@ int erst_write(const struct cper_record_header *record) | |||
624 | return -EINVAL; | 794 | return -EINVAL; |
625 | 795 | ||
626 | if (erst_erange.attr & ERST_RANGE_NVRAM) { | 796 | if (erst_erange.attr & ERST_RANGE_NVRAM) { |
627 | if (!spin_trylock_irqsave(&erst_lock, flags)) | 797 | if (!raw_spin_trylock_irqsave(&erst_lock, flags)) |
628 | return -EBUSY; | 798 | return -EBUSY; |
629 | rc = __erst_write_to_nvram(record); | 799 | rc = __erst_write_to_nvram(record); |
630 | spin_unlock_irqrestore(&erst_lock, flags); | 800 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
631 | return rc; | 801 | return rc; |
632 | } | 802 | } |
633 | 803 | ||
634 | if (record->record_length > erst_erange.size) | 804 | if (record->record_length > erst_erange.size) |
635 | return -EINVAL; | 805 | return -EINVAL; |
636 | 806 | ||
637 | if (!spin_trylock_irqsave(&erst_lock, flags)) | 807 | if (!raw_spin_trylock_irqsave(&erst_lock, flags)) |
638 | return -EBUSY; | 808 | return -EBUSY; |
639 | memcpy(erst_erange.vaddr, record, record->record_length); | 809 | memcpy(erst_erange.vaddr, record, record->record_length); |
640 | rcd_erange = erst_erange.vaddr; | 810 | rcd_erange = erst_erange.vaddr; |
@@ -642,7 +812,7 @@ int erst_write(const struct cper_record_header *record) | |||
642 | memcpy(&rcd_erange->persistence_information, "ER", 2); | 812 | memcpy(&rcd_erange->persistence_information, "ER", 2); |
643 | 813 | ||
644 | rc = __erst_write_to_storage(0); | 814 | rc = __erst_write_to_storage(0); |
645 | spin_unlock_irqrestore(&erst_lock, flags); | 815 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
646 | 816 | ||
647 | return rc; | 817 | return rc; |
648 | } | 818 | } |
@@ -696,63 +866,41 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record, | |||
696 | if (erst_disable) | 866 | if (erst_disable) |
697 | return -ENODEV; | 867 | return -ENODEV; |
698 | 868 | ||
699 | spin_lock_irqsave(&erst_lock, flags); | 869 | raw_spin_lock_irqsave(&erst_lock, flags); |
700 | len = __erst_read(record_id, record, buflen); | 870 | len = __erst_read(record_id, record, buflen); |
701 | spin_unlock_irqrestore(&erst_lock, flags); | 871 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
702 | return len; | 872 | return len; |
703 | } | 873 | } |
704 | EXPORT_SYMBOL_GPL(erst_read); | 874 | EXPORT_SYMBOL_GPL(erst_read); |
705 | 875 | ||
706 | /* | ||
707 | * If return value > buflen, the buffer size is not big enough, | ||
708 | * else if return value = 0, there is no more record to read, | ||
709 | * else if return value < 0, something goes wrong, | ||
710 | * else everything is OK, and return value is record length | ||
711 | */ | ||
712 | ssize_t erst_read_next(struct cper_record_header *record, size_t buflen) | ||
713 | { | ||
714 | int rc; | ||
715 | ssize_t len; | ||
716 | unsigned long flags; | ||
717 | u64 record_id; | ||
718 | |||
719 | if (erst_disable) | ||
720 | return -ENODEV; | ||
721 | |||
722 | spin_lock_irqsave(&erst_lock, flags); | ||
723 | rc = __erst_get_next_record_id(&record_id); | ||
724 | if (rc) { | ||
725 | spin_unlock_irqrestore(&erst_lock, flags); | ||
726 | return rc; | ||
727 | } | ||
728 | /* no more record */ | ||
729 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { | ||
730 | spin_unlock_irqrestore(&erst_lock, flags); | ||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | len = __erst_read(record_id, record, buflen); | ||
735 | spin_unlock_irqrestore(&erst_lock, flags); | ||
736 | |||
737 | return len; | ||
738 | } | ||
739 | EXPORT_SYMBOL_GPL(erst_read_next); | ||
740 | |||
741 | int erst_clear(u64 record_id) | 876 | int erst_clear(u64 record_id) |
742 | { | 877 | { |
743 | int rc; | 878 | int rc, i; |
744 | unsigned long flags; | 879 | unsigned long flags; |
880 | u64 *entries; | ||
745 | 881 | ||
746 | if (erst_disable) | 882 | if (erst_disable) |
747 | return -ENODEV; | 883 | return -ENODEV; |
748 | 884 | ||
749 | spin_lock_irqsave(&erst_lock, flags); | 885 | rc = mutex_lock_interruptible(&erst_record_id_cache.lock); |
886 | if (rc) | ||
887 | return rc; | ||
888 | raw_spin_lock_irqsave(&erst_lock, flags); | ||
750 | if (erst_erange.attr & ERST_RANGE_NVRAM) | 889 | if (erst_erange.attr & ERST_RANGE_NVRAM) |
751 | rc = __erst_clear_from_nvram(record_id); | 890 | rc = __erst_clear_from_nvram(record_id); |
752 | else | 891 | else |
753 | rc = __erst_clear_from_storage(record_id); | 892 | rc = __erst_clear_from_storage(record_id); |
754 | spin_unlock_irqrestore(&erst_lock, flags); | 893 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
755 | 894 | if (rc) | |
895 | goto out; | ||
896 | entries = erst_record_id_cache.entries; | ||
897 | for (i = 0; i < erst_record_id_cache.len; i++) { | ||
898 | if (entries[i] == record_id) | ||
899 | entries[i] = APEI_ERST_INVALID_RECORD_ID; | ||
900 | } | ||
901 | __erst_record_id_cache_compact(); | ||
902 | out: | ||
903 | mutex_unlock(&erst_record_id_cache.lock); | ||
756 | return rc; | 904 | return rc; |
757 | } | 905 | } |
758 | EXPORT_SYMBOL_GPL(erst_clear); | 906 | EXPORT_SYMBOL_GPL(erst_clear); |
@@ -781,6 +929,128 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) | |||
781 | return 0; | 929 | return 0; |
782 | } | 930 | } |
783 | 931 | ||
932 | static size_t erst_reader(u64 *id, enum pstore_type_id *type, | ||
933 | struct timespec *time); | ||
934 | static u64 erst_writer(enum pstore_type_id type, size_t size); | ||
935 | |||
936 | static struct pstore_info erst_info = { | ||
937 | .owner = THIS_MODULE, | ||
938 | .name = "erst", | ||
939 | .read = erst_reader, | ||
940 | .write = erst_writer, | ||
941 | .erase = erst_clear | ||
942 | }; | ||
943 | |||
944 | #define CPER_CREATOR_PSTORE \ | ||
945 | UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \ | ||
946 | 0x64, 0x90, 0xb8, 0x9d) | ||
947 | #define CPER_SECTION_TYPE_DMESG \ | ||
948 | UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \ | ||
949 | 0x94, 0x19, 0xeb, 0x12) | ||
950 | #define CPER_SECTION_TYPE_MCE \ | ||
951 | UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \ | ||
952 | 0x04, 0x4a, 0x38, 0xfc) | ||
953 | |||
954 | struct cper_pstore_record { | ||
955 | struct cper_record_header hdr; | ||
956 | struct cper_section_descriptor sec_hdr; | ||
957 | char data[]; | ||
958 | } __packed; | ||
959 | |||
960 | static size_t erst_reader(u64 *id, enum pstore_type_id *type, | ||
961 | struct timespec *time) | ||
962 | { | ||
963 | int rc; | ||
964 | ssize_t len; | ||
965 | unsigned long flags; | ||
966 | u64 record_id; | ||
967 | struct cper_pstore_record *rcd = (struct cper_pstore_record *) | ||
968 | (erst_info.buf - sizeof(*rcd)); | ||
969 | |||
970 | if (erst_disable) | ||
971 | return -ENODEV; | ||
972 | |||
973 | raw_spin_lock_irqsave(&erst_lock, flags); | ||
974 | skip: | ||
975 | rc = __erst_get_next_record_id(&record_id); | ||
976 | if (rc) { | ||
977 | raw_spin_unlock_irqrestore(&erst_lock, flags); | ||
978 | return rc; | ||
979 | } | ||
980 | /* no more record */ | ||
981 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { | ||
982 | raw_spin_unlock_irqrestore(&erst_lock, flags); | ||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) + | ||
987 | erst_erange.size); | ||
988 | if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) | ||
989 | goto skip; | ||
990 | raw_spin_unlock_irqrestore(&erst_lock, flags); | ||
991 | |||
992 | *id = record_id; | ||
993 | if (uuid_le_cmp(rcd->sec_hdr.section_type, | ||
994 | CPER_SECTION_TYPE_DMESG) == 0) | ||
995 | *type = PSTORE_TYPE_DMESG; | ||
996 | else if (uuid_le_cmp(rcd->sec_hdr.section_type, | ||
997 | CPER_SECTION_TYPE_MCE) == 0) | ||
998 | *type = PSTORE_TYPE_MCE; | ||
999 | else | ||
1000 | *type = PSTORE_TYPE_UNKNOWN; | ||
1001 | |||
1002 | if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP) | ||
1003 | time->tv_sec = rcd->hdr.timestamp; | ||
1004 | else | ||
1005 | time->tv_sec = 0; | ||
1006 | time->tv_nsec = 0; | ||
1007 | |||
1008 | return len - sizeof(*rcd); | ||
1009 | } | ||
1010 | |||
1011 | static u64 erst_writer(enum pstore_type_id type, size_t size) | ||
1012 | { | ||
1013 | struct cper_pstore_record *rcd = (struct cper_pstore_record *) | ||
1014 | (erst_info.buf - sizeof(*rcd)); | ||
1015 | |||
1016 | memset(rcd, 0, sizeof(*rcd)); | ||
1017 | memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); | ||
1018 | rcd->hdr.revision = CPER_RECORD_REV; | ||
1019 | rcd->hdr.signature_end = CPER_SIG_END; | ||
1020 | rcd->hdr.section_count = 1; | ||
1021 | rcd->hdr.error_severity = CPER_SEV_FATAL; | ||
1022 | /* timestamp valid. platform_id, partition_id are invalid */ | ||
1023 | rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; | ||
1024 | rcd->hdr.timestamp = get_seconds(); | ||
1025 | rcd->hdr.record_length = sizeof(*rcd) + size; | ||
1026 | rcd->hdr.creator_id = CPER_CREATOR_PSTORE; | ||
1027 | rcd->hdr.notification_type = CPER_NOTIFY_MCE; | ||
1028 | rcd->hdr.record_id = cper_next_record_id(); | ||
1029 | rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR; | ||
1030 | |||
1031 | rcd->sec_hdr.section_offset = sizeof(*rcd); | ||
1032 | rcd->sec_hdr.section_length = size; | ||
1033 | rcd->sec_hdr.revision = CPER_SEC_REV; | ||
1034 | /* fru_id and fru_text is invalid */ | ||
1035 | rcd->sec_hdr.validation_bits = 0; | ||
1036 | rcd->sec_hdr.flags = CPER_SEC_PRIMARY; | ||
1037 | switch (type) { | ||
1038 | case PSTORE_TYPE_DMESG: | ||
1039 | rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG; | ||
1040 | break; | ||
1041 | case PSTORE_TYPE_MCE: | ||
1042 | rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE; | ||
1043 | break; | ||
1044 | default: | ||
1045 | return -EINVAL; | ||
1046 | } | ||
1047 | rcd->sec_hdr.section_severity = CPER_SEV_FATAL; | ||
1048 | |||
1049 | erst_write(&rcd->hdr); | ||
1050 | |||
1051 | return rcd->hdr.record_id; | ||
1052 | } | ||
1053 | |||
784 | static int __init erst_init(void) | 1054 | static int __init erst_init(void) |
785 | { | 1055 | { |
786 | int rc = 0; | 1056 | int rc = 0; |
@@ -788,6 +1058,7 @@ static int __init erst_init(void) | |||
788 | struct apei_exec_context ctx; | 1058 | struct apei_exec_context ctx; |
789 | struct apei_resources erst_resources; | 1059 | struct apei_resources erst_resources; |
790 | struct resource *r; | 1060 | struct resource *r; |
1061 | char *buf; | ||
791 | 1062 | ||
792 | if (acpi_disabled) | 1063 | if (acpi_disabled) |
793 | goto err; | 1064 | goto err; |
@@ -854,6 +1125,18 @@ static int __init erst_init(void) | |||
854 | if (!erst_erange.vaddr) | 1125 | if (!erst_erange.vaddr) |
855 | goto err_release_erange; | 1126 | goto err_release_erange; |
856 | 1127 | ||
1128 | buf = kmalloc(erst_erange.size, GFP_KERNEL); | ||
1129 | mutex_init(&erst_info.buf_mutex); | ||
1130 | if (buf) { | ||
1131 | erst_info.buf = buf + sizeof(struct cper_pstore_record); | ||
1132 | erst_info.bufsize = erst_erange.size - | ||
1133 | sizeof(struct cper_pstore_record); | ||
1134 | if (pstore_register(&erst_info)) { | ||
1135 | pr_info(ERST_PFX "Could not register with persistent store\n"); | ||
1136 | kfree(buf); | ||
1137 | } | ||
1138 | } | ||
1139 | |||
857 | pr_info(ERST_PFX | 1140 | pr_info(ERST_PFX |
858 | "Error Record Serialization Table (ERST) support is initialized.\n"); | 1141 | "Error Record Serialization Table (ERST) support is initialized.\n"); |
859 | 1142 | ||
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 0d505e59214..f703b288115 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -12,10 +12,6 @@ | |||
12 | * For more information about Generic Hardware Error Source, please | 12 | * For more information about Generic Hardware Error Source, please |
13 | * refer to ACPI Specification version 4.0, section 17.3.2.6 | 13 | * refer to ACPI Specification version 4.0, section 17.3.2.6 |
14 | * | 14 | * |
15 | * Now, only SCI notification type and memory errors are | ||
16 | * supported. More notification type and hardware error type will be | ||
17 | * added later. | ||
18 | * | ||
19 | * Copyright 2010 Intel Corp. | 15 | * Copyright 2010 Intel Corp. |
20 | * Author: Huang Ying <ying.huang@intel.com> | 16 | * Author: Huang Ying <ying.huang@intel.com> |
21 | * | 17 | * |
@@ -39,14 +35,18 @@ | |||
39 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
40 | #include <linux/io.h> | 36 | #include <linux/io.h> |
41 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/timer.h> | ||
42 | #include <linux/cper.h> | 39 | #include <linux/cper.h> |
43 | #include <linux/kdebug.h> | 40 | #include <linux/kdebug.h> |
44 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
45 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
43 | #include <linux/ratelimit.h> | ||
44 | #include <linux/vmalloc.h> | ||
46 | #include <acpi/apei.h> | 45 | #include <acpi/apei.h> |
47 | #include <acpi/atomicio.h> | 46 | #include <acpi/atomicio.h> |
48 | #include <acpi/hed.h> | 47 | #include <acpi/hed.h> |
49 | #include <asm/mce.h> | 48 | #include <asm/mce.h> |
49 | #include <asm/tlbflush.h> | ||
50 | 50 | ||
51 | #include "apei-internal.h" | 51 | #include "apei-internal.h" |
52 | 52 | ||
@@ -55,42 +55,131 @@ | |||
55 | #define GHES_ESTATUS_MAX_SIZE 65536 | 55 | #define GHES_ESTATUS_MAX_SIZE 65536 |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * One struct ghes is created for each generic hardware error | 58 | * One struct ghes is created for each generic hardware error source. |
59 | * source. | ||
60 | * | ||
61 | * It provides the context for APEI hardware error timer/IRQ/SCI/NMI | 59 | * It provides the context for APEI hardware error timer/IRQ/SCI/NMI |
62 | * handler. Handler for one generic hardware error source is only | 60 | * handler. |
63 | * triggered after the previous one is done. So handler can uses | ||
64 | * struct ghes without locking. | ||
65 | * | 61 | * |
66 | * estatus: memory buffer for error status block, allocated during | 62 | * estatus: memory buffer for error status block, allocated during |
67 | * HEST parsing. | 63 | * HEST parsing. |
68 | */ | 64 | */ |
69 | #define GHES_TO_CLEAR 0x0001 | 65 | #define GHES_TO_CLEAR 0x0001 |
66 | #define GHES_EXITING 0x0002 | ||
70 | 67 | ||
71 | struct ghes { | 68 | struct ghes { |
72 | struct acpi_hest_generic *generic; | 69 | struct acpi_hest_generic *generic; |
73 | struct acpi_hest_generic_status *estatus; | 70 | struct acpi_hest_generic_status *estatus; |
74 | struct list_head list; | ||
75 | u64 buffer_paddr; | 71 | u64 buffer_paddr; |
76 | unsigned long flags; | 72 | unsigned long flags; |
73 | union { | ||
74 | struct list_head list; | ||
75 | struct timer_list timer; | ||
76 | unsigned int irq; | ||
77 | }; | ||
77 | }; | 78 | }; |
78 | 79 | ||
80 | static int ghes_panic_timeout __read_mostly = 30; | ||
81 | |||
79 | /* | 82 | /* |
80 | * Error source lists, one list for each notification method. The | 83 | * All error sources notified with SCI shares one notifier function, |
81 | * members in lists are struct ghes. | 84 | * so they need to be linked and checked one by one. This is applied |
85 | * to NMI too. | ||
82 | * | 86 | * |
83 | * The list members are only added in HEST parsing and deleted during | 87 | * RCU is used for these lists, so ghes_list_mutex is only used for |
84 | * module_exit, that is, single-threaded. So no lock is needed for | 88 | * list changing, not for traversing. |
85 | * that. | ||
86 | * | ||
87 | * But the mutual exclusion is needed between members adding/deleting | ||
88 | * and timer/IRQ/SCI/NMI handler, which may traverse the list. RCU is | ||
89 | * used for that. | ||
90 | */ | 89 | */ |
91 | static LIST_HEAD(ghes_sci); | 90 | static LIST_HEAD(ghes_sci); |
91 | static LIST_HEAD(ghes_nmi); | ||
92 | static DEFINE_MUTEX(ghes_list_mutex); | 92 | static DEFINE_MUTEX(ghes_list_mutex); |
93 | 93 | ||
94 | /* | ||
95 | * NMI may be triggered on any CPU, so ghes_nmi_lock is used for | ||
96 | * mutual exclusion. | ||
97 | */ | ||
98 | static DEFINE_RAW_SPINLOCK(ghes_nmi_lock); | ||
99 | |||
100 | /* | ||
101 | * Because the memory area used to transfer hardware error information | ||
102 | * from BIOS to Linux can be determined only in NMI, IRQ or timer | ||
103 | * handler, but general ioremap can not be used in atomic context, so | ||
104 | * a special version of atomic ioremap is implemented for that. | ||
105 | */ | ||
106 | |||
107 | /* | ||
108 | * Two virtual pages are used, one for NMI context, the other for | ||
109 | * IRQ/PROCESS context | ||
110 | */ | ||
111 | #define GHES_IOREMAP_PAGES 2 | ||
112 | #define GHES_IOREMAP_NMI_PAGE(base) (base) | ||
113 | #define GHES_IOREMAP_IRQ_PAGE(base) ((base) + PAGE_SIZE) | ||
114 | |||
115 | /* virtual memory area for atomic ioremap */ | ||
116 | static struct vm_struct *ghes_ioremap_area; | ||
117 | /* | ||
118 | * These 2 spinlock is used to prevent atomic ioremap virtual memory | ||
119 | * area from being mapped simultaneously. | ||
120 | */ | ||
121 | static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); | ||
122 | static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); | ||
123 | |||
124 | static int ghes_ioremap_init(void) | ||
125 | { | ||
126 | ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, | ||
127 | VM_IOREMAP, VMALLOC_START, VMALLOC_END); | ||
128 | if (!ghes_ioremap_area) { | ||
129 | pr_err(GHES_PFX "Failed to allocate virtual memory area for atomic ioremap.\n"); | ||
130 | return -ENOMEM; | ||
131 | } | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static void ghes_ioremap_exit(void) | ||
137 | { | ||
138 | free_vm_area(ghes_ioremap_area); | ||
139 | } | ||
140 | |||
141 | static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn) | ||
142 | { | ||
143 | unsigned long vaddr; | ||
144 | |||
145 | vaddr = (unsigned long)GHES_IOREMAP_NMI_PAGE(ghes_ioremap_area->addr); | ||
146 | ioremap_page_range(vaddr, vaddr + PAGE_SIZE, | ||
147 | pfn << PAGE_SHIFT, PAGE_KERNEL); | ||
148 | |||
149 | return (void __iomem *)vaddr; | ||
150 | } | ||
151 | |||
152 | static void __iomem *ghes_ioremap_pfn_irq(u64 pfn) | ||
153 | { | ||
154 | unsigned long vaddr; | ||
155 | |||
156 | vaddr = (unsigned long)GHES_IOREMAP_IRQ_PAGE(ghes_ioremap_area->addr); | ||
157 | ioremap_page_range(vaddr, vaddr + PAGE_SIZE, | ||
158 | pfn << PAGE_SHIFT, PAGE_KERNEL); | ||
159 | |||
160 | return (void __iomem *)vaddr; | ||
161 | } | ||
162 | |||
163 | static void ghes_iounmap_nmi(void __iomem *vaddr_ptr) | ||
164 | { | ||
165 | unsigned long vaddr = (unsigned long __force)vaddr_ptr; | ||
166 | void *base = ghes_ioremap_area->addr; | ||
167 | |||
168 | BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); | ||
169 | unmap_kernel_range_noflush(vaddr, PAGE_SIZE); | ||
170 | __flush_tlb_one(vaddr); | ||
171 | } | ||
172 | |||
173 | static void ghes_iounmap_irq(void __iomem *vaddr_ptr) | ||
174 | { | ||
175 | unsigned long vaddr = (unsigned long __force)vaddr_ptr; | ||
176 | void *base = ghes_ioremap_area->addr; | ||
177 | |||
178 | BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); | ||
179 | unmap_kernel_range_noflush(vaddr, PAGE_SIZE); | ||
180 | __flush_tlb_one(vaddr); | ||
181 | } | ||
182 | |||
94 | static struct ghes *ghes_new(struct acpi_hest_generic *generic) | 183 | static struct ghes *ghes_new(struct acpi_hest_generic *generic) |
95 | { | 184 | { |
96 | struct ghes *ghes; | 185 | struct ghes *ghes; |
@@ -101,7 +190,6 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) | |||
101 | if (!ghes) | 190 | if (!ghes) |
102 | return ERR_PTR(-ENOMEM); | 191 | return ERR_PTR(-ENOMEM); |
103 | ghes->generic = generic; | 192 | ghes->generic = generic; |
104 | INIT_LIST_HEAD(&ghes->list); | ||
105 | rc = acpi_pre_map_gar(&generic->error_status_address); | 193 | rc = acpi_pre_map_gar(&generic->error_status_address); |
106 | if (rc) | 194 | if (rc) |
107 | goto err_free; | 195 | goto err_free; |
@@ -153,27 +241,46 @@ static inline int ghes_severity(int severity) | |||
153 | case CPER_SEV_FATAL: | 241 | case CPER_SEV_FATAL: |
154 | return GHES_SEV_PANIC; | 242 | return GHES_SEV_PANIC; |
155 | default: | 243 | default: |
156 | /* Unkown, go panic */ | 244 | /* Unknown, go panic */ |
157 | return GHES_SEV_PANIC; | 245 | return GHES_SEV_PANIC; |
158 | } | 246 | } |
159 | } | 247 | } |
160 | 248 | ||
161 | /* SCI handler run in work queue, so ioremap can be used here */ | 249 | static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, |
162 | static int ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, | 250 | int from_phys) |
163 | int from_phys) | ||
164 | { | 251 | { |
165 | void *vaddr; | 252 | void __iomem *vaddr; |
166 | 253 | unsigned long flags = 0; | |
167 | vaddr = ioremap_cache(paddr, len); | 254 | int in_nmi = in_nmi(); |
168 | if (!vaddr) | 255 | u64 offset; |
169 | return -ENOMEM; | 256 | u32 trunk; |
170 | if (from_phys) | 257 | |
171 | memcpy(buffer, vaddr, len); | 258 | while (len > 0) { |
172 | else | 259 | offset = paddr - (paddr & PAGE_MASK); |
173 | memcpy(vaddr, buffer, len); | 260 | if (in_nmi) { |
174 | iounmap(vaddr); | 261 | raw_spin_lock(&ghes_ioremap_lock_nmi); |
175 | 262 | vaddr = ghes_ioremap_pfn_nmi(paddr >> PAGE_SHIFT); | |
176 | return 0; | 263 | } else { |
264 | spin_lock_irqsave(&ghes_ioremap_lock_irq, flags); | ||
265 | vaddr = ghes_ioremap_pfn_irq(paddr >> PAGE_SHIFT); | ||
266 | } | ||
267 | trunk = PAGE_SIZE - offset; | ||
268 | trunk = min(trunk, len); | ||
269 | if (from_phys) | ||
270 | memcpy_fromio(buffer, vaddr + offset, trunk); | ||
271 | else | ||
272 | memcpy_toio(vaddr + offset, buffer, trunk); | ||
273 | len -= trunk; | ||
274 | paddr += trunk; | ||
275 | buffer += trunk; | ||
276 | if (in_nmi) { | ||
277 | ghes_iounmap_nmi(vaddr); | ||
278 | raw_spin_unlock(&ghes_ioremap_lock_nmi); | ||
279 | } else { | ||
280 | ghes_iounmap_irq(vaddr); | ||
281 | spin_unlock_irqrestore(&ghes_ioremap_lock_irq, flags); | ||
282 | } | ||
283 | } | ||
177 | } | 284 | } |
178 | 285 | ||
179 | static int ghes_read_estatus(struct ghes *ghes, int silent) | 286 | static int ghes_read_estatus(struct ghes *ghes, int silent) |
@@ -194,10 +301,8 @@ static int ghes_read_estatus(struct ghes *ghes, int silent) | |||
194 | if (!buf_paddr) | 301 | if (!buf_paddr) |
195 | return -ENOENT; | 302 | return -ENOENT; |
196 | 303 | ||
197 | rc = ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, | 304 | ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, |
198 | sizeof(*ghes->estatus), 1); | 305 | sizeof(*ghes->estatus), 1); |
199 | if (rc) | ||
200 | return rc; | ||
201 | if (!ghes->estatus->block_status) | 306 | if (!ghes->estatus->block_status) |
202 | return -ENOENT; | 307 | return -ENOENT; |
203 | 308 | ||
@@ -212,17 +317,15 @@ static int ghes_read_estatus(struct ghes *ghes, int silent) | |||
212 | goto err_read_block; | 317 | goto err_read_block; |
213 | if (apei_estatus_check_header(ghes->estatus)) | 318 | if (apei_estatus_check_header(ghes->estatus)) |
214 | goto err_read_block; | 319 | goto err_read_block; |
215 | rc = ghes_copy_tofrom_phys(ghes->estatus + 1, | 320 | ghes_copy_tofrom_phys(ghes->estatus + 1, |
216 | buf_paddr + sizeof(*ghes->estatus), | 321 | buf_paddr + sizeof(*ghes->estatus), |
217 | len - sizeof(*ghes->estatus), 1); | 322 | len - sizeof(*ghes->estatus), 1); |
218 | if (rc) | ||
219 | return rc; | ||
220 | if (apei_estatus_check(ghes->estatus)) | 323 | if (apei_estatus_check(ghes->estatus)) |
221 | goto err_read_block; | 324 | goto err_read_block; |
222 | rc = 0; | 325 | rc = 0; |
223 | 326 | ||
224 | err_read_block: | 327 | err_read_block: |
225 | if (rc && !silent) | 328 | if (rc && !silent && printk_ratelimit()) |
226 | pr_warning(FW_WARN GHES_PFX | 329 | pr_warning(FW_WARN GHES_PFX |
227 | "Failed to read error status block!\n"); | 330 | "Failed to read error status block!\n"); |
228 | return rc; | 331 | return rc; |
@@ -255,11 +358,26 @@ static void ghes_do_proc(struct ghes *ghes) | |||
255 | } | 358 | } |
256 | #endif | 359 | #endif |
257 | } | 360 | } |
361 | } | ||
258 | 362 | ||
259 | if (!processed && printk_ratelimit()) | 363 | static void ghes_print_estatus(const char *pfx, struct ghes *ghes) |
260 | pr_warning(GHES_PFX | 364 | { |
261 | "Unknown error record from generic hardware error source: %d\n", | 365 | /* Not more than 2 messages every 5 seconds */ |
262 | ghes->generic->header.source_id); | 366 | static DEFINE_RATELIMIT_STATE(ratelimit, 5*HZ, 2); |
367 | |||
368 | if (pfx == NULL) { | ||
369 | if (ghes_severity(ghes->estatus->error_severity) <= | ||
370 | GHES_SEV_CORRECTED) | ||
371 | pfx = KERN_WARNING HW_ERR; | ||
372 | else | ||
373 | pfx = KERN_ERR HW_ERR; | ||
374 | } | ||
375 | if (__ratelimit(&ratelimit)) { | ||
376 | printk( | ||
377 | "%s""Hardware error from APEI Generic Hardware Error Source: %d\n", | ||
378 | pfx, ghes->generic->header.source_id); | ||
379 | apei_estatus_print(pfx, ghes->estatus); | ||
380 | } | ||
263 | } | 381 | } |
264 | 382 | ||
265 | static int ghes_proc(struct ghes *ghes) | 383 | static int ghes_proc(struct ghes *ghes) |
@@ -269,6 +387,7 @@ static int ghes_proc(struct ghes *ghes) | |||
269 | rc = ghes_read_estatus(ghes, 0); | 387 | rc = ghes_read_estatus(ghes, 0); |
270 | if (rc) | 388 | if (rc) |
271 | goto out; | 389 | goto out; |
390 | ghes_print_estatus(NULL, ghes); | ||
272 | ghes_do_proc(ghes); | 391 | ghes_do_proc(ghes); |
273 | 392 | ||
274 | out: | 393 | out: |
@@ -276,6 +395,42 @@ out: | |||
276 | return 0; | 395 | return 0; |
277 | } | 396 | } |
278 | 397 | ||
398 | static void ghes_add_timer(struct ghes *ghes) | ||
399 | { | ||
400 | struct acpi_hest_generic *g = ghes->generic; | ||
401 | unsigned long expire; | ||
402 | |||
403 | if (!g->notify.poll_interval) { | ||
404 | pr_warning(FW_WARN GHES_PFX "Poll interval is 0 for generic hardware error source: %d, disabled.\n", | ||
405 | g->header.source_id); | ||
406 | return; | ||
407 | } | ||
408 | expire = jiffies + msecs_to_jiffies(g->notify.poll_interval); | ||
409 | ghes->timer.expires = round_jiffies_relative(expire); | ||
410 | add_timer(&ghes->timer); | ||
411 | } | ||
412 | |||
413 | static void ghes_poll_func(unsigned long data) | ||
414 | { | ||
415 | struct ghes *ghes = (void *)data; | ||
416 | |||
417 | ghes_proc(ghes); | ||
418 | if (!(ghes->flags & GHES_EXITING)) | ||
419 | ghes_add_timer(ghes); | ||
420 | } | ||
421 | |||
422 | static irqreturn_t ghes_irq_func(int irq, void *data) | ||
423 | { | ||
424 | struct ghes *ghes = data; | ||
425 | int rc; | ||
426 | |||
427 | rc = ghes_proc(ghes); | ||
428 | if (rc) | ||
429 | return IRQ_NONE; | ||
430 | |||
431 | return IRQ_HANDLED; | ||
432 | } | ||
433 | |||
279 | static int ghes_notify_sci(struct notifier_block *this, | 434 | static int ghes_notify_sci(struct notifier_block *this, |
280 | unsigned long event, void *data) | 435 | unsigned long event, void *data) |
281 | { | 436 | { |
@@ -292,10 +447,63 @@ static int ghes_notify_sci(struct notifier_block *this, | |||
292 | return ret; | 447 | return ret; |
293 | } | 448 | } |
294 | 449 | ||
450 | static int ghes_notify_nmi(struct notifier_block *this, | ||
451 | unsigned long cmd, void *data) | ||
452 | { | ||
453 | struct ghes *ghes, *ghes_global = NULL; | ||
454 | int sev, sev_global = -1; | ||
455 | int ret = NOTIFY_DONE; | ||
456 | |||
457 | if (cmd != DIE_NMI) | ||
458 | return ret; | ||
459 | |||
460 | raw_spin_lock(&ghes_nmi_lock); | ||
461 | list_for_each_entry_rcu(ghes, &ghes_nmi, list) { | ||
462 | if (ghes_read_estatus(ghes, 1)) { | ||
463 | ghes_clear_estatus(ghes); | ||
464 | continue; | ||
465 | } | ||
466 | sev = ghes_severity(ghes->estatus->error_severity); | ||
467 | if (sev > sev_global) { | ||
468 | sev_global = sev; | ||
469 | ghes_global = ghes; | ||
470 | } | ||
471 | ret = NOTIFY_STOP; | ||
472 | } | ||
473 | |||
474 | if (ret == NOTIFY_DONE) | ||
475 | goto out; | ||
476 | |||
477 | if (sev_global >= GHES_SEV_PANIC) { | ||
478 | oops_begin(); | ||
479 | ghes_print_estatus(KERN_EMERG HW_ERR, ghes_global); | ||
480 | /* reboot to log the error! */ | ||
481 | if (panic_timeout == 0) | ||
482 | panic_timeout = ghes_panic_timeout; | ||
483 | panic("Fatal hardware error!"); | ||
484 | } | ||
485 | |||
486 | list_for_each_entry_rcu(ghes, &ghes_nmi, list) { | ||
487 | if (!(ghes->flags & GHES_TO_CLEAR)) | ||
488 | continue; | ||
489 | /* Do not print estatus because printk is not NMI safe */ | ||
490 | ghes_do_proc(ghes); | ||
491 | ghes_clear_estatus(ghes); | ||
492 | } | ||
493 | |||
494 | out: | ||
495 | raw_spin_unlock(&ghes_nmi_lock); | ||
496 | return ret; | ||
497 | } | ||
498 | |||
295 | static struct notifier_block ghes_notifier_sci = { | 499 | static struct notifier_block ghes_notifier_sci = { |
296 | .notifier_call = ghes_notify_sci, | 500 | .notifier_call = ghes_notify_sci, |
297 | }; | 501 | }; |
298 | 502 | ||
503 | static struct notifier_block ghes_notifier_nmi = { | ||
504 | .notifier_call = ghes_notify_nmi, | ||
505 | }; | ||
506 | |||
299 | static int __devinit ghes_probe(struct platform_device *ghes_dev) | 507 | static int __devinit ghes_probe(struct platform_device *ghes_dev) |
300 | { | 508 | { |
301 | struct acpi_hest_generic *generic; | 509 | struct acpi_hest_generic *generic; |
@@ -306,18 +514,27 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) | |||
306 | if (!generic->enabled) | 514 | if (!generic->enabled) |
307 | return -ENODEV; | 515 | return -ENODEV; |
308 | 516 | ||
309 | if (generic->error_block_length < | 517 | switch (generic->notify.type) { |
310 | sizeof(struct acpi_hest_generic_status)) { | 518 | case ACPI_HEST_NOTIFY_POLLED: |
311 | pr_warning(FW_BUG GHES_PFX | 519 | case ACPI_HEST_NOTIFY_EXTERNAL: |
312 | "Invalid error block length: %u for generic hardware error source: %d\n", | 520 | case ACPI_HEST_NOTIFY_SCI: |
313 | generic->error_block_length, | 521 | case ACPI_HEST_NOTIFY_NMI: |
522 | break; | ||
523 | case ACPI_HEST_NOTIFY_LOCAL: | ||
524 | pr_warning(GHES_PFX "Generic hardware error source: %d notified via local interrupt is not supported!\n", | ||
314 | generic->header.source_id); | 525 | generic->header.source_id); |
315 | goto err; | 526 | goto err; |
527 | default: | ||
528 | pr_warning(FW_WARN GHES_PFX "Unknown notification type: %u for generic hardware error source: %d\n", | ||
529 | generic->notify.type, generic->header.source_id); | ||
530 | goto err; | ||
316 | } | 531 | } |
317 | if (generic->records_to_preallocate == 0) { | 532 | |
318 | pr_warning(FW_BUG GHES_PFX | 533 | rc = -EIO; |
319 | "Invalid records to preallocate: %u for generic hardware error source: %d\n", | 534 | if (generic->error_block_length < |
320 | generic->records_to_preallocate, | 535 | sizeof(struct acpi_hest_generic_status)) { |
536 | pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n", | ||
537 | generic->error_block_length, | ||
321 | generic->header.source_id); | 538 | generic->header.source_id); |
322 | goto err; | 539 | goto err; |
323 | } | 540 | } |
@@ -327,38 +544,43 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) | |||
327 | ghes = NULL; | 544 | ghes = NULL; |
328 | goto err; | 545 | goto err; |
329 | } | 546 | } |
330 | if (generic->notify.type == ACPI_HEST_NOTIFY_SCI) { | 547 | switch (generic->notify.type) { |
548 | case ACPI_HEST_NOTIFY_POLLED: | ||
549 | ghes->timer.function = ghes_poll_func; | ||
550 | ghes->timer.data = (unsigned long)ghes; | ||
551 | init_timer_deferrable(&ghes->timer); | ||
552 | ghes_add_timer(ghes); | ||
553 | break; | ||
554 | case ACPI_HEST_NOTIFY_EXTERNAL: | ||
555 | /* External interrupt vector is GSI */ | ||
556 | if (acpi_gsi_to_irq(generic->notify.vector, &ghes->irq)) { | ||
557 | pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n", | ||
558 | generic->header.source_id); | ||
559 | goto err; | ||
560 | } | ||
561 | if (request_irq(ghes->irq, ghes_irq_func, | ||
562 | 0, "GHES IRQ", ghes)) { | ||
563 | pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n", | ||
564 | generic->header.source_id); | ||
565 | goto err; | ||
566 | } | ||
567 | break; | ||
568 | case ACPI_HEST_NOTIFY_SCI: | ||
331 | mutex_lock(&ghes_list_mutex); | 569 | mutex_lock(&ghes_list_mutex); |
332 | if (list_empty(&ghes_sci)) | 570 | if (list_empty(&ghes_sci)) |
333 | register_acpi_hed_notifier(&ghes_notifier_sci); | 571 | register_acpi_hed_notifier(&ghes_notifier_sci); |
334 | list_add_rcu(&ghes->list, &ghes_sci); | 572 | list_add_rcu(&ghes->list, &ghes_sci); |
335 | mutex_unlock(&ghes_list_mutex); | 573 | mutex_unlock(&ghes_list_mutex); |
336 | } else { | 574 | break; |
337 | unsigned char *notify = NULL; | 575 | case ACPI_HEST_NOTIFY_NMI: |
338 | 576 | mutex_lock(&ghes_list_mutex); | |
339 | switch (generic->notify.type) { | 577 | if (list_empty(&ghes_nmi)) |
340 | case ACPI_HEST_NOTIFY_POLLED: | 578 | register_die_notifier(&ghes_notifier_nmi); |
341 | notify = "POLL"; | 579 | list_add_rcu(&ghes->list, &ghes_nmi); |
342 | break; | 580 | mutex_unlock(&ghes_list_mutex); |
343 | case ACPI_HEST_NOTIFY_EXTERNAL: | 581 | break; |
344 | case ACPI_HEST_NOTIFY_LOCAL: | 582 | default: |
345 | notify = "IRQ"; | 583 | BUG(); |
346 | break; | ||
347 | case ACPI_HEST_NOTIFY_NMI: | ||
348 | notify = "NMI"; | ||
349 | break; | ||
350 | } | ||
351 | if (notify) { | ||
352 | pr_warning(GHES_PFX | ||
353 | "Generic hardware error source: %d notified via %s is not supported!\n", | ||
354 | generic->header.source_id, notify); | ||
355 | } else { | ||
356 | pr_warning(FW_WARN GHES_PFX | ||
357 | "Unknown notification type: %u for generic hardware error source: %d\n", | ||
358 | generic->notify.type, generic->header.source_id); | ||
359 | } | ||
360 | rc = -ENODEV; | ||
361 | goto err; | ||
362 | } | 584 | } |
363 | platform_set_drvdata(ghes_dev, ghes); | 585 | platform_set_drvdata(ghes_dev, ghes); |
364 | 586 | ||
@@ -379,7 +601,14 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev) | |||
379 | ghes = platform_get_drvdata(ghes_dev); | 601 | ghes = platform_get_drvdata(ghes_dev); |
380 | generic = ghes->generic; | 602 | generic = ghes->generic; |
381 | 603 | ||
604 | ghes->flags |= GHES_EXITING; | ||
382 | switch (generic->notify.type) { | 605 | switch (generic->notify.type) { |
606 | case ACPI_HEST_NOTIFY_POLLED: | ||
607 | del_timer_sync(&ghes->timer); | ||
608 | break; | ||
609 | case ACPI_HEST_NOTIFY_EXTERNAL: | ||
610 | free_irq(ghes->irq, ghes); | ||
611 | break; | ||
383 | case ACPI_HEST_NOTIFY_SCI: | 612 | case ACPI_HEST_NOTIFY_SCI: |
384 | mutex_lock(&ghes_list_mutex); | 613 | mutex_lock(&ghes_list_mutex); |
385 | list_del_rcu(&ghes->list); | 614 | list_del_rcu(&ghes->list); |
@@ -387,12 +616,23 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev) | |||
387 | unregister_acpi_hed_notifier(&ghes_notifier_sci); | 616 | unregister_acpi_hed_notifier(&ghes_notifier_sci); |
388 | mutex_unlock(&ghes_list_mutex); | 617 | mutex_unlock(&ghes_list_mutex); |
389 | break; | 618 | break; |
619 | case ACPI_HEST_NOTIFY_NMI: | ||
620 | mutex_lock(&ghes_list_mutex); | ||
621 | list_del_rcu(&ghes->list); | ||
622 | if (list_empty(&ghes_nmi)) | ||
623 | unregister_die_notifier(&ghes_notifier_nmi); | ||
624 | mutex_unlock(&ghes_list_mutex); | ||
625 | /* | ||
626 | * To synchronize with NMI handler, ghes can only be | ||
627 | * freed after NMI handler finishes. | ||
628 | */ | ||
629 | synchronize_rcu(); | ||
630 | break; | ||
390 | default: | 631 | default: |
391 | BUG(); | 632 | BUG(); |
392 | break; | 633 | break; |
393 | } | 634 | } |
394 | 635 | ||
395 | synchronize_rcu(); | ||
396 | ghes_fini(ghes); | 636 | ghes_fini(ghes); |
397 | kfree(ghes); | 637 | kfree(ghes); |
398 | 638 | ||
@@ -412,6 +652,8 @@ static struct platform_driver ghes_platform_driver = { | |||
412 | 652 | ||
413 | static int __init ghes_init(void) | 653 | static int __init ghes_init(void) |
414 | { | 654 | { |
655 | int rc; | ||
656 | |||
415 | if (acpi_disabled) | 657 | if (acpi_disabled) |
416 | return -ENODEV; | 658 | return -ENODEV; |
417 | 659 | ||
@@ -420,12 +662,25 @@ static int __init ghes_init(void) | |||
420 | return -EINVAL; | 662 | return -EINVAL; |
421 | } | 663 | } |
422 | 664 | ||
423 | return platform_driver_register(&ghes_platform_driver); | 665 | rc = ghes_ioremap_init(); |
666 | if (rc) | ||
667 | goto err; | ||
668 | |||
669 | rc = platform_driver_register(&ghes_platform_driver); | ||
670 | if (rc) | ||
671 | goto err_ioremap_exit; | ||
672 | |||
673 | return 0; | ||
674 | err_ioremap_exit: | ||
675 | ghes_ioremap_exit(); | ||
676 | err: | ||
677 | return rc; | ||
424 | } | 678 | } |
425 | 679 | ||
426 | static void __exit ghes_exit(void) | 680 | static void __exit ghes_exit(void) |
427 | { | 681 | { |
428 | platform_driver_unregister(&ghes_platform_driver); | 682 | platform_driver_unregister(&ghes_platform_driver); |
683 | ghes_ioremap_exit(); | ||
429 | } | 684 | } |
430 | 685 | ||
431 | module_init(ghes_init); | 686 | module_init(ghes_init); |
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 1a3508a7fe0..abda3786a5d 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable); | |||
46 | 46 | ||
47 | /* HEST table parsing */ | 47 | /* HEST table parsing */ |
48 | 48 | ||
49 | static struct acpi_table_hest *hest_tab; | 49 | static struct acpi_table_hest *__read_mostly hest_tab; |
50 | 50 | ||
51 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { | 51 | static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { |
52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ | 52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ |
53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, | 53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, |
54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), | 54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), |
@@ -126,7 +126,7 @@ struct ghes_arr { | |||
126 | unsigned int count; | 126 | unsigned int count; |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | 129 | static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) |
130 | { | 130 | { |
131 | int *count = data; | 131 | int *count = data; |
132 | 132 | ||
@@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
137 | 137 | ||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
139 | { | 139 | { |
140 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
141 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
@@ -165,7 +165,7 @@ err: | |||
165 | return rc; | 165 | return rc; |
166 | } | 166 | } |
167 | 167 | ||
168 | static int hest_ghes_dev_register(unsigned int ghes_count) | 168 | static int __init hest_ghes_dev_register(unsigned int ghes_count) |
169 | { | 169 | { |
170 | int rc, i; | 170 | int rc, i; |
171 | struct ghes_arr ghes_arr; | 171 | struct ghes_arr ghes_arr; |
@@ -195,24 +195,24 @@ static int __init setup_hest_disable(char *str) | |||
195 | 195 | ||
196 | __setup("hest_disable", setup_hest_disable); | 196 | __setup("hest_disable", setup_hest_disable); |
197 | 197 | ||
198 | static int __init hest_init(void) | 198 | void __init acpi_hest_init(void) |
199 | { | 199 | { |
200 | acpi_status status; | 200 | acpi_status status; |
201 | int rc = -ENODEV; | 201 | int rc = -ENODEV; |
202 | unsigned int ghes_count = 0; | 202 | unsigned int ghes_count = 0; |
203 | 203 | ||
204 | if (acpi_disabled) | ||
205 | goto err; | ||
206 | |||
207 | if (hest_disable) { | 204 | if (hest_disable) { |
208 | pr_info(HEST_PFX "HEST tabling parsing is disabled.\n"); | 205 | pr_info(HEST_PFX "Table parsing disabled.\n"); |
209 | goto err; | 206 | return; |
210 | } | 207 | } |
211 | 208 | ||
209 | if (acpi_disabled) | ||
210 | goto err; | ||
211 | |||
212 | status = acpi_get_table(ACPI_SIG_HEST, 0, | 212 | status = acpi_get_table(ACPI_SIG_HEST, 0, |
213 | (struct acpi_table_header **)&hest_tab); | 213 | (struct acpi_table_header **)&hest_tab); |
214 | if (status == AE_NOT_FOUND) { | 214 | if (status == AE_NOT_FOUND) { |
215 | pr_info(HEST_PFX "Table is not found!\n"); | 215 | pr_info(HEST_PFX "Table not found.\n"); |
216 | goto err; | 216 | goto err; |
217 | } else if (ACPI_FAILURE(status)) { | 217 | } else if (ACPI_FAILURE(status)) { |
218 | const char *msg = acpi_format_exception(status); | 218 | const char *msg = acpi_format_exception(status); |
@@ -226,15 +226,11 @@ static int __init hest_init(void) | |||
226 | goto err; | 226 | goto err; |
227 | 227 | ||
228 | rc = hest_ghes_dev_register(ghes_count); | 228 | rc = hest_ghes_dev_register(ghes_count); |
229 | if (rc) | 229 | if (!rc) { |
230 | goto err; | 230 | pr_info(HEST_PFX "Table parsing has been initialized.\n"); |
231 | 231 | return; | |
232 | pr_info(HEST_PFX "HEST table parsing is initialized.\n"); | 232 | } |
233 | 233 | ||
234 | return 0; | ||
235 | err: | 234 | err: |
236 | hest_disable = 1; | 235 | hest_disable = 1; |
237 | return rc; | ||
238 | } | 236 | } |
239 | |||
240 | subsys_initcall(hest_init); | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 95649d37307..fcc13ac0aa1 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/async.h> | 33 | #include <linux/async.h> |
34 | #include <linux/dmi.h> | 34 | #include <linux/dmi.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/suspend.h> | ||
36 | 37 | ||
37 | #ifdef CONFIG_ACPI_PROCFS_POWER | 38 | #ifdef CONFIG_ACPI_PROCFS_POWER |
38 | #include <linux/proc_fs.h> | 39 | #include <linux/proc_fs.h> |
@@ -102,6 +103,7 @@ struct acpi_battery { | |||
102 | struct mutex lock; | 103 | struct mutex lock; |
103 | struct power_supply bat; | 104 | struct power_supply bat; |
104 | struct acpi_device *device; | 105 | struct acpi_device *device; |
106 | struct notifier_block pm_nb; | ||
105 | unsigned long update_time; | 107 | unsigned long update_time; |
106 | int rate_now; | 108 | int rate_now; |
107 | int capacity_now; | 109 | int capacity_now; |
@@ -631,6 +633,17 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
631 | return result; | 633 | return result; |
632 | } | 634 | } |
633 | 635 | ||
636 | static void acpi_battery_refresh(struct acpi_battery *battery) | ||
637 | { | ||
638 | if (!battery->bat.dev) | ||
639 | return; | ||
640 | |||
641 | acpi_battery_get_info(battery); | ||
642 | /* The battery may have changed its reporting units. */ | ||
643 | sysfs_remove_battery(battery); | ||
644 | sysfs_add_battery(battery); | ||
645 | } | ||
646 | |||
634 | /* -------------------------------------------------------------------------- | 647 | /* -------------------------------------------------------------------------- |
635 | FS Interface (/proc) | 648 | FS Interface (/proc) |
636 | -------------------------------------------------------------------------- */ | 649 | -------------------------------------------------------------------------- */ |
@@ -868,6 +881,8 @@ static int acpi_battery_add_fs(struct acpi_device *device) | |||
868 | struct proc_dir_entry *entry = NULL; | 881 | struct proc_dir_entry *entry = NULL; |
869 | int i; | 882 | int i; |
870 | 883 | ||
884 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," | ||
885 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
871 | if (!acpi_device_dir(device)) { | 886 | if (!acpi_device_dir(device)) { |
872 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 887 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), |
873 | acpi_battery_dir); | 888 | acpi_battery_dir); |
@@ -914,6 +929,8 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) | |||
914 | if (!battery) | 929 | if (!battery) |
915 | return; | 930 | return; |
916 | old = battery->bat.dev; | 931 | old = battery->bat.dev; |
932 | if (event == ACPI_BATTERY_NOTIFY_INFO) | ||
933 | acpi_battery_refresh(battery); | ||
917 | acpi_battery_update(battery); | 934 | acpi_battery_update(battery); |
918 | acpi_bus_generate_proc_event(device, event, | 935 | acpi_bus_generate_proc_event(device, event, |
919 | acpi_battery_present(battery)); | 936 | acpi_battery_present(battery)); |
@@ -925,6 +942,21 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) | |||
925 | power_supply_changed(&battery->bat); | 942 | power_supply_changed(&battery->bat); |
926 | } | 943 | } |
927 | 944 | ||
945 | static int battery_notify(struct notifier_block *nb, | ||
946 | unsigned long mode, void *_unused) | ||
947 | { | ||
948 | struct acpi_battery *battery = container_of(nb, struct acpi_battery, | ||
949 | pm_nb); | ||
950 | switch (mode) { | ||
951 | case PM_POST_SUSPEND: | ||
952 | sysfs_remove_battery(battery); | ||
953 | sysfs_add_battery(battery); | ||
954 | break; | ||
955 | } | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
928 | static int acpi_battery_add(struct acpi_device *device) | 960 | static int acpi_battery_add(struct acpi_device *device) |
929 | { | 961 | { |
930 | int result = 0; | 962 | int result = 0; |
@@ -957,6 +989,10 @@ static int acpi_battery_add(struct acpi_device *device) | |||
957 | #endif | 989 | #endif |
958 | kfree(battery); | 990 | kfree(battery); |
959 | } | 991 | } |
992 | |||
993 | battery->pm_nb.notifier_call = battery_notify; | ||
994 | register_pm_notifier(&battery->pm_nb); | ||
995 | |||
960 | return result; | 996 | return result; |
961 | } | 997 | } |
962 | 998 | ||
@@ -967,6 +1003,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
967 | if (!device || !acpi_driver_data(device)) | 1003 | if (!device || !acpi_driver_data(device)) |
968 | return -EINVAL; | 1004 | return -EINVAL; |
969 | battery = acpi_driver_data(device); | 1005 | battery = acpi_driver_data(device); |
1006 | unregister_pm_notifier(&battery->pm_nb); | ||
970 | #ifdef CONFIG_ACPI_PROCFS_POWER | 1007 | #ifdef CONFIG_ACPI_PROCFS_POWER |
971 | acpi_battery_remove_fs(device); | 1008 | acpi_battery_remove_fs(device); |
972 | #endif | 1009 | #endif |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d68bd61072b..9749980ca6c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <acpi/acpi_bus.h> | 40 | #include <acpi/acpi_bus.h> |
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | #include <linux/dmi.h> | 42 | #include <linux/dmi.h> |
43 | #include <linux/suspend.h> | ||
43 | 44 | ||
44 | #include "internal.h" | 45 | #include "internal.h" |
45 | 46 | ||
@@ -52,22 +53,6 @@ EXPORT_SYMBOL(acpi_root_dir); | |||
52 | 53 | ||
53 | #define STRUCT_TO_INT(s) (*((int*)&s)) | 54 | #define STRUCT_TO_INT(s) (*((int*)&s)) |
54 | 55 | ||
55 | static int set_power_nocheck(const struct dmi_system_id *id) | ||
56 | { | ||
57 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
58 | "disable power check in power transition\n", id->ident); | ||
59 | acpi_power_nocheck = 1; | ||
60 | return 0; | ||
61 | } | ||
62 | static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = { | ||
63 | { | ||
64 | set_power_nocheck, "HP Pavilion 05", { | ||
65 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | ||
66 | DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"), | ||
67 | DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL}, | ||
68 | {}, | ||
69 | }; | ||
70 | |||
71 | 56 | ||
72 | #ifdef CONFIG_X86 | 57 | #ifdef CONFIG_X86 |
73 | static int set_copy_dsdt(const struct dmi_system_id *id) | 58 | static int set_copy_dsdt(const struct dmi_system_id *id) |
@@ -196,33 +181,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data); | |||
196 | Power Management | 181 | Power Management |
197 | -------------------------------------------------------------------------- */ | 182 | -------------------------------------------------------------------------- */ |
198 | 183 | ||
199 | int acpi_bus_get_power(acpi_handle handle, int *state) | 184 | static int __acpi_bus_get_power(struct acpi_device *device, int *state) |
200 | { | 185 | { |
201 | int result = 0; | 186 | int result = 0; |
202 | acpi_status status = 0; | 187 | acpi_status status = 0; |
203 | struct acpi_device *device = NULL; | ||
204 | unsigned long long psc = 0; | 188 | unsigned long long psc = 0; |
205 | 189 | ||
206 | 190 | if (!device || !state) | |
207 | result = acpi_bus_get_device(handle, &device); | 191 | return -EINVAL; |
208 | if (result) | ||
209 | return result; | ||
210 | 192 | ||
211 | *state = ACPI_STATE_UNKNOWN; | 193 | *state = ACPI_STATE_UNKNOWN; |
212 | 194 | ||
213 | if (!device->flags.power_manageable) { | 195 | if (device->flags.power_manageable) { |
214 | /* TBD: Non-recursive algorithm for walking up hierarchy */ | ||
215 | if (device->parent) | ||
216 | *state = device->parent->power.state; | ||
217 | else | ||
218 | *state = ACPI_STATE_D0; | ||
219 | } else { | ||
220 | /* | 196 | /* |
221 | * Get the device's power state either directly (via _PSC) or | 197 | * Get the device's power state either directly (via _PSC) or |
222 | * indirectly (via power resources). | 198 | * indirectly (via power resources). |
223 | */ | 199 | */ |
224 | if (device->power.flags.power_resources) { | 200 | if (device->power.flags.power_resources) { |
225 | result = acpi_power_get_inferred_state(device); | 201 | result = acpi_power_get_inferred_state(device, state); |
226 | if (result) | 202 | if (result) |
227 | return result; | 203 | return result; |
228 | } else if (device->power.flags.explicit_get) { | 204 | } else if (device->power.flags.explicit_get) { |
@@ -230,59 +206,33 @@ int acpi_bus_get_power(acpi_handle handle, int *state) | |||
230 | NULL, &psc); | 206 | NULL, &psc); |
231 | if (ACPI_FAILURE(status)) | 207 | if (ACPI_FAILURE(status)) |
232 | return -ENODEV; | 208 | return -ENODEV; |
233 | device->power.state = (int)psc; | 209 | *state = (int)psc; |
234 | } | 210 | } |
235 | 211 | } else { | |
236 | *state = device->power.state; | 212 | /* TBD: Non-recursive algorithm for walking up hierarchy. */ |
213 | *state = device->parent ? | ||
214 | device->parent->power.state : ACPI_STATE_D0; | ||
237 | } | 215 | } |
238 | 216 | ||
239 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", | 217 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", |
240 | device->pnp.bus_id, device->power.state)); | 218 | device->pnp.bus_id, *state)); |
241 | 219 | ||
242 | return 0; | 220 | return 0; |
243 | } | 221 | } |
244 | 222 | ||
245 | EXPORT_SYMBOL(acpi_bus_get_power); | ||
246 | 223 | ||
247 | int acpi_bus_set_power(acpi_handle handle, int state) | 224 | static int __acpi_bus_set_power(struct acpi_device *device, int state) |
248 | { | 225 | { |
249 | int result = 0; | 226 | int result = 0; |
250 | acpi_status status = AE_OK; | 227 | acpi_status status = AE_OK; |
251 | struct acpi_device *device = NULL; | ||
252 | char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; | 228 | char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; |
253 | 229 | ||
254 | 230 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | |
255 | result = acpi_bus_get_device(handle, &device); | ||
256 | if (result) | ||
257 | return result; | ||
258 | |||
259 | if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | ||
260 | return -EINVAL; | 231 | return -EINVAL; |
261 | 232 | ||
262 | /* Make sure this is a valid target state */ | 233 | /* Make sure this is a valid target state */ |
263 | 234 | ||
264 | if (!device->flags.power_manageable) { | 235 | if (state == device->power.state) { |
265 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", | ||
266 | kobject_name(&device->dev.kobj))); | ||
267 | return -ENODEV; | ||
268 | } | ||
269 | /* | ||
270 | * Get device's current power state | ||
271 | */ | ||
272 | if (!acpi_power_nocheck) { | ||
273 | /* | ||
274 | * Maybe the incorrect power state is returned on the bogus | ||
275 | * bios, which is different with the real power state. | ||
276 | * For example: the bios returns D0 state and the real power | ||
277 | * state is D3. OS expects to set the device to D0 state. In | ||
278 | * such case if OS uses the power state returned by the BIOS, | ||
279 | * the device can't be transisted to the correct power state. | ||
280 | * So if the acpi_power_nocheck is set, it is unnecessary to | ||
281 | * get the power state by calling acpi_bus_get_power. | ||
282 | */ | ||
283 | acpi_bus_get_power(device->handle, &device->power.state); | ||
284 | } | ||
285 | if ((state == device->power.state) && !device->flags.force_power_state) { | ||
286 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", | 236 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", |
287 | state)); | 237 | state)); |
288 | return 0; | 238 | return 0; |
@@ -351,8 +301,75 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
351 | return result; | 301 | return result; |
352 | } | 302 | } |
353 | 303 | ||
304 | |||
305 | int acpi_bus_set_power(acpi_handle handle, int state) | ||
306 | { | ||
307 | struct acpi_device *device; | ||
308 | int result; | ||
309 | |||
310 | result = acpi_bus_get_device(handle, &device); | ||
311 | if (result) | ||
312 | return result; | ||
313 | |||
314 | if (!device->flags.power_manageable) { | ||
315 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
316 | "Device [%s] is not power manageable\n", | ||
317 | dev_name(&device->dev))); | ||
318 | return -ENODEV; | ||
319 | } | ||
320 | |||
321 | return __acpi_bus_set_power(device, state); | ||
322 | } | ||
354 | EXPORT_SYMBOL(acpi_bus_set_power); | 323 | EXPORT_SYMBOL(acpi_bus_set_power); |
355 | 324 | ||
325 | |||
326 | int acpi_bus_init_power(struct acpi_device *device) | ||
327 | { | ||
328 | int state; | ||
329 | int result; | ||
330 | |||
331 | if (!device) | ||
332 | return -EINVAL; | ||
333 | |||
334 | device->power.state = ACPI_STATE_UNKNOWN; | ||
335 | |||
336 | result = __acpi_bus_get_power(device, &state); | ||
337 | if (result) | ||
338 | return result; | ||
339 | |||
340 | if (device->power.flags.power_resources) | ||
341 | result = acpi_power_on_resources(device, state); | ||
342 | |||
343 | if (!result) | ||
344 | device->power.state = state; | ||
345 | |||
346 | return result; | ||
347 | } | ||
348 | |||
349 | |||
350 | int acpi_bus_update_power(acpi_handle handle, int *state_p) | ||
351 | { | ||
352 | struct acpi_device *device; | ||
353 | int state; | ||
354 | int result; | ||
355 | |||
356 | result = acpi_bus_get_device(handle, &device); | ||
357 | if (result) | ||
358 | return result; | ||
359 | |||
360 | result = __acpi_bus_get_power(device, &state); | ||
361 | if (result) | ||
362 | return result; | ||
363 | |||
364 | result = __acpi_bus_set_power(device, state); | ||
365 | if (!result && state_p) | ||
366 | *state_p = state; | ||
367 | |||
368 | return result; | ||
369 | } | ||
370 | EXPORT_SYMBOL_GPL(acpi_bus_update_power); | ||
371 | |||
372 | |||
356 | bool acpi_bus_power_manageable(acpi_handle handle) | 373 | bool acpi_bus_power_manageable(acpi_handle handle) |
357 | { | 374 | { |
358 | struct acpi_device *device; | 375 | struct acpi_device *device; |
@@ -990,8 +1007,7 @@ struct kobject *acpi_kobj; | |||
990 | 1007 | ||
991 | static int __init acpi_init(void) | 1008 | static int __init acpi_init(void) |
992 | { | 1009 | { |
993 | int result = 0; | 1010 | int result; |
994 | |||
995 | 1011 | ||
996 | if (acpi_disabled) { | 1012 | if (acpi_disabled) { |
997 | printk(KERN_INFO PREFIX "Interpreter disabled.\n"); | 1013 | printk(KERN_INFO PREFIX "Interpreter disabled.\n"); |
@@ -1006,36 +1022,18 @@ static int __init acpi_init(void) | |||
1006 | 1022 | ||
1007 | init_acpi_device_notify(); | 1023 | init_acpi_device_notify(); |
1008 | result = acpi_bus_init(); | 1024 | result = acpi_bus_init(); |
1009 | 1025 | if (result) { | |
1010 | if (!result) { | ||
1011 | pci_mmcfg_late_init(); | ||
1012 | if (!(pm_flags & PM_APM)) | ||
1013 | pm_flags |= PM_ACPI; | ||
1014 | else { | ||
1015 | printk(KERN_INFO PREFIX | ||
1016 | "APM is already active, exiting\n"); | ||
1017 | disable_acpi(); | ||
1018 | result = -ENODEV; | ||
1019 | } | ||
1020 | } else | ||
1021 | disable_acpi(); | 1026 | disable_acpi(); |
1022 | |||
1023 | if (acpi_disabled) | ||
1024 | return result; | 1027 | return result; |
1028 | } | ||
1025 | 1029 | ||
1026 | /* | 1030 | pci_mmcfg_late_init(); |
1027 | * If the laptop falls into the DMI check table, the power state check | ||
1028 | * will be disabled in the course of device power transition. | ||
1029 | */ | ||
1030 | dmi_check_system(power_nocheck_dmi_table); | ||
1031 | |||
1032 | acpi_scan_init(); | 1031 | acpi_scan_init(); |
1033 | acpi_ec_init(); | 1032 | acpi_ec_init(); |
1034 | acpi_power_init(); | ||
1035 | acpi_debugfs_init(); | 1033 | acpi_debugfs_init(); |
1036 | acpi_sleep_proc_init(); | 1034 | acpi_sleep_proc_init(); |
1037 | acpi_wakeup_device_init(); | 1035 | acpi_wakeup_device_init(); |
1038 | return result; | 1036 | return 0; |
1039 | } | 1037 | } |
1040 | 1038 | ||
1041 | subsys_initcall(acpi_init); | 1039 | subsys_initcall(acpi_init); |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 71ef9cd0735..d27d072472f 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -78,8 +78,6 @@ static int acpi_button_add(struct acpi_device *device); | |||
78 | static int acpi_button_remove(struct acpi_device *device, int type); | 78 | static int acpi_button_remove(struct acpi_device *device, int type); |
79 | static int acpi_button_resume(struct acpi_device *device); | 79 | static int acpi_button_resume(struct acpi_device *device); |
80 | static void acpi_button_notify(struct acpi_device *device, u32 event); | 80 | static void acpi_button_notify(struct acpi_device *device, u32 event); |
81 | static int acpi_button_info_open_fs(struct inode *inode, struct file *file); | ||
82 | static int acpi_button_state_open_fs(struct inode *inode, struct file *file); | ||
83 | 81 | ||
84 | static struct acpi_driver acpi_button_driver = { | 82 | static struct acpi_driver acpi_button_driver = { |
85 | .name = "button", | 83 | .name = "button", |
@@ -98,22 +96,7 @@ struct acpi_button { | |||
98 | struct input_dev *input; | 96 | struct input_dev *input; |
99 | char phys[32]; /* for input device */ | 97 | char phys[32]; /* for input device */ |
100 | unsigned long pushed; | 98 | unsigned long pushed; |
101 | }; | 99 | bool wakeup_enabled; |
102 | |||
103 | static const struct file_operations acpi_button_info_fops = { | ||
104 | .owner = THIS_MODULE, | ||
105 | .open = acpi_button_info_open_fs, | ||
106 | .read = seq_read, | ||
107 | .llseek = seq_lseek, | ||
108 | .release = single_release, | ||
109 | }; | ||
110 | |||
111 | static const struct file_operations acpi_button_state_fops = { | ||
112 | .owner = THIS_MODULE, | ||
113 | .open = acpi_button_state_open_fs, | ||
114 | .read = seq_read, | ||
115 | .llseek = seq_lseek, | ||
116 | .release = single_release, | ||
117 | }; | 100 | }; |
118 | 101 | ||
119 | static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); | 102 | static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); |
@@ -124,20 +107,7 @@ static struct acpi_device *lid_device; | |||
124 | -------------------------------------------------------------------------- */ | 107 | -------------------------------------------------------------------------- */ |
125 | 108 | ||
126 | static struct proc_dir_entry *acpi_button_dir; | 109 | static struct proc_dir_entry *acpi_button_dir; |
127 | 110 | static struct proc_dir_entry *acpi_lid_dir; | |
128 | static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) | ||
129 | { | ||
130 | struct acpi_device *device = seq->private; | ||
131 | |||
132 | seq_printf(seq, "type: %s\n", | ||
133 | acpi_device_name(device)); | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int acpi_button_info_open_fs(struct inode *inode, struct file *file) | ||
138 | { | ||
139 | return single_open(file, acpi_button_info_seq_show, PDE(inode)->data); | ||
140 | } | ||
141 | 111 | ||
142 | static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) | 112 | static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) |
143 | { | 113 | { |
@@ -157,77 +127,85 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file) | |||
157 | return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); | 127 | return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); |
158 | } | 128 | } |
159 | 129 | ||
160 | static struct proc_dir_entry *acpi_power_dir; | 130 | static const struct file_operations acpi_button_state_fops = { |
161 | static struct proc_dir_entry *acpi_sleep_dir; | 131 | .owner = THIS_MODULE, |
162 | static struct proc_dir_entry *acpi_lid_dir; | 132 | .open = acpi_button_state_open_fs, |
133 | .read = seq_read, | ||
134 | .llseek = seq_lseek, | ||
135 | .release = single_release, | ||
136 | }; | ||
163 | 137 | ||
164 | static int acpi_button_add_fs(struct acpi_device *device) | 138 | static int acpi_button_add_fs(struct acpi_device *device) |
165 | { | 139 | { |
166 | struct acpi_button *button = acpi_driver_data(device); | 140 | struct acpi_button *button = acpi_driver_data(device); |
167 | struct proc_dir_entry *entry = NULL; | 141 | struct proc_dir_entry *entry = NULL; |
142 | int ret = 0; | ||
168 | 143 | ||
169 | switch (button->type) { | 144 | /* procfs I/F for ACPI lid device only */ |
170 | case ACPI_BUTTON_TYPE_POWER: | 145 | if (button->type != ACPI_BUTTON_TYPE_LID) |
171 | if (!acpi_power_dir) | 146 | return 0; |
172 | acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, | 147 | |
173 | acpi_button_dir); | 148 | if (acpi_button_dir || acpi_lid_dir) { |
174 | entry = acpi_power_dir; | 149 | printk(KERN_ERR PREFIX "More than one Lid device found!\n"); |
175 | break; | 150 | return -EEXIST; |
176 | case ACPI_BUTTON_TYPE_SLEEP: | ||
177 | if (!acpi_sleep_dir) | ||
178 | acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, | ||
179 | acpi_button_dir); | ||
180 | entry = acpi_sleep_dir; | ||
181 | break; | ||
182 | case ACPI_BUTTON_TYPE_LID: | ||
183 | if (!acpi_lid_dir) | ||
184 | acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, | ||
185 | acpi_button_dir); | ||
186 | entry = acpi_lid_dir; | ||
187 | break; | ||
188 | } | 151 | } |
189 | 152 | ||
190 | if (!entry) | 153 | /* create /proc/acpi/button */ |
154 | acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
155 | if (!acpi_button_dir) | ||
191 | return -ENODEV; | 156 | return -ENODEV; |
192 | 157 | ||
193 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); | 158 | /* create /proc/acpi/button/lid */ |
194 | if (!acpi_device_dir(device)) | 159 | acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); |
195 | return -ENODEV; | 160 | if (!acpi_lid_dir) { |
161 | ret = -ENODEV; | ||
162 | goto remove_button_dir; | ||
163 | } | ||
196 | 164 | ||
197 | /* 'info' [R] */ | 165 | /* create /proc/acpi/button/lid/LID/ */ |
198 | entry = proc_create_data(ACPI_BUTTON_FILE_INFO, | 166 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir); |
199 | S_IRUGO, acpi_device_dir(device), | 167 | if (!acpi_device_dir(device)) { |
200 | &acpi_button_info_fops, device); | 168 | ret = -ENODEV; |
201 | if (!entry) | 169 | goto remove_lid_dir; |
202 | return -ENODEV; | 170 | } |
203 | 171 | ||
204 | /* show lid state [R] */ | 172 | /* create /proc/acpi/button/lid/LID/state */ |
205 | if (button->type == ACPI_BUTTON_TYPE_LID) { | 173 | entry = proc_create_data(ACPI_BUTTON_FILE_STATE, |
206 | entry = proc_create_data(ACPI_BUTTON_FILE_STATE, | 174 | S_IRUGO, acpi_device_dir(device), |
207 | S_IRUGO, acpi_device_dir(device), | 175 | &acpi_button_state_fops, device); |
208 | &acpi_button_state_fops, device); | 176 | if (!entry) { |
209 | if (!entry) | 177 | ret = -ENODEV; |
210 | return -ENODEV; | 178 | goto remove_dev_dir; |
211 | } | 179 | } |
212 | 180 | ||
213 | return 0; | 181 | done: |
182 | return ret; | ||
183 | |||
184 | remove_dev_dir: | ||
185 | remove_proc_entry(acpi_device_bid(device), | ||
186 | acpi_lid_dir); | ||
187 | acpi_device_dir(device) = NULL; | ||
188 | remove_lid_dir: | ||
189 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); | ||
190 | remove_button_dir: | ||
191 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
192 | goto done; | ||
214 | } | 193 | } |
215 | 194 | ||
216 | static int acpi_button_remove_fs(struct acpi_device *device) | 195 | static int acpi_button_remove_fs(struct acpi_device *device) |
217 | { | 196 | { |
218 | struct acpi_button *button = acpi_driver_data(device); | 197 | struct acpi_button *button = acpi_driver_data(device); |
219 | 198 | ||
220 | if (acpi_device_dir(device)) { | 199 | if (button->type != ACPI_BUTTON_TYPE_LID) |
221 | if (button->type == ACPI_BUTTON_TYPE_LID) | 200 | return 0; |
222 | remove_proc_entry(ACPI_BUTTON_FILE_STATE, | ||
223 | acpi_device_dir(device)); | ||
224 | remove_proc_entry(ACPI_BUTTON_FILE_INFO, | ||
225 | acpi_device_dir(device)); | ||
226 | 201 | ||
227 | remove_proc_entry(acpi_device_bid(device), | 202 | remove_proc_entry(ACPI_BUTTON_FILE_STATE, |
228 | acpi_device_dir(device)->parent); | 203 | acpi_device_dir(device)); |
229 | acpi_device_dir(device) = NULL; | 204 | remove_proc_entry(acpi_device_bid(device), |
230 | } | 205 | acpi_lid_dir); |
206 | acpi_device_dir(device) = NULL; | ||
207 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); | ||
208 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
231 | 209 | ||
232 | return 0; | 210 | return 0; |
233 | } | 211 | } |
@@ -279,6 +257,9 @@ static int acpi_lid_send_state(struct acpi_device *device) | |||
279 | input_report_switch(button->input, SW_LID, !state); | 257 | input_report_switch(button->input, SW_LID, !state); |
280 | input_sync(button->input); | 258 | input_sync(button->input); |
281 | 259 | ||
260 | if (state) | ||
261 | pm_wakeup_event(&device->dev, 0); | ||
262 | |||
282 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); | 263 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); |
283 | if (ret == NOTIFY_DONE) | 264 | if (ret == NOTIFY_DONE) |
284 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, | 265 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, |
@@ -314,6 +295,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
314 | input_sync(input); | 295 | input_sync(input); |
315 | input_report_key(input, keycode, 0); | 296 | input_report_key(input, keycode, 0); |
316 | input_sync(input); | 297 | input_sync(input); |
298 | |||
299 | pm_wakeup_event(&device->dev, 0); | ||
317 | } | 300 | } |
318 | 301 | ||
319 | acpi_bus_generate_proc_event(device, event, ++button->pushed); | 302 | acpi_bus_generate_proc_event(device, event, ++button->pushed); |
@@ -425,8 +408,10 @@ static int acpi_button_add(struct acpi_device *device) | |||
425 | /* Button's GPE is run-wake GPE */ | 408 | /* Button's GPE is run-wake GPE */ |
426 | acpi_enable_gpe(device->wakeup.gpe_device, | 409 | acpi_enable_gpe(device->wakeup.gpe_device, |
427 | device->wakeup.gpe_number); | 410 | device->wakeup.gpe_number); |
428 | device->wakeup.run_wake_count++; | 411 | if (!device_may_wakeup(&device->dev)) { |
429 | device->wakeup.state.enabled = 1; | 412 | device_set_wakeup_enable(&device->dev, true); |
413 | button->wakeup_enabled = true; | ||
414 | } | ||
430 | } | 415 | } |
431 | 416 | ||
432 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); | 417 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); |
@@ -448,8 +433,8 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
448 | if (device->wakeup.flags.valid) { | 433 | if (device->wakeup.flags.valid) { |
449 | acpi_disable_gpe(device->wakeup.gpe_device, | 434 | acpi_disable_gpe(device->wakeup.gpe_device, |
450 | device->wakeup.gpe_number); | 435 | device->wakeup.gpe_number); |
451 | device->wakeup.run_wake_count--; | 436 | if (button->wakeup_enabled) |
452 | device->wakeup.state.enabled = 0; | 437 | device_set_wakeup_enable(&device->dev, false); |
453 | } | 438 | } |
454 | 439 | ||
455 | acpi_button_remove_fs(device); | 440 | acpi_button_remove_fs(device); |
@@ -460,32 +445,12 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
460 | 445 | ||
461 | static int __init acpi_button_init(void) | 446 | static int __init acpi_button_init(void) |
462 | { | 447 | { |
463 | int result; | 448 | return acpi_bus_register_driver(&acpi_button_driver); |
464 | |||
465 | acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
466 | if (!acpi_button_dir) | ||
467 | return -ENODEV; | ||
468 | |||
469 | result = acpi_bus_register_driver(&acpi_button_driver); | ||
470 | if (result < 0) { | ||
471 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
472 | return -ENODEV; | ||
473 | } | ||
474 | |||
475 | return 0; | ||
476 | } | 449 | } |
477 | 450 | ||
478 | static void __exit acpi_button_exit(void) | 451 | static void __exit acpi_button_exit(void) |
479 | { | 452 | { |
480 | acpi_bus_unregister_driver(&acpi_button_driver); | 453 | acpi_bus_unregister_driver(&acpi_button_driver); |
481 | |||
482 | if (acpi_power_dir) | ||
483 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir); | ||
484 | if (acpi_sleep_dir) | ||
485 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir); | ||
486 | if (acpi_lid_dir) | ||
487 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); | ||
488 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
489 | } | 454 | } |
490 | 455 | ||
491 | module_init(acpi_button_init); | 456 | module_init(acpi_button_init); |
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 5df67f1d6c6..384f7abcff7 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c | |||
@@ -26,7 +26,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, | |||
26 | size_t count, loff_t *ppos) | 26 | size_t count, loff_t *ppos) |
27 | { | 27 | { |
28 | static char *buf; | 28 | static char *buf; |
29 | static int uncopied_bytes; | 29 | static u32 max_size; |
30 | static u32 uncopied_bytes; | ||
31 | |||
30 | struct acpi_table_header table; | 32 | struct acpi_table_header table; |
31 | acpi_status status; | 33 | acpi_status status; |
32 | 34 | ||
@@ -37,19 +39,24 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, | |||
37 | if (copy_from_user(&table, user_buf, | 39 | if (copy_from_user(&table, user_buf, |
38 | sizeof(struct acpi_table_header))) | 40 | sizeof(struct acpi_table_header))) |
39 | return -EFAULT; | 41 | return -EFAULT; |
40 | uncopied_bytes = table.length; | 42 | uncopied_bytes = max_size = table.length; |
41 | buf = kzalloc(uncopied_bytes, GFP_KERNEL); | 43 | buf = kzalloc(max_size, GFP_KERNEL); |
42 | if (!buf) | 44 | if (!buf) |
43 | return -ENOMEM; | 45 | return -ENOMEM; |
44 | } | 46 | } |
45 | 47 | ||
46 | if (uncopied_bytes < count) { | 48 | if (buf == NULL) |
47 | kfree(buf); | 49 | return -EINVAL; |
50 | |||
51 | if ((*ppos > max_size) || | ||
52 | (*ppos + count > max_size) || | ||
53 | (*ppos + count < count) || | ||
54 | (count > uncopied_bytes)) | ||
48 | return -EINVAL; | 55 | return -EINVAL; |
49 | } | ||
50 | 56 | ||
51 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | 57 | if (copy_from_user(buf + (*ppos), user_buf, count)) { |
52 | kfree(buf); | 58 | kfree(buf); |
59 | buf = NULL; | ||
53 | return -EFAULT; | 60 | return -EFAULT; |
54 | } | 61 | } |
55 | 62 | ||
@@ -59,6 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, | |||
59 | if (!uncopied_bytes) { | 66 | if (!uncopied_bytes) { |
60 | status = acpi_install_method(buf); | 67 | status = acpi_install_method(buf); |
61 | kfree(buf); | 68 | kfree(buf); |
69 | buf = NULL; | ||
62 | if (ACPI_FAILURE(status)) | 70 | if (ACPI_FAILURE(status)) |
63 | return -EINVAL; | 71 | return -EINVAL; |
64 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | 72 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 81514a4918c..1864ad3cf89 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -725,7 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
725 | complete_dock(ds); | 725 | complete_dock(ds); |
726 | dock_event(ds, event, DOCK_EVENT); | 726 | dock_event(ds, event, DOCK_EVENT); |
727 | dock_lock(ds, 1); | 727 | dock_lock(ds, 1); |
728 | acpi_update_gpes(); | 728 | acpi_update_all_gpes(); |
729 | break; | 729 | break; |
730 | } | 730 | } |
731 | if (dock_present(ds) || dock_in_progress(ds)) | 731 | if (dock_present(ds) || dock_in_progress(ds)) |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 372ff80b7b0..fa848c4116a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -606,7 +606,8 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
606 | return 0; | 606 | return 0; |
607 | } | 607 | } |
608 | 608 | ||
609 | static u32 acpi_ec_gpe_handler(void *data) | 609 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, |
610 | u32 gpe_number, void *data) | ||
610 | { | 611 | { |
611 | struct acpi_ec *ec = data; | 612 | struct acpi_ec *ec = data; |
612 | 613 | ||
@@ -618,7 +619,7 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
618 | wake_up(&ec->wait); | 619 | wake_up(&ec->wait); |
619 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 620 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
620 | } | 621 | } |
621 | return ACPI_INTERRUPT_HANDLED; | 622 | return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; |
622 | } | 623 | } |
623 | 624 | ||
624 | /* -------------------------------------------------------------------------- | 625 | /* -------------------------------------------------------------------------- |
@@ -934,6 +935,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { | |||
934 | ec_flag_msi, "MSI hardware", { | 935 | ec_flag_msi, "MSI hardware", { |
935 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, | 936 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, |
936 | { | 937 | { |
938 | ec_flag_msi, "MSI hardware", { | ||
939 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, | ||
940 | { | ||
937 | ec_validate_ecdt, "ASUS hardware", { | 941 | ec_validate_ecdt, "ASUS hardware", { |
938 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 942 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
939 | {}, | 943 | {}, |
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index 411620ef84c..05b44201a61 100644 --- a/drivers/acpi/ec_sys.c +++ b/drivers/acpi/ec_sys.c | |||
@@ -24,10 +24,6 @@ MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may " | |||
24 | 24 | ||
25 | #define EC_SPACE_SIZE 256 | 25 | #define EC_SPACE_SIZE 256 |
26 | 26 | ||
27 | struct sysdev_class acpi_ec_sysdev_class = { | ||
28 | .name = "ec", | ||
29 | }; | ||
30 | |||
31 | static struct dentry *acpi_ec_debugfs_dir; | 27 | static struct dentry *acpi_ec_debugfs_dir; |
32 | 28 | ||
33 | static int acpi_ec_open_io(struct inode *i, struct file *f) | 29 | static int acpi_ec_open_io(struct inode *i, struct file *f) |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 60049080c86..467479f07c1 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -86,7 +86,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long | |||
86 | if (!device) | 86 | if (!device) |
87 | return -EINVAL; | 87 | return -EINVAL; |
88 | 88 | ||
89 | result = acpi_bus_get_power(device->handle, &acpi_state); | 89 | result = acpi_bus_update_power(device->handle, &acpi_state); |
90 | if (result) | 90 | if (result) |
91 | return result; | 91 | return result; |
92 | 92 | ||
@@ -123,7 +123,6 @@ static struct thermal_cooling_device_ops fan_cooling_ops = { | |||
123 | static int acpi_fan_add(struct acpi_device *device) | 123 | static int acpi_fan_add(struct acpi_device *device) |
124 | { | 124 | { |
125 | int result = 0; | 125 | int result = 0; |
126 | int state = 0; | ||
127 | struct thermal_cooling_device *cdev; | 126 | struct thermal_cooling_device *cdev; |
128 | 127 | ||
129 | if (!device) | 128 | if (!device) |
@@ -132,16 +131,12 @@ static int acpi_fan_add(struct acpi_device *device) | |||
132 | strcpy(acpi_device_name(device), "Fan"); | 131 | strcpy(acpi_device_name(device), "Fan"); |
133 | strcpy(acpi_device_class(device), ACPI_FAN_CLASS); | 132 | strcpy(acpi_device_class(device), ACPI_FAN_CLASS); |
134 | 133 | ||
135 | result = acpi_bus_get_power(device->handle, &state); | 134 | result = acpi_bus_update_power(device->handle, NULL); |
136 | if (result) { | 135 | if (result) { |
137 | printk(KERN_ERR PREFIX "Reading power state\n"); | 136 | printk(KERN_ERR PREFIX "Setting initial power state\n"); |
138 | goto end; | 137 | goto end; |
139 | } | 138 | } |
140 | 139 | ||
141 | device->flags.force_power_state = 1; | ||
142 | acpi_bus_set_power(device->handle, state); | ||
143 | device->flags.force_power_state = 0; | ||
144 | |||
145 | cdev = thermal_cooling_device_register("Fan", device, | 140 | cdev = thermal_cooling_device_register("Fan", device, |
146 | &fan_cooling_ops); | 141 | &fan_cooling_ops); |
147 | if (IS_ERR(cdev)) { | 142 | if (IS_ERR(cdev)) { |
@@ -200,22 +195,14 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) | |||
200 | 195 | ||
201 | static int acpi_fan_resume(struct acpi_device *device) | 196 | static int acpi_fan_resume(struct acpi_device *device) |
202 | { | 197 | { |
203 | int result = 0; | 198 | int result; |
204 | int power_state = 0; | ||
205 | 199 | ||
206 | if (!device) | 200 | if (!device) |
207 | return -EINVAL; | 201 | return -EINVAL; |
208 | 202 | ||
209 | result = acpi_bus_get_power(device->handle, &power_state); | 203 | result = acpi_bus_update_power(device->handle, NULL); |
210 | if (result) { | 204 | if (result) |
211 | printk(KERN_ERR PREFIX | 205 | printk(KERN_ERR PREFIX "Error updating fan power state\n"); |
212 | "Error reading fan power state\n"); | ||
213 | return result; | ||
214 | } | ||
215 | |||
216 | device->flags.force_power_state = 1; | ||
217 | acpi_bus_set_power(device->handle, power_state); | ||
218 | device->flags.force_power_state = 0; | ||
219 | 206 | ||
220 | return result; | 207 | return result; |
221 | } | 208 | } |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 78b0164c35b..7c47ed55e52 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
167 | "firmware_node"); | 167 | "firmware_node"); |
168 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | 168 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, |
169 | "physical_node"); | 169 | "physical_node"); |
170 | if (acpi_dev->wakeup.flags.valid) { | 170 | if (acpi_dev->wakeup.flags.valid) |
171 | device_set_wakeup_capable(dev, true); | 171 | device_set_wakeup_capable(dev, true); |
172 | device_set_wakeup_enable(dev, | ||
173 | acpi_dev->wakeup.state.enabled); | ||
174 | } | ||
175 | } | 172 | } |
176 | 173 | ||
177 | return 0; | 174 | return 0; |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index a212bfeddf8..4bfb759deb1 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -21,8 +21,6 @@ | |||
21 | #ifndef _ACPI_INTERNAL_H_ | 21 | #ifndef _ACPI_INTERNAL_H_ |
22 | #define _ACPI_INTERNAL_H_ | 22 | #define _ACPI_INTERNAL_H_ |
23 | 23 | ||
24 | #include <linux/sysdev.h> | ||
25 | |||
26 | #define PREFIX "ACPI: " | 24 | #define PREFIX "ACPI: " |
27 | 25 | ||
28 | int init_acpi_device_notify(void); | 26 | int init_acpi_device_notify(void); |
@@ -41,9 +39,10 @@ static inline int acpi_debugfs_init(void) { return 0; } | |||
41 | int acpi_power_init(void); | 39 | int acpi_power_init(void); |
42 | int acpi_device_sleep_wake(struct acpi_device *dev, | 40 | int acpi_device_sleep_wake(struct acpi_device *dev, |
43 | int enable, int sleep_state, int dev_state); | 41 | int enable, int sleep_state, int dev_state); |
44 | int acpi_power_get_inferred_state(struct acpi_device *device); | 42 | int acpi_power_get_inferred_state(struct acpi_device *device, int *state); |
43 | int acpi_power_on_resources(struct acpi_device *device, int state); | ||
45 | int acpi_power_transition(struct acpi_device *device, int state); | 44 | int acpi_power_transition(struct acpi_device *device, int state); |
46 | extern int acpi_power_nocheck; | 45 | int acpi_bus_init_power(struct acpi_device *device); |
47 | 46 | ||
48 | int acpi_wakeup_device_init(void); | 47 | int acpi_wakeup_device_init(void); |
49 | void acpi_early_processor_set_pdc(void); | 48 | void acpi_early_processor_set_pdc(void); |
@@ -63,7 +62,6 @@ struct acpi_ec { | |||
63 | struct list_head list; | 62 | struct list_head list; |
64 | struct transaction *curr; | 63 | struct transaction *curr; |
65 | spinlock_t curr_lock; | 64 | spinlock_t curr_lock; |
66 | struct sys_device sysdev; | ||
67 | }; | 65 | }; |
68 | 66 | ||
69 | extern struct acpi_ec *first_ec; | 67 | extern struct acpi_ec *first_ec; |
@@ -82,8 +80,16 @@ extern int acpi_sleep_init(void); | |||
82 | 80 | ||
83 | #ifdef CONFIG_ACPI_SLEEP | 81 | #ifdef CONFIG_ACPI_SLEEP |
84 | int acpi_sleep_proc_init(void); | 82 | int acpi_sleep_proc_init(void); |
83 | int suspend_nvs_alloc(void); | ||
84 | void suspend_nvs_free(void); | ||
85 | int suspend_nvs_save(void); | ||
86 | void suspend_nvs_restore(void); | ||
85 | #else | 87 | #else |
86 | static inline int acpi_sleep_proc_init(void) { return 0; } | 88 | static inline int acpi_sleep_proc_init(void) { return 0; } |
89 | static inline int suspend_nvs_alloc(void) { return 0; } | ||
90 | static inline void suspend_nvs_free(void) {} | ||
91 | static inline int suspend_nvs_save(void) { return 0; } | ||
92 | static inline void suspend_nvs_restore(void) {} | ||
87 | #endif | 93 | #endif |
88 | 94 | ||
89 | #endif /* _ACPI_INTERNAL_H_ */ | 95 | #endif /* _ACPI_INTERNAL_H_ */ |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 5718566e00f..3b5c3189fd9 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -274,15 +274,21 @@ acpi_table_parse_srat(enum acpi_srat_type id, | |||
274 | 274 | ||
275 | int __init acpi_numa_init(void) | 275 | int __init acpi_numa_init(void) |
276 | { | 276 | { |
277 | int ret = 0; | 277 | int cnt = 0; |
278 | |||
279 | /* | ||
280 | * Should not limit number with cpu num that is from NR_CPUS or nr_cpus= | ||
281 | * SRAT cpu entries could have different order with that in MADT. | ||
282 | * So go over all cpu entries in SRAT to get apicid to node mapping. | ||
283 | */ | ||
278 | 284 | ||
279 | /* SRAT: Static Resource Affinity Table */ | 285 | /* SRAT: Static Resource Affinity Table */ |
280 | if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { | 286 | if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { |
281 | acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, | 287 | acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, |
282 | acpi_parse_x2apic_affinity, nr_cpu_ids); | 288 | acpi_parse_x2apic_affinity, 0); |
283 | acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, | 289 | acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, |
284 | acpi_parse_processor_affinity, nr_cpu_ids); | 290 | acpi_parse_processor_affinity, 0); |
285 | ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, | 291 | cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, |
286 | acpi_parse_memory_affinity, | 292 | acpi_parse_memory_affinity, |
287 | NR_NODE_MEMBLKS); | 293 | NR_NODE_MEMBLKS); |
288 | } | 294 | } |
@@ -291,7 +297,10 @@ int __init acpi_numa_init(void) | |||
291 | acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); | 297 | acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); |
292 | 298 | ||
293 | acpi_numa_arch_fixup(); | 299 | acpi_numa_arch_fixup(); |
294 | return ret; | 300 | |
301 | if (cnt <= 0) | ||
302 | return cnt ?: -ENOENT; | ||
303 | return 0; | ||
295 | } | 304 | } |
296 | 305 | ||
297 | int acpi_get_pxm(acpi_handle h) | 306 | int acpi_get_pxm(acpi_handle h) |
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c new file mode 100644 index 00000000000..096787b43c9 --- /dev/null +++ b/drivers/acpi/nvs.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * nvs.c - Routines for saving and restoring ACPI NVS memory region | ||
3 | * | ||
4 | * Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
5 | * | ||
6 | * This file is released under the GPLv2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/list.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/acpi_io.h> | ||
16 | #include <acpi/acpiosxf.h> | ||
17 | |||
18 | /* | ||
19 | * Platforms, like ACPI, may want us to save some memory used by them during | ||
20 | * suspend and to restore the contents of this memory during the subsequent | ||
21 | * resume. The code below implements a mechanism allowing us to do that. | ||
22 | */ | ||
23 | |||
24 | struct nvs_page { | ||
25 | unsigned long phys_start; | ||
26 | unsigned int size; | ||
27 | void *kaddr; | ||
28 | void *data; | ||
29 | bool unmap; | ||
30 | struct list_head node; | ||
31 | }; | ||
32 | |||
33 | static LIST_HEAD(nvs_list); | ||
34 | |||
35 | /** | ||
36 | * suspend_nvs_register - register platform NVS memory region to save | ||
37 | * @start - physical address of the region | ||
38 | * @size - size of the region | ||
39 | * | ||
40 | * The NVS region need not be page-aligned (both ends) and we arrange | ||
41 | * things so that the data from page-aligned addresses in this region will | ||
42 | * be copied into separate RAM pages. | ||
43 | */ | ||
44 | int suspend_nvs_register(unsigned long start, unsigned long size) | ||
45 | { | ||
46 | struct nvs_page *entry, *next; | ||
47 | |||
48 | pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n", | ||
49 | start, size); | ||
50 | |||
51 | while (size > 0) { | ||
52 | unsigned int nr_bytes; | ||
53 | |||
54 | entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL); | ||
55 | if (!entry) | ||
56 | goto Error; | ||
57 | |||
58 | list_add_tail(&entry->node, &nvs_list); | ||
59 | entry->phys_start = start; | ||
60 | nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK); | ||
61 | entry->size = (size < nr_bytes) ? size : nr_bytes; | ||
62 | |||
63 | start += entry->size; | ||
64 | size -= entry->size; | ||
65 | } | ||
66 | return 0; | ||
67 | |||
68 | Error: | ||
69 | list_for_each_entry_safe(entry, next, &nvs_list, node) { | ||
70 | list_del(&entry->node); | ||
71 | kfree(entry); | ||
72 | } | ||
73 | return -ENOMEM; | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * suspend_nvs_free - free data pages allocated for saving NVS regions | ||
78 | */ | ||
79 | void suspend_nvs_free(void) | ||
80 | { | ||
81 | struct nvs_page *entry; | ||
82 | |||
83 | list_for_each_entry(entry, &nvs_list, node) | ||
84 | if (entry->data) { | ||
85 | free_page((unsigned long)entry->data); | ||
86 | entry->data = NULL; | ||
87 | if (entry->kaddr) { | ||
88 | if (entry->unmap) { | ||
89 | iounmap(entry->kaddr); | ||
90 | entry->unmap = false; | ||
91 | } else { | ||
92 | acpi_os_unmap_memory(entry->kaddr, | ||
93 | entry->size); | ||
94 | } | ||
95 | entry->kaddr = NULL; | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * suspend_nvs_alloc - allocate memory necessary for saving NVS regions | ||
102 | */ | ||
103 | int suspend_nvs_alloc(void) | ||
104 | { | ||
105 | struct nvs_page *entry; | ||
106 | |||
107 | list_for_each_entry(entry, &nvs_list, node) { | ||
108 | entry->data = (void *)__get_free_page(GFP_KERNEL); | ||
109 | if (!entry->data) { | ||
110 | suspend_nvs_free(); | ||
111 | return -ENOMEM; | ||
112 | } | ||
113 | } | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * suspend_nvs_save - save NVS memory regions | ||
119 | */ | ||
120 | int suspend_nvs_save(void) | ||
121 | { | ||
122 | struct nvs_page *entry; | ||
123 | |||
124 | printk(KERN_INFO "PM: Saving platform NVS memory\n"); | ||
125 | |||
126 | list_for_each_entry(entry, &nvs_list, node) | ||
127 | if (entry->data) { | ||
128 | unsigned long phys = entry->phys_start; | ||
129 | unsigned int size = entry->size; | ||
130 | |||
131 | entry->kaddr = acpi_os_get_iomem(phys, size); | ||
132 | if (!entry->kaddr) { | ||
133 | entry->kaddr = acpi_os_ioremap(phys, size); | ||
134 | entry->unmap = !!entry->kaddr; | ||
135 | } | ||
136 | if (!entry->kaddr) { | ||
137 | suspend_nvs_free(); | ||
138 | return -ENOMEM; | ||
139 | } | ||
140 | memcpy(entry->data, entry->kaddr, entry->size); | ||
141 | } | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * suspend_nvs_restore - restore NVS memory regions | ||
148 | * | ||
149 | * This function is going to be called with interrupts disabled, so it | ||
150 | * cannot iounmap the virtual addresses used to access the NVS region. | ||
151 | */ | ||
152 | void suspend_nvs_restore(void) | ||
153 | { | ||
154 | struct nvs_page *entry; | ||
155 | |||
156 | printk(KERN_INFO "PM: Restoring platform NVS memory\n"); | ||
157 | |||
158 | list_for_each_entry(entry, &nvs_list, node) | ||
159 | if (entry->data) | ||
160 | memcpy(entry->kaddr, entry->data, entry->size); | ||
161 | } | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 966feddf6b1..45ad4ffef53 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
39 | #include <linux/nmi.h> | 39 | #include <linux/nmi.h> |
40 | #include <linux/acpi.h> | 40 | #include <linux/acpi.h> |
41 | #include <linux/acpi_io.h> | ||
41 | #include <linux/efi.h> | 42 | #include <linux/efi.h> |
42 | #include <linux/ioport.h> | 43 | #include <linux/ioport.h> |
43 | #include <linux/list.h> | 44 | #include <linux/list.h> |
@@ -75,7 +76,6 @@ EXPORT_SYMBOL(acpi_in_debugger); | |||
75 | extern char line_buf[80]; | 76 | extern char line_buf[80]; |
76 | #endif /*ENABLE_DEBUGGER */ | 77 | #endif /*ENABLE_DEBUGGER */ |
77 | 78 | ||
78 | static unsigned int acpi_irq_irq; | ||
79 | static acpi_osd_handler acpi_irq_handler; | 79 | static acpi_osd_handler acpi_irq_handler; |
80 | static void *acpi_irq_context; | 80 | static void *acpi_irq_context; |
81 | static struct workqueue_struct *kacpid_wq; | 81 | static struct workqueue_struct *kacpid_wq; |
@@ -104,14 +104,11 @@ struct acpi_ioremap { | |||
104 | void __iomem *virt; | 104 | void __iomem *virt; |
105 | acpi_physical_address phys; | 105 | acpi_physical_address phys; |
106 | acpi_size size; | 106 | acpi_size size; |
107 | struct kref ref; | 107 | unsigned long refcount; |
108 | }; | 108 | }; |
109 | 109 | ||
110 | static LIST_HEAD(acpi_ioremaps); | 110 | static LIST_HEAD(acpi_ioremaps); |
111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); | 111 | static DEFINE_MUTEX(acpi_ioremap_lock); |
112 | |||
113 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
114 | static char osi_setup_string[OSI_STRING_LENGTH_MAX]; | ||
115 | 112 | ||
116 | static void __init acpi_osi_setup_late(void); | 113 | static void __init acpi_osi_setup_late(void); |
117 | 114 | ||
@@ -152,8 +149,7 @@ static struct osi_linux { | |||
152 | unsigned int enable:1; | 149 | unsigned int enable:1; |
153 | unsigned int dmi:1; | 150 | unsigned int dmi:1; |
154 | unsigned int cmdline:1; | 151 | unsigned int cmdline:1; |
155 | unsigned int known:1; | 152 | } osi_linux = {0, 0, 0}; |
156 | } osi_linux = { 0, 0, 0, 0}; | ||
157 | 153 | ||
158 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | 154 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) |
159 | { | 155 | { |
@@ -288,6 +284,22 @@ acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size) | |||
288 | return NULL; | 284 | return NULL; |
289 | } | 285 | } |
290 | 286 | ||
287 | void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size) | ||
288 | { | ||
289 | struct acpi_ioremap *map; | ||
290 | void __iomem *virt = NULL; | ||
291 | |||
292 | mutex_lock(&acpi_ioremap_lock); | ||
293 | map = acpi_map_lookup(phys, size); | ||
294 | if (map) { | ||
295 | virt = map->virt + (phys - map->phys); | ||
296 | map->refcount++; | ||
297 | } | ||
298 | mutex_unlock(&acpi_ioremap_lock); | ||
299 | return virt; | ||
300 | } | ||
301 | EXPORT_SYMBOL_GPL(acpi_os_get_iomem); | ||
302 | |||
291 | /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ | 303 | /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ |
292 | static struct acpi_ioremap * | 304 | static struct acpi_ioremap * |
293 | acpi_map_lookup_virt(void __iomem *virt, acpi_size size) | 305 | acpi_map_lookup_virt(void __iomem *virt, acpi_size size) |
@@ -305,10 +317,10 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size) | |||
305 | void __iomem *__init_refok | 317 | void __iomem *__init_refok |
306 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | 318 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) |
307 | { | 319 | { |
308 | struct acpi_ioremap *map, *tmp_map; | 320 | struct acpi_ioremap *map; |
309 | unsigned long flags, pg_sz; | ||
310 | void __iomem *virt; | 321 | void __iomem *virt; |
311 | phys_addr_t pg_off; | 322 | acpi_physical_address pg_off; |
323 | acpi_size pg_sz; | ||
312 | 324 | ||
313 | if (phys > ULONG_MAX) { | 325 | if (phys > ULONG_MAX) { |
314 | printk(KERN_ERR PREFIX "Cannot map memory that high\n"); | 326 | printk(KERN_ERR PREFIX "Cannot map memory that high\n"); |
@@ -318,14 +330,25 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | |||
318 | if (!acpi_gbl_permanent_mmap) | 330 | if (!acpi_gbl_permanent_mmap) |
319 | return __acpi_map_table((unsigned long)phys, size); | 331 | return __acpi_map_table((unsigned long)phys, size); |
320 | 332 | ||
333 | mutex_lock(&acpi_ioremap_lock); | ||
334 | /* Check if there's a suitable mapping already. */ | ||
335 | map = acpi_map_lookup(phys, size); | ||
336 | if (map) { | ||
337 | map->refcount++; | ||
338 | goto out; | ||
339 | } | ||
340 | |||
321 | map = kzalloc(sizeof(*map), GFP_KERNEL); | 341 | map = kzalloc(sizeof(*map), GFP_KERNEL); |
322 | if (!map) | 342 | if (!map) { |
343 | mutex_unlock(&acpi_ioremap_lock); | ||
323 | return NULL; | 344 | return NULL; |
345 | } | ||
324 | 346 | ||
325 | pg_off = round_down(phys, PAGE_SIZE); | 347 | pg_off = round_down(phys, PAGE_SIZE); |
326 | pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; | 348 | pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; |
327 | virt = ioremap(pg_off, pg_sz); | 349 | virt = acpi_os_ioremap(pg_off, pg_sz); |
328 | if (!virt) { | 350 | if (!virt) { |
351 | mutex_unlock(&acpi_ioremap_lock); | ||
329 | kfree(map); | 352 | kfree(map); |
330 | return NULL; | 353 | return NULL; |
331 | } | 354 | } |
@@ -334,62 +357,51 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | |||
334 | map->virt = virt; | 357 | map->virt = virt; |
335 | map->phys = pg_off; | 358 | map->phys = pg_off; |
336 | map->size = pg_sz; | 359 | map->size = pg_sz; |
337 | kref_init(&map->ref); | 360 | map->refcount = 1; |
338 | 361 | ||
339 | spin_lock_irqsave(&acpi_ioremap_lock, flags); | ||
340 | /* Check if page has already been mapped. */ | ||
341 | tmp_map = acpi_map_lookup(phys, size); | ||
342 | if (tmp_map) { | ||
343 | kref_get(&tmp_map->ref); | ||
344 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | ||
345 | iounmap(map->virt); | ||
346 | kfree(map); | ||
347 | return tmp_map->virt + (phys - tmp_map->phys); | ||
348 | } | ||
349 | list_add_tail_rcu(&map->list, &acpi_ioremaps); | 362 | list_add_tail_rcu(&map->list, &acpi_ioremaps); |
350 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | ||
351 | 363 | ||
364 | out: | ||
365 | mutex_unlock(&acpi_ioremap_lock); | ||
352 | return map->virt + (phys - map->phys); | 366 | return map->virt + (phys - map->phys); |
353 | } | 367 | } |
354 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); | 368 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); |
355 | 369 | ||
356 | static void acpi_kref_del_iomap(struct kref *ref) | 370 | static void acpi_os_drop_map_ref(struct acpi_ioremap *map) |
357 | { | 371 | { |
358 | struct acpi_ioremap *map; | 372 | if (!--map->refcount) |
373 | list_del_rcu(&map->list); | ||
374 | } | ||
359 | 375 | ||
360 | map = container_of(ref, struct acpi_ioremap, ref); | 376 | static void acpi_os_map_cleanup(struct acpi_ioremap *map) |
361 | list_del_rcu(&map->list); | 377 | { |
378 | if (!map->refcount) { | ||
379 | synchronize_rcu(); | ||
380 | iounmap(map->virt); | ||
381 | kfree(map); | ||
382 | } | ||
362 | } | 383 | } |
363 | 384 | ||
364 | void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | 385 | void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) |
365 | { | 386 | { |
366 | struct acpi_ioremap *map; | 387 | struct acpi_ioremap *map; |
367 | unsigned long flags; | ||
368 | int del; | ||
369 | 388 | ||
370 | if (!acpi_gbl_permanent_mmap) { | 389 | if (!acpi_gbl_permanent_mmap) { |
371 | __acpi_unmap_table(virt, size); | 390 | __acpi_unmap_table(virt, size); |
372 | return; | 391 | return; |
373 | } | 392 | } |
374 | 393 | ||
375 | spin_lock_irqsave(&acpi_ioremap_lock, flags); | 394 | mutex_lock(&acpi_ioremap_lock); |
376 | map = acpi_map_lookup_virt(virt, size); | 395 | map = acpi_map_lookup_virt(virt, size); |
377 | if (!map) { | 396 | if (!map) { |
378 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | 397 | mutex_unlock(&acpi_ioremap_lock); |
379 | printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt); | 398 | WARN(true, PREFIX "%s: bad address %p\n", __func__, virt); |
380 | dump_stack(); | ||
381 | return; | 399 | return; |
382 | } | 400 | } |
401 | acpi_os_drop_map_ref(map); | ||
402 | mutex_unlock(&acpi_ioremap_lock); | ||
383 | 403 | ||
384 | del = kref_put(&map->ref, acpi_kref_del_iomap); | 404 | acpi_os_map_cleanup(map); |
385 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | ||
386 | |||
387 | if (!del) | ||
388 | return; | ||
389 | |||
390 | synchronize_rcu(); | ||
391 | iounmap(map->virt); | ||
392 | kfree(map); | ||
393 | } | 405 | } |
394 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); | 406 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); |
395 | 407 | ||
@@ -399,7 +411,7 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | |||
399 | __acpi_unmap_table(virt, size); | 411 | __acpi_unmap_table(virt, size); |
400 | } | 412 | } |
401 | 413 | ||
402 | int acpi_os_map_generic_address(struct acpi_generic_address *addr) | 414 | static int acpi_os_map_generic_address(struct acpi_generic_address *addr) |
403 | { | 415 | { |
404 | void __iomem *virt; | 416 | void __iomem *virt; |
405 | 417 | ||
@@ -415,13 +427,10 @@ int acpi_os_map_generic_address(struct acpi_generic_address *addr) | |||
415 | 427 | ||
416 | return 0; | 428 | return 0; |
417 | } | 429 | } |
418 | EXPORT_SYMBOL_GPL(acpi_os_map_generic_address); | ||
419 | 430 | ||
420 | void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | 431 | static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) |
421 | { | 432 | { |
422 | void __iomem *virt; | 433 | struct acpi_ioremap *map; |
423 | unsigned long flags; | ||
424 | acpi_size size = addr->bit_width / 8; | ||
425 | 434 | ||
426 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | 435 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) |
427 | return; | 436 | return; |
@@ -429,13 +438,17 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | |||
429 | if (!addr->address || !addr->bit_width) | 438 | if (!addr->address || !addr->bit_width) |
430 | return; | 439 | return; |
431 | 440 | ||
432 | spin_lock_irqsave(&acpi_ioremap_lock, flags); | 441 | mutex_lock(&acpi_ioremap_lock); |
433 | virt = acpi_map_vaddr_lookup(addr->address, size); | 442 | map = acpi_map_lookup(addr->address, addr->bit_width / 8); |
434 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | 443 | if (!map) { |
444 | mutex_unlock(&acpi_ioremap_lock); | ||
445 | return; | ||
446 | } | ||
447 | acpi_os_drop_map_ref(map); | ||
448 | mutex_unlock(&acpi_ioremap_lock); | ||
435 | 449 | ||
436 | acpi_os_unmap_memory(virt, size); | 450 | acpi_os_map_cleanup(map); |
437 | } | 451 | } |
438 | EXPORT_SYMBOL_GPL(acpi_os_unmap_generic_address); | ||
439 | 452 | ||
440 | #ifdef ACPI_FUTURE_USAGE | 453 | #ifdef ACPI_FUTURE_USAGE |
441 | acpi_status | 454 | acpi_status |
@@ -518,11 +531,15 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
518 | acpi_irq_stats_init(); | 531 | acpi_irq_stats_init(); |
519 | 532 | ||
520 | /* | 533 | /* |
521 | * Ignore the GSI from the core, and use the value in our copy of the | 534 | * ACPI interrupts different from the SCI in our copy of the FADT are |
522 | * FADT. It may not be the same if an interrupt source override exists | 535 | * not supported. |
523 | * for the SCI. | ||
524 | */ | 536 | */ |
525 | gsi = acpi_gbl_FADT.sci_interrupt; | 537 | if (gsi != acpi_gbl_FADT.sci_interrupt) |
538 | return AE_BAD_PARAMETER; | ||
539 | |||
540 | if (acpi_irq_handler) | ||
541 | return AE_ALREADY_ACQUIRED; | ||
542 | |||
526 | if (acpi_gsi_to_irq(gsi, &irq) < 0) { | 543 | if (acpi_gsi_to_irq(gsi, &irq) < 0) { |
527 | printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", | 544 | printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", |
528 | gsi); | 545 | gsi); |
@@ -533,20 +550,20 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
533 | acpi_irq_context = context; | 550 | acpi_irq_context = context; |
534 | if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { | 551 | if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { |
535 | printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); | 552 | printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); |
553 | acpi_irq_handler = NULL; | ||
536 | return AE_NOT_ACQUIRED; | 554 | return AE_NOT_ACQUIRED; |
537 | } | 555 | } |
538 | acpi_irq_irq = irq; | ||
539 | 556 | ||
540 | return AE_OK; | 557 | return AE_OK; |
541 | } | 558 | } |
542 | 559 | ||
543 | acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) | 560 | acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) |
544 | { | 561 | { |
545 | if (irq) { | 562 | if (irq != acpi_gbl_FADT.sci_interrupt) |
546 | free_irq(irq, acpi_irq); | 563 | return AE_BAD_PARAMETER; |
547 | acpi_irq_handler = NULL; | 564 | |
548 | acpi_irq_irq = 0; | 565 | free_irq(irq, acpi_irq); |
549 | } | 566 | acpi_irq_handler = NULL; |
550 | 567 | ||
551 | return AE_OK; | 568 | return AE_OK; |
552 | } | 569 | } |
@@ -638,17 +655,21 @@ EXPORT_SYMBOL(acpi_os_write_port); | |||
638 | acpi_status | 655 | acpi_status |
639 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | 656 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) |
640 | { | 657 | { |
641 | u32 dummy; | ||
642 | void __iomem *virt_addr; | 658 | void __iomem *virt_addr; |
643 | int size = width / 8, unmap = 0; | 659 | unsigned int size = width / 8; |
660 | bool unmap = false; | ||
661 | u32 dummy; | ||
644 | 662 | ||
645 | rcu_read_lock(); | 663 | rcu_read_lock(); |
646 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | 664 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); |
647 | rcu_read_unlock(); | ||
648 | if (!virt_addr) { | 665 | if (!virt_addr) { |
649 | virt_addr = ioremap(phys_addr, size); | 666 | rcu_read_unlock(); |
650 | unmap = 1; | 667 | virt_addr = acpi_os_ioremap(phys_addr, size); |
668 | if (!virt_addr) | ||
669 | return AE_BAD_ADDRESS; | ||
670 | unmap = true; | ||
651 | } | 671 | } |
672 | |||
652 | if (!value) | 673 | if (!value) |
653 | value = &dummy; | 674 | value = &dummy; |
654 | 675 | ||
@@ -668,6 +689,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | |||
668 | 689 | ||
669 | if (unmap) | 690 | if (unmap) |
670 | iounmap(virt_addr); | 691 | iounmap(virt_addr); |
692 | else | ||
693 | rcu_read_unlock(); | ||
671 | 694 | ||
672 | return AE_OK; | 695 | return AE_OK; |
673 | } | 696 | } |
@@ -676,14 +699,17 @@ acpi_status | |||
676 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | 699 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) |
677 | { | 700 | { |
678 | void __iomem *virt_addr; | 701 | void __iomem *virt_addr; |
679 | int size = width / 8, unmap = 0; | 702 | unsigned int size = width / 8; |
703 | bool unmap = false; | ||
680 | 704 | ||
681 | rcu_read_lock(); | 705 | rcu_read_lock(); |
682 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | 706 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); |
683 | rcu_read_unlock(); | ||
684 | if (!virt_addr) { | 707 | if (!virt_addr) { |
685 | virt_addr = ioremap(phys_addr, size); | 708 | rcu_read_unlock(); |
686 | unmap = 1; | 709 | virt_addr = acpi_os_ioremap(phys_addr, size); |
710 | if (!virt_addr) | ||
711 | return AE_BAD_ADDRESS; | ||
712 | unmap = true; | ||
687 | } | 713 | } |
688 | 714 | ||
689 | switch (width) { | 715 | switch (width) { |
@@ -702,6 +728,8 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | |||
702 | 728 | ||
703 | if (unmap) | 729 | if (unmap) |
704 | iounmap(virt_addr); | 730 | iounmap(virt_addr); |
731 | else | ||
732 | rcu_read_unlock(); | ||
705 | 733 | ||
706 | return AE_OK; | 734 | return AE_OK; |
707 | } | 735 | } |
@@ -1055,13 +1083,53 @@ static int __init acpi_os_name_setup(char *str) | |||
1055 | 1083 | ||
1056 | __setup("acpi_os_name=", acpi_os_name_setup); | 1084 | __setup("acpi_os_name=", acpi_os_name_setup); |
1057 | 1085 | ||
1086 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
1087 | #define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */ | ||
1088 | |||
1089 | struct osi_setup_entry { | ||
1090 | char string[OSI_STRING_LENGTH_MAX]; | ||
1091 | bool enable; | ||
1092 | }; | ||
1093 | |||
1094 | static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; | ||
1095 | |||
1096 | void __init acpi_osi_setup(char *str) | ||
1097 | { | ||
1098 | struct osi_setup_entry *osi; | ||
1099 | bool enable = true; | ||
1100 | int i; | ||
1101 | |||
1102 | if (!acpi_gbl_create_osi_method) | ||
1103 | return; | ||
1104 | |||
1105 | if (str == NULL || *str == '\0') { | ||
1106 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | ||
1107 | acpi_gbl_create_osi_method = FALSE; | ||
1108 | return; | ||
1109 | } | ||
1110 | |||
1111 | if (*str == '!') { | ||
1112 | str++; | ||
1113 | enable = false; | ||
1114 | } | ||
1115 | |||
1116 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1117 | osi = &osi_setup_entries[i]; | ||
1118 | if (!strcmp(osi->string, str)) { | ||
1119 | osi->enable = enable; | ||
1120 | break; | ||
1121 | } else if (osi->string[0] == '\0') { | ||
1122 | osi->enable = enable; | ||
1123 | strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); | ||
1124 | break; | ||
1125 | } | ||
1126 | } | ||
1127 | } | ||
1128 | |||
1058 | static void __init set_osi_linux(unsigned int enable) | 1129 | static void __init set_osi_linux(unsigned int enable) |
1059 | { | 1130 | { |
1060 | if (osi_linux.enable != enable) { | 1131 | if (osi_linux.enable != enable) |
1061 | osi_linux.enable = enable; | 1132 | osi_linux.enable = enable; |
1062 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | ||
1063 | enable ? "Add": "Delet"); | ||
1064 | } | ||
1065 | 1133 | ||
1066 | if (osi_linux.enable) | 1134 | if (osi_linux.enable) |
1067 | acpi_osi_setup("Linux"); | 1135 | acpi_osi_setup("Linux"); |
@@ -1073,7 +1141,8 @@ static void __init set_osi_linux(unsigned int enable) | |||
1073 | 1141 | ||
1074 | static void __init acpi_cmdline_osi_linux(unsigned int enable) | 1142 | static void __init acpi_cmdline_osi_linux(unsigned int enable) |
1075 | { | 1143 | { |
1076 | osi_linux.cmdline = 1; /* cmdline set the default */ | 1144 | osi_linux.cmdline = 1; /* cmdline set the default and override DMI */ |
1145 | osi_linux.dmi = 0; | ||
1077 | set_osi_linux(enable); | 1146 | set_osi_linux(enable); |
1078 | 1147 | ||
1079 | return; | 1148 | return; |
@@ -1081,15 +1150,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable) | |||
1081 | 1150 | ||
1082 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | 1151 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) |
1083 | { | 1152 | { |
1084 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ | ||
1085 | |||
1086 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 1153 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
1087 | 1154 | ||
1088 | if (enable == -1) | 1155 | if (enable == -1) |
1089 | return; | 1156 | return; |
1090 | 1157 | ||
1091 | osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ | 1158 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ |
1092 | |||
1093 | set_osi_linux(enable); | 1159 | set_osi_linux(enable); |
1094 | 1160 | ||
1095 | return; | 1161 | return; |
@@ -1104,37 +1170,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | |||
1104 | */ | 1170 | */ |
1105 | static void __init acpi_osi_setup_late(void) | 1171 | static void __init acpi_osi_setup_late(void) |
1106 | { | 1172 | { |
1107 | char *str = osi_setup_string; | 1173 | struct osi_setup_entry *osi; |
1174 | char *str; | ||
1175 | int i; | ||
1176 | acpi_status status; | ||
1108 | 1177 | ||
1109 | if (*str == '\0') | 1178 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { |
1110 | return; | 1179 | osi = &osi_setup_entries[i]; |
1180 | str = osi->string; | ||
1111 | 1181 | ||
1112 | if (!strcmp("!Linux", str)) { | 1182 | if (*str == '\0') |
1113 | acpi_cmdline_osi_linux(0); /* !enable */ | 1183 | break; |
1114 | } else if (*str == '!') { | 1184 | if (osi->enable) { |
1115 | if (acpi_remove_interface(++str) == AE_OK) | 1185 | status = acpi_install_interface(str); |
1116 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1186 | |
1117 | } else if (!strcmp("Linux", str)) { | 1187 | if (ACPI_SUCCESS(status)) |
1118 | acpi_cmdline_osi_linux(1); /* enable */ | 1188 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
1119 | } else { | 1189 | } else { |
1120 | if (acpi_install_interface(str) == AE_OK) | 1190 | status = acpi_remove_interface(str); |
1121 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1191 | |
1192 | if (ACPI_SUCCESS(status)) | ||
1193 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | ||
1194 | } | ||
1122 | } | 1195 | } |
1123 | } | 1196 | } |
1124 | 1197 | ||
1125 | int __init acpi_osi_setup(char *str) | 1198 | static int __init osi_setup(char *str) |
1126 | { | 1199 | { |
1127 | if (str == NULL || *str == '\0') { | 1200 | if (str && !strcmp("Linux", str)) |
1128 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1201 | acpi_cmdline_osi_linux(1); |
1129 | acpi_gbl_create_osi_method = FALSE; | 1202 | else if (str && !strcmp("!Linux", str)) |
1130 | } else { | 1203 | acpi_cmdline_osi_linux(0); |
1131 | strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); | 1204 | else |
1132 | } | 1205 | acpi_osi_setup(str); |
1133 | 1206 | ||
1134 | return 1; | 1207 | return 1; |
1135 | } | 1208 | } |
1136 | 1209 | ||
1137 | __setup("acpi_osi=", acpi_osi_setup); | 1210 | __setup("acpi_osi=", osi_setup); |
1138 | 1211 | ||
1139 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ | 1212 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ |
1140 | static int __init acpi_serialize_setup(char *str) | 1213 | static int __init acpi_serialize_setup(char *str) |
@@ -1192,8 +1265,7 @@ __setup("acpi_enforce_resources=", acpi_enforce_resources_setup); | |||
1192 | int acpi_check_resource_conflict(const struct resource *res) | 1265 | int acpi_check_resource_conflict(const struct resource *res) |
1193 | { | 1266 | { |
1194 | struct acpi_res_list *res_list_elem; | 1267 | struct acpi_res_list *res_list_elem; |
1195 | int ioport; | 1268 | int ioport = 0, clash = 0; |
1196 | int clash = 0; | ||
1197 | 1269 | ||
1198 | if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) | 1270 | if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) |
1199 | return 0; | 1271 | return 0; |
@@ -1223,9 +1295,13 @@ int acpi_check_resource_conflict(const struct resource *res) | |||
1223 | if (clash) { | 1295 | if (clash) { |
1224 | if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) { | 1296 | if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) { |
1225 | printk(KERN_WARNING "ACPI: resource %s %pR" | 1297 | printk(KERN_WARNING "ACPI: resource %s %pR" |
1226 | " conflicts with ACPI region %s %pR\n", | 1298 | " conflicts with ACPI region %s " |
1299 | "[%s 0x%zx-0x%zx]\n", | ||
1227 | res->name, res, res_list_elem->name, | 1300 | res->name, res, res_list_elem->name, |
1228 | res_list_elem); | 1301 | (res_list_elem->resource_type == |
1302 | ACPI_ADR_SPACE_SYSTEM_IO) ? "io" : "mem", | ||
1303 | (size_t) res_list_elem->start, | ||
1304 | (size_t) res_list_elem->end); | ||
1229 | if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX) | 1305 | if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX) |
1230 | printk(KERN_NOTICE "ACPI: This conflict may" | 1306 | printk(KERN_NOTICE "ACPI: This conflict may" |
1231 | " cause random problems and system" | 1307 | " cause random problems and system" |
@@ -1530,11 +1606,11 @@ acpi_status __init acpi_os_initialize(void) | |||
1530 | return AE_OK; | 1606 | return AE_OK; |
1531 | } | 1607 | } |
1532 | 1608 | ||
1533 | acpi_status acpi_os_initialize1(void) | 1609 | acpi_status __init acpi_os_initialize1(void) |
1534 | { | 1610 | { |
1535 | kacpid_wq = create_workqueue("kacpid"); | 1611 | kacpid_wq = alloc_workqueue("kacpid", 0, 1); |
1536 | kacpi_notify_wq = create_workqueue("kacpi_notify"); | 1612 | kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); |
1537 | kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); | 1613 | kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1); |
1538 | BUG_ON(!kacpid_wq); | 1614 | BUG_ON(!kacpid_wq); |
1539 | BUG_ON(!kacpi_notify_wq); | 1615 | BUG_ON(!kacpi_notify_wq); |
1540 | BUG_ON(!kacpi_hotplug_wq); | 1616 | BUG_ON(!kacpi_hotplug_wq); |
@@ -1546,7 +1622,7 @@ acpi_status acpi_os_initialize1(void) | |||
1546 | acpi_status acpi_os_terminate(void) | 1622 | acpi_status acpi_os_terminate(void) |
1547 | { | 1623 | { |
1548 | if (acpi_irq_handler) { | 1624 | if (acpi_irq_handler) { |
1549 | acpi_os_remove_interrupt_handler(acpi_irq_irq, | 1625 | acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt, |
1550 | acpi_irq_handler); | 1626 | acpi_irq_handler); |
1551 | } | 1627 | } |
1552 | 1628 | ||
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 9ff80a7e9f6..4a29763b8eb 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -29,7 +29,7 @@ | |||
29 | * for IRQ management (e.g. start()->_SRS). | 29 | * for IRQ management (e.g. start()->_SRS). |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include <linux/sysdev.h> | 32 | #include <linux/syscore_ops.h> |
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
@@ -757,14 +757,13 @@ static int acpi_pci_link_resume(struct acpi_pci_link *link) | |||
757 | return 0; | 757 | return 0; |
758 | } | 758 | } |
759 | 759 | ||
760 | static int irqrouter_resume(struct sys_device *dev) | 760 | static void irqrouter_resume(void) |
761 | { | 761 | { |
762 | struct acpi_pci_link *link; | 762 | struct acpi_pci_link *link; |
763 | 763 | ||
764 | list_for_each_entry(link, &acpi_link_list, list) { | 764 | list_for_each_entry(link, &acpi_link_list, list) { |
765 | acpi_pci_link_resume(link); | 765 | acpi_pci_link_resume(link); |
766 | } | 766 | } |
767 | return 0; | ||
768 | } | 767 | } |
769 | 768 | ||
770 | static int acpi_pci_link_remove(struct acpi_device *device, int type) | 769 | static int acpi_pci_link_remove(struct acpi_device *device, int type) |
@@ -871,32 +870,19 @@ static int __init acpi_irq_balance_set(char *str) | |||
871 | 870 | ||
872 | __setup("acpi_irq_balance", acpi_irq_balance_set); | 871 | __setup("acpi_irq_balance", acpi_irq_balance_set); |
873 | 872 | ||
874 | /* FIXME: we will remove this interface after all drivers call pci_disable_device */ | 873 | static struct syscore_ops irqrouter_syscore_ops = { |
875 | static struct sysdev_class irqrouter_sysdev_class = { | ||
876 | .name = "irqrouter", | ||
877 | .resume = irqrouter_resume, | 874 | .resume = irqrouter_resume, |
878 | }; | 875 | }; |
879 | 876 | ||
880 | static struct sys_device device_irqrouter = { | 877 | static int __init irqrouter_init_ops(void) |
881 | .id = 0, | ||
882 | .cls = &irqrouter_sysdev_class, | ||
883 | }; | ||
884 | |||
885 | static int __init irqrouter_init_sysfs(void) | ||
886 | { | 878 | { |
887 | int error; | 879 | if (!acpi_disabled && !acpi_noirq) |
880 | register_syscore_ops(&irqrouter_syscore_ops); | ||
888 | 881 | ||
889 | if (acpi_disabled || acpi_noirq) | 882 | return 0; |
890 | return 0; | ||
891 | |||
892 | error = sysdev_class_register(&irqrouter_sysdev_class); | ||
893 | if (!error) | ||
894 | error = sysdev_register(&device_irqrouter); | ||
895 | |||
896 | return error; | ||
897 | } | 883 | } |
898 | 884 | ||
899 | device_initcall(irqrouter_init_sysfs); | 885 | device_initcall(irqrouter_init_ops); |
900 | 886 | ||
901 | static int __init acpi_pci_link_init(void) | 887 | static int __init acpi_pci_link_init(void) |
902 | { | 888 | { |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 96668ad0962..f911a2f8cc3 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -32,10 +32,12 @@ | |||
32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/pci-acpi.h> | 34 | #include <linux/pci-acpi.h> |
35 | #include <linux/pci-aspm.h> | ||
35 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
36 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
37 | #include <acpi/acpi_bus.h> | 38 | #include <acpi/acpi_bus.h> |
38 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
40 | #include <acpi/apei.h> | ||
39 | 41 | ||
40 | #define PREFIX "ACPI: " | 42 | #define PREFIX "ACPI: " |
41 | 43 | ||
@@ -47,6 +49,11 @@ static int acpi_pci_root_add(struct acpi_device *device); | |||
47 | static int acpi_pci_root_remove(struct acpi_device *device, int type); | 49 | static int acpi_pci_root_remove(struct acpi_device *device, int type); |
48 | static int acpi_pci_root_start(struct acpi_device *device); | 50 | static int acpi_pci_root_start(struct acpi_device *device); |
49 | 51 | ||
52 | #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ | ||
53 | | OSC_ACTIVE_STATE_PWR_SUPPORT \ | ||
54 | | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \ | ||
55 | | OSC_MSI_SUPPORT) | ||
56 | |||
50 | static const struct acpi_device_id root_device_ids[] = { | 57 | static const struct acpi_device_id root_device_ids[] = { |
51 | {"PNP0A03", 0}, | 58 | {"PNP0A03", 0}, |
52 | {"", 0}, | 59 | {"", 0}, |
@@ -558,7 +565,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
558 | /* Indicate support for various _OSC capabilities. */ | 565 | /* Indicate support for various _OSC capabilities. */ |
559 | if (pci_ext_cfg_avail(root->bus->self)) | 566 | if (pci_ext_cfg_avail(root->bus->self)) |
560 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; | 567 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; |
561 | if (pcie_aspm_enabled()) | 568 | if (pcie_aspm_support_enabled()) |
562 | flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | | 569 | flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | |
563 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; | 570 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; |
564 | if (pci_msi_enabled()) | 571 | if (pci_msi_enabled()) |
@@ -566,6 +573,37 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
566 | if (flags != base_flags) | 573 | if (flags != base_flags) |
567 | acpi_pci_osc_support(root, flags); | 574 | acpi_pci_osc_support(root, flags); |
568 | 575 | ||
576 | if (!pcie_ports_disabled | ||
577 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { | ||
578 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | ||
579 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
580 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
581 | |||
582 | if (pci_aer_available()) { | ||
583 | if (aer_acpi_firmware_first()) | ||
584 | dev_dbg(root->bus->bridge, | ||
585 | "PCIe errors handled by BIOS.\n"); | ||
586 | else | ||
587 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
588 | } | ||
589 | |||
590 | dev_info(root->bus->bridge, | ||
591 | "Requesting ACPI _OSC control (0x%02x)\n", flags); | ||
592 | |||
593 | status = acpi_pci_osc_control_set(device->handle, &flags, | ||
594 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
595 | if (ACPI_SUCCESS(status)) { | ||
596 | dev_info(root->bus->bridge, | ||
597 | "ACPI _OSC control (0x%02x) granted\n", flags); | ||
598 | } else { | ||
599 | dev_dbg(root->bus->bridge, | ||
600 | "ACPI _OSC request failed (code %d)\n", status); | ||
601 | printk(KERN_INFO "Unable to assume _OSC PCIe control. " | ||
602 | "Disabling ASPM\n"); | ||
603 | pcie_no_aspm(); | ||
604 | } | ||
605 | } | ||
606 | |||
569 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 607 | pci_acpi_add_bus_pm_notifier(device, root->bus); |
570 | if (device->wakeup.flags.run_wake) | 608 | if (device->wakeup.flags.run_wake) |
571 | device_set_run_wake(root->bus->bridge, true); | 609 | device_set_run_wake(root->bus->bridge, true); |
@@ -600,6 +638,8 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
600 | 638 | ||
601 | static int __init acpi_pci_root_init(void) | 639 | static int __init acpi_pci_root_init(void) |
602 | { | 640 | { |
641 | acpi_hest_init(); | ||
642 | |||
603 | if (acpi_pci_disabled) | 643 | if (acpi_pci_disabled) |
604 | return 0; | 644 | return 0; |
605 | 645 | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 67dedeed144..9ac2a9fa90f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -56,9 +56,6 @@ ACPI_MODULE_NAME("power"); | |||
56 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 | 56 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 |
57 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF | 57 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF |
58 | 58 | ||
59 | int acpi_power_nocheck; | ||
60 | module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); | ||
61 | |||
62 | static int acpi_power_add(struct acpi_device *device); | 59 | static int acpi_power_add(struct acpi_device *device); |
63 | static int acpi_power_remove(struct acpi_device *device, int type); | 60 | static int acpi_power_remove(struct acpi_device *device, int type); |
64 | static int acpi_power_resume(struct acpi_device *device); | 61 | static int acpi_power_resume(struct acpi_device *device); |
@@ -148,9 +145,8 @@ static int acpi_power_get_state(acpi_handle handle, int *state) | |||
148 | 145 | ||
149 | static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) | 146 | static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) |
150 | { | 147 | { |
151 | int result = 0, state1; | 148 | int cur_state; |
152 | u32 i = 0; | 149 | int i = 0; |
153 | |||
154 | 150 | ||
155 | if (!list || !state) | 151 | if (!list || !state) |
156 | return -EINVAL; | 152 | return -EINVAL; |
@@ -158,25 +154,33 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) | |||
158 | /* The state of the list is 'on' IFF all resources are 'on'. */ | 154 | /* The state of the list is 'on' IFF all resources are 'on'. */ |
159 | 155 | ||
160 | for (i = 0; i < list->count; i++) { | 156 | for (i = 0; i < list->count; i++) { |
161 | /* | 157 | struct acpi_power_resource *resource; |
162 | * The state of the power resource can be obtained by | 158 | acpi_handle handle = list->handles[i]; |
163 | * using the ACPI handle. In such case it is unnecessary to | 159 | int result; |
164 | * get the Power resource first and then get its state again. | 160 | |
165 | */ | 161 | result = acpi_power_get_context(handle, &resource); |
166 | result = acpi_power_get_state(list->handles[i], &state1); | ||
167 | if (result) | 162 | if (result) |
168 | return result; | 163 | return result; |
169 | 164 | ||
170 | *state = state1; | 165 | mutex_lock(&resource->resource_lock); |
166 | |||
167 | result = acpi_power_get_state(handle, &cur_state); | ||
168 | |||
169 | mutex_unlock(&resource->resource_lock); | ||
170 | |||
171 | if (result) | ||
172 | return result; | ||
171 | 173 | ||
172 | if (*state != ACPI_POWER_RESOURCE_STATE_ON) | 174 | if (cur_state != ACPI_POWER_RESOURCE_STATE_ON) |
173 | break; | 175 | break; |
174 | } | 176 | } |
175 | 177 | ||
176 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", | 178 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", |
177 | *state ? "on" : "off")); | 179 | cur_state ? "on" : "off")); |
178 | 180 | ||
179 | return result; | 181 | *state = cur_state; |
182 | |||
183 | return 0; | ||
180 | } | 184 | } |
181 | 185 | ||
182 | static int __acpi_power_on(struct acpi_power_resource *resource) | 186 | static int __acpi_power_on(struct acpi_power_resource *resource) |
@@ -213,14 +217,16 @@ static int acpi_power_on(acpi_handle handle) | |||
213 | resource->name)); | 217 | resource->name)); |
214 | } else { | 218 | } else { |
215 | result = __acpi_power_on(resource); | 219 | result = __acpi_power_on(resource); |
220 | if (result) | ||
221 | resource->ref_count--; | ||
216 | } | 222 | } |
217 | 223 | ||
218 | mutex_unlock(&resource->resource_lock); | 224 | mutex_unlock(&resource->resource_lock); |
219 | 225 | ||
220 | return 0; | 226 | return result; |
221 | } | 227 | } |
222 | 228 | ||
223 | static int acpi_power_off_device(acpi_handle handle) | 229 | static int acpi_power_off(acpi_handle handle) |
224 | { | 230 | { |
225 | int result = 0; | 231 | int result = 0; |
226 | acpi_status status = AE_OK; | 232 | acpi_status status = AE_OK; |
@@ -264,6 +270,35 @@ static int acpi_power_off_device(acpi_handle handle) | |||
264 | return result; | 270 | return result; |
265 | } | 271 | } |
266 | 272 | ||
273 | static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res) | ||
274 | { | ||
275 | int i; | ||
276 | |||
277 | for (i = num_res - 1; i >= 0 ; i--) | ||
278 | acpi_power_off(list->handles[i]); | ||
279 | } | ||
280 | |||
281 | static void acpi_power_off_list(struct acpi_handle_list *list) | ||
282 | { | ||
283 | __acpi_power_off_list(list, list->count); | ||
284 | } | ||
285 | |||
286 | static int acpi_power_on_list(struct acpi_handle_list *list) | ||
287 | { | ||
288 | int result = 0; | ||
289 | int i; | ||
290 | |||
291 | for (i = 0; i < list->count; i++) { | ||
292 | result = acpi_power_on(list->handles[i]); | ||
293 | if (result) { | ||
294 | __acpi_power_off_list(list, i); | ||
295 | break; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | return result; | ||
300 | } | ||
301 | |||
267 | /** | 302 | /** |
268 | * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in | 303 | * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in |
269 | * ACPI 3.0) _PSW (Power State Wake) | 304 | * ACPI 3.0) _PSW (Power State Wake) |
@@ -402,8 +437,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) | |||
402 | 437 | ||
403 | /* Close power resource */ | 438 | /* Close power resource */ |
404 | for (i = 0; i < dev->wakeup.resources.count; i++) { | 439 | for (i = 0; i < dev->wakeup.resources.count; i++) { |
405 | int ret = acpi_power_off_device( | 440 | int ret = acpi_power_off(dev->wakeup.resources.handles[i]); |
406 | dev->wakeup.resources.handles[i]); | ||
407 | if (ret) { | 441 | if (ret) { |
408 | printk(KERN_ERR PREFIX "Transition power state\n"); | 442 | printk(KERN_ERR PREFIX "Transition power state\n"); |
409 | dev->wakeup.flags.valid = 0; | 443 | dev->wakeup.flags.valid = 0; |
@@ -421,19 +455,16 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) | |||
421 | Device Power Management | 455 | Device Power Management |
422 | -------------------------------------------------------------------------- */ | 456 | -------------------------------------------------------------------------- */ |
423 | 457 | ||
424 | int acpi_power_get_inferred_state(struct acpi_device *device) | 458 | int acpi_power_get_inferred_state(struct acpi_device *device, int *state) |
425 | { | 459 | { |
426 | int result = 0; | 460 | int result = 0; |
427 | struct acpi_handle_list *list = NULL; | 461 | struct acpi_handle_list *list = NULL; |
428 | int list_state = 0; | 462 | int list_state = 0; |
429 | int i = 0; | 463 | int i = 0; |
430 | 464 | ||
431 | 465 | if (!device || !state) | |
432 | if (!device) | ||
433 | return -EINVAL; | 466 | return -EINVAL; |
434 | 467 | ||
435 | device->power.state = ACPI_STATE_UNKNOWN; | ||
436 | |||
437 | /* | 468 | /* |
438 | * We know a device's inferred power state when all the resources | 469 | * We know a device's inferred power state when all the resources |
439 | * required for a given D-state are 'on'. | 470 | * required for a given D-state are 'on'. |
@@ -448,66 +479,51 @@ int acpi_power_get_inferred_state(struct acpi_device *device) | |||
448 | return result; | 479 | return result; |
449 | 480 | ||
450 | if (list_state == ACPI_POWER_RESOURCE_STATE_ON) { | 481 | if (list_state == ACPI_POWER_RESOURCE_STATE_ON) { |
451 | device->power.state = i; | 482 | *state = i; |
452 | return 0; | 483 | return 0; |
453 | } | 484 | } |
454 | } | 485 | } |
455 | 486 | ||
456 | device->power.state = ACPI_STATE_D3; | 487 | *state = ACPI_STATE_D3; |
457 | |||
458 | return 0; | 488 | return 0; |
459 | } | 489 | } |
460 | 490 | ||
461 | int acpi_power_transition(struct acpi_device *device, int state) | 491 | int acpi_power_on_resources(struct acpi_device *device, int state) |
462 | { | 492 | { |
463 | int result = 0; | 493 | if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3) |
464 | struct acpi_handle_list *cl = NULL; /* Current Resources */ | 494 | return -EINVAL; |
465 | struct acpi_handle_list *tl = NULL; /* Target Resources */ | ||
466 | int i = 0; | ||
467 | 495 | ||
496 | return acpi_power_on_list(&device->power.states[state].resources); | ||
497 | } | ||
498 | |||
499 | int acpi_power_transition(struct acpi_device *device, int state) | ||
500 | { | ||
501 | int result; | ||
468 | 502 | ||
469 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | 503 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) |
470 | return -EINVAL; | 504 | return -EINVAL; |
471 | 505 | ||
506 | if (device->power.state == state) | ||
507 | return 0; | ||
508 | |||
472 | if ((device->power.state < ACPI_STATE_D0) | 509 | if ((device->power.state < ACPI_STATE_D0) |
473 | || (device->power.state > ACPI_STATE_D3)) | 510 | || (device->power.state > ACPI_STATE_D3)) |
474 | return -ENODEV; | 511 | return -ENODEV; |
475 | 512 | ||
476 | cl = &device->power.states[device->power.state].resources; | ||
477 | tl = &device->power.states[state].resources; | ||
478 | |||
479 | /* TBD: Resources must be ordered. */ | 513 | /* TBD: Resources must be ordered. */ |
480 | 514 | ||
481 | /* | 515 | /* |
482 | * First we reference all power resources required in the target list | 516 | * First we reference all power resources required in the target list |
483 | * (e.g. so the device doesn't lose power while transitioning). | 517 | * (e.g. so the device doesn't lose power while transitioning). Then, |
518 | * we dereference all power resources used in the current list. | ||
484 | */ | 519 | */ |
485 | for (i = 0; i < tl->count; i++) { | 520 | result = acpi_power_on_list(&device->power.states[state].resources); |
486 | result = acpi_power_on(tl->handles[i]); | 521 | if (!result) |
487 | if (result) | 522 | acpi_power_off_list( |
488 | goto end; | 523 | &device->power.states[device->power.state].resources); |
489 | } | ||
490 | 524 | ||
491 | if (device->power.state == state) { | 525 | /* We shouldn't change the state unless the above operations succeed. */ |
492 | goto end; | 526 | device->power.state = result ? ACPI_STATE_UNKNOWN : state; |
493 | } | ||
494 | |||
495 | /* | ||
496 | * Then we dereference all power resources used in the current list. | ||
497 | */ | ||
498 | for (i = 0; i < cl->count; i++) { | ||
499 | result = acpi_power_off_device(cl->handles[i]); | ||
500 | if (result) | ||
501 | goto end; | ||
502 | } | ||
503 | |||
504 | end: | ||
505 | if (result) | ||
506 | device->power.state = ACPI_STATE_UNKNOWN; | ||
507 | else { | ||
508 | /* We shouldn't change the state till all above operations succeed */ | ||
509 | device->power.state = state; | ||
510 | } | ||
511 | 527 | ||
512 | return result; | 528 | return result; |
513 | } | 529 | } |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index afad67769db..f5f986991b5 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
311 | dev->pnp.bus_id, | 311 | dev->pnp.bus_id, |
312 | (u32) dev->wakeup.sleep_state, | 312 | (u32) dev->wakeup.sleep_state, |
313 | dev->wakeup.flags.run_wake ? '*' : ' ', | 313 | dev->wakeup.flags.run_wake ? '*' : ' ', |
314 | dev->wakeup.state.enabled ? "enabled" : "disabled"); | 314 | (device_may_wakeup(&dev->dev) |
315 | || (ldev && device_may_wakeup(ldev))) ? | ||
316 | "enabled" : "disabled"); | ||
315 | if (ldev) | 317 | if (ldev) |
316 | seq_printf(seq, "%s:%s", | 318 | seq_printf(seq, "%s:%s", |
317 | ldev->bus ? ldev->bus->name : "no-bus", | 319 | ldev->bus ? ldev->bus->name : "no-bus", |
@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev) | |||
328 | { | 330 | { |
329 | struct device *dev = acpi_get_physical_device(adev->handle); | 331 | struct device *dev = acpi_get_physical_device(adev->handle); |
330 | 332 | ||
331 | if (dev && device_can_wakeup(dev)) | 333 | if (dev && device_can_wakeup(dev)) { |
332 | device_set_wakeup_enable(dev, adev->wakeup.state.enabled); | 334 | bool enable = !device_may_wakeup(dev); |
335 | device_set_wakeup_enable(dev, enable); | ||
336 | } | ||
333 | } | 337 | } |
334 | 338 | ||
335 | static ssize_t | 339 | static ssize_t |
@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file, | |||
341 | char strbuf[5]; | 345 | char strbuf[5]; |
342 | char str[5] = ""; | 346 | char str[5] = ""; |
343 | unsigned int len = count; | 347 | unsigned int len = count; |
344 | struct acpi_device *found_dev = NULL; | ||
345 | 348 | ||
346 | if (len > 4) | 349 | if (len > 4) |
347 | len = 4; | 350 | len = 4; |
@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file, | |||
361 | continue; | 364 | continue; |
362 | 365 | ||
363 | if (!strncmp(dev->pnp.bus_id, str, 4)) { | 366 | if (!strncmp(dev->pnp.bus_id, str, 4)) { |
364 | dev->wakeup.state.enabled = | 367 | if (device_can_wakeup(&dev->dev)) { |
365 | dev->wakeup.state.enabled ? 0 : 1; | 368 | bool enable = !device_may_wakeup(&dev->dev); |
366 | found_dev = dev; | 369 | device_set_wakeup_enable(&dev->dev, enable); |
367 | break; | 370 | } else { |
368 | } | ||
369 | } | ||
370 | if (found_dev) { | ||
371 | physical_device_enable_wakeup(found_dev); | ||
372 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | ||
373 | struct acpi_device *dev = container_of(node, | ||
374 | struct | ||
375 | acpi_device, | ||
376 | wakeup_list); | ||
377 | |||
378 | if ((dev != found_dev) && | ||
379 | (dev->wakeup.gpe_number == | ||
380 | found_dev->wakeup.gpe_number) | ||
381 | && (dev->wakeup.gpe_device == | ||
382 | found_dev->wakeup.gpe_device)) { | ||
383 | printk(KERN_WARNING | ||
384 | "ACPI: '%s' and '%s' have the same GPE, " | ||
385 | "can't disable/enable one separately\n", | ||
386 | dev->pnp.bus_id, found_dev->pnp.bus_id); | ||
387 | dev->wakeup.state.enabled = | ||
388 | found_dev->wakeup.state.enabled; | ||
389 | physical_device_enable_wakeup(dev); | 371 | physical_device_enable_wakeup(dev); |
390 | } | 372 | } |
373 | break; | ||
391 | } | 374 | } |
392 | } | 375 | } |
393 | mutex_unlock(&acpi_device_lock); | 376 | mutex_unlock(&acpi_device_lock); |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index bec561c14be..25bf17da69f 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -19,15 +19,15 @@ | |||
19 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 19 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
20 | ACPI_MODULE_NAME("processor_core"); | 20 | ACPI_MODULE_NAME("processor_core"); |
21 | 21 | ||
22 | static int set_no_mwait(const struct dmi_system_id *id) | 22 | static int __init set_no_mwait(const struct dmi_system_id *id) |
23 | { | 23 | { |
24 | printk(KERN_NOTICE PREFIX "%s detected - " | 24 | printk(KERN_NOTICE PREFIX "%s detected - " |
25 | "disabling mwait for CPU C-states\n", id->ident); | 25 | "disabling mwait for CPU C-states\n", id->ident); |
26 | idle_nomwait = 1; | 26 | boot_option_idle_override = IDLE_NOMWAIT; |
27 | return 0; | 27 | return 0; |
28 | } | 28 | } |
29 | 29 | ||
30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | 30 | static struct dmi_system_id __initdata processor_idle_dmi_table[] = { |
31 | { | 31 | { |
32 | set_no_mwait, "Extensa 5220", { | 32 | set_no_mwait, "Extensa 5220", { |
33 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | 33 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
@@ -183,7 +183,7 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | |||
183 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 183 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
184 | #endif | 184 | #endif |
185 | 185 | ||
186 | static bool processor_physically_present(acpi_handle handle) | 186 | static bool __init processor_physically_present(acpi_handle handle) |
187 | { | 187 | { |
188 | int cpuid, type; | 188 | int cpuid, type; |
189 | u32 acpi_id; | 189 | u32 acpi_id; |
@@ -223,7 +223,7 @@ static bool processor_physically_present(acpi_handle handle) | |||
223 | return true; | 223 | return true; |
224 | } | 224 | } |
225 | 225 | ||
226 | static void acpi_set_pdc_bits(u32 *buf) | 226 | static void __cpuinit acpi_set_pdc_bits(u32 *buf) |
227 | { | 227 | { |
228 | buf[0] = ACPI_PDC_REVISION_ID; | 228 | buf[0] = ACPI_PDC_REVISION_ID; |
229 | buf[1] = 1; | 229 | buf[1] = 1; |
@@ -235,7 +235,7 @@ static void acpi_set_pdc_bits(u32 *buf) | |||
235 | arch_acpi_set_pdc_bits(buf); | 235 | arch_acpi_set_pdc_bits(buf); |
236 | } | 236 | } |
237 | 237 | ||
238 | static struct acpi_object_list *acpi_processor_alloc_pdc(void) | 238 | static struct acpi_object_list *__cpuinit acpi_processor_alloc_pdc(void) |
239 | { | 239 | { |
240 | struct acpi_object_list *obj_list; | 240 | struct acpi_object_list *obj_list; |
241 | union acpi_object *obj; | 241 | union acpi_object *obj; |
@@ -278,12 +278,12 @@ static struct acpi_object_list *acpi_processor_alloc_pdc(void) | |||
278 | * _PDC is required for a BIOS-OS handshake for most of the newer | 278 | * _PDC is required for a BIOS-OS handshake for most of the newer |
279 | * ACPI processor features. | 279 | * ACPI processor features. |
280 | */ | 280 | */ |
281 | static int | 281 | static int __cpuinit |
282 | acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) | 282 | acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) |
283 | { | 283 | { |
284 | acpi_status status = AE_OK; | 284 | acpi_status status = AE_OK; |
285 | 285 | ||
286 | if (idle_nomwait) { | 286 | if (boot_option_idle_override == IDLE_NOMWAIT) { |
287 | /* | 287 | /* |
288 | * If mwait is disabled for CPU C-states, the C2C3_FFH access | 288 | * If mwait is disabled for CPU C-states, the C2C3_FFH access |
289 | * mode will be disabled in the parameter of _PDC object. | 289 | * mode will be disabled in the parameter of _PDC object. |
@@ -306,7 +306,7 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) | |||
306 | return status; | 306 | return status; |
307 | } | 307 | } |
308 | 308 | ||
309 | void acpi_processor_set_pdc(acpi_handle handle) | 309 | void __cpuinit acpi_processor_set_pdc(acpi_handle handle) |
310 | { | 310 | { |
311 | struct acpi_object_list *obj_list; | 311 | struct acpi_object_list *obj_list; |
312 | 312 | ||
@@ -323,9 +323,8 @@ void acpi_processor_set_pdc(acpi_handle handle) | |||
323 | kfree(obj_list->pointer); | 323 | kfree(obj_list->pointer); |
324 | kfree(obj_list); | 324 | kfree(obj_list); |
325 | } | 325 | } |
326 | EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); | ||
327 | 326 | ||
328 | static acpi_status | 327 | static acpi_status __init |
329 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) | 328 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) |
330 | { | 329 | { |
331 | if (processor_physically_present(handle) == false) | 330 | if (processor_physically_present(handle) == false) |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 85e48047d7b..a4e0f1ba604 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -40,10 +40,6 @@ | |||
40 | #include <linux/pm.h> | 40 | #include <linux/pm.h> |
41 | #include <linux/cpufreq.h> | 41 | #include <linux/cpufreq.h> |
42 | #include <linux/cpu.h> | 42 | #include <linux/cpu.h> |
43 | #ifdef CONFIG_ACPI_PROCFS | ||
44 | #include <linux/proc_fs.h> | ||
45 | #include <linux/seq_file.h> | ||
46 | #endif | ||
47 | #include <linux/dmi.h> | 43 | #include <linux/dmi.h> |
48 | #include <linux/moduleparam.h> | 44 | #include <linux/moduleparam.h> |
49 | #include <linux/cpuidle.h> | 45 | #include <linux/cpuidle.h> |
@@ -246,53 +242,6 @@ static int acpi_processor_errata(struct acpi_processor *pr) | |||
246 | return result; | 242 | return result; |
247 | } | 243 | } |
248 | 244 | ||
249 | #ifdef CONFIG_ACPI_PROCFS | ||
250 | static struct proc_dir_entry *acpi_processor_dir = NULL; | ||
251 | |||
252 | static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | ||
253 | { | ||
254 | struct proc_dir_entry *entry = NULL; | ||
255 | |||
256 | |||
257 | if (!acpi_device_dir(device)) { | ||
258 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
259 | acpi_processor_dir); | ||
260 | if (!acpi_device_dir(device)) | ||
261 | return -ENODEV; | ||
262 | } | ||
263 | |||
264 | /* 'throttling' [R/W] */ | ||
265 | entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, | ||
266 | S_IFREG | S_IRUGO | S_IWUSR, | ||
267 | acpi_device_dir(device), | ||
268 | &acpi_processor_throttling_fops, | ||
269 | acpi_driver_data(device)); | ||
270 | if (!entry) | ||
271 | return -EIO; | ||
272 | return 0; | ||
273 | } | ||
274 | static int acpi_processor_remove_fs(struct acpi_device *device) | ||
275 | { | ||
276 | |||
277 | if (acpi_device_dir(device)) { | ||
278 | remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, | ||
279 | acpi_device_dir(device)); | ||
280 | remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); | ||
281 | acpi_device_dir(device) = NULL; | ||
282 | } | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | #else | ||
287 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
288 | { | ||
289 | return 0; | ||
290 | } | ||
291 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
292 | { | ||
293 | return 0; | ||
294 | } | ||
295 | #endif | ||
296 | /* -------------------------------------------------------------------------- | 245 | /* -------------------------------------------------------------------------- |
297 | Driver Interface | 246 | Driver Interface |
298 | -------------------------------------------------------------------------- */ | 247 | -------------------------------------------------------------------------- */ |
@@ -478,8 +427,13 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, | |||
478 | if (action == CPU_ONLINE && pr) { | 427 | if (action == CPU_ONLINE && pr) { |
479 | acpi_processor_ppc_has_changed(pr, 0); | 428 | acpi_processor_ppc_has_changed(pr, 0); |
480 | acpi_processor_cst_has_changed(pr); | 429 | acpi_processor_cst_has_changed(pr); |
430 | acpi_processor_reevaluate_tstate(pr, action); | ||
481 | acpi_processor_tstate_has_changed(pr); | 431 | acpi_processor_tstate_has_changed(pr); |
482 | } | 432 | } |
433 | if (action == CPU_DEAD && pr) { | ||
434 | /* invalidate the flag.throttling after one CPU is offline */ | ||
435 | acpi_processor_reevaluate_tstate(pr, action); | ||
436 | } | ||
483 | return NOTIFY_OK; | 437 | return NOTIFY_OK; |
484 | } | 438 | } |
485 | 439 | ||
@@ -537,14 +491,10 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
537 | 491 | ||
538 | per_cpu(processors, pr->id) = pr; | 492 | per_cpu(processors, pr->id) = pr; |
539 | 493 | ||
540 | result = acpi_processor_add_fs(device); | ||
541 | if (result) | ||
542 | goto err_free_cpumask; | ||
543 | |||
544 | sysdev = get_cpu_sysdev(pr->id); | 494 | sysdev = get_cpu_sysdev(pr->id); |
545 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { | 495 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { |
546 | result = -EFAULT; | 496 | result = -EFAULT; |
547 | goto err_remove_fs; | 497 | goto err_free_cpumask; |
548 | } | 498 | } |
549 | 499 | ||
550 | #ifdef CONFIG_CPU_FREQ | 500 | #ifdef CONFIG_CPU_FREQ |
@@ -590,8 +540,6 @@ err_thermal_unregister: | |||
590 | thermal_cooling_device_unregister(pr->cdev); | 540 | thermal_cooling_device_unregister(pr->cdev); |
591 | err_power_exit: | 541 | err_power_exit: |
592 | acpi_processor_power_exit(pr, device); | 542 | acpi_processor_power_exit(pr, device); |
593 | err_remove_fs: | ||
594 | acpi_processor_remove_fs(device); | ||
595 | err_free_cpumask: | 543 | err_free_cpumask: |
596 | free_cpumask_var(pr->throttling.shared_cpu_map); | 544 | free_cpumask_var(pr->throttling.shared_cpu_map); |
597 | 545 | ||
@@ -620,8 +568,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type) | |||
620 | 568 | ||
621 | sysfs_remove_link(&device->dev.kobj, "sysdev"); | 569 | sysfs_remove_link(&device->dev.kobj, "sysdev"); |
622 | 570 | ||
623 | acpi_processor_remove_fs(device); | ||
624 | |||
625 | if (pr->cdev) { | 571 | if (pr->cdev) { |
626 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | 572 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); |
627 | sysfs_remove_link(&pr->cdev->device.kobj, "device"); | 573 | sysfs_remove_link(&pr->cdev->device.kobj, "device"); |
@@ -689,8 +635,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
689 | return 0; | 635 | return 0; |
690 | } | 636 | } |
691 | 637 | ||
692 | static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | 638 | static void acpi_processor_hotplug_notify(acpi_handle handle, |
693 | u32 event, void *data) | 639 | u32 event, void *data) |
694 | { | 640 | { |
695 | struct acpi_processor *pr; | 641 | struct acpi_processor *pr; |
696 | struct acpi_device *device = NULL; | 642 | struct acpi_device *device = NULL; |
@@ -854,12 +800,6 @@ static int __init acpi_processor_init(void) | |||
854 | 800 | ||
855 | memset(&errata, 0, sizeof(errata)); | 801 | memset(&errata, 0, sizeof(errata)); |
856 | 802 | ||
857 | #ifdef CONFIG_ACPI_PROCFS | ||
858 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
859 | if (!acpi_processor_dir) | ||
860 | return -ENOMEM; | ||
861 | #endif | ||
862 | |||
863 | if (!cpuidle_register_driver(&acpi_idle_driver)) { | 803 | if (!cpuidle_register_driver(&acpi_idle_driver)) { |
864 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", | 804 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
865 | acpi_idle_driver.name); | 805 | acpi_idle_driver.name); |
@@ -885,10 +825,6 @@ static int __init acpi_processor_init(void) | |||
885 | out_cpuidle: | 825 | out_cpuidle: |
886 | cpuidle_unregister_driver(&acpi_idle_driver); | 826 | cpuidle_unregister_driver(&acpi_idle_driver); |
887 | 827 | ||
888 | #ifdef CONFIG_ACPI_PROCFS | ||
889 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
890 | #endif | ||
891 | |||
892 | return result; | 828 | return result; |
893 | } | 829 | } |
894 | 830 | ||
@@ -907,10 +843,6 @@ static void __exit acpi_processor_exit(void) | |||
907 | 843 | ||
908 | cpuidle_unregister_driver(&acpi_idle_driver); | 844 | cpuidle_unregister_driver(&acpi_idle_driver); |
909 | 845 | ||
910 | #ifdef CONFIG_ACPI_PROCFS | ||
911 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
912 | #endif | ||
913 | |||
914 | return; | 846 | return; |
915 | } | 847 | } |
916 | 848 | ||
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index dcb38f8ddfd..d615b7d69bc 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -79,6 +79,13 @@ module_param(bm_check_disable, uint, 0000); | |||
79 | static unsigned int latency_factor __read_mostly = 2; | 79 | static unsigned int latency_factor __read_mostly = 2; |
80 | module_param(latency_factor, uint, 0644); | 80 | module_param(latency_factor, uint, 0644); |
81 | 81 | ||
82 | static int disabled_by_idle_boot_param(void) | ||
83 | { | ||
84 | return boot_option_idle_override == IDLE_POLL || | ||
85 | boot_option_idle_override == IDLE_FORCE_MWAIT || | ||
86 | boot_option_idle_override == IDLE_HALT; | ||
87 | } | ||
88 | |||
82 | /* | 89 | /* |
83 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. | 90 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. |
84 | * For now disable this. Probably a bug somewhere else. | 91 | * For now disable this. Probably a bug somewhere else. |
@@ -455,7 +462,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
455 | continue; | 462 | continue; |
456 | } | 463 | } |
457 | if (cx.type == ACPI_STATE_C1 && | 464 | if (cx.type == ACPI_STATE_C1 && |
458 | (idle_halt || idle_nomwait)) { | 465 | (boot_option_idle_override == IDLE_NOMWAIT)) { |
459 | /* | 466 | /* |
460 | * In most cases the C1 space_id obtained from | 467 | * In most cases the C1 space_id obtained from |
461 | * _CST object is FIXED_HARDWARE access mode. | 468 | * _CST object is FIXED_HARDWARE access mode. |
@@ -746,7 +753,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
746 | struct acpi_processor *pr; | 753 | struct acpi_processor *pr; |
747 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 754 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
748 | 755 | ||
749 | pr = __get_cpu_var(processors); | 756 | pr = __this_cpu_read(processors); |
750 | 757 | ||
751 | if (unlikely(!pr)) | 758 | if (unlikely(!pr)) |
752 | return 0; | 759 | return 0; |
@@ -787,7 +794,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
787 | s64 idle_time_ns; | 794 | s64 idle_time_ns; |
788 | s64 idle_time; | 795 | s64 idle_time; |
789 | 796 | ||
790 | pr = __get_cpu_var(processors); | 797 | pr = __this_cpu_read(processors); |
791 | 798 | ||
792 | if (unlikely(!pr)) | 799 | if (unlikely(!pr)) |
793 | return 0; | 800 | return 0; |
@@ -864,7 +871,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
864 | s64 idle_time; | 871 | s64 idle_time; |
865 | 872 | ||
866 | 873 | ||
867 | pr = __get_cpu_var(processors); | 874 | pr = __this_cpu_read(processors); |
868 | 875 | ||
869 | if (unlikely(!pr)) | 876 | if (unlikely(!pr)) |
870 | return 0; | 877 | return 0; |
@@ -1016,7 +1023,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1016 | state->flags = 0; | 1023 | state->flags = 0; |
1017 | switch (cx->type) { | 1024 | switch (cx->type) { |
1018 | case ACPI_STATE_C1: | 1025 | case ACPI_STATE_C1: |
1019 | state->flags |= CPUIDLE_FLAG_SHALLOW; | ||
1020 | if (cx->entry_method == ACPI_CSTATE_FFH) | 1026 | if (cx->entry_method == ACPI_CSTATE_FFH) |
1021 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | 1027 | state->flags |= CPUIDLE_FLAG_TIME_VALID; |
1022 | 1028 | ||
@@ -1025,16 +1031,13 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1025 | break; | 1031 | break; |
1026 | 1032 | ||
1027 | case ACPI_STATE_C2: | 1033 | case ACPI_STATE_C2: |
1028 | state->flags |= CPUIDLE_FLAG_BALANCED; | ||
1029 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | 1034 | state->flags |= CPUIDLE_FLAG_TIME_VALID; |
1030 | state->enter = acpi_idle_enter_simple; | 1035 | state->enter = acpi_idle_enter_simple; |
1031 | dev->safe_state = state; | 1036 | dev->safe_state = state; |
1032 | break; | 1037 | break; |
1033 | 1038 | ||
1034 | case ACPI_STATE_C3: | 1039 | case ACPI_STATE_C3: |
1035 | state->flags |= CPUIDLE_FLAG_DEEP; | ||
1036 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | 1040 | state->flags |= CPUIDLE_FLAG_TIME_VALID; |
1037 | state->flags |= CPUIDLE_FLAG_CHECK_BM; | ||
1038 | state->enter = pr->flags.bm_check ? | 1041 | state->enter = pr->flags.bm_check ? |
1039 | acpi_idle_enter_bm : | 1042 | acpi_idle_enter_bm : |
1040 | acpi_idle_enter_simple; | 1043 | acpi_idle_enter_simple; |
@@ -1058,7 +1061,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
1058 | { | 1061 | { |
1059 | int ret = 0; | 1062 | int ret = 0; |
1060 | 1063 | ||
1061 | if (boot_option_idle_override) | 1064 | if (disabled_by_idle_boot_param()) |
1062 | return 0; | 1065 | return 0; |
1063 | 1066 | ||
1064 | if (!pr) | 1067 | if (!pr) |
@@ -1089,19 +1092,10 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1089 | acpi_status status = 0; | 1092 | acpi_status status = 0; |
1090 | static int first_run; | 1093 | static int first_run; |
1091 | 1094 | ||
1092 | if (boot_option_idle_override) | 1095 | if (disabled_by_idle_boot_param()) |
1093 | return 0; | 1096 | return 0; |
1094 | 1097 | ||
1095 | if (!first_run) { | 1098 | if (!first_run) { |
1096 | if (idle_halt) { | ||
1097 | /* | ||
1098 | * When the boot option of "idle=halt" is added, halt | ||
1099 | * is used for CPU IDLE. | ||
1100 | * In such case C2/C3 is meaningless. So the max_cstate | ||
1101 | * is set to one. | ||
1102 | */ | ||
1103 | max_cstate = 1; | ||
1104 | } | ||
1105 | dmi_check_system(processor_power_dmi_table); | 1099 | dmi_check_system(processor_power_dmi_table); |
1106 | max_cstate = acpi_processor_cstate_check(max_cstate); | 1100 | max_cstate = acpi_processor_cstate_check(max_cstate); |
1107 | if (max_cstate < ACPI_C_STATES_MAX) | 1101 | if (max_cstate < ACPI_C_STATES_MAX) |
@@ -1142,7 +1136,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1142 | int acpi_processor_power_exit(struct acpi_processor *pr, | 1136 | int acpi_processor_power_exit(struct acpi_processor *pr, |
1143 | struct acpi_device *device) | 1137 | struct acpi_device *device) |
1144 | { | 1138 | { |
1145 | if (boot_option_idle_override) | 1139 | if (disabled_by_idle_boot_param()) |
1146 | return 0; | 1140 | return 0; |
1147 | 1141 | ||
1148 | cpuidle_unregister_device(&pr->power.dev); | 1142 | cpuidle_unregister_device(&pr->power.dev); |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index fde49b9b1d9..79cb6533289 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int acpi_thermal_cpufreq_increase(unsigned int cpu) | ||
160 | { | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | static int acpi_thermal_cpufreq_decrease(unsigned int cpu) | ||
164 | { | ||
165 | return -ENODEV; | ||
166 | } | ||
167 | |||
168 | #endif | 159 | #endif |
169 | 160 | ||
170 | int acpi_processor_get_limit_info(struct acpi_processor *pr) | 161 | int acpi_processor_get_limit_info(struct acpi_processor *pr) |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index ff3632717c5..ad350173956 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -32,10 +32,6 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/cpufreq.h> | 34 | #include <linux/cpufreq.h> |
35 | #ifdef CONFIG_ACPI_PROCFS | ||
36 | #include <linux/proc_fs.h> | ||
37 | #include <linux/seq_file.h> | ||
38 | #endif | ||
39 | 35 | ||
40 | #include <asm/io.h> | 36 | #include <asm/io.h> |
41 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
@@ -370,6 +366,58 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr) | |||
370 | } | 366 | } |
371 | 367 | ||
372 | /* | 368 | /* |
369 | * This function is used to reevaluate whether the T-state is valid | ||
370 | * after one CPU is onlined/offlined. | ||
371 | * It is noted that it won't reevaluate the following properties for | ||
372 | * the T-state. | ||
373 | * 1. Control method. | ||
374 | * 2. the number of supported T-state | ||
375 | * 3. TSD domain | ||
376 | */ | ||
377 | void acpi_processor_reevaluate_tstate(struct acpi_processor *pr, | ||
378 | unsigned long action) | ||
379 | { | ||
380 | int result = 0; | ||
381 | |||
382 | if (action == CPU_DEAD) { | ||
383 | /* When one CPU is offline, the T-state throttling | ||
384 | * will be invalidated. | ||
385 | */ | ||
386 | pr->flags.throttling = 0; | ||
387 | return; | ||
388 | } | ||
389 | /* the following is to recheck whether the T-state is valid for | ||
390 | * the online CPU | ||
391 | */ | ||
392 | if (!pr->throttling.state_count) { | ||
393 | /* If the number of T-state is invalid, it is | ||
394 | * invalidated. | ||
395 | */ | ||
396 | pr->flags.throttling = 0; | ||
397 | return; | ||
398 | } | ||
399 | pr->flags.throttling = 1; | ||
400 | |||
401 | /* Disable throttling (if enabled). We'll let subsequent | ||
402 | * policy (e.g.thermal) decide to lower performance if it | ||
403 | * so chooses, but for now we'll crank up the speed. | ||
404 | */ | ||
405 | |||
406 | result = acpi_processor_get_throttling(pr); | ||
407 | if (result) | ||
408 | goto end; | ||
409 | |||
410 | if (pr->throttling.state) { | ||
411 | result = acpi_processor_set_throttling(pr, 0, false); | ||
412 | if (result) | ||
413 | goto end; | ||
414 | } | ||
415 | |||
416 | end: | ||
417 | if (result) | ||
418 | pr->flags.throttling = 0; | ||
419 | } | ||
420 | /* | ||
373 | * _PTC - Processor Throttling Control (and status) register location | 421 | * _PTC - Processor Throttling Control (and status) register location |
374 | */ | 422 | */ |
375 | static int acpi_processor_get_throttling_control(struct acpi_processor *pr) | 423 | static int acpi_processor_get_throttling_control(struct acpi_processor *pr) |
@@ -876,7 +924,11 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr) | |||
876 | */ | 924 | */ |
877 | cpumask_copy(saved_mask, ¤t->cpus_allowed); | 925 | cpumask_copy(saved_mask, ¤t->cpus_allowed); |
878 | /* FIXME: use work_on_cpu() */ | 926 | /* FIXME: use work_on_cpu() */ |
879 | set_cpus_allowed_ptr(current, cpumask_of(pr->id)); | 927 | if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) { |
928 | /* Can't migrate to the target pr->id CPU. Exit */ | ||
929 | free_cpumask_var(saved_mask); | ||
930 | return -ENODEV; | ||
931 | } | ||
880 | ret = pr->throttling.acpi_processor_get_throttling(pr); | 932 | ret = pr->throttling.acpi_processor_get_throttling(pr); |
881 | /* restore the previous state */ | 933 | /* restore the previous state */ |
882 | set_cpus_allowed_ptr(current, saved_mask); | 934 | set_cpus_allowed_ptr(current, saved_mask); |
@@ -1051,6 +1103,14 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1051 | return -ENOMEM; | 1103 | return -ENOMEM; |
1052 | } | 1104 | } |
1053 | 1105 | ||
1106 | if (cpu_is_offline(pr->id)) { | ||
1107 | /* | ||
1108 | * the cpu pointed by pr->id is offline. Unnecessary to change | ||
1109 | * the throttling state any more. | ||
1110 | */ | ||
1111 | return -ENODEV; | ||
1112 | } | ||
1113 | |||
1054 | cpumask_copy(saved_mask, ¤t->cpus_allowed); | 1114 | cpumask_copy(saved_mask, ¤t->cpus_allowed); |
1055 | t_state.target_state = state; | 1115 | t_state.target_state = state; |
1056 | p_throttling = &(pr->throttling); | 1116 | p_throttling = &(pr->throttling); |
@@ -1074,7 +1134,11 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1074 | */ | 1134 | */ |
1075 | if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { | 1135 | if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { |
1076 | /* FIXME: use work_on_cpu() */ | 1136 | /* FIXME: use work_on_cpu() */ |
1077 | set_cpus_allowed_ptr(current, cpumask_of(pr->id)); | 1137 | if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) { |
1138 | /* Can't migrate to the pr->id CPU. Exit */ | ||
1139 | ret = -ENODEV; | ||
1140 | goto exit; | ||
1141 | } | ||
1078 | ret = p_throttling->acpi_processor_set_throttling(pr, | 1142 | ret = p_throttling->acpi_processor_set_throttling(pr, |
1079 | t_state.target_state, force); | 1143 | t_state.target_state, force); |
1080 | } else { | 1144 | } else { |
@@ -1100,13 +1164,14 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1100 | */ | 1164 | */ |
1101 | if (!match_pr->flags.throttling) { | 1165 | if (!match_pr->flags.throttling) { |
1102 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1166 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
1103 | "Throttling Controll is unsupported " | 1167 | "Throttling Control is unsupported " |
1104 | "on CPU %d\n", i)); | 1168 | "on CPU %d\n", i)); |
1105 | continue; | 1169 | continue; |
1106 | } | 1170 | } |
1107 | t_state.cpu = i; | 1171 | t_state.cpu = i; |
1108 | /* FIXME: use work_on_cpu() */ | 1172 | /* FIXME: use work_on_cpu() */ |
1109 | set_cpus_allowed_ptr(current, cpumask_of(i)); | 1173 | if (set_cpus_allowed_ptr(current, cpumask_of(i))) |
1174 | continue; | ||
1110 | ret = match_pr->throttling. | 1175 | ret = match_pr->throttling. |
1111 | acpi_processor_set_throttling( | 1176 | acpi_processor_set_throttling( |
1112 | match_pr, t_state.target_state, force); | 1177 | match_pr, t_state.target_state, force); |
@@ -1126,6 +1191,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1126 | /* restore the previous state */ | 1191 | /* restore the previous state */ |
1127 | /* FIXME: use work_on_cpu() */ | 1192 | /* FIXME: use work_on_cpu() */ |
1128 | set_cpus_allowed_ptr(current, saved_mask); | 1193 | set_cpus_allowed_ptr(current, saved_mask); |
1194 | exit: | ||
1129 | free_cpumask_var(online_throttling_cpus); | 1195 | free_cpumask_var(online_throttling_cpus); |
1130 | free_cpumask_var(saved_mask); | 1196 | free_cpumask_var(saved_mask); |
1131 | return ret; | 1197 | return ret; |
@@ -1216,113 +1282,3 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
1216 | return result; | 1282 | return result; |
1217 | } | 1283 | } |
1218 | 1284 | ||
1219 | #ifdef CONFIG_ACPI_PROCFS | ||
1220 | /* proc interface */ | ||
1221 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, | ||
1222 | void *offset) | ||
1223 | { | ||
1224 | struct acpi_processor *pr = seq->private; | ||
1225 | int i = 0; | ||
1226 | int result = 0; | ||
1227 | |||
1228 | if (!pr) | ||
1229 | goto end; | ||
1230 | |||
1231 | if (!(pr->throttling.state_count > 0)) { | ||
1232 | seq_puts(seq, "<not supported>\n"); | ||
1233 | goto end; | ||
1234 | } | ||
1235 | |||
1236 | result = acpi_processor_get_throttling(pr); | ||
1237 | |||
1238 | if (result) { | ||
1239 | seq_puts(seq, | ||
1240 | "Could not determine current throttling state.\n"); | ||
1241 | goto end; | ||
1242 | } | ||
1243 | |||
1244 | seq_printf(seq, "state count: %d\n" | ||
1245 | "active state: T%d\n" | ||
1246 | "state available: T%d to T%d\n", | ||
1247 | pr->throttling.state_count, pr->throttling.state, | ||
1248 | pr->throttling_platform_limit, | ||
1249 | pr->throttling.state_count - 1); | ||
1250 | |||
1251 | seq_puts(seq, "states:\n"); | ||
1252 | if (pr->throttling.acpi_processor_get_throttling == | ||
1253 | acpi_processor_get_throttling_fadt) { | ||
1254 | for (i = 0; i < pr->throttling.state_count; i++) | ||
1255 | seq_printf(seq, " %cT%d: %02d%%\n", | ||
1256 | (i == pr->throttling.state ? '*' : ' '), i, | ||
1257 | (pr->throttling.states[i].performance ? pr-> | ||
1258 | throttling.states[i].performance / 10 : 0)); | ||
1259 | } else { | ||
1260 | for (i = 0; i < pr->throttling.state_count; i++) | ||
1261 | seq_printf(seq, " %cT%d: %02d%%\n", | ||
1262 | (i == pr->throttling.state ? '*' : ' '), i, | ||
1263 | (int)pr->throttling.states_tss[i]. | ||
1264 | freqpercentage); | ||
1265 | } | ||
1266 | |||
1267 | end: | ||
1268 | return 0; | ||
1269 | } | ||
1270 | |||
1271 | static int acpi_processor_throttling_open_fs(struct inode *inode, | ||
1272 | struct file *file) | ||
1273 | { | ||
1274 | return single_open(file, acpi_processor_throttling_seq_show, | ||
1275 | PDE(inode)->data); | ||
1276 | } | ||
1277 | |||
1278 | static ssize_t acpi_processor_write_throttling(struct file *file, | ||
1279 | const char __user * buffer, | ||
1280 | size_t count, loff_t * data) | ||
1281 | { | ||
1282 | int result = 0; | ||
1283 | struct seq_file *m = file->private_data; | ||
1284 | struct acpi_processor *pr = m->private; | ||
1285 | char state_string[5] = ""; | ||
1286 | char *charp = NULL; | ||
1287 | size_t state_val = 0; | ||
1288 | char tmpbuf[5] = ""; | ||
1289 | |||
1290 | if (!pr || (count > sizeof(state_string) - 1)) | ||
1291 | return -EINVAL; | ||
1292 | |||
1293 | if (copy_from_user(state_string, buffer, count)) | ||
1294 | return -EFAULT; | ||
1295 | |||
1296 | state_string[count] = '\0'; | ||
1297 | if ((count > 0) && (state_string[count-1] == '\n')) | ||
1298 | state_string[count-1] = '\0'; | ||
1299 | |||
1300 | charp = state_string; | ||
1301 | if ((state_string[0] == 't') || (state_string[0] == 'T')) | ||
1302 | charp++; | ||
1303 | |||
1304 | state_val = simple_strtoul(charp, NULL, 0); | ||
1305 | if (state_val >= pr->throttling.state_count) | ||
1306 | return -EINVAL; | ||
1307 | |||
1308 | snprintf(tmpbuf, 5, "%zu", state_val); | ||
1309 | |||
1310 | if (strcmp(tmpbuf, charp) != 0) | ||
1311 | return -EINVAL; | ||
1312 | |||
1313 | result = acpi_processor_set_throttling(pr, state_val, false); | ||
1314 | if (result) | ||
1315 | return result; | ||
1316 | |||
1317 | return count; | ||
1318 | } | ||
1319 | |||
1320 | const struct file_operations acpi_processor_throttling_fops = { | ||
1321 | .owner = THIS_MODULE, | ||
1322 | .open = acpi_processor_throttling_open_fs, | ||
1323 | .read = seq_read, | ||
1324 | .write = acpi_processor_write_throttling, | ||
1325 | .llseek = seq_lseek, | ||
1326 | .release = single_release, | ||
1327 | }; | ||
1328 | #endif | ||
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index 93f91142d7a..a6c77e8b37b 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c | |||
@@ -15,9 +15,15 @@ void acpi_reboot(void) | |||
15 | 15 | ||
16 | rr = &acpi_gbl_FADT.reset_register; | 16 | rr = &acpi_gbl_FADT.reset_register; |
17 | 17 | ||
18 | /* Is the reset register supported? */ | 18 | /* ACPI reset register was only introduced with v2 of the FADT */ |
19 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || | 19 | |
20 | rr->bit_width != 8 || rr->bit_offset != 0) | 20 | if (acpi_gbl_FADT.header.revision < 2) |
21 | return; | ||
22 | |||
23 | /* Is the reset register supported? The spec says we should be | ||
24 | * checking the bit width and bit offset, but Windows ignores | ||
25 | * these fields */ | ||
26 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) | ||
21 | return; | 27 | return; |
22 | 28 | ||
23 | reset_value = acpi_gbl_FADT.reset_value; | 29 | reset_value = acpi_gbl_FADT.reset_value; |
@@ -45,6 +51,4 @@ void acpi_reboot(void) | |||
45 | acpi_reset(); | 51 | acpi_reset(); |
46 | break; | 52 | break; |
47 | } | 53 | } |
48 | /* Wait ten seconds */ | ||
49 | acpi_os_stall(10000000); | ||
50 | } | 54 | } |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index e5dbedb16bb..51ae3794ec7 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -484,6 +484,8 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir, | |||
484 | const struct file_operations *state_fops, | 484 | const struct file_operations *state_fops, |
485 | const struct file_operations *alarm_fops, void *data) | 485 | const struct file_operations *alarm_fops, void *data) |
486 | { | 486 | { |
487 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for SBS is loaded," | ||
488 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
487 | if (!*dir) { | 489 | if (!*dir) { |
488 | *dir = proc_mkdir(dir_name, parent_dir); | 490 | *dir = proc_mkdir(dir_name, parent_dir); |
489 | if (!*dir) { | 491 | if (!*dir) { |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 2b6c21d86b9..449c556274c 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -705,54 +705,85 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device) | |||
705 | } | 705 | } |
706 | 706 | ||
707 | static acpi_status | 707 | static acpi_status |
708 | acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, | 708 | acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, |
709 | union acpi_object *package) | 709 | struct acpi_device_wakeup *wakeup) |
710 | { | 710 | { |
711 | int i = 0; | 711 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
712 | union acpi_object *package = NULL; | ||
712 | union acpi_object *element = NULL; | 713 | union acpi_object *element = NULL; |
714 | acpi_status status; | ||
715 | int i = 0; | ||
713 | 716 | ||
714 | if (!device || !package || (package->package.count < 2)) | 717 | if (!wakeup) |
715 | return AE_BAD_PARAMETER; | 718 | return AE_BAD_PARAMETER; |
716 | 719 | ||
720 | /* _PRW */ | ||
721 | status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer); | ||
722 | if (ACPI_FAILURE(status)) { | ||
723 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); | ||
724 | return status; | ||
725 | } | ||
726 | |||
727 | package = (union acpi_object *)buffer.pointer; | ||
728 | |||
729 | if (!package || (package->package.count < 2)) { | ||
730 | status = AE_BAD_DATA; | ||
731 | goto out; | ||
732 | } | ||
733 | |||
717 | element = &(package->package.elements[0]); | 734 | element = &(package->package.elements[0]); |
718 | if (!element) | 735 | if (!element) { |
719 | return AE_BAD_PARAMETER; | 736 | status = AE_BAD_DATA; |
737 | goto out; | ||
738 | } | ||
720 | if (element->type == ACPI_TYPE_PACKAGE) { | 739 | if (element->type == ACPI_TYPE_PACKAGE) { |
721 | if ((element->package.count < 2) || | 740 | if ((element->package.count < 2) || |
722 | (element->package.elements[0].type != | 741 | (element->package.elements[0].type != |
723 | ACPI_TYPE_LOCAL_REFERENCE) | 742 | ACPI_TYPE_LOCAL_REFERENCE) |
724 | || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) | 743 | || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) { |
725 | return AE_BAD_DATA; | 744 | status = AE_BAD_DATA; |
726 | device->wakeup.gpe_device = | 745 | goto out; |
746 | } | ||
747 | wakeup->gpe_device = | ||
727 | element->package.elements[0].reference.handle; | 748 | element->package.elements[0].reference.handle; |
728 | device->wakeup.gpe_number = | 749 | wakeup->gpe_number = |
729 | (u32) element->package.elements[1].integer.value; | 750 | (u32) element->package.elements[1].integer.value; |
730 | } else if (element->type == ACPI_TYPE_INTEGER) { | 751 | } else if (element->type == ACPI_TYPE_INTEGER) { |
731 | device->wakeup.gpe_number = element->integer.value; | 752 | wakeup->gpe_device = NULL; |
732 | } else | 753 | wakeup->gpe_number = element->integer.value; |
733 | return AE_BAD_DATA; | 754 | } else { |
755 | status = AE_BAD_DATA; | ||
756 | goto out; | ||
757 | } | ||
734 | 758 | ||
735 | element = &(package->package.elements[1]); | 759 | element = &(package->package.elements[1]); |
736 | if (element->type != ACPI_TYPE_INTEGER) { | 760 | if (element->type != ACPI_TYPE_INTEGER) { |
737 | return AE_BAD_DATA; | 761 | status = AE_BAD_DATA; |
762 | goto out; | ||
738 | } | 763 | } |
739 | device->wakeup.sleep_state = element->integer.value; | 764 | wakeup->sleep_state = element->integer.value; |
740 | 765 | ||
741 | if ((package->package.count - 2) > ACPI_MAX_HANDLES) { | 766 | if ((package->package.count - 2) > ACPI_MAX_HANDLES) { |
742 | return AE_NO_MEMORY; | 767 | status = AE_NO_MEMORY; |
768 | goto out; | ||
743 | } | 769 | } |
744 | device->wakeup.resources.count = package->package.count - 2; | 770 | wakeup->resources.count = package->package.count - 2; |
745 | for (i = 0; i < device->wakeup.resources.count; i++) { | 771 | for (i = 0; i < wakeup->resources.count; i++) { |
746 | element = &(package->package.elements[i + 2]); | 772 | element = &(package->package.elements[i + 2]); |
747 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) | 773 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { |
748 | return AE_BAD_DATA; | 774 | status = AE_BAD_DATA; |
775 | goto out; | ||
776 | } | ||
749 | 777 | ||
750 | device->wakeup.resources.handles[i] = element->reference.handle; | 778 | wakeup->resources.handles[i] = element->reference.handle; |
751 | } | 779 | } |
752 | 780 | ||
753 | acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); | 781 | acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number); |
754 | 782 | ||
755 | return AE_OK; | 783 | out: |
784 | kfree(buffer.pointer); | ||
785 | |||
786 | return status; | ||
756 | } | 787 | } |
757 | 788 | ||
758 | static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | 789 | static void acpi_bus_set_run_wake_flags(struct acpi_device *device) |
@@ -766,13 +797,12 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
766 | acpi_status status; | 797 | acpi_status status; |
767 | acpi_event_status event_status; | 798 | acpi_event_status event_status; |
768 | 799 | ||
769 | device->wakeup.run_wake_count = 0; | ||
770 | device->wakeup.flags.notifier_present = 0; | 800 | device->wakeup.flags.notifier_present = 0; |
771 | 801 | ||
772 | /* Power button, Lid switch always enable wakeup */ | 802 | /* Power button, Lid switch always enable wakeup */ |
773 | if (!acpi_match_device_ids(device, button_device_ids)) { | 803 | if (!acpi_match_device_ids(device, button_device_ids)) { |
774 | device->wakeup.flags.run_wake = 1; | 804 | device->wakeup.flags.run_wake = 1; |
775 | device->wakeup.flags.always_enabled = 1; | 805 | device_set_wakeup_capable(&device->dev, true); |
776 | return; | 806 | return; |
777 | } | 807 | } |
778 | 808 | ||
@@ -784,29 +814,24 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
784 | !!(event_status & ACPI_EVENT_FLAG_HANDLE); | 814 | !!(event_status & ACPI_EVENT_FLAG_HANDLE); |
785 | } | 815 | } |
786 | 816 | ||
787 | static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | 817 | static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) |
788 | { | 818 | { |
819 | acpi_handle temp; | ||
789 | acpi_status status = 0; | 820 | acpi_status status = 0; |
790 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
791 | union acpi_object *package = NULL; | ||
792 | int psw_error; | 821 | int psw_error; |
793 | 822 | ||
794 | /* _PRW */ | 823 | /* Presence of _PRW indicates wake capable */ |
795 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); | 824 | status = acpi_get_handle(device->handle, "_PRW", &temp); |
796 | if (ACPI_FAILURE(status)) { | 825 | if (ACPI_FAILURE(status)) |
797 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); | 826 | return; |
798 | goto end; | ||
799 | } | ||
800 | 827 | ||
801 | package = (union acpi_object *)buffer.pointer; | 828 | status = acpi_bus_extract_wakeup_device_power_package(device->handle, |
802 | status = acpi_bus_extract_wakeup_device_power_package(device, package); | 829 | &device->wakeup); |
803 | if (ACPI_FAILURE(status)) { | 830 | if (ACPI_FAILURE(status)) { |
804 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); | 831 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); |
805 | goto end; | 832 | return; |
806 | } | 833 | } |
807 | 834 | ||
808 | kfree(buffer.pointer); | ||
809 | |||
810 | device->wakeup.flags.valid = 1; | 835 | device->wakeup.flags.valid = 1; |
811 | device->wakeup.prepare_count = 0; | 836 | device->wakeup.prepare_count = 0; |
812 | acpi_bus_set_run_wake_flags(device); | 837 | acpi_bus_set_run_wake_flags(device); |
@@ -820,13 +845,10 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
820 | if (psw_error) | 845 | if (psw_error) |
821 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 846 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
822 | "error in _DSW or _PSW evaluation\n")); | 847 | "error in _DSW or _PSW evaluation\n")); |
823 | |||
824 | end: | ||
825 | if (ACPI_FAILURE(status)) | ||
826 | device->flags.wake_capable = 0; | ||
827 | return 0; | ||
828 | } | 848 | } |
829 | 849 | ||
850 | static void acpi_bus_add_power_resource(acpi_handle handle); | ||
851 | |||
830 | static int acpi_bus_get_power_flags(struct acpi_device *device) | 852 | static int acpi_bus_get_power_flags(struct acpi_device *device) |
831 | { | 853 | { |
832 | acpi_status status = 0; | 854 | acpi_status status = 0; |
@@ -855,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
855 | acpi_evaluate_reference(device->handle, object_name, NULL, | 877 | acpi_evaluate_reference(device->handle, object_name, NULL, |
856 | &ps->resources); | 878 | &ps->resources); |
857 | if (ps->resources.count) { | 879 | if (ps->resources.count) { |
880 | int j; | ||
881 | |||
858 | device->power.flags.power_resources = 1; | 882 | device->power.flags.power_resources = 1; |
859 | ps->flags.valid = 1; | 883 | ps->flags.valid = 1; |
884 | for (j = 0; j < ps->resources.count; j++) | ||
885 | acpi_bus_add_power_resource(ps->resources.handles[j]); | ||
860 | } | 886 | } |
861 | 887 | ||
862 | /* Evaluate "_PSx" to see if we can do explicit sets */ | 888 | /* Evaluate "_PSx" to see if we can do explicit sets */ |
@@ -881,10 +907,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
881 | device->power.states[ACPI_STATE_D3].flags.valid = 1; | 907 | device->power.states[ACPI_STATE_D3].flags.valid = 1; |
882 | device->power.states[ACPI_STATE_D3].power = 0; | 908 | device->power.states[ACPI_STATE_D3].power = 0; |
883 | 909 | ||
884 | /* TBD: System wake support and resource requirements. */ | 910 | acpi_bus_init_power(device); |
885 | |||
886 | device->power.state = ACPI_STATE_UNKNOWN; | ||
887 | acpi_bus_get_power(device->handle, &(device->power.state)); | ||
888 | 911 | ||
889 | return 0; | 912 | return 0; |
890 | } | 913 | } |
@@ -920,6 +943,10 @@ static int acpi_bus_get_flags(struct acpi_device *device) | |||
920 | if (ACPI_SUCCESS(status)) | 943 | if (ACPI_SUCCESS(status)) |
921 | device->flags.lockable = 1; | 944 | device->flags.lockable = 1; |
922 | 945 | ||
946 | /* Power resources cannot be power manageable. */ | ||
947 | if (device->device_type == ACPI_BUS_TYPE_POWER) | ||
948 | return 0; | ||
949 | |||
923 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ | 950 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ |
924 | status = acpi_get_handle(device->handle, "_PS0", &temp); | 951 | status = acpi_get_handle(device->handle, "_PS0", &temp); |
925 | if (ACPI_FAILURE(status)) | 952 | if (ACPI_FAILURE(status)) |
@@ -927,11 +954,6 @@ static int acpi_bus_get_flags(struct acpi_device *device) | |||
927 | if (ACPI_SUCCESS(status)) | 954 | if (ACPI_SUCCESS(status)) |
928 | device->flags.power_manageable = 1; | 955 | device->flags.power_manageable = 1; |
929 | 956 | ||
930 | /* Presence of _PRW indicates wake capable */ | ||
931 | status = acpi_get_handle(device->handle, "_PRW", &temp); | ||
932 | if (ACPI_SUCCESS(status)) | ||
933 | device->flags.wake_capable = 1; | ||
934 | |||
935 | /* TBD: Performance management */ | 957 | /* TBD: Performance management */ |
936 | 958 | ||
937 | return 0; | 959 | return 0; |
@@ -1258,11 +1280,7 @@ static int acpi_add_single_object(struct acpi_device **child, | |||
1258 | * Wakeup device management | 1280 | * Wakeup device management |
1259 | *----------------------- | 1281 | *----------------------- |
1260 | */ | 1282 | */ |
1261 | if (device->flags.wake_capable) { | 1283 | acpi_bus_get_wakeup_device_flags(device); |
1262 | result = acpi_bus_get_wakeup_device_flags(device); | ||
1263 | if (result) | ||
1264 | goto end; | ||
1265 | } | ||
1266 | 1284 | ||
1267 | /* | 1285 | /* |
1268 | * Performance Management | 1286 | * Performance Management |
@@ -1306,6 +1324,20 @@ end: | |||
1306 | #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ | 1324 | #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ |
1307 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) | 1325 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) |
1308 | 1326 | ||
1327 | static void acpi_bus_add_power_resource(acpi_handle handle) | ||
1328 | { | ||
1329 | struct acpi_bus_ops ops = { | ||
1330 | .acpi_op_add = 1, | ||
1331 | .acpi_op_start = 1, | ||
1332 | }; | ||
1333 | struct acpi_device *device = NULL; | ||
1334 | |||
1335 | acpi_bus_get_device(handle, &device); | ||
1336 | if (!device) | ||
1337 | acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER, | ||
1338 | ACPI_STA_DEFAULT, &ops); | ||
1339 | } | ||
1340 | |||
1309 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, | 1341 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, |
1310 | unsigned long long *sta) | 1342 | unsigned long long *sta) |
1311 | { | 1343 | { |
@@ -1360,8 +1392,16 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | |||
1360 | return AE_OK; | 1392 | return AE_OK; |
1361 | 1393 | ||
1362 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && | 1394 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && |
1363 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) | 1395 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { |
1396 | struct acpi_device_wakeup wakeup; | ||
1397 | acpi_handle temp; | ||
1398 | |||
1399 | status = acpi_get_handle(handle, "_PRW", &temp); | ||
1400 | if (ACPI_SUCCESS(status)) | ||
1401 | acpi_bus_extract_wakeup_device_power_package(handle, | ||
1402 | &wakeup); | ||
1364 | return AE_CTRL_DEPTH; | 1403 | return AE_CTRL_DEPTH; |
1404 | } | ||
1365 | 1405 | ||
1366 | /* | 1406 | /* |
1367 | * We may already have an acpi_device from a previous enumeration. If | 1407 | * We may already have an acpi_device from a previous enumeration. If |
@@ -1444,7 +1484,7 @@ int acpi_bus_start(struct acpi_device *device) | |||
1444 | 1484 | ||
1445 | result = acpi_bus_scan(device->handle, &ops, NULL); | 1485 | result = acpi_bus_scan(device->handle, &ops, NULL); |
1446 | 1486 | ||
1447 | acpi_update_gpes(); | 1487 | acpi_update_all_gpes(); |
1448 | 1488 | ||
1449 | return result; | 1489 | return result; |
1450 | } | 1490 | } |
@@ -1550,6 +1590,8 @@ int __init acpi_scan_init(void) | |||
1550 | printk(KERN_ERR PREFIX "Could not register bus type\n"); | 1590 | printk(KERN_ERR PREFIX "Could not register bus type\n"); |
1551 | } | 1591 | } |
1552 | 1592 | ||
1593 | acpi_power_init(); | ||
1594 | |||
1553 | /* | 1595 | /* |
1554 | * Enumerate devices in the ACPI namespace. | 1596 | * Enumerate devices in the ACPI namespace. |
1555 | */ | 1597 | */ |
@@ -1561,7 +1603,7 @@ int __init acpi_scan_init(void) | |||
1561 | if (result) | 1603 | if (result) |
1562 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1604 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
1563 | else | 1605 | else |
1564 | acpi_update_gpes(); | 1606 | acpi_update_all_gpes(); |
1565 | 1607 | ||
1566 | return result; | 1608 | return result; |
1567 | } | 1609 | } |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721d93b3cee..6c949602cbd 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/suspend.h> | 17 | #include <linux/suspend.h> |
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/acpi.h> | ||
19 | 20 | ||
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
21 | 22 | ||
@@ -27,8 +28,6 @@ | |||
27 | 28 | ||
28 | static u8 sleep_states[ACPI_S_STATE_COUNT]; | 29 | static u8 sleep_states[ACPI_S_STATE_COUNT]; |
29 | 30 | ||
30 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
31 | |||
32 | static void acpi_sleep_tts_switch(u32 acpi_state) | 31 | static void acpi_sleep_tts_switch(u32 acpi_state) |
33 | { | 32 | { |
34 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; | 33 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; |
@@ -81,6 +80,8 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
81 | } | 80 | } |
82 | 81 | ||
83 | #ifdef CONFIG_ACPI_SLEEP | 82 | #ifdef CONFIG_ACPI_SLEEP |
83 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
84 | |||
84 | /* | 85 | /* |
85 | * The ACPI specification wants us to save NVS memory regions during hibernation | 86 | * The ACPI specification wants us to save NVS memory regions during hibernation |
86 | * and to restore them during the subsequent resume. Windows does that also for | 87 | * and to restore them during the subsequent resume. Windows does that also for |
@@ -124,8 +125,7 @@ static int acpi_pm_freeze(void) | |||
124 | static int acpi_pm_pre_suspend(void) | 125 | static int acpi_pm_pre_suspend(void) |
125 | { | 126 | { |
126 | acpi_pm_freeze(); | 127 | acpi_pm_freeze(); |
127 | suspend_nvs_save(); | 128 | return suspend_nvs_save(); |
128 | return 0; | ||
129 | } | 129 | } |
130 | 130 | ||
131 | /** | 131 | /** |
@@ -151,7 +151,7 @@ static int acpi_pm_prepare(void) | |||
151 | { | 151 | { |
152 | int error = __acpi_pm_prepare(); | 152 | int error = __acpi_pm_prepare(); |
153 | if (!error) | 153 | if (!error) |
154 | acpi_pm_pre_suspend(); | 154 | error = acpi_pm_pre_suspend(); |
155 | 155 | ||
156 | return error; | 156 | return error; |
157 | } | 157 | } |
@@ -167,6 +167,7 @@ static void acpi_pm_finish(void) | |||
167 | u32 acpi_state = acpi_target_sleep_state; | 167 | u32 acpi_state = acpi_target_sleep_state; |
168 | 168 | ||
169 | acpi_ec_unblock_transactions(); | 169 | acpi_ec_unblock_transactions(); |
170 | suspend_nvs_free(); | ||
170 | 171 | ||
171 | if (acpi_state == ACPI_STATE_S0) | 172 | if (acpi_state == ACPI_STATE_S0) |
172 | return; | 173 | return; |
@@ -187,7 +188,6 @@ static void acpi_pm_finish(void) | |||
187 | */ | 188 | */ |
188 | static void acpi_pm_end(void) | 189 | static void acpi_pm_end(void) |
189 | { | 190 | { |
190 | suspend_nvs_free(); | ||
191 | /* | 191 | /* |
192 | * This is necessary in case acpi_pm_finish() is not called during a | 192 | * This is necessary in case acpi_pm_finish() is not called during a |
193 | * failing transition to a sleep state. | 193 | * failing transition to a sleep state. |
@@ -200,8 +200,6 @@ static void acpi_pm_end(void) | |||
200 | #endif /* CONFIG_ACPI_SLEEP */ | 200 | #endif /* CONFIG_ACPI_SLEEP */ |
201 | 201 | ||
202 | #ifdef CONFIG_SUSPEND | 202 | #ifdef CONFIG_SUSPEND |
203 | extern void do_suspend_lowlevel(void); | ||
204 | |||
205 | static u32 acpi_suspend_states[] = { | 203 | static u32 acpi_suspend_states[] = { |
206 | [PM_SUSPEND_ON] = ACPI_STATE_S0, | 204 | [PM_SUSPEND_ON] = ACPI_STATE_S0, |
207 | [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, | 205 | [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, |
@@ -244,20 +242,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state) | |||
244 | static int acpi_suspend_enter(suspend_state_t pm_state) | 242 | static int acpi_suspend_enter(suspend_state_t pm_state) |
245 | { | 243 | { |
246 | acpi_status status = AE_OK; | 244 | acpi_status status = AE_OK; |
247 | unsigned long flags = 0; | ||
248 | u32 acpi_state = acpi_target_sleep_state; | 245 | u32 acpi_state = acpi_target_sleep_state; |
246 | int error; | ||
249 | 247 | ||
250 | ACPI_FLUSH_CPU_CACHE(); | 248 | ACPI_FLUSH_CPU_CACHE(); |
251 | 249 | ||
252 | /* Do arch specific saving of state. */ | ||
253 | if (acpi_state == ACPI_STATE_S3) { | ||
254 | int error = acpi_save_state_mem(); | ||
255 | |||
256 | if (error) | ||
257 | return error; | ||
258 | } | ||
259 | |||
260 | local_irq_save(flags); | ||
261 | switch (acpi_state) { | 250 | switch (acpi_state) { |
262 | case ACPI_STATE_S1: | 251 | case ACPI_STATE_S1: |
263 | barrier(); | 252 | barrier(); |
@@ -265,7 +254,10 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
265 | break; | 254 | break; |
266 | 255 | ||
267 | case ACPI_STATE_S3: | 256 | case ACPI_STATE_S3: |
268 | do_suspend_lowlevel(); | 257 | error = acpi_suspend_lowlevel(); |
258 | if (error) | ||
259 | return error; | ||
260 | pr_info(PREFIX "Low-level resume complete\n"); | ||
269 | break; | 261 | break; |
270 | } | 262 | } |
271 | 263 | ||
@@ -291,13 +283,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
291 | /* Allow EC transactions to happen. */ | 283 | /* Allow EC transactions to happen. */ |
292 | acpi_ec_unblock_transactions_early(); | 284 | acpi_ec_unblock_transactions_early(); |
293 | 285 | ||
294 | local_irq_restore(flags); | ||
295 | printk(KERN_DEBUG "Back to C!\n"); | ||
296 | |||
297 | /* restore processor state */ | ||
298 | if (acpi_state == ACPI_STATE_S3) | ||
299 | acpi_restore_state_mem(); | ||
300 | |||
301 | suspend_nvs_restore(); | 286 | suspend_nvs_restore(); |
302 | 287 | ||
303 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 288 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
@@ -319,7 +304,7 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state) | |||
319 | } | 304 | } |
320 | } | 305 | } |
321 | 306 | ||
322 | static struct platform_suspend_ops acpi_suspend_ops = { | 307 | static const struct platform_suspend_ops acpi_suspend_ops = { |
323 | .valid = acpi_suspend_state_valid, | 308 | .valid = acpi_suspend_state_valid, |
324 | .begin = acpi_suspend_begin, | 309 | .begin = acpi_suspend_begin, |
325 | .prepare_late = acpi_pm_prepare, | 310 | .prepare_late = acpi_pm_prepare, |
@@ -347,7 +332,7 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) | |||
347 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has | 332 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has |
348 | * been requested. | 333 | * been requested. |
349 | */ | 334 | */ |
350 | static struct platform_suspend_ops acpi_suspend_ops_old = { | 335 | static const struct platform_suspend_ops acpi_suspend_ops_old = { |
351 | .valid = acpi_suspend_state_valid, | 336 | .valid = acpi_suspend_state_valid, |
352 | .begin = acpi_suspend_begin_old, | 337 | .begin = acpi_suspend_begin_old, |
353 | .prepare_late = acpi_pm_pre_suspend, | 338 | .prepare_late = acpi_pm_pre_suspend, |
@@ -427,6 +412,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
427 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), | 412 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), |
428 | }, | 413 | }, |
429 | }, | 414 | }, |
415 | { | ||
416 | .callback = init_nvs_nosave, | ||
417 | .ident = "Sony Vaio VGN-NW130D", | ||
418 | .matches = { | ||
419 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
420 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), | ||
421 | }, | ||
422 | }, | ||
423 | { | ||
424 | .callback = init_nvs_nosave, | ||
425 | .ident = "Averatec AV1020-ED2", | ||
426 | .matches = { | ||
427 | DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"), | ||
428 | DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"), | ||
429 | }, | ||
430 | }, | ||
430 | {}, | 431 | {}, |
431 | }; | 432 | }; |
432 | #endif /* CONFIG_SUSPEND */ | 433 | #endif /* CONFIG_SUSPEND */ |
@@ -457,16 +458,13 @@ static int acpi_hibernation_begin(void) | |||
457 | static int acpi_hibernation_enter(void) | 458 | static int acpi_hibernation_enter(void) |
458 | { | 459 | { |
459 | acpi_status status = AE_OK; | 460 | acpi_status status = AE_OK; |
460 | unsigned long flags = 0; | ||
461 | 461 | ||
462 | ACPI_FLUSH_CPU_CACHE(); | 462 | ACPI_FLUSH_CPU_CACHE(); |
463 | 463 | ||
464 | local_irq_save(flags); | ||
465 | /* This shouldn't return. If it returns, we have a problem */ | 464 | /* This shouldn't return. If it returns, we have a problem */ |
466 | status = acpi_enter_sleep_state(ACPI_STATE_S4); | 465 | status = acpi_enter_sleep_state(ACPI_STATE_S4); |
467 | /* Reprogram control registers and execute _BFS */ | 466 | /* Reprogram control registers and execute _BFS */ |
468 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | 467 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
469 | local_irq_restore(flags); | ||
470 | 468 | ||
471 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 469 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
472 | } | 470 | } |
@@ -498,7 +496,7 @@ static void acpi_pm_thaw(void) | |||
498 | acpi_enable_all_runtime_gpes(); | 496 | acpi_enable_all_runtime_gpes(); |
499 | } | 497 | } |
500 | 498 | ||
501 | static struct platform_hibernation_ops acpi_hibernation_ops = { | 499 | static const struct platform_hibernation_ops acpi_hibernation_ops = { |
502 | .begin = acpi_hibernation_begin, | 500 | .begin = acpi_hibernation_begin, |
503 | .end = acpi_pm_end, | 501 | .end = acpi_pm_end, |
504 | .pre_snapshot = acpi_pm_prepare, | 502 | .pre_snapshot = acpi_pm_prepare, |
@@ -541,7 +539,7 @@ static int acpi_hibernation_begin_old(void) | |||
541 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has | 539 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has |
542 | * been requested. | 540 | * been requested. |
543 | */ | 541 | */ |
544 | static struct platform_hibernation_ops acpi_hibernation_ops_old = { | 542 | static const struct platform_hibernation_ops acpi_hibernation_ops_old = { |
545 | .begin = acpi_hibernation_begin_old, | 543 | .begin = acpi_hibernation_begin_old, |
546 | .end = acpi_pm_end, | 544 | .end = acpi_pm_end, |
547 | .pre_snapshot = acpi_pm_pre_suspend, | 545 | .pre_snapshot = acpi_pm_pre_suspend, |
@@ -570,7 +568,7 @@ int acpi_suspend(u32 acpi_state) | |||
570 | return -EINVAL; | 568 | return -EINVAL; |
571 | } | 569 | } |
572 | 570 | ||
573 | #ifdef CONFIG_PM_OPS | 571 | #ifdef CONFIG_PM |
574 | /** | 572 | /** |
575 | * acpi_pm_device_sleep_state - return preferred power state of ACPI device | 573 | * acpi_pm_device_sleep_state - return preferred power state of ACPI device |
576 | * in the system sleep state given by %acpi_target_sleep_state | 574 | * in the system sleep state given by %acpi_target_sleep_state |
@@ -656,7 +654,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) | |||
656 | *d_min_p = d_min; | 654 | *d_min_p = d_min; |
657 | return d_max; | 655 | return d_max; |
658 | } | 656 | } |
659 | #endif /* CONFIG_PM_OPS */ | 657 | #endif /* CONFIG_PM */ |
660 | 658 | ||
661 | #ifdef CONFIG_PM_SLEEP | 659 | #ifdef CONFIG_PM_SLEEP |
662 | /** | 660 | /** |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index f8588f81048..61891e75583 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -438,7 +438,7 @@ static void delete_gpe_attr_array(void) | |||
438 | return; | 438 | return; |
439 | } | 439 | } |
440 | 440 | ||
441 | void acpi_os_gpe_count(u32 gpe_number) | 441 | static void gpe_count(u32 gpe_number) |
442 | { | 442 | { |
443 | acpi_gpe_count++; | 443 | acpi_gpe_count++; |
444 | 444 | ||
@@ -454,7 +454,7 @@ void acpi_os_gpe_count(u32 gpe_number) | |||
454 | return; | 454 | return; |
455 | } | 455 | } |
456 | 456 | ||
457 | void acpi_os_fixed_event_count(u32 event_number) | 457 | static void fixed_event_count(u32 event_number) |
458 | { | 458 | { |
459 | if (!all_counters) | 459 | if (!all_counters) |
460 | return; | 460 | return; |
@@ -468,6 +468,16 @@ void acpi_os_fixed_event_count(u32 event_number) | |||
468 | return; | 468 | return; |
469 | } | 469 | } |
470 | 470 | ||
471 | static void acpi_gbl_event_handler(u32 event_type, acpi_handle device, | ||
472 | u32 event_number, void *context) | ||
473 | { | ||
474 | if (event_type == ACPI_EVENT_TYPE_GPE) | ||
475 | gpe_count(event_number); | ||
476 | |||
477 | if (event_type == ACPI_EVENT_TYPE_FIXED) | ||
478 | fixed_event_count(event_number); | ||
479 | } | ||
480 | |||
471 | static int get_status(u32 index, acpi_event_status *status, | 481 | static int get_status(u32 index, acpi_event_status *status, |
472 | acpi_handle *handle) | 482 | acpi_handle *handle) |
473 | { | 483 | { |
@@ -601,6 +611,7 @@ end: | |||
601 | 611 | ||
602 | void acpi_irq_stats_init(void) | 612 | void acpi_irq_stats_init(void) |
603 | { | 613 | { |
614 | acpi_status status; | ||
604 | int i; | 615 | int i; |
605 | 616 | ||
606 | if (all_counters) | 617 | if (all_counters) |
@@ -619,6 +630,10 @@ void acpi_irq_stats_init(void) | |||
619 | if (all_counters == NULL) | 630 | if (all_counters == NULL) |
620 | goto fail; | 631 | goto fail; |
621 | 632 | ||
633 | status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL); | ||
634 | if (ACPI_FAILURE(status)) | ||
635 | goto fail; | ||
636 | |||
622 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), | 637 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), |
623 | GFP_KERNEL); | 638 | GFP_KERNEL); |
624 | if (counter_attrs == NULL) | 639 | if (counter_attrs == NULL) |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 5a27b0a3131..2607e17b520 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -1059,8 +1059,9 @@ static int acpi_thermal_resume(struct acpi_device *device) | |||
1059 | break; | 1059 | break; |
1060 | tz->trips.active[i].flags.enabled = 1; | 1060 | tz->trips.active[i].flags.enabled = 1; |
1061 | for (j = 0; j < tz->trips.active[i].devices.count; j++) { | 1061 | for (j = 0; j < tz->trips.active[i].devices.count; j++) { |
1062 | result = acpi_bus_get_power(tz->trips.active[i].devices. | 1062 | result = acpi_bus_update_power( |
1063 | handles[j], &power_state); | 1063 | tz->trips.active[i].devices.handles[j], |
1064 | &power_state); | ||
1064 | if (result || (power_state != ACPI_STATE_D0)) { | 1065 | if (result || (power_state != ACPI_STATE_D0)) { |
1065 | tz->trips.active[i].flags.enabled = 0; | 1066 | tz->trips.active[i].flags.enabled = 0; |
1066 | break; | 1067 | break; |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5cd0228d2da..ec574fc8fbc 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/input.h> | 33 | #include <linux/input.h> |
34 | #include <linux/backlight.h> | 34 | #include <linux/backlight.h> |
35 | #include <linux/thermal.h> | 35 | #include <linux/thermal.h> |
36 | #include <linux/video_output.h> | ||
37 | #include <linux/sort.h> | 36 | #include <linux/sort.h> |
38 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
39 | #include <linux/pci_ids.h> | 38 | #include <linux/pci_ids.h> |
@@ -81,6 +80,13 @@ module_param(brightness_switch_enabled, bool, 0644); | |||
81 | static int allow_duplicates; | 80 | static int allow_duplicates; |
82 | module_param(allow_duplicates, bool, 0644); | 81 | module_param(allow_duplicates, bool, 0644); |
83 | 82 | ||
83 | /* | ||
84 | * Some BIOSes claim they use minimum backlight at boot, | ||
85 | * and this may bring dimming screen after boot | ||
86 | */ | ||
87 | static int use_bios_initial_backlight = 1; | ||
88 | module_param(use_bios_initial_backlight, bool, 0644); | ||
89 | |||
84 | static int register_count = 0; | 90 | static int register_count = 0; |
85 | static int acpi_video_bus_add(struct acpi_device *device); | 91 | static int acpi_video_bus_add(struct acpi_device *device); |
86 | static int acpi_video_bus_remove(struct acpi_device *device, int type); | 92 | static int acpi_video_bus_remove(struct acpi_device *device, int type); |
@@ -172,9 +178,6 @@ struct acpi_video_device_cap { | |||
172 | u8 _BQC:1; /* Get current brightness level */ | 178 | u8 _BQC:1; /* Get current brightness level */ |
173 | u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ | 179 | u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ |
174 | u8 _DDC:1; /*Return the EDID for this device */ | 180 | u8 _DDC:1; /*Return the EDID for this device */ |
175 | u8 _DCS:1; /*Return status of output device */ | ||
176 | u8 _DGS:1; /*Query graphics state */ | ||
177 | u8 _DSS:1; /*Device state set */ | ||
178 | }; | 181 | }; |
179 | 182 | ||
180 | struct acpi_video_brightness_flags { | 183 | struct acpi_video_brightness_flags { |
@@ -202,7 +205,6 @@ struct acpi_video_device { | |||
202 | struct acpi_video_device_brightness *brightness; | 205 | struct acpi_video_device_brightness *brightness; |
203 | struct backlight_device *backlight; | 206 | struct backlight_device *backlight; |
204 | struct thermal_cooling_device *cooling_dev; | 207 | struct thermal_cooling_device *cooling_dev; |
205 | struct output_device *output_dev; | ||
206 | }; | 208 | }; |
207 | 209 | ||
208 | static const char device_decode[][30] = { | 210 | static const char device_decode[][30] = { |
@@ -226,10 +228,6 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, | |||
226 | u32 level_current, u32 event); | 228 | u32 level_current, u32 event); |
227 | static int acpi_video_switch_brightness(struct acpi_video_device *device, | 229 | static int acpi_video_switch_brightness(struct acpi_video_device *device, |
228 | int event); | 230 | int event); |
229 | static int acpi_video_device_get_state(struct acpi_video_device *device, | ||
230 | unsigned long long *state); | ||
231 | static int acpi_video_output_get(struct output_device *od); | ||
232 | static int acpi_video_device_set_state(struct acpi_video_device *device, int state); | ||
233 | 231 | ||
234 | /*backlight device sysfs support*/ | 232 | /*backlight device sysfs support*/ |
235 | static int acpi_video_get_brightness(struct backlight_device *bd) | 233 | static int acpi_video_get_brightness(struct backlight_device *bd) |
@@ -260,35 +258,11 @@ static int acpi_video_set_brightness(struct backlight_device *bd) | |||
260 | vd->brightness->levels[request_level]); | 258 | vd->brightness->levels[request_level]); |
261 | } | 259 | } |
262 | 260 | ||
263 | static struct backlight_ops acpi_backlight_ops = { | 261 | static const struct backlight_ops acpi_backlight_ops = { |
264 | .get_brightness = acpi_video_get_brightness, | 262 | .get_brightness = acpi_video_get_brightness, |
265 | .update_status = acpi_video_set_brightness, | 263 | .update_status = acpi_video_set_brightness, |
266 | }; | 264 | }; |
267 | 265 | ||
268 | /*video output device sysfs support*/ | ||
269 | static int acpi_video_output_get(struct output_device *od) | ||
270 | { | ||
271 | unsigned long long state; | ||
272 | struct acpi_video_device *vd = | ||
273 | (struct acpi_video_device *)dev_get_drvdata(&od->dev); | ||
274 | acpi_video_device_get_state(vd, &state); | ||
275 | return (int)state; | ||
276 | } | ||
277 | |||
278 | static int acpi_video_output_set(struct output_device *od) | ||
279 | { | ||
280 | unsigned long state = od->request_state; | ||
281 | struct acpi_video_device *vd= | ||
282 | (struct acpi_video_device *)dev_get_drvdata(&od->dev); | ||
283 | return acpi_video_device_set_state(vd, state); | ||
284 | } | ||
285 | |||
286 | static struct output_properties acpi_output_properties = { | ||
287 | .set_state = acpi_video_output_set, | ||
288 | .get_status = acpi_video_output_get, | ||
289 | }; | ||
290 | |||
291 | |||
292 | /* thermal cooling device callbacks */ | 266 | /* thermal cooling device callbacks */ |
293 | static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned | 267 | static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned |
294 | long *state) | 268 | long *state) |
@@ -344,34 +318,6 @@ static struct thermal_cooling_device_ops video_cooling_ops = { | |||
344 | Video Management | 318 | Video Management |
345 | -------------------------------------------------------------------------- */ | 319 | -------------------------------------------------------------------------- */ |
346 | 320 | ||
347 | /* device */ | ||
348 | |||
349 | static int | ||
350 | acpi_video_device_get_state(struct acpi_video_device *device, | ||
351 | unsigned long long *state) | ||
352 | { | ||
353 | int status; | ||
354 | |||
355 | status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state); | ||
356 | |||
357 | return status; | ||
358 | } | ||
359 | |||
360 | static int | ||
361 | acpi_video_device_set_state(struct acpi_video_device *device, int state) | ||
362 | { | ||
363 | int status; | ||
364 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
365 | struct acpi_object_list args = { 1, &arg0 }; | ||
366 | unsigned long long ret; | ||
367 | |||
368 | |||
369 | arg0.integer.value = state; | ||
370 | status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret); | ||
371 | |||
372 | return status; | ||
373 | } | ||
374 | |||
375 | static int | 321 | static int |
376 | acpi_video_device_lcd_query_levels(struct acpi_video_device *device, | 322 | acpi_video_device_lcd_query_levels(struct acpi_video_device *device, |
377 | union acpi_object **levels) | 323 | union acpi_object **levels) |
@@ -766,9 +712,11 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
766 | * when invoked for the first time, i.e. level_old is invalid. | 712 | * when invoked for the first time, i.e. level_old is invalid. |
767 | * set the backlight to max_level in this case | 713 | * set the backlight to max_level in this case |
768 | */ | 714 | */ |
769 | for (i = 2; i < br->count; i++) | 715 | if (use_bios_initial_backlight) { |
770 | if (level_old == br->levels[i]) | 716 | for (i = 2; i < br->count; i++) |
771 | level = level_old; | 717 | if (level_old == br->levels[i]) |
718 | level = level_old; | ||
719 | } | ||
772 | goto set_level; | 720 | goto set_level; |
773 | } | 721 | } |
774 | 722 | ||
@@ -831,18 +779,12 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
831 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { | 779 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { |
832 | device->cap._DDC = 1; | 780 | device->cap._DDC = 1; |
833 | } | 781 | } |
834 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) { | ||
835 | device->cap._DCS = 1; | ||
836 | } | ||
837 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) { | ||
838 | device->cap._DGS = 1; | ||
839 | } | ||
840 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) { | ||
841 | device->cap._DSS = 1; | ||
842 | } | ||
843 | 782 | ||
844 | if (acpi_video_backlight_support()) { | 783 | if (acpi_video_backlight_support()) { |
845 | struct backlight_properties props; | 784 | struct backlight_properties props; |
785 | struct pci_dev *pdev; | ||
786 | acpi_handle acpi_parent; | ||
787 | struct device *parent = NULL; | ||
846 | int result; | 788 | int result; |
847 | static int count = 0; | 789 | static int count = 0; |
848 | char *name; | 790 | char *name; |
@@ -855,9 +797,20 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
855 | return; | 797 | return; |
856 | count++; | 798 | count++; |
857 | 799 | ||
800 | acpi_get_parent(device->dev->handle, &acpi_parent); | ||
801 | |||
802 | pdev = acpi_get_pci_dev(acpi_parent); | ||
803 | if (pdev) { | ||
804 | parent = &pdev->dev; | ||
805 | pci_dev_put(pdev); | ||
806 | } | ||
807 | |||
858 | memset(&props, 0, sizeof(struct backlight_properties)); | 808 | memset(&props, 0, sizeof(struct backlight_properties)); |
809 | props.type = BACKLIGHT_FIRMWARE; | ||
859 | props.max_brightness = device->brightness->count - 3; | 810 | props.max_brightness = device->brightness->count - 3; |
860 | device->backlight = backlight_device_register(name, NULL, device, | 811 | device->backlight = backlight_device_register(name, |
812 | parent, | ||
813 | device, | ||
861 | &acpi_backlight_ops, | 814 | &acpi_backlight_ops, |
862 | &props); | 815 | &props); |
863 | kfree(name); | 816 | kfree(name); |
@@ -871,11 +824,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
871 | device->backlight->props.brightness = | 824 | device->backlight->props.brightness = |
872 | acpi_video_get_brightness(device->backlight); | 825 | acpi_video_get_brightness(device->backlight); |
873 | 826 | ||
874 | result = sysfs_create_link(&device->backlight->dev.kobj, | ||
875 | &device->dev->dev.kobj, "device"); | ||
876 | if (result) | ||
877 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
878 | |||
879 | device->cooling_dev = thermal_cooling_device_register("LCD", | 827 | device->cooling_dev = thermal_cooling_device_register("LCD", |
880 | device->dev, &video_cooling_ops); | 828 | device->dev, &video_cooling_ops); |
881 | if (IS_ERR(device->cooling_dev)) { | 829 | if (IS_ERR(device->cooling_dev)) { |
@@ -904,21 +852,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
904 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 852 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
905 | 853 | ||
906 | } | 854 | } |
907 | |||
908 | if (acpi_video_display_switch_support()) { | ||
909 | |||
910 | if (device->cap._DCS && device->cap._DSS) { | ||
911 | static int count; | ||
912 | char *name; | ||
913 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); | ||
914 | if (!name) | ||
915 | return; | ||
916 | count++; | ||
917 | device->output_dev = video_output_register(name, | ||
918 | NULL, device, &acpi_output_properties); | ||
919 | kfree(name); | ||
920 | } | ||
921 | } | ||
922 | } | 855 | } |
923 | 856 | ||
924 | /* | 857 | /* |
@@ -1360,6 +1293,9 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, | |||
1360 | if (!video_device) | 1293 | if (!video_device) |
1361 | continue; | 1294 | continue; |
1362 | 1295 | ||
1296 | if (!video_device->cap._DDC) | ||
1297 | continue; | ||
1298 | |||
1363 | if (type) { | 1299 | if (type) { |
1364 | switch (type) { | 1300 | switch (type) { |
1365 | case ACPI_VIDEO_DISPLAY_CRT: | 1301 | case ACPI_VIDEO_DISPLAY_CRT: |
@@ -1418,7 +1354,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, | |||
1418 | status = acpi_video_bus_get_one_device(dev, video); | 1354 | status = acpi_video_bus_get_one_device(dev, video); |
1419 | if (ACPI_FAILURE(status)) { | 1355 | if (ACPI_FAILURE(status)) { |
1420 | printk(KERN_WARNING PREFIX | 1356 | printk(KERN_WARNING PREFIX |
1421 | "Cant attach device\n"); | 1357 | "Can't attach device\n"); |
1422 | continue; | 1358 | continue; |
1423 | } | 1359 | } |
1424 | } | 1360 | } |
@@ -1437,10 +1373,9 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1437 | acpi_video_device_notify); | 1373 | acpi_video_device_notify); |
1438 | if (ACPI_FAILURE(status)) { | 1374 | if (ACPI_FAILURE(status)) { |
1439 | printk(KERN_WARNING PREFIX | 1375 | printk(KERN_WARNING PREFIX |
1440 | "Cant remove video notify handler\n"); | 1376 | "Can't remove video notify handler\n"); |
1441 | } | 1377 | } |
1442 | if (device->backlight) { | 1378 | if (device->backlight) { |
1443 | sysfs_remove_link(&device->backlight->dev.kobj, "device"); | ||
1444 | backlight_device_unregister(device->backlight); | 1379 | backlight_device_unregister(device->backlight); |
1445 | device->backlight = NULL; | 1380 | device->backlight = NULL; |
1446 | } | 1381 | } |
@@ -1452,7 +1387,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1452 | thermal_cooling_device_unregister(device->cooling_dev); | 1387 | thermal_cooling_device_unregister(device->cooling_dev); |
1453 | device->cooling_dev = NULL; | 1388 | device->cooling_dev = NULL; |
1454 | } | 1389 | } |
1455 | video_output_unregister(device->output_dev); | ||
1456 | 1390 | ||
1457 | return 0; | 1391 | return 0; |
1458 | } | 1392 | } |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index b8367612659..5af3479714f 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -17,15 +17,14 @@ | |||
17 | * capabilities the graphics cards plugged in support. The check for general | 17 | * capabilities the graphics cards plugged in support. The check for general |
18 | * video capabilities will be triggered by the first caller of | 18 | * video capabilities will be triggered by the first caller of |
19 | * acpi_video_get_capabilities(NULL); which will happen when the first | 19 | * acpi_video_get_capabilities(NULL); which will happen when the first |
20 | * backlight (or display output) switching supporting driver calls: | 20 | * backlight switching supporting driver calls: |
21 | * acpi_video_backlight_support(); | 21 | * acpi_video_backlight_support(); |
22 | * | 22 | * |
23 | * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B) | 23 | * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B) |
24 | * are available, video.ko should be used to handle the device. | 24 | * are available, video.ko should be used to handle the device. |
25 | * | 25 | * |
26 | * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi, | 26 | * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi, |
27 | * sony_acpi,... can take care about backlight brightness and display output | 27 | * sony_acpi,... can take care about backlight brightness. |
28 | * switching. | ||
29 | * | 28 | * |
30 | * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m) | 29 | * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m) |
31 | * this file will not be compiled, acpi_video_get_capabilities() and | 30 | * this file will not be compiled, acpi_video_get_capabilities() and |
@@ -161,8 +160,6 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle) | |||
161 | * | 160 | * |
162 | * if (dmi_name_in_vendors("XY")) { | 161 | * if (dmi_name_in_vendors("XY")) { |
163 | * acpi_video_support |= | 162 | * acpi_video_support |= |
164 | * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR; | ||
165 | * acpi_video_support |= | ||
166 | * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; | 163 | * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; |
167 | *} | 164 | *} |
168 | */ | 165 | */ |
@@ -212,33 +209,8 @@ int acpi_video_backlight_support(void) | |||
212 | EXPORT_SYMBOL(acpi_video_backlight_support); | 209 | EXPORT_SYMBOL(acpi_video_backlight_support); |
213 | 210 | ||
214 | /* | 211 | /* |
215 | * Returns true if video.ko can do display output switching. | 212 | * Use acpi_backlight=vendor/video to force that backlight switching |
216 | * This does not work well/at all with binary graphics drivers | 213 | * is processed by vendor specific acpi drivers or video.ko driver. |
217 | * which disable system io ranges and do it on their own. | ||
218 | */ | ||
219 | int acpi_video_display_switch_support(void) | ||
220 | { | ||
221 | if (!acpi_video_caps_checked) | ||
222 | acpi_video_get_capabilities(NULL); | ||
223 | |||
224 | if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR) | ||
225 | return 0; | ||
226 | else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO) | ||
227 | return 1; | ||
228 | |||
229 | if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR) | ||
230 | return 0; | ||
231 | else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO) | ||
232 | return 1; | ||
233 | |||
234 | return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING; | ||
235 | } | ||
236 | EXPORT_SYMBOL(acpi_video_display_switch_support); | ||
237 | |||
238 | /* | ||
239 | * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video | ||
240 | * To force that backlight or display output switching is processed by vendor | ||
241 | * specific acpi drivers or video.ko driver. | ||
242 | */ | 214 | */ |
243 | static int __init acpi_backlight(char *str) | 215 | static int __init acpi_backlight(char *str) |
244 | { | 216 | { |
@@ -255,19 +227,3 @@ static int __init acpi_backlight(char *str) | |||
255 | return 1; | 227 | return 1; |
256 | } | 228 | } |
257 | __setup("acpi_backlight=", acpi_backlight); | 229 | __setup("acpi_backlight=", acpi_backlight); |
258 | |||
259 | static int __init acpi_display_output(char *str) | ||
260 | { | ||
261 | if (str == NULL || *str == '\0') | ||
262 | return 1; | ||
263 | else { | ||
264 | if (!strcmp("vendor", str)) | ||
265 | acpi_video_support |= | ||
266 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR; | ||
267 | if (!strcmp("video", str)) | ||
268 | acpi_video_support |= | ||
269 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; | ||
270 | } | ||
271 | return 1; | ||
272 | } | ||
273 | __setup("acpi_display_output=", acpi_display_output); | ||
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index f62a50c3ed3..7bfbe40bc43 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
@@ -37,15 +37,16 @@ void acpi_enable_wakeup_devices(u8 sleep_state) | |||
37 | container_of(node, struct acpi_device, wakeup_list); | 37 | container_of(node, struct acpi_device, wakeup_list); |
38 | 38 | ||
39 | if (!dev->wakeup.flags.valid | 39 | if (!dev->wakeup.flags.valid |
40 | || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) | 40 | || sleep_state > (u32) dev->wakeup.sleep_state |
41 | || sleep_state > (u32) dev->wakeup.sleep_state) | 41 | || !(device_may_wakeup(&dev->dev) |
42 | || dev->wakeup.prepare_count)) | ||
42 | continue; | 43 | continue; |
43 | 44 | ||
44 | if (dev->wakeup.state.enabled) | 45 | if (device_may_wakeup(&dev->dev)) |
45 | acpi_enable_wakeup_device_power(dev, sleep_state); | 46 | acpi_enable_wakeup_device_power(dev, sleep_state); |
46 | 47 | ||
47 | /* The wake-up power should have been enabled already. */ | 48 | /* The wake-up power should have been enabled already. */ |
48 | acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | 49 | acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
49 | ACPI_GPE_ENABLE); | 50 | ACPI_GPE_ENABLE); |
50 | } | 51 | } |
51 | } | 52 | } |
@@ -63,14 +64,15 @@ void acpi_disable_wakeup_devices(u8 sleep_state) | |||
63 | container_of(node, struct acpi_device, wakeup_list); | 64 | container_of(node, struct acpi_device, wakeup_list); |
64 | 65 | ||
65 | if (!dev->wakeup.flags.valid | 66 | if (!dev->wakeup.flags.valid |
66 | || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) | 67 | || sleep_state > (u32) dev->wakeup.sleep_state |
67 | || (sleep_state > (u32) dev->wakeup.sleep_state)) | 68 | || !(device_may_wakeup(&dev->dev) |
69 | || dev->wakeup.prepare_count)) | ||
68 | continue; | 70 | continue; |
69 | 71 | ||
70 | acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | 72 | acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
71 | ACPI_GPE_DISABLE); | 73 | ACPI_GPE_DISABLE); |
72 | 74 | ||
73 | if (dev->wakeup.state.enabled) | 75 | if (device_may_wakeup(&dev->dev)) |
74 | acpi_disable_wakeup_device_power(dev); | 76 | acpi_disable_wakeup_device_power(dev); |
75 | } | 77 | } |
76 | } | 78 | } |
@@ -84,8 +86,12 @@ int __init acpi_wakeup_device_init(void) | |||
84 | struct acpi_device *dev = container_of(node, | 86 | struct acpi_device *dev = container_of(node, |
85 | struct acpi_device, | 87 | struct acpi_device, |
86 | wakeup_list); | 88 | wakeup_list); |
87 | if (dev->wakeup.flags.always_enabled) | 89 | if (device_can_wakeup(&dev->dev)) { |
88 | dev->wakeup.state.enabled = 1; | 90 | /* Button GPEs are supposed to be always enabled. */ |
91 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
92 | dev->wakeup.gpe_number); | ||
93 | device_set_wakeup_enable(&dev->dev, true); | ||
94 | } | ||
89 | } | 95 | } |
90 | mutex_unlock(&acpi_device_lock); | 96 | mutex_unlock(&acpi_device_lock); |
91 | return 0; | 97 | return 0; |