Commit 864bdfb912e372670b5b2541dac9d273a4a7722a

Authored by Zhang Rui
Committed by Len Brown
1 parent 872aad45d6

ACPI: Export events via generic netlink

Upon ACPI events, send an "acpi_event" via Generic Netlink.
This is in addition to /proc/acpi/event, which remains intact for now.

Thanks to Jamal for his great help.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

Showing 3 changed files with 165 additions and 8 deletions Inline Diff

1 /* 1 /*
2 * acpi_bus.c - ACPI Bus Driver ($Revision: 80 $) 2 * acpi_bus.c - ACPI Bus Driver ($Revision: 80 $)
3 * 3 *
4 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 4 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5 * 5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at 10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version. 11 * your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, but 13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details. 16 * General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License along 18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc., 19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 * 21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */ 23 */
24 24
25 #include <linux/module.h> 25 #include <linux/module.h>
26 #include <linux/init.h> 26 #include <linux/init.h>
27 #include <linux/ioport.h> 27 #include <linux/ioport.h>
28 #include <linux/kernel.h> 28 #include <linux/kernel.h>
29 #include <linux/list.h> 29 #include <linux/list.h>
30 #include <linux/sched.h> 30 #include <linux/sched.h>
31 #include <linux/pm.h> 31 #include <linux/pm.h>
32 #include <linux/pm_legacy.h> 32 #include <linux/pm_legacy.h>
33 #include <linux/device.h> 33 #include <linux/device.h>
34 #include <linux/proc_fs.h> 34 #include <linux/proc_fs.h>
35 #ifdef CONFIG_X86 35 #ifdef CONFIG_X86
36 #include <asm/mpspec.h> 36 #include <asm/mpspec.h>
37 #endif 37 #endif
38 #include <acpi/acpi_bus.h> 38 #include <acpi/acpi_bus.h>
39 #include <acpi/acpi_drivers.h> 39 #include <acpi/acpi_drivers.h>
40 40
41 #define _COMPONENT ACPI_BUS_COMPONENT 41 #define _COMPONENT ACPI_BUS_COMPONENT
42 ACPI_MODULE_NAME("bus"); 42 ACPI_MODULE_NAME("bus");
43 #ifdef CONFIG_X86 43 #ifdef CONFIG_X86
44 extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); 44 extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
45 #endif 45 #endif
46 46
47 struct acpi_device *acpi_root; 47 struct acpi_device *acpi_root;
48 struct proc_dir_entry *acpi_root_dir; 48 struct proc_dir_entry *acpi_root_dir;
49 EXPORT_SYMBOL(acpi_root_dir); 49 EXPORT_SYMBOL(acpi_root_dir);
50 50
51 #define STRUCT_TO_INT(s) (*((int*)&s)) 51 #define STRUCT_TO_INT(s) (*((int*)&s))
52 52
53 /* -------------------------------------------------------------------------- 53 /* --------------------------------------------------------------------------
54 Device Management 54 Device Management
55 -------------------------------------------------------------------------- */ 55 -------------------------------------------------------------------------- */
56 56
57 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) 57 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
58 { 58 {
59 acpi_status status = AE_OK; 59 acpi_status status = AE_OK;
60 60
61 61
62 if (!device) 62 if (!device)
63 return -EINVAL; 63 return -EINVAL;
64 64
65 /* TBD: Support fixed-feature devices */ 65 /* TBD: Support fixed-feature devices */
66 66
67 status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device); 67 status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
68 if (ACPI_FAILURE(status) || !*device) { 68 if (ACPI_FAILURE(status) || !*device) {
69 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", 69 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
70 handle)); 70 handle));
71 return -ENODEV; 71 return -ENODEV;
72 } 72 }
73 73
74 return 0; 74 return 0;
75 } 75 }
76 76
77 EXPORT_SYMBOL(acpi_bus_get_device); 77 EXPORT_SYMBOL(acpi_bus_get_device);
78 78
79 int acpi_bus_get_status(struct acpi_device *device) 79 int acpi_bus_get_status(struct acpi_device *device)
80 { 80 {
81 acpi_status status = AE_OK; 81 acpi_status status = AE_OK;
82 unsigned long sta = 0; 82 unsigned long sta = 0;
83 83
84 84
85 if (!device) 85 if (!device)
86 return -EINVAL; 86 return -EINVAL;
87 87
88 /* 88 /*
89 * Evaluate _STA if present. 89 * Evaluate _STA if present.
90 */ 90 */
91 if (device->flags.dynamic_status) { 91 if (device->flags.dynamic_status) {
92 status = 92 status =
93 acpi_evaluate_integer(device->handle, "_STA", NULL, &sta); 93 acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
94 if (ACPI_FAILURE(status)) 94 if (ACPI_FAILURE(status))
95 return -ENODEV; 95 return -ENODEV;
96 STRUCT_TO_INT(device->status) = (int)sta; 96 STRUCT_TO_INT(device->status) = (int)sta;
97 } 97 }
98 98
99 /* 99 /*
100 * Otherwise we assume the status of our parent (unless we don't 100 * Otherwise we assume the status of our parent (unless we don't
101 * have one, in which case status is implied). 101 * have one, in which case status is implied).
102 */ 102 */
103 else if (device->parent) 103 else if (device->parent)
104 device->status = device->parent->status; 104 device->status = device->parent->status;
105 else 105 else
106 STRUCT_TO_INT(device->status) = 106 STRUCT_TO_INT(device->status) =
107 ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | 107 ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
108 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; 108 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING;
109 109
110 if (device->status.functional && !device->status.present) { 110 if (device->status.functional && !device->status.present) {
111 printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: " 111 printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
112 "functional but not present; setting present\n", 112 "functional but not present; setting present\n",
113 device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status)); 113 device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
114 device->status.present = 1; 114 device->status.present = 1;
115 } 115 }
116 116
117 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", 117 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
118 device->pnp.bus_id, 118 device->pnp.bus_id,
119 (u32) STRUCT_TO_INT(device->status))); 119 (u32) STRUCT_TO_INT(device->status)));
120 120
121 return 0; 121 return 0;
122 } 122 }
123 123
124 EXPORT_SYMBOL(acpi_bus_get_status); 124 EXPORT_SYMBOL(acpi_bus_get_status);
125 125
126 /* -------------------------------------------------------------------------- 126 /* --------------------------------------------------------------------------
127 Power Management 127 Power Management
128 -------------------------------------------------------------------------- */ 128 -------------------------------------------------------------------------- */
129 129
130 int acpi_bus_get_power(acpi_handle handle, int *state) 130 int acpi_bus_get_power(acpi_handle handle, int *state)
131 { 131 {
132 int result = 0; 132 int result = 0;
133 acpi_status status = 0; 133 acpi_status status = 0;
134 struct acpi_device *device = NULL; 134 struct acpi_device *device = NULL;
135 unsigned long psc = 0; 135 unsigned long psc = 0;
136 136
137 137
138 result = acpi_bus_get_device(handle, &device); 138 result = acpi_bus_get_device(handle, &device);
139 if (result) 139 if (result)
140 return result; 140 return result;
141 141
142 *state = ACPI_STATE_UNKNOWN; 142 *state = ACPI_STATE_UNKNOWN;
143 143
144 if (!device->flags.power_manageable) { 144 if (!device->flags.power_manageable) {
145 /* TBD: Non-recursive algorithm for walking up hierarchy */ 145 /* TBD: Non-recursive algorithm for walking up hierarchy */
146 if (device->parent) 146 if (device->parent)
147 *state = device->parent->power.state; 147 *state = device->parent->power.state;
148 else 148 else
149 *state = ACPI_STATE_D0; 149 *state = ACPI_STATE_D0;
150 } else { 150 } else {
151 /* 151 /*
152 * Get the device's power state either directly (via _PSC) or 152 * Get the device's power state either directly (via _PSC) or
153 * indirectly (via power resources). 153 * indirectly (via power resources).
154 */ 154 */
155 if (device->power.flags.explicit_get) { 155 if (device->power.flags.explicit_get) {
156 status = acpi_evaluate_integer(device->handle, "_PSC", 156 status = acpi_evaluate_integer(device->handle, "_PSC",
157 NULL, &psc); 157 NULL, &psc);
158 if (ACPI_FAILURE(status)) 158 if (ACPI_FAILURE(status))
159 return -ENODEV; 159 return -ENODEV;
160 device->power.state = (int)psc; 160 device->power.state = (int)psc;
161 } else if (device->power.flags.power_resources) { 161 } else if (device->power.flags.power_resources) {
162 result = acpi_power_get_inferred_state(device); 162 result = acpi_power_get_inferred_state(device);
163 if (result) 163 if (result)
164 return result; 164 return result;
165 } 165 }
166 166
167 *state = device->power.state; 167 *state = device->power.state;
168 } 168 }
169 169
170 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", 170 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
171 device->pnp.bus_id, device->power.state)); 171 device->pnp.bus_id, device->power.state));
172 172
173 return 0; 173 return 0;
174 } 174 }
175 175
176 EXPORT_SYMBOL(acpi_bus_get_power); 176 EXPORT_SYMBOL(acpi_bus_get_power);
177 177
178 int acpi_bus_set_power(acpi_handle handle, int state) 178 int acpi_bus_set_power(acpi_handle handle, int state)
179 { 179 {
180 int result = 0; 180 int result = 0;
181 acpi_status status = AE_OK; 181 acpi_status status = AE_OK;
182 struct acpi_device *device = NULL; 182 struct acpi_device *device = NULL;
183 char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; 183 char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
184 184
185 185
186 result = acpi_bus_get_device(handle, &device); 186 result = acpi_bus_get_device(handle, &device);
187 if (result) 187 if (result)
188 return result; 188 return result;
189 189
190 if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) 190 if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
191 return -EINVAL; 191 return -EINVAL;
192 192
193 /* Make sure this is a valid target state */ 193 /* Make sure this is a valid target state */
194 194
195 if (!device->flags.power_manageable) { 195 if (!device->flags.power_manageable) {
196 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", 196 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
197 device->dev.kobj.name)); 197 device->dev.kobj.name));
198 return -ENODEV; 198 return -ENODEV;
199 } 199 }
200 /* 200 /*
201 * Get device's current power state if it's unknown 201 * Get device's current power state if it's unknown
202 * This means device power state isn't initialized or previous setting failed 202 * This means device power state isn't initialized or previous setting failed
203 */ 203 */
204 if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state) 204 if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state)
205 acpi_bus_get_power(device->handle, &device->power.state); 205 acpi_bus_get_power(device->handle, &device->power.state);
206 if ((state == device->power.state) && !device->flags.force_power_state) { 206 if ((state == device->power.state) && !device->flags.force_power_state) {
207 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", 207 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
208 state)); 208 state));
209 return 0; 209 return 0;
210 } 210 }
211 211
212 if (!device->power.states[state].flags.valid) { 212 if (!device->power.states[state].flags.valid) {
213 printk(KERN_WARNING PREFIX "Device does not support D%d\n", state); 213 printk(KERN_WARNING PREFIX "Device does not support D%d\n", state);
214 return -ENODEV; 214 return -ENODEV;
215 } 215 }
216 if (device->parent && (state < device->parent->power.state)) { 216 if (device->parent && (state < device->parent->power.state)) {
217 printk(KERN_WARNING PREFIX 217 printk(KERN_WARNING PREFIX
218 "Cannot set device to a higher-powered" 218 "Cannot set device to a higher-powered"
219 " state than parent\n"); 219 " state than parent\n");
220 return -ENODEV; 220 return -ENODEV;
221 } 221 }
222 222
223 /* 223 /*
224 * Transition Power 224 * Transition Power
225 * ---------------- 225 * ----------------
226 * On transitions to a high-powered state we first apply power (via 226 * On transitions to a high-powered state we first apply power (via
227 * power resources) then evalute _PSx. Conversly for transitions to 227 * power resources) then evalute _PSx. Conversly for transitions to
228 * a lower-powered state. 228 * a lower-powered state.
229 */ 229 */
230 if (state < device->power.state) { 230 if (state < device->power.state) {
231 if (device->power.flags.power_resources) { 231 if (device->power.flags.power_resources) {
232 result = acpi_power_transition(device, state); 232 result = acpi_power_transition(device, state);
233 if (result) 233 if (result)
234 goto end; 234 goto end;
235 } 235 }
236 if (device->power.states[state].flags.explicit_set) { 236 if (device->power.states[state].flags.explicit_set) {
237 status = acpi_evaluate_object(device->handle, 237 status = acpi_evaluate_object(device->handle,
238 object_name, NULL, NULL); 238 object_name, NULL, NULL);
239 if (ACPI_FAILURE(status)) { 239 if (ACPI_FAILURE(status)) {
240 result = -ENODEV; 240 result = -ENODEV;
241 goto end; 241 goto end;
242 } 242 }
243 } 243 }
244 } else { 244 } else {
245 if (device->power.states[state].flags.explicit_set) { 245 if (device->power.states[state].flags.explicit_set) {
246 status = acpi_evaluate_object(device->handle, 246 status = acpi_evaluate_object(device->handle,
247 object_name, NULL, NULL); 247 object_name, NULL, NULL);
248 if (ACPI_FAILURE(status)) { 248 if (ACPI_FAILURE(status)) {
249 result = -ENODEV; 249 result = -ENODEV;
250 goto end; 250 goto end;
251 } 251 }
252 } 252 }
253 if (device->power.flags.power_resources) { 253 if (device->power.flags.power_resources) {
254 result = acpi_power_transition(device, state); 254 result = acpi_power_transition(device, state);
255 if (result) 255 if (result)
256 goto end; 256 goto end;
257 } 257 }
258 } 258 }
259 259
260 end: 260 end:
261 if (result) 261 if (result)
262 printk(KERN_WARNING PREFIX 262 printk(KERN_WARNING PREFIX
263 "Transitioning device [%s] to D%d\n", 263 "Transitioning device [%s] to D%d\n",
264 device->pnp.bus_id, state); 264 device->pnp.bus_id, state);
265 else 265 else
266 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 266 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
267 "Device [%s] transitioned to D%d\n", 267 "Device [%s] transitioned to D%d\n",
268 device->pnp.bus_id, state)); 268 device->pnp.bus_id, state));
269 269
270 return result; 270 return result;
271 } 271 }
272 272
273 EXPORT_SYMBOL(acpi_bus_set_power); 273 EXPORT_SYMBOL(acpi_bus_set_power);
274 274
275 /* -------------------------------------------------------------------------- 275 /* --------------------------------------------------------------------------
276 Event Management 276 Event Management
277 -------------------------------------------------------------------------- */ 277 -------------------------------------------------------------------------- */
278 278
279 static DEFINE_SPINLOCK(acpi_bus_event_lock); 279 static DEFINE_SPINLOCK(acpi_bus_event_lock);
280 280
281 LIST_HEAD(acpi_bus_event_list); 281 LIST_HEAD(acpi_bus_event_list);
282 DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); 282 DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
283 283
284 extern int event_is_open; 284 extern int event_is_open;
285 285
286 int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) 286 int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
287 { 287 {
288 struct acpi_bus_event *event = NULL; 288 struct acpi_bus_event *event = NULL;
289 unsigned long flags = 0; 289 unsigned long flags = 0;
290 290
291 291
292 if (!device) 292 if (!device)
293 return -EINVAL; 293 return -EINVAL;
294 294
295 if (acpi_bus_generate_genetlink_event(device, type, data))
296 printk(KERN_WARNING PREFIX
297 "Failed to generate an ACPI event via genetlink!\n");
298
295 /* drop event on the floor if no one's listening */ 299 /* drop event on the floor if no one's listening */
296 if (!event_is_open) 300 if (!event_is_open)
297 return 0; 301 return 0;
298 302
299 event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC); 303 event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
300 if (!event) 304 if (!event)
301 return -ENOMEM; 305 return -ENOMEM;
302 306
303 strcpy(event->device_class, device->pnp.device_class); 307 strcpy(event->device_class, device->pnp.device_class);
304 strcpy(event->bus_id, device->pnp.bus_id); 308 strcpy(event->bus_id, device->pnp.bus_id);
305 event->type = type; 309 event->type = type;
306 event->data = data; 310 event->data = data;
307 311
308 spin_lock_irqsave(&acpi_bus_event_lock, flags); 312 spin_lock_irqsave(&acpi_bus_event_lock, flags);
309 list_add_tail(&event->node, &acpi_bus_event_list); 313 list_add_tail(&event->node, &acpi_bus_event_list);
310 spin_unlock_irqrestore(&acpi_bus_event_lock, flags); 314 spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
311 315
312 wake_up_interruptible(&acpi_bus_event_queue); 316 wake_up_interruptible(&acpi_bus_event_queue);
313 317
314 return 0; 318 return 0;
315 } 319 }
316 320
317 EXPORT_SYMBOL(acpi_bus_generate_event); 321 EXPORT_SYMBOL(acpi_bus_generate_event);
318 322
319 int acpi_bus_receive_event(struct acpi_bus_event *event) 323 int acpi_bus_receive_event(struct acpi_bus_event *event)
320 { 324 {
321 unsigned long flags = 0; 325 unsigned long flags = 0;
322 struct acpi_bus_event *entry = NULL; 326 struct acpi_bus_event *entry = NULL;
323 327
324 DECLARE_WAITQUEUE(wait, current); 328 DECLARE_WAITQUEUE(wait, current);
325 329
326 330
327 if (!event) 331 if (!event)
328 return -EINVAL; 332 return -EINVAL;
329 333
330 if (list_empty(&acpi_bus_event_list)) { 334 if (list_empty(&acpi_bus_event_list)) {
331 335
332 set_current_state(TASK_INTERRUPTIBLE); 336 set_current_state(TASK_INTERRUPTIBLE);
333 add_wait_queue(&acpi_bus_event_queue, &wait); 337 add_wait_queue(&acpi_bus_event_queue, &wait);
334 338
335 if (list_empty(&acpi_bus_event_list)) 339 if (list_empty(&acpi_bus_event_list))
336 schedule(); 340 schedule();
337 341
338 remove_wait_queue(&acpi_bus_event_queue, &wait); 342 remove_wait_queue(&acpi_bus_event_queue, &wait);
339 set_current_state(TASK_RUNNING); 343 set_current_state(TASK_RUNNING);
340 344
341 if (signal_pending(current)) 345 if (signal_pending(current))
342 return -ERESTARTSYS; 346 return -ERESTARTSYS;
343 } 347 }
344 348
345 spin_lock_irqsave(&acpi_bus_event_lock, flags); 349 spin_lock_irqsave(&acpi_bus_event_lock, flags);
346 entry = 350 entry =
347 list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node); 351 list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
348 if (entry) 352 if (entry)
349 list_del(&entry->node); 353 list_del(&entry->node);
350 spin_unlock_irqrestore(&acpi_bus_event_lock, flags); 354 spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
351 355
352 if (!entry) 356 if (!entry)
353 return -ENODEV; 357 return -ENODEV;
354 358
355 memcpy(event, entry, sizeof(struct acpi_bus_event)); 359 memcpy(event, entry, sizeof(struct acpi_bus_event));
356 360
357 kfree(entry); 361 kfree(entry);
358 362
359 return 0; 363 return 0;
360 } 364 }
361 365
362 EXPORT_SYMBOL(acpi_bus_receive_event); 366 EXPORT_SYMBOL(acpi_bus_receive_event);
363 367
364 /* -------------------------------------------------------------------------- 368 /* --------------------------------------------------------------------------
365 Notification Handling 369 Notification Handling
366 -------------------------------------------------------------------------- */ 370 -------------------------------------------------------------------------- */
367 371
368 static int 372 static int
369 acpi_bus_check_device(struct acpi_device *device, int *status_changed) 373 acpi_bus_check_device(struct acpi_device *device, int *status_changed)
370 { 374 {
371 acpi_status status = 0; 375 acpi_status status = 0;
372 struct acpi_device_status old_status; 376 struct acpi_device_status old_status;
373 377
374 378
375 if (!device) 379 if (!device)
376 return -EINVAL; 380 return -EINVAL;
377 381
378 if (status_changed) 382 if (status_changed)
379 *status_changed = 0; 383 *status_changed = 0;
380 384
381 old_status = device->status; 385 old_status = device->status;
382 386
383 /* 387 /*
384 * Make sure this device's parent is present before we go about 388 * Make sure this device's parent is present before we go about
385 * messing with the device. 389 * messing with the device.
386 */ 390 */
387 if (device->parent && !device->parent->status.present) { 391 if (device->parent && !device->parent->status.present) {
388 device->status = device->parent->status; 392 device->status = device->parent->status;
389 if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) { 393 if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) {
390 if (status_changed) 394 if (status_changed)
391 *status_changed = 1; 395 *status_changed = 1;
392 } 396 }
393 return 0; 397 return 0;
394 } 398 }
395 399
396 status = acpi_bus_get_status(device); 400 status = acpi_bus_get_status(device);
397 if (ACPI_FAILURE(status)) 401 if (ACPI_FAILURE(status))
398 return -ENODEV; 402 return -ENODEV;
399 403
400 if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) 404 if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
401 return 0; 405 return 0;
402 406
403 if (status_changed) 407 if (status_changed)
404 *status_changed = 1; 408 *status_changed = 1;
405 409
406 /* 410 /*
407 * Device Insertion/Removal 411 * Device Insertion/Removal
408 */ 412 */
409 if ((device->status.present) && !(old_status.present)) { 413 if ((device->status.present) && !(old_status.present)) {
410 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n")); 414 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
411 /* TBD: Handle device insertion */ 415 /* TBD: Handle device insertion */
412 } else if (!(device->status.present) && (old_status.present)) { 416 } else if (!(device->status.present) && (old_status.present)) {
413 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); 417 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
414 /* TBD: Handle device removal */ 418 /* TBD: Handle device removal */
415 } 419 }
416 420
417 return 0; 421 return 0;
418 } 422 }
419 423
420 static int acpi_bus_check_scope(struct acpi_device *device) 424 static int acpi_bus_check_scope(struct acpi_device *device)
421 { 425 {
422 int result = 0; 426 int result = 0;
423 int status_changed = 0; 427 int status_changed = 0;
424 428
425 429
426 if (!device) 430 if (!device)
427 return -EINVAL; 431 return -EINVAL;
428 432
429 /* Status Change? */ 433 /* Status Change? */
430 result = acpi_bus_check_device(device, &status_changed); 434 result = acpi_bus_check_device(device, &status_changed);
431 if (result) 435 if (result)
432 return result; 436 return result;
433 437
434 if (!status_changed) 438 if (!status_changed)
435 return 0; 439 return 0;
436 440
437 /* 441 /*
438 * TBD: Enumerate child devices within this device's scope and 442 * TBD: Enumerate child devices within this device's scope and
439 * run acpi_bus_check_device()'s on them. 443 * run acpi_bus_check_device()'s on them.
440 */ 444 */
441 445
442 return 0; 446 return 0;
443 } 447 }
444 448
445 /** 449 /**
446 * acpi_bus_notify 450 * acpi_bus_notify
447 * --------------- 451 * ---------------
448 * Callback for all 'system-level' device notifications (values 0x00-0x7F). 452 * Callback for all 'system-level' device notifications (values 0x00-0x7F).
449 */ 453 */
450 static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) 454 static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
451 { 455 {
452 int result = 0; 456 int result = 0;
453 struct acpi_device *device = NULL; 457 struct acpi_device *device = NULL;
454 458
455 459
456 if (acpi_bus_get_device(handle, &device)) 460 if (acpi_bus_get_device(handle, &device))
457 return; 461 return;
458 462
459 switch (type) { 463 switch (type) {
460 464
461 case ACPI_NOTIFY_BUS_CHECK: 465 case ACPI_NOTIFY_BUS_CHECK:
462 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 466 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
463 "Received BUS CHECK notification for device [%s]\n", 467 "Received BUS CHECK notification for device [%s]\n",
464 device->pnp.bus_id)); 468 device->pnp.bus_id));
465 result = acpi_bus_check_scope(device); 469 result = acpi_bus_check_scope(device);
466 /* 470 /*
467 * TBD: We'll need to outsource certain events to non-ACPI 471 * TBD: We'll need to outsource certain events to non-ACPI
468 * drivers via the device manager (device.c). 472 * drivers via the device manager (device.c).
469 */ 473 */
470 break; 474 break;
471 475
472 case ACPI_NOTIFY_DEVICE_CHECK: 476 case ACPI_NOTIFY_DEVICE_CHECK:
473 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 477 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
474 "Received DEVICE CHECK notification for device [%s]\n", 478 "Received DEVICE CHECK notification for device [%s]\n",
475 device->pnp.bus_id)); 479 device->pnp.bus_id));
476 result = acpi_bus_check_device(device, NULL); 480 result = acpi_bus_check_device(device, NULL);
477 /* 481 /*
478 * TBD: We'll need to outsource certain events to non-ACPI 482 * TBD: We'll need to outsource certain events to non-ACPI
479 * drivers via the device manager (device.c). 483 * drivers via the device manager (device.c).
480 */ 484 */
481 break; 485 break;
482 486
483 case ACPI_NOTIFY_DEVICE_WAKE: 487 case ACPI_NOTIFY_DEVICE_WAKE:
484 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 488 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
485 "Received DEVICE WAKE notification for device [%s]\n", 489 "Received DEVICE WAKE notification for device [%s]\n",
486 device->pnp.bus_id)); 490 device->pnp.bus_id));
487 /* TBD */ 491 /* TBD */
488 break; 492 break;
489 493
490 case ACPI_NOTIFY_EJECT_REQUEST: 494 case ACPI_NOTIFY_EJECT_REQUEST:
491 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 495 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
492 "Received EJECT REQUEST notification for device [%s]\n", 496 "Received EJECT REQUEST notification for device [%s]\n",
493 device->pnp.bus_id)); 497 device->pnp.bus_id));
494 /* TBD */ 498 /* TBD */
495 break; 499 break;
496 500
497 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: 501 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
498 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 502 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
499 "Received DEVICE CHECK LIGHT notification for device [%s]\n", 503 "Received DEVICE CHECK LIGHT notification for device [%s]\n",
500 device->pnp.bus_id)); 504 device->pnp.bus_id));
501 /* TBD: Exactly what does 'light' mean? */ 505 /* TBD: Exactly what does 'light' mean? */
502 break; 506 break;
503 507
504 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 508 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
505 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 509 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
506 "Received FREQUENCY MISMATCH notification for device [%s]\n", 510 "Received FREQUENCY MISMATCH notification for device [%s]\n",
507 device->pnp.bus_id)); 511 device->pnp.bus_id));
508 /* TBD */ 512 /* TBD */
509 break; 513 break;
510 514
511 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 515 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
512 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 516 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
513 "Received BUS MODE MISMATCH notification for device [%s]\n", 517 "Received BUS MODE MISMATCH notification for device [%s]\n",
514 device->pnp.bus_id)); 518 device->pnp.bus_id));
515 /* TBD */ 519 /* TBD */
516 break; 520 break;
517 521
518 case ACPI_NOTIFY_POWER_FAULT: 522 case ACPI_NOTIFY_POWER_FAULT:
519 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 523 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
520 "Received POWER FAULT notification for device [%s]\n", 524 "Received POWER FAULT notification for device [%s]\n",
521 device->pnp.bus_id)); 525 device->pnp.bus_id));
522 /* TBD */ 526 /* TBD */
523 break; 527 break;
524 528
525 default: 529 default:
526 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 530 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
527 "Received unknown/unsupported notification [%08x]\n", 531 "Received unknown/unsupported notification [%08x]\n",
528 type)); 532 type));
529 break; 533 break;
530 } 534 }
531 535
532 return; 536 return;
533 } 537 }
534 538
535 /* -------------------------------------------------------------------------- 539 /* --------------------------------------------------------------------------
536 Initialization/Cleanup 540 Initialization/Cleanup
537 -------------------------------------------------------------------------- */ 541 -------------------------------------------------------------------------- */
538 542
539 static int __init acpi_bus_init_irq(void) 543 static int __init acpi_bus_init_irq(void)
540 { 544 {
541 acpi_status status = AE_OK; 545 acpi_status status = AE_OK;
542 union acpi_object arg = { ACPI_TYPE_INTEGER }; 546 union acpi_object arg = { ACPI_TYPE_INTEGER };
543 struct acpi_object_list arg_list = { 1, &arg }; 547 struct acpi_object_list arg_list = { 1, &arg };
544 char *message = NULL; 548 char *message = NULL;
545 549
546 550
547 /* 551 /*
548 * Let the system know what interrupt model we are using by 552 * Let the system know what interrupt model we are using by
549 * evaluating the \_PIC object, if exists. 553 * evaluating the \_PIC object, if exists.
550 */ 554 */
551 555
552 switch (acpi_irq_model) { 556 switch (acpi_irq_model) {
553 case ACPI_IRQ_MODEL_PIC: 557 case ACPI_IRQ_MODEL_PIC:
554 message = "PIC"; 558 message = "PIC";
555 break; 559 break;
556 case ACPI_IRQ_MODEL_IOAPIC: 560 case ACPI_IRQ_MODEL_IOAPIC:
557 message = "IOAPIC"; 561 message = "IOAPIC";
558 break; 562 break;
559 case ACPI_IRQ_MODEL_IOSAPIC: 563 case ACPI_IRQ_MODEL_IOSAPIC:
560 message = "IOSAPIC"; 564 message = "IOSAPIC";
561 break; 565 break;
562 case ACPI_IRQ_MODEL_PLATFORM: 566 case ACPI_IRQ_MODEL_PLATFORM:
563 message = "platform specific model"; 567 message = "platform specific model";
564 break; 568 break;
565 default: 569 default:
566 printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n"); 570 printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n");
567 return -ENODEV; 571 return -ENODEV;
568 } 572 }
569 573
570 printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message); 574 printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);
571 575
572 arg.integer.value = acpi_irq_model; 576 arg.integer.value = acpi_irq_model;
573 577
574 status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL); 578 status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
575 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { 579 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
576 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC")); 580 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC"));
577 return -ENODEV; 581 return -ENODEV;
578 } 582 }
579 583
580 return 0; 584 return 0;
581 } 585 }
582 586
583 acpi_native_uint acpi_gbl_permanent_mmap; 587 acpi_native_uint acpi_gbl_permanent_mmap;
584 588
585 589
586 void __init acpi_early_init(void) 590 void __init acpi_early_init(void)
587 { 591 {
588 acpi_status status = AE_OK; 592 acpi_status status = AE_OK;
589 593
590 if (acpi_disabled) 594 if (acpi_disabled)
591 return; 595 return;
592 596
593 printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); 597 printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
594 598
595 /* enable workarounds, unless strict ACPI spec. compliance */ 599 /* enable workarounds, unless strict ACPI spec. compliance */
596 if (!acpi_strict) 600 if (!acpi_strict)
597 acpi_gbl_enable_interpreter_slack = TRUE; 601 acpi_gbl_enable_interpreter_slack = TRUE;
598 602
599 acpi_gbl_permanent_mmap = 1; 603 acpi_gbl_permanent_mmap = 1;
600 604
601 status = acpi_reallocate_root_table(); 605 status = acpi_reallocate_root_table();
602 if (ACPI_FAILURE(status)) { 606 if (ACPI_FAILURE(status)) {
603 printk(KERN_ERR PREFIX 607 printk(KERN_ERR PREFIX
604 "Unable to reallocate ACPI tables\n"); 608 "Unable to reallocate ACPI tables\n");
605 goto error0; 609 goto error0;
606 } 610 }
607 611
608 status = acpi_initialize_subsystem(); 612 status = acpi_initialize_subsystem();
609 if (ACPI_FAILURE(status)) { 613 if (ACPI_FAILURE(status)) {
610 printk(KERN_ERR PREFIX 614 printk(KERN_ERR PREFIX
611 "Unable to initialize the ACPI Interpreter\n"); 615 "Unable to initialize the ACPI Interpreter\n");
612 goto error0; 616 goto error0;
613 } 617 }
614 618
615 status = acpi_load_tables(); 619 status = acpi_load_tables();
616 if (ACPI_FAILURE(status)) { 620 if (ACPI_FAILURE(status)) {
617 printk(KERN_ERR PREFIX 621 printk(KERN_ERR PREFIX
618 "Unable to load the System Description Tables\n"); 622 "Unable to load the System Description Tables\n");
619 goto error0; 623 goto error0;
620 } 624 }
621 625
622 #ifdef CONFIG_X86 626 #ifdef CONFIG_X86
623 if (!acpi_ioapic) { 627 if (!acpi_ioapic) {
624 extern u8 acpi_sci_flags; 628 extern u8 acpi_sci_flags;
625 629
626 /* compatible (0) means level (3) */ 630 /* compatible (0) means level (3) */
627 if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) { 631 if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
628 acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK; 632 acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
629 acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL; 633 acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
630 } 634 }
631 /* Set PIC-mode SCI trigger type */ 635 /* Set PIC-mode SCI trigger type */
632 acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt, 636 acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
633 (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2); 637 (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
634 } else { 638 } else {
635 extern int acpi_sci_override_gsi; 639 extern int acpi_sci_override_gsi;
636 /* 640 /*
637 * now that acpi_gbl_FADT is initialized, 641 * now that acpi_gbl_FADT is initialized,
638 * update it with result from INT_SRC_OVR parsing 642 * update it with result from INT_SRC_OVR parsing
639 */ 643 */
640 acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi; 644 acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
641 } 645 }
642 #endif 646 #endif
643 647
644 status = 648 status =
645 acpi_enable_subsystem(~ 649 acpi_enable_subsystem(~
646 (ACPI_NO_HARDWARE_INIT | 650 (ACPI_NO_HARDWARE_INIT |
647 ACPI_NO_ACPI_ENABLE)); 651 ACPI_NO_ACPI_ENABLE));
648 if (ACPI_FAILURE(status)) { 652 if (ACPI_FAILURE(status)) {
649 printk(KERN_ERR PREFIX "Unable to enable ACPI\n"); 653 printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
650 goto error0; 654 goto error0;
651 } 655 }
652 656
653 return; 657 return;
654 658
655 error0: 659 error0:
656 disable_acpi(); 660 disable_acpi();
657 return; 661 return;
658 } 662 }
659 663
660 static int __init acpi_bus_init(void) 664 static int __init acpi_bus_init(void)
661 { 665 {
662 int result = 0; 666 int result = 0;
663 acpi_status status = AE_OK; 667 acpi_status status = AE_OK;
664 extern acpi_status acpi_os_initialize1(void); 668 extern acpi_status acpi_os_initialize1(void);
665 669
666 670
667 status = acpi_os_initialize1(); 671 status = acpi_os_initialize1();
668 672
669 status = 673 status =
670 acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE); 674 acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
671 if (ACPI_FAILURE(status)) { 675 if (ACPI_FAILURE(status)) {
672 printk(KERN_ERR PREFIX 676 printk(KERN_ERR PREFIX
673 "Unable to start the ACPI Interpreter\n"); 677 "Unable to start the ACPI Interpreter\n");
674 goto error1; 678 goto error1;
675 } 679 }
676 680
677 if (ACPI_FAILURE(status)) { 681 if (ACPI_FAILURE(status)) {
678 printk(KERN_ERR PREFIX 682 printk(KERN_ERR PREFIX
679 "Unable to initialize ACPI OS objects\n"); 683 "Unable to initialize ACPI OS objects\n");
680 goto error1; 684 goto error1;
681 } 685 }
682 #ifdef CONFIG_ACPI_EC 686 #ifdef CONFIG_ACPI_EC
683 /* 687 /*
684 * ACPI 2.0 requires the EC driver to be loaded and work before 688 * ACPI 2.0 requires the EC driver to be loaded and work before
685 * the EC device is found in the namespace (i.e. before acpi_initialize_objects() 689 * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
686 * is called). 690 * is called).
687 * 691 *
688 * This is accomplished by looking for the ECDT table, and getting 692 * This is accomplished by looking for the ECDT table, and getting
689 * the EC parameters out of that. 693 * the EC parameters out of that.
690 */ 694 */
691 status = acpi_ec_ecdt_probe(); 695 status = acpi_ec_ecdt_probe();
692 /* Ignore result. Not having an ECDT is not fatal. */ 696 /* Ignore result. Not having an ECDT is not fatal. */
693 #endif 697 #endif
694 698
695 status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); 699 status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
696 if (ACPI_FAILURE(status)) { 700 if (ACPI_FAILURE(status)) {
697 printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n"); 701 printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
698 goto error1; 702 goto error1;
699 } 703 }
700 704
701 printk(KERN_INFO PREFIX "Interpreter enabled\n"); 705 printk(KERN_INFO PREFIX "Interpreter enabled\n");
702 706
703 /* Initialize sleep structures */ 707 /* Initialize sleep structures */
704 acpi_sleep_init(); 708 acpi_sleep_init();
705 709
706 /* 710 /*
707 * Get the system interrupt model and evaluate \_PIC. 711 * Get the system interrupt model and evaluate \_PIC.
708 */ 712 */
709 result = acpi_bus_init_irq(); 713 result = acpi_bus_init_irq();
710 if (result) 714 if (result)
711 goto error1; 715 goto error1;
712 716
713 /* 717 /*
714 * Register the for all standard device notifications. 718 * Register the for all standard device notifications.
715 */ 719 */
716 status = 720 status =
717 acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, 721 acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
718 &acpi_bus_notify, NULL); 722 &acpi_bus_notify, NULL);
719 if (ACPI_FAILURE(status)) { 723 if (ACPI_FAILURE(status)) {
720 printk(KERN_ERR PREFIX 724 printk(KERN_ERR PREFIX
721 "Unable to register for device notifications\n"); 725 "Unable to register for device notifications\n");
722 goto error1; 726 goto error1;
723 } 727 }
724 728
725 /* 729 /*
726 * Create the top ACPI proc directory 730 * Create the top ACPI proc directory
727 */ 731 */
728 acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL); 732 acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
729 733
730 return 0; 734 return 0;
731 735
732 /* Mimic structured exception handling */ 736 /* Mimic structured exception handling */
733 error1: 737 error1:
734 acpi_terminate(); 738 acpi_terminate();
735 return -ENODEV; 739 return -ENODEV;
736 } 740 }
737 741
738 decl_subsys(acpi, NULL, NULL); 742 decl_subsys(acpi, NULL, NULL);
739 743
740 static int __init acpi_init(void) 744 static int __init acpi_init(void)
741 { 745 {
742 int result = 0; 746 int result = 0;
743 747
744 748
745 if (acpi_disabled) { 749 if (acpi_disabled) {
746 printk(KERN_INFO PREFIX "Interpreter disabled.\n"); 750 printk(KERN_INFO PREFIX "Interpreter disabled.\n");
747 return -ENODEV; 751 return -ENODEV;
748 } 752 }
749 753
750 result = firmware_register(&acpi_subsys); 754 result = firmware_register(&acpi_subsys);
751 if (result < 0) 755 if (result < 0)
752 printk(KERN_WARNING "%s: firmware_register error: %d\n", 756 printk(KERN_WARNING "%s: firmware_register error: %d\n",
753 __FUNCTION__, result); 757 __FUNCTION__, result);
754 758
755 result = acpi_bus_init(); 759 result = acpi_bus_init();
756 760
757 if (!result) { 761 if (!result) {
758 #ifdef CONFIG_PM_LEGACY 762 #ifdef CONFIG_PM_LEGACY
759 if (!PM_IS_ACTIVE()) 763 if (!PM_IS_ACTIVE())
760 pm_active = 1; 764 pm_active = 1;
761 else { 765 else {
762 printk(KERN_INFO PREFIX 766 printk(KERN_INFO PREFIX
763 "APM is already active, exiting\n"); 767 "APM is already active, exiting\n");
764 disable_acpi(); 768 disable_acpi();
765 result = -ENODEV; 769 result = -ENODEV;
766 } 770 }
767 #endif 771 #endif
768 } else 772 } else
769 disable_acpi(); 773 disable_acpi();
770 774
771 return result; 775 return result;
772 } 776 }
773 777
774 subsys_initcall(acpi_init); 778 subsys_initcall(acpi_init);
775 779
drivers/acpi/event.c
1 /* 1 /*
2 * event.c - exporting ACPI events via procfs 2 * event.c - exporting ACPI events via procfs
3 * 3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * 6 *
7 */ 7 */
8 8
9 #include <linux/spinlock.h> 9 #include <linux/spinlock.h>
10 #include <linux/proc_fs.h> 10 #include <linux/proc_fs.h>
11 #include <linux/init.h> 11 #include <linux/init.h>
12 #include <linux/poll.h> 12 #include <linux/poll.h>
13 #include <acpi/acpi_drivers.h> 13 #include <acpi/acpi_drivers.h>
14 #include <net/netlink.h>
15 #include <net/genetlink.h>
14 16
15 #define _COMPONENT ACPI_SYSTEM_COMPONENT 17 #define _COMPONENT ACPI_SYSTEM_COMPONENT
16 ACPI_MODULE_NAME("event"); 18 ACPI_MODULE_NAME("event");
17 19
18 /* Global vars for handling event proc entry */ 20 /* Global vars for handling event proc entry */
19 static DEFINE_SPINLOCK(acpi_system_event_lock); 21 static DEFINE_SPINLOCK(acpi_system_event_lock);
20 int event_is_open = 0; 22 int event_is_open = 0;
21 extern struct list_head acpi_bus_event_list; 23 extern struct list_head acpi_bus_event_list;
22 extern wait_queue_head_t acpi_bus_event_queue; 24 extern wait_queue_head_t acpi_bus_event_queue;
23 25
24 static int acpi_system_open_event(struct inode *inode, struct file *file) 26 static int acpi_system_open_event(struct inode *inode, struct file *file)
25 { 27 {
26 spin_lock_irq(&acpi_system_event_lock); 28 spin_lock_irq(&acpi_system_event_lock);
27 29
28 if (event_is_open) 30 if (event_is_open)
29 goto out_busy; 31 goto out_busy;
30 32
31 event_is_open = 1; 33 event_is_open = 1;
32 34
33 spin_unlock_irq(&acpi_system_event_lock); 35 spin_unlock_irq(&acpi_system_event_lock);
34 return 0; 36 return 0;
35 37
36 out_busy: 38 out_busy:
37 spin_unlock_irq(&acpi_system_event_lock); 39 spin_unlock_irq(&acpi_system_event_lock);
38 return -EBUSY; 40 return -EBUSY;
39 } 41 }
40 42
41 static ssize_t 43 static ssize_t
42 acpi_system_read_event(struct file *file, char __user * buffer, size_t count, 44 acpi_system_read_event(struct file *file, char __user * buffer, size_t count,
43 loff_t * ppos) 45 loff_t * ppos)
44 { 46 {
45 int result = 0; 47 int result = 0;
46 struct acpi_bus_event event; 48 struct acpi_bus_event event;
47 static char str[ACPI_MAX_STRING]; 49 static char str[ACPI_MAX_STRING];
48 static int chars_remaining = 0; 50 static int chars_remaining = 0;
49 static char *ptr; 51 static char *ptr;
50 52
51
52 if (!chars_remaining) { 53 if (!chars_remaining) {
53 memset(&event, 0, sizeof(struct acpi_bus_event)); 54 memset(&event, 0, sizeof(struct acpi_bus_event));
54 55
55 if ((file->f_flags & O_NONBLOCK) 56 if ((file->f_flags & O_NONBLOCK)
56 && (list_empty(&acpi_bus_event_list))) 57 && (list_empty(&acpi_bus_event_list)))
57 return -EAGAIN; 58 return -EAGAIN;
58 59
59 result = acpi_bus_receive_event(&event); 60 result = acpi_bus_receive_event(&event);
60 if (result) 61 if (result)
61 return result; 62 return result;
62 63
63 chars_remaining = sprintf(str, "%s %s %08x %08x\n", 64 chars_remaining = sprintf(str, "%s %s %08x %08x\n",
64 event.device_class ? event. 65 event.device_class ? event.
65 device_class : "<unknown>", 66 device_class : "<unknown>",
66 event.bus_id ? event. 67 event.bus_id ? event.
67 bus_id : "<unknown>", event.type, 68 bus_id : "<unknown>", event.type,
68 event.data); 69 event.data);
69 ptr = str; 70 ptr = str;
70 } 71 }
71 72
72 if (chars_remaining < count) { 73 if (chars_remaining < count) {
73 count = chars_remaining; 74 count = chars_remaining;
74 } 75 }
75 76
76 if (copy_to_user(buffer, ptr, count)) 77 if (copy_to_user(buffer, ptr, count))
77 return -EFAULT; 78 return -EFAULT;
78 79
79 *ppos += count; 80 *ppos += count;
80 chars_remaining -= count; 81 chars_remaining -= count;
81 ptr += count; 82 ptr += count;
82 83
83 return count; 84 return count;
84 } 85 }
85 86
86 static int acpi_system_close_event(struct inode *inode, struct file *file) 87 static int acpi_system_close_event(struct inode *inode, struct file *file)
87 { 88 {
88 spin_lock_irq(&acpi_system_event_lock); 89 spin_lock_irq(&acpi_system_event_lock);
89 event_is_open = 0; 90 event_is_open = 0;
90 spin_unlock_irq(&acpi_system_event_lock); 91 spin_unlock_irq(&acpi_system_event_lock);
91 return 0; 92 return 0;
92 } 93 }
93 94
94 static unsigned int acpi_system_poll_event(struct file *file, poll_table * wait) 95 static unsigned int acpi_system_poll_event(struct file *file, poll_table * wait)
95 { 96 {
96 poll_wait(file, &acpi_bus_event_queue, wait); 97 poll_wait(file, &acpi_bus_event_queue, wait);
97 if (!list_empty(&acpi_bus_event_list)) 98 if (!list_empty(&acpi_bus_event_list))
98 return POLLIN | POLLRDNORM; 99 return POLLIN | POLLRDNORM;
99 return 0; 100 return 0;
100 } 101 }
101 102
102 static const struct file_operations acpi_system_event_ops = { 103 static const struct file_operations acpi_system_event_ops = {
103 .open = acpi_system_open_event, 104 .open = acpi_system_open_event,
104 .read = acpi_system_read_event, 105 .read = acpi_system_read_event,
105 .release = acpi_system_close_event, 106 .release = acpi_system_close_event,
106 .poll = acpi_system_poll_event, 107 .poll = acpi_system_poll_event,
107 }; 108 };
108 109
110 #ifdef CONFIG_NET
111 unsigned int acpi_event_seqnum;
112 struct acpi_genl_event {
113 acpi_device_class device_class;
114 char bus_id[15];
115 u32 type;
116 u32 data;
117 };
118
119 /* attributes of acpi_genl_family */
120 enum {
121 ACPI_GENL_ATTR_UNSPEC,
122 ACPI_GENL_ATTR_EVENT, /* ACPI event info needed by user space */
123 __ACPI_GENL_ATTR_MAX,
124 };
125 #define ACPI_GENL_ATTR_MAX (__ACPI_GENL_ATTR_MAX - 1)
126
127 /* commands supported by the acpi_genl_family */
128 enum {
129 ACPI_GENL_CMD_UNSPEC,
130 ACPI_GENL_CMD_EVENT, /* kernel->user notifications for ACPI events */
131 __ACPI_GENL_CMD_MAX,
132 };
133 #define ACPI_GENL_CMD_MAX (__ACPI_GENL_CMD_MAX - 1)
134
135 #define ACPI_GENL_NAME "acpi_event"
136 #define ACPI_GENL_VERSION 0x01
137
138 static struct genl_family acpi_event_genl_family = {
139 .id = GENL_ID_GENERATE,
140 .name = ACPI_GENL_NAME,
141 .version = ACPI_GENL_VERSION,
142 .maxattr = ACPI_GENL_ATTR_MAX,
143 };
144
145 /* .doit: standard command callback */
146 static int acpi_genl_cmd_event(struct sk_buff *skb, struct genl_info *info)
147 {
148 struct acpi_genl_event *event = info->userhdr;
149
150 if (!event)
151 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "ACPI event: NULL\n"));
152
153 return 0;
154 }
155
156 static struct genl_ops acpi_event_genl_ops = {
157 .cmd = ACPI_GENL_CMD_EVENT,
158 .doit = acpi_genl_cmd_event,
159 };
160
161 int acpi_bus_generate_genetlink_event(struct acpi_device *device,
162 u8 type, int data)
163 {
164 struct sk_buff *skb;
165 struct nlattr *attr;
166 struct acpi_genl_event *event;
167 void *msg_header;
168 int size;
169 int result;
170
171 /* allocate memory */
172 size = nla_total_size(sizeof(struct acpi_genl_event)) +
173 nla_total_size(0);
174
175 skb = genlmsg_new(size, GFP_ATOMIC);
176 if (!skb)
177 return -ENOMEM;
178
179 /* add the genetlink message header */
180 msg_header = genlmsg_put(skb, 0, acpi_event_seqnum++,
181 &acpi_event_genl_family, 0,
182 ACPI_GENL_CMD_EVENT);
183 if (!msg_header) {
184 nlmsg_free(skb);
185 return -ENOMEM;
186 }
187
188 /* fill the data */
189 attr =
190 nla_reserve(skb, ACPI_GENL_ATTR_EVENT,
191 sizeof(struct acpi_genl_event));
192 if (!attr) {
193 nlmsg_free(skb);
194 return -EINVAL;
195 }
196
197 event = nla_data(attr);
198 if (!event) {
199 nlmsg_free(skb);
200 return -EINVAL;
201 }
202
203 memset(event, 0, sizeof(struct acpi_genl_event));
204
205 strcpy(event->device_class, device->pnp.device_class);
206 strcpy(event->bus_id, device->dev.bus_id);
207 event->type = type;
208 event->data = data;
209
210 /* send multicast genetlink message */
211 result = genlmsg_end(skb, msg_header);
212 if (result < 0) {
213 nlmsg_free(skb);
214 return result;
215 }
216
217 result =
218 genlmsg_multicast(skb, 0, acpi_event_genl_family.id, GFP_ATOMIC);
219 if (result)
220 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
221 "Failed to send a Genetlink message!\n"));
222 return 0;
223 }
224 EXPORT_SYMBOL(acpi_bus_generate_genetlink_event);
225
226 static int acpi_event_genetlink_init(void)
227 {
228 int result;
229
230 result = genl_register_family(&acpi_event_genl_family);
231 if (result)
232 return result;
233
234 result =
235 genl_register_ops(&acpi_event_genl_family, &acpi_event_genl_ops);
236 if (result)
237 genl_unregister_family(&acpi_event_genl_family);
238
239 return result;
240 }
241
242 #else
243 int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type,
244 int data)
245 {
246 return 0;
247 }
248 EXPORT_SYMBOL(acpi_bus_generate_genetlink_event);
249
250 static int acpi_event_genetlink_init(void)
251 {
252 return -ENODEV;
253 }
254 #endif
255
109 static int __init acpi_event_init(void) 256 static int __init acpi_event_init(void)
110 { 257 {
111 struct proc_dir_entry *entry; 258 struct proc_dir_entry *entry;
112 int error = 0; 259 int error = 0;
113 260
114
115 if (acpi_disabled) 261 if (acpi_disabled)
116 return 0; 262 return 0;
117 263
264 /* create genetlink for acpi event */
265 error = acpi_event_genetlink_init();
266 if (error)
267 printk(KERN_WARNING PREFIX
268 "Failed to create genetlink family for ACPI event\n");
269
118 /* 'event' [R] */ 270 /* 'event' [R] */
119 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); 271 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
120 if (entry) 272 if (entry)
121 entry->proc_fops = &acpi_system_event_ops; 273 entry->proc_fops = &acpi_system_event_ops;
122 else { 274 else
123 error = -ENODEV; 275 return -ENODEV;
124 } 276
125 return error; 277 return 0;
126 } 278 }
127 279
include/acpi/acpi_bus.h
1 /* 1 /*
2 * acpi_bus.h - ACPI Bus Driver ($Revision: 22 $) 2 * acpi_bus.h - ACPI Bus Driver ($Revision: 22 $)
3 * 3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * 6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 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 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 11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version. 12 * your option) any later version.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, but 14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. 17 * General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License along 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., 20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 * 22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */ 24 */
25 25
26 #ifndef __ACPI_BUS_H__ 26 #ifndef __ACPI_BUS_H__
27 #define __ACPI_BUS_H__ 27 #define __ACPI_BUS_H__
28 28
29 #include <linux/device.h> 29 #include <linux/device.h>
30 30
31 #include <acpi/acpi.h> 31 #include <acpi/acpi.h>
32 32
33 #define PREFIX "ACPI: " 33 #define PREFIX "ACPI: "
34 34
35 /* TBD: Make dynamic */ 35 /* TBD: Make dynamic */
36 #define ACPI_MAX_HANDLES 10 36 #define ACPI_MAX_HANDLES 10
37 struct acpi_handle_list { 37 struct acpi_handle_list {
38 u32 count; 38 u32 count;
39 acpi_handle handles[ACPI_MAX_HANDLES]; 39 acpi_handle handles[ACPI_MAX_HANDLES];
40 }; 40 };
41 41
42 /* acpi_utils.h */ 42 /* acpi_utils.h */
43 acpi_status 43 acpi_status
44 acpi_extract_package(union acpi_object *package, 44 acpi_extract_package(union acpi_object *package,
45 struct acpi_buffer *format, struct acpi_buffer *buffer); 45 struct acpi_buffer *format, struct acpi_buffer *buffer);
46 acpi_status 46 acpi_status
47 acpi_evaluate_integer(acpi_handle handle, 47 acpi_evaluate_integer(acpi_handle handle,
48 acpi_string pathname, 48 acpi_string pathname,
49 struct acpi_object_list *arguments, unsigned long *data); 49 struct acpi_object_list *arguments, unsigned long *data);
50 acpi_status 50 acpi_status
51 acpi_evaluate_reference(acpi_handle handle, 51 acpi_evaluate_reference(acpi_handle handle,
52 acpi_string pathname, 52 acpi_string pathname,
53 struct acpi_object_list *arguments, 53 struct acpi_object_list *arguments,
54 struct acpi_handle_list *list); 54 struct acpi_handle_list *list);
55 55
56 #ifdef CONFIG_ACPI 56 #ifdef CONFIG_ACPI
57 57
58 #include <linux/proc_fs.h> 58 #include <linux/proc_fs.h>
59 59
60 #define ACPI_BUS_FILE_ROOT "acpi" 60 #define ACPI_BUS_FILE_ROOT "acpi"
61 extern struct proc_dir_entry *acpi_root_dir; 61 extern struct proc_dir_entry *acpi_root_dir;
62 62
63 enum acpi_bus_removal_type { 63 enum acpi_bus_removal_type {
64 ACPI_BUS_REMOVAL_NORMAL = 0, 64 ACPI_BUS_REMOVAL_NORMAL = 0,
65 ACPI_BUS_REMOVAL_EJECT, 65 ACPI_BUS_REMOVAL_EJECT,
66 ACPI_BUS_REMOVAL_SUPRISE, 66 ACPI_BUS_REMOVAL_SUPRISE,
67 ACPI_BUS_REMOVAL_TYPE_COUNT 67 ACPI_BUS_REMOVAL_TYPE_COUNT
68 }; 68 };
69 69
70 enum acpi_bus_device_type { 70 enum acpi_bus_device_type {
71 ACPI_BUS_TYPE_DEVICE = 0, 71 ACPI_BUS_TYPE_DEVICE = 0,
72 ACPI_BUS_TYPE_POWER, 72 ACPI_BUS_TYPE_POWER,
73 ACPI_BUS_TYPE_PROCESSOR, 73 ACPI_BUS_TYPE_PROCESSOR,
74 ACPI_BUS_TYPE_THERMAL, 74 ACPI_BUS_TYPE_THERMAL,
75 ACPI_BUS_TYPE_SYSTEM, 75 ACPI_BUS_TYPE_SYSTEM,
76 ACPI_BUS_TYPE_POWER_BUTTON, 76 ACPI_BUS_TYPE_POWER_BUTTON,
77 ACPI_BUS_TYPE_SLEEP_BUTTON, 77 ACPI_BUS_TYPE_SLEEP_BUTTON,
78 ACPI_BUS_DEVICE_TYPE_COUNT 78 ACPI_BUS_DEVICE_TYPE_COUNT
79 }; 79 };
80 80
81 struct acpi_driver; 81 struct acpi_driver;
82 struct acpi_device; 82 struct acpi_device;
83 83
84 /* 84 /*
85 * ACPI Driver 85 * ACPI Driver
86 * ----------- 86 * -----------
87 */ 87 */
88 88
89 typedef int (*acpi_op_add) (struct acpi_device * device); 89 typedef int (*acpi_op_add) (struct acpi_device * device);
90 typedef int (*acpi_op_remove) (struct acpi_device * device, int type); 90 typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
91 typedef int (*acpi_op_lock) (struct acpi_device * device, int type); 91 typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
92 typedef int (*acpi_op_start) (struct acpi_device * device); 92 typedef int (*acpi_op_start) (struct acpi_device * device);
93 typedef int (*acpi_op_stop) (struct acpi_device * device, int type); 93 typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
94 typedef int (*acpi_op_suspend) (struct acpi_device * device, 94 typedef int (*acpi_op_suspend) (struct acpi_device * device,
95 pm_message_t state); 95 pm_message_t state);
96 typedef int (*acpi_op_resume) (struct acpi_device * device); 96 typedef int (*acpi_op_resume) (struct acpi_device * device);
97 typedef int (*acpi_op_scan) (struct acpi_device * device); 97 typedef int (*acpi_op_scan) (struct acpi_device * device);
98 typedef int (*acpi_op_bind) (struct acpi_device * device); 98 typedef int (*acpi_op_bind) (struct acpi_device * device);
99 typedef int (*acpi_op_unbind) (struct acpi_device * device); 99 typedef int (*acpi_op_unbind) (struct acpi_device * device);
100 typedef int (*acpi_op_shutdown) (struct acpi_device * device); 100 typedef int (*acpi_op_shutdown) (struct acpi_device * device);
101 101
102 struct acpi_bus_ops { 102 struct acpi_bus_ops {
103 u32 acpi_op_add:1; 103 u32 acpi_op_add:1;
104 u32 acpi_op_remove:1; 104 u32 acpi_op_remove:1;
105 u32 acpi_op_lock:1; 105 u32 acpi_op_lock:1;
106 u32 acpi_op_start:1; 106 u32 acpi_op_start:1;
107 u32 acpi_op_stop:1; 107 u32 acpi_op_stop:1;
108 u32 acpi_op_suspend:1; 108 u32 acpi_op_suspend:1;
109 u32 acpi_op_resume:1; 109 u32 acpi_op_resume:1;
110 u32 acpi_op_scan:1; 110 u32 acpi_op_scan:1;
111 u32 acpi_op_bind:1; 111 u32 acpi_op_bind:1;
112 u32 acpi_op_unbind:1; 112 u32 acpi_op_unbind:1;
113 u32 acpi_op_shutdown:1; 113 u32 acpi_op_shutdown:1;
114 u32 reserved:21; 114 u32 reserved:21;
115 }; 115 };
116 116
117 struct acpi_device_ops { 117 struct acpi_device_ops {
118 acpi_op_add add; 118 acpi_op_add add;
119 acpi_op_remove remove; 119 acpi_op_remove remove;
120 acpi_op_lock lock; 120 acpi_op_lock lock;
121 acpi_op_start start; 121 acpi_op_start start;
122 acpi_op_stop stop; 122 acpi_op_stop stop;
123 acpi_op_suspend suspend; 123 acpi_op_suspend suspend;
124 acpi_op_resume resume; 124 acpi_op_resume resume;
125 acpi_op_scan scan; 125 acpi_op_scan scan;
126 acpi_op_bind bind; 126 acpi_op_bind bind;
127 acpi_op_unbind unbind; 127 acpi_op_unbind unbind;
128 acpi_op_shutdown shutdown; 128 acpi_op_shutdown shutdown;
129 }; 129 };
130 130
131 struct acpi_driver { 131 struct acpi_driver {
132 char name[80]; 132 char name[80];
133 char class[80]; 133 char class[80];
134 char *ids; /* Supported Hardware IDs */ 134 char *ids; /* Supported Hardware IDs */
135 struct acpi_device_ops ops; 135 struct acpi_device_ops ops;
136 struct device_driver drv; 136 struct device_driver drv;
137 struct module *owner; 137 struct module *owner;
138 }; 138 };
139 139
140 /* 140 /*
141 * ACPI Device 141 * ACPI Device
142 * ----------- 142 * -----------
143 */ 143 */
144 144
145 /* Status (_STA) */ 145 /* Status (_STA) */
146 146
147 struct acpi_device_status { 147 struct acpi_device_status {
148 u32 present:1; 148 u32 present:1;
149 u32 enabled:1; 149 u32 enabled:1;
150 u32 show_in_ui:1; 150 u32 show_in_ui:1;
151 u32 functional:1; 151 u32 functional:1;
152 u32 battery_present:1; 152 u32 battery_present:1;
153 u32 reserved:27; 153 u32 reserved:27;
154 }; 154 };
155 155
156 /* Flags */ 156 /* Flags */
157 157
158 struct acpi_device_flags { 158 struct acpi_device_flags {
159 u32 dynamic_status:1; 159 u32 dynamic_status:1;
160 u32 hardware_id:1; 160 u32 hardware_id:1;
161 u32 compatible_ids:1; 161 u32 compatible_ids:1;
162 u32 bus_address:1; 162 u32 bus_address:1;
163 u32 unique_id:1; 163 u32 unique_id:1;
164 u32 removable:1; 164 u32 removable:1;
165 u32 ejectable:1; 165 u32 ejectable:1;
166 u32 lockable:1; 166 u32 lockable:1;
167 u32 suprise_removal_ok:1; 167 u32 suprise_removal_ok:1;
168 u32 power_manageable:1; 168 u32 power_manageable:1;
169 u32 performance_manageable:1; 169 u32 performance_manageable:1;
170 u32 wake_capable:1; /* Wakeup(_PRW) supported? */ 170 u32 wake_capable:1; /* Wakeup(_PRW) supported? */
171 u32 force_power_state:1; 171 u32 force_power_state:1;
172 u32 reserved:19; 172 u32 reserved:19;
173 }; 173 };
174 174
175 /* File System */ 175 /* File System */
176 176
177 struct acpi_device_dir { 177 struct acpi_device_dir {
178 struct proc_dir_entry *entry; 178 struct proc_dir_entry *entry;
179 }; 179 };
180 180
181 #define acpi_device_dir(d) ((d)->dir.entry) 181 #define acpi_device_dir(d) ((d)->dir.entry)
182 182
183 /* Plug and Play */ 183 /* Plug and Play */
184 184
185 typedef char acpi_bus_id[5]; 185 typedef char acpi_bus_id[5];
186 typedef unsigned long acpi_bus_address; 186 typedef unsigned long acpi_bus_address;
187 typedef char acpi_hardware_id[15]; 187 typedef char acpi_hardware_id[15];
188 typedef char acpi_unique_id[9]; 188 typedef char acpi_unique_id[9];
189 typedef char acpi_device_name[40]; 189 typedef char acpi_device_name[40];
190 typedef char acpi_device_class[20]; 190 typedef char acpi_device_class[20];
191 191
192 struct acpi_device_pnp { 192 struct acpi_device_pnp {
193 acpi_bus_id bus_id; /* Object name */ 193 acpi_bus_id bus_id; /* Object name */
194 acpi_bus_address bus_address; /* _ADR */ 194 acpi_bus_address bus_address; /* _ADR */
195 acpi_hardware_id hardware_id; /* _HID */ 195 acpi_hardware_id hardware_id; /* _HID */
196 struct acpi_compatible_id_list *cid_list; /* _CIDs */ 196 struct acpi_compatible_id_list *cid_list; /* _CIDs */
197 acpi_unique_id unique_id; /* _UID */ 197 acpi_unique_id unique_id; /* _UID */
198 acpi_device_name device_name; /* Driver-determined */ 198 acpi_device_name device_name; /* Driver-determined */
199 acpi_device_class device_class; /* " */ 199 acpi_device_class device_class; /* " */
200 }; 200 };
201 201
202 #define acpi_device_bid(d) ((d)->pnp.bus_id) 202 #define acpi_device_bid(d) ((d)->pnp.bus_id)
203 #define acpi_device_adr(d) ((d)->pnp.bus_address) 203 #define acpi_device_adr(d) ((d)->pnp.bus_address)
204 #define acpi_device_hid(d) ((d)->pnp.hardware_id) 204 #define acpi_device_hid(d) ((d)->pnp.hardware_id)
205 #define acpi_device_uid(d) ((d)->pnp.unique_id) 205 #define acpi_device_uid(d) ((d)->pnp.unique_id)
206 #define acpi_device_name(d) ((d)->pnp.device_name) 206 #define acpi_device_name(d) ((d)->pnp.device_name)
207 #define acpi_device_class(d) ((d)->pnp.device_class) 207 #define acpi_device_class(d) ((d)->pnp.device_class)
208 208
209 /* Power Management */ 209 /* Power Management */
210 210
211 struct acpi_device_power_flags { 211 struct acpi_device_power_flags {
212 u32 explicit_get:1; /* _PSC present? */ 212 u32 explicit_get:1; /* _PSC present? */
213 u32 power_resources:1; /* Power resources */ 213 u32 power_resources:1; /* Power resources */
214 u32 inrush_current:1; /* Serialize Dx->D0 */ 214 u32 inrush_current:1; /* Serialize Dx->D0 */
215 u32 power_removed:1; /* Optimize Dx->D0 */ 215 u32 power_removed:1; /* Optimize Dx->D0 */
216 u32 reserved:28; 216 u32 reserved:28;
217 }; 217 };
218 218
219 struct acpi_device_power_state { 219 struct acpi_device_power_state {
220 struct { 220 struct {
221 u8 valid:1; 221 u8 valid:1;
222 u8 explicit_set:1; /* _PSx present? */ 222 u8 explicit_set:1; /* _PSx present? */
223 u8 reserved:6; 223 u8 reserved:6;
224 } flags; 224 } flags;
225 int power; /* % Power (compared to D0) */ 225 int power; /* % Power (compared to D0) */
226 int latency; /* Dx->D0 time (microseconds) */ 226 int latency; /* Dx->D0 time (microseconds) */
227 struct acpi_handle_list resources; /* Power resources referenced */ 227 struct acpi_handle_list resources; /* Power resources referenced */
228 }; 228 };
229 229
230 struct acpi_device_power { 230 struct acpi_device_power {
231 int state; /* Current state */ 231 int state; /* Current state */
232 struct acpi_device_power_flags flags; 232 struct acpi_device_power_flags flags;
233 struct acpi_device_power_state states[4]; /* Power states (D0-D3) */ 233 struct acpi_device_power_state states[4]; /* Power states (D0-D3) */
234 }; 234 };
235 235
236 /* Performance Management */ 236 /* Performance Management */
237 237
238 struct acpi_device_perf_flags { 238 struct acpi_device_perf_flags {
239 u8 reserved:8; 239 u8 reserved:8;
240 }; 240 };
241 241
242 struct acpi_device_perf_state { 242 struct acpi_device_perf_state {
243 struct { 243 struct {
244 u8 valid:1; 244 u8 valid:1;
245 u8 reserved:7; 245 u8 reserved:7;
246 } flags; 246 } flags;
247 u8 power; /* % Power (compared to P0) */ 247 u8 power; /* % Power (compared to P0) */
248 u8 performance; /* % Performance ( " ) */ 248 u8 performance; /* % Performance ( " ) */
249 int latency; /* Px->P0 time (microseconds) */ 249 int latency; /* Px->P0 time (microseconds) */
250 }; 250 };
251 251
252 struct acpi_device_perf { 252 struct acpi_device_perf {
253 int state; 253 int state;
254 struct acpi_device_perf_flags flags; 254 struct acpi_device_perf_flags flags;
255 int state_count; 255 int state_count;
256 struct acpi_device_perf_state *states; 256 struct acpi_device_perf_state *states;
257 }; 257 };
258 258
259 /* Wakeup Management */ 259 /* Wakeup Management */
260 struct acpi_device_wakeup_flags { 260 struct acpi_device_wakeup_flags {
261 u8 valid:1; /* Can successfully enable wakeup? */ 261 u8 valid:1; /* Can successfully enable wakeup? */
262 u8 run_wake:1; /* Run-Wake GPE devices */ 262 u8 run_wake:1; /* Run-Wake GPE devices */
263 }; 263 };
264 264
265 struct acpi_device_wakeup_state { 265 struct acpi_device_wakeup_state {
266 u8 enabled:1; 266 u8 enabled:1;
267 u8 active:1; 267 u8 active:1;
268 }; 268 };
269 269
270 struct acpi_device_wakeup { 270 struct acpi_device_wakeup {
271 acpi_handle gpe_device; 271 acpi_handle gpe_device;
272 acpi_integer gpe_number; 272 acpi_integer gpe_number;
273 acpi_integer sleep_state; 273 acpi_integer sleep_state;
274 struct acpi_handle_list resources; 274 struct acpi_handle_list resources;
275 struct acpi_device_wakeup_state state; 275 struct acpi_device_wakeup_state state;
276 struct acpi_device_wakeup_flags flags; 276 struct acpi_device_wakeup_flags flags;
277 }; 277 };
278 278
279 /* Device */ 279 /* Device */
280 280
281 struct acpi_device { 281 struct acpi_device {
282 acpi_handle handle; 282 acpi_handle handle;
283 struct acpi_device *parent; 283 struct acpi_device *parent;
284 struct list_head children; 284 struct list_head children;
285 struct list_head node; 285 struct list_head node;
286 struct list_head wakeup_list; 286 struct list_head wakeup_list;
287 struct list_head g_list; 287 struct list_head g_list;
288 struct acpi_device_status status; 288 struct acpi_device_status status;
289 struct acpi_device_flags flags; 289 struct acpi_device_flags flags;
290 struct acpi_device_pnp pnp; 290 struct acpi_device_pnp pnp;
291 struct acpi_device_power power; 291 struct acpi_device_power power;
292 struct acpi_device_wakeup wakeup; 292 struct acpi_device_wakeup wakeup;
293 struct acpi_device_perf performance; 293 struct acpi_device_perf performance;
294 struct acpi_device_dir dir; 294 struct acpi_device_dir dir;
295 struct acpi_device_ops ops; 295 struct acpi_device_ops ops;
296 struct acpi_driver *driver; 296 struct acpi_driver *driver;
297 void *driver_data; 297 void *driver_data;
298 struct device dev; 298 struct device dev;
299 struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */ 299 struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */
300 enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ 300 enum acpi_bus_removal_type removal_type; /* indicate for different removal type */
301 }; 301 };
302 302
303 #define acpi_driver_data(d) ((d)->driver_data) 303 #define acpi_driver_data(d) ((d)->driver_data)
304 #define to_acpi_device(d) container_of(d, struct acpi_device, dev) 304 #define to_acpi_device(d) container_of(d, struct acpi_device, dev)
305 #define to_acpi_driver(d) container_of(d, struct acpi_driver, drv) 305 #define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
306 306
307 /* acpi_device.dev.bus == &acpi_bus_type */ 307 /* acpi_device.dev.bus == &acpi_bus_type */
308 extern struct bus_type acpi_bus_type; 308 extern struct bus_type acpi_bus_type;
309 309
310 /* 310 /*
311 * Events 311 * Events
312 * ------ 312 * ------
313 */ 313 */
314 314
315 struct acpi_bus_event { 315 struct acpi_bus_event {
316 struct list_head node; 316 struct list_head node;
317 acpi_device_class device_class; 317 acpi_device_class device_class;
318 acpi_bus_id bus_id; 318 acpi_bus_id bus_id;
319 u32 type; 319 u32 type;
320 u32 data; 320 u32 data;
321 }; 321 };
322 322
323 extern struct kset acpi_subsys; 323 extern struct kset acpi_subsys;
324 324 extern int acpi_bus_generate_genetlink_event(struct acpi_device *device,
325 u8 type, int data);
325 /* 326 /*
326 * External Functions 327 * External Functions
327 */ 328 */
328 329
329 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); 330 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
330 void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context); 331 void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context);
331 int acpi_bus_get_status(struct acpi_device *device); 332 int acpi_bus_get_status(struct acpi_device *device);
332 int acpi_bus_get_power(acpi_handle handle, int *state); 333 int acpi_bus_get_power(acpi_handle handle, int *state);
333 int acpi_bus_set_power(acpi_handle handle, int state); 334 int acpi_bus_set_power(acpi_handle handle, int state);
334 int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data); 335 int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data);
335 int acpi_bus_receive_event(struct acpi_bus_event *event); 336 int acpi_bus_receive_event(struct acpi_bus_event *event);
336 int acpi_bus_register_driver(struct acpi_driver *driver); 337 int acpi_bus_register_driver(struct acpi_driver *driver);
337 void acpi_bus_unregister_driver(struct acpi_driver *driver); 338 void acpi_bus_unregister_driver(struct acpi_driver *driver);
338 int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, 339 int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
339 acpi_handle handle, int type); 340 acpi_handle handle, int type);
340 int acpi_bus_trim(struct acpi_device *start, int rmdevice); 341 int acpi_bus_trim(struct acpi_device *start, int rmdevice);
341 int acpi_bus_start(struct acpi_device *device); 342 int acpi_bus_start(struct acpi_device *device);
342 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); 343 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
343 int acpi_match_ids(struct acpi_device *device, char *ids); 344 int acpi_match_ids(struct acpi_device *device, char *ids);
344 int acpi_create_dir(struct acpi_device *); 345 int acpi_create_dir(struct acpi_device *);
345 void acpi_remove_dir(struct acpi_device *); 346 void acpi_remove_dir(struct acpi_device *);
346 347
347 /* 348 /*
348 * Bind physical devices with ACPI devices 349 * Bind physical devices with ACPI devices
349 */ 350 */
350 #include <linux/device.h> 351 #include <linux/device.h>
351 struct acpi_bus_type { 352 struct acpi_bus_type {
352 struct list_head list; 353 struct list_head list;
353 struct bus_type *bus; 354 struct bus_type *bus;
354 /* For general devices under the bus */ 355 /* For general devices under the bus */
355 int (*find_device) (struct device *, acpi_handle *); 356 int (*find_device) (struct device *, acpi_handle *);
356 /* For bridges, such as PCI root bridge, IDE controller */ 357 /* For bridges, such as PCI root bridge, IDE controller */
357 int (*find_bridge) (struct device *, acpi_handle *); 358 int (*find_bridge) (struct device *, acpi_handle *);
358 }; 359 };
359 int register_acpi_bus_type(struct acpi_bus_type *); 360 int register_acpi_bus_type(struct acpi_bus_type *);
360 int unregister_acpi_bus_type(struct acpi_bus_type *); 361 int unregister_acpi_bus_type(struct acpi_bus_type *);
361 struct device *acpi_get_physical_device(acpi_handle); 362 struct device *acpi_get_physical_device(acpi_handle);
362 /* helper */ 363 /* helper */
363 acpi_handle acpi_get_child(acpi_handle, acpi_integer); 364 acpi_handle acpi_get_child(acpi_handle, acpi_integer);
364 acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); 365 acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
365 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) 366 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
366 367
367 #endif /* CONFIG_ACPI */ 368 #endif /* CONFIG_ACPI */
368 369
369 #endif /*__ACPI_BUS_H__*/ 370 #endif /*__ACPI_BUS_H__*/
370 371