aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig23
-rw-r--r--drivers/acpi/battery.c673
-rw-r--r--drivers/acpi/bay.c19
-rw-r--r--drivers/acpi/bus.c4
-rw-r--r--drivers/acpi/dock.c127
-rw-r--r--drivers/acpi/ec.c247
-rw-r--r--drivers/acpi/event.c153
-rw-r--r--drivers/acpi/events/evgpeblk.c4
-rw-r--r--drivers/acpi/events/evrgnini.c1
-rw-r--r--drivers/acpi/glue.c2
-rw-r--r--drivers/acpi/numa.c31
-rw-r--r--drivers/acpi/osl.c42
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/processor_core.c6
-rw-r--r--drivers/acpi/processor_idle.c24
-rw-r--r--drivers/acpi/processor_throttling.c410
-rw-r--r--drivers/acpi/sbs.c33
-rw-r--r--drivers/acpi/sleep/main.c19
-rw-r--r--drivers/acpi/sleep/poweroff.c41
-rw-r--r--drivers/acpi/system.c165
-rw-r--r--drivers/acpi/tables/tbfadt.c44
-rw-r--r--drivers/acpi/thermal.c24
-rw-r--r--drivers/acpi/utilities/uteval.c17
-rw-r--r--drivers/acpi/video.c120
24 files changed, 1588 insertions, 643 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 139f41f033d8..408b45168aba 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -2,16 +2,12 @@
2# ACPI Configuration 2# ACPI Configuration
3# 3#
4 4
5menu "ACPI (Advanced Configuration and Power Interface) Support" 5menuconfig ACPI
6 bool "ACPI Support (Advanced Configuration and Power Interface) Support"
6 depends on !X86_NUMAQ 7 depends on !X86_NUMAQ
7 depends on !X86_VISWS 8 depends on !X86_VISWS
8 depends on !IA64_HP_SIM 9 depends on !IA64_HP_SIM
9 depends on IA64 || X86 10 depends on IA64 || X86
10 depends on PM
11
12config ACPI
13 bool "ACPI Support"
14 depends on IA64 || X86
15 depends on PCI 11 depends on PCI
16 depends on PM 12 depends on PM
17 select PNP 13 select PNP
@@ -49,7 +45,6 @@ if ACPI
49config ACPI_SLEEP 45config ACPI_SLEEP
50 bool "Sleep States" 46 bool "Sleep States"
51 depends on X86 && (!SMP || SUSPEND_SMP) 47 depends on X86 && (!SMP || SUSPEND_SMP)
52 depends on PM
53 default y 48 default y
54 ---help--- 49 ---help---
55 This option adds support for ACPI suspend states. 50 This option adds support for ACPI suspend states.
@@ -82,7 +77,6 @@ config ACPI_SLEEP_PROC_SLEEP
82 77
83config ACPI_PROCFS 78config ACPI_PROCFS
84 bool "Procfs interface (deprecated)" 79 bool "Procfs interface (deprecated)"
85 depends on ACPI
86 default y 80 default y
87 ---help--- 81 ---help---
88 The Procfs interface for ACPI is made optional for backward compatibility. 82 The Procfs interface for ACPI is made optional for backward compatibility.
@@ -124,7 +118,7 @@ config ACPI_BUTTON
124 118
125config ACPI_VIDEO 119config ACPI_VIDEO
126 tristate "Video" 120 tristate "Video"
127 depends on X86 && BACKLIGHT_CLASS_DEVICE 121 depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
128 help 122 help
129 This driver implement the ACPI Extensions For Display Adapters 123 This driver implement the ACPI Extensions For Display Adapters
130 for integrated graphics devices on motherboard, as specified in 124 for integrated graphics devices on motherboard, as specified in
@@ -280,6 +274,14 @@ config ACPI_DEBUG
280 of verbosity. Saying Y enables these statements. This will increase 274 of verbosity. Saying Y enables these statements. This will increase
281 your kernel size by around 50K. 275 your kernel size by around 50K.
282 276
277config ACPI_DEBUG_FUNC_TRACE
278 bool "Additionally enable ACPI function tracing"
279 default n
280 depends on ACPI_DEBUG
281 help
282 ACPI Debug Statements slow down ACPI processing. Function trace
283 is about half of the penalty and is rarely useful.
284
283config ACPI_EC 285config ACPI_EC
284 bool 286 bool
285 default y 287 default y
@@ -330,7 +332,6 @@ config ACPI_CONTAINER
330 332
331config ACPI_HOTPLUG_MEMORY 333config ACPI_HOTPLUG_MEMORY
332 tristate "Memory Hotplug" 334 tristate "Memory Hotplug"
333 depends on ACPI
334 depends on MEMORY_HOTPLUG 335 depends on MEMORY_HOTPLUG
335 default n 336 default n
336 help 337 help
@@ -359,5 +360,3 @@ config ACPI_SBS
359 to today's ACPI "Control Method" battery. 360 to today's ACPI "Control Method" battery.
360 361
361endif # ACPI 362endif # ACPI
362
363endmenu
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index e64c76c8b726..cad932de383d 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -43,21 +43,30 @@
43#define ACPI_BATTERY_CLASS "battery" 43#define ACPI_BATTERY_CLASS "battery"
44#define ACPI_BATTERY_HID "PNP0C0A" 44#define ACPI_BATTERY_HID "PNP0C0A"
45#define ACPI_BATTERY_DEVICE_NAME "Battery" 45#define ACPI_BATTERY_DEVICE_NAME "Battery"
46#define ACPI_BATTERY_FILE_INFO "info"
47#define ACPI_BATTERY_FILE_STATUS "state"
48#define ACPI_BATTERY_FILE_ALARM "alarm"
49#define ACPI_BATTERY_NOTIFY_STATUS 0x80 46#define ACPI_BATTERY_NOTIFY_STATUS 0x80
50#define ACPI_BATTERY_NOTIFY_INFO 0x81 47#define ACPI_BATTERY_NOTIFY_INFO 0x81
51#define ACPI_BATTERY_UNITS_WATTS "mW" 48#define ACPI_BATTERY_UNITS_WATTS "mW"
52#define ACPI_BATTERY_UNITS_AMPS "mA" 49#define ACPI_BATTERY_UNITS_AMPS "mA"
53 50
54#define _COMPONENT ACPI_BATTERY_COMPONENT 51#define _COMPONENT ACPI_BATTERY_COMPONENT
52
53#define ACPI_BATTERY_UPDATE_TIME 0
54
55#define ACPI_BATTERY_NONE_UPDATE 0
56#define ACPI_BATTERY_EASY_UPDATE 1
57#define ACPI_BATTERY_INIT_UPDATE 2
58
55ACPI_MODULE_NAME("battery"); 59ACPI_MODULE_NAME("battery");
56 60
57MODULE_AUTHOR("Paul Diefenbaugh"); 61MODULE_AUTHOR("Paul Diefenbaugh");
58MODULE_DESCRIPTION("ACPI Battery Driver"); 62MODULE_DESCRIPTION("ACPI Battery Driver");
59MODULE_LICENSE("GPL"); 63MODULE_LICENSE("GPL");
60 64
65static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
66
67/* 0 - every time, > 0 - by update_time */
68module_param(update_time, uint, 0644);
69
61extern struct proc_dir_entry *acpi_lock_battery_dir(void); 70extern struct proc_dir_entry *acpi_lock_battery_dir(void);
62extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); 71extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
63 72
@@ -76,7 +85,7 @@ static struct acpi_driver acpi_battery_driver = {
76 }, 85 },
77}; 86};
78 87
79struct acpi_battery_status { 88struct acpi_battery_state {
80 acpi_integer state; 89 acpi_integer state;
81 acpi_integer present_rate; 90 acpi_integer present_rate;
82 acpi_integer remaining_capacity; 91 acpi_integer remaining_capacity;
@@ -99,33 +108,111 @@ struct acpi_battery_info {
99 acpi_string oem_info; 108 acpi_string oem_info;
100}; 109};
101 110
102struct acpi_battery_flags { 111enum acpi_battery_files{
103 u8 present:1; /* Bay occupied? */ 112 ACPI_BATTERY_INFO = 0,
104 u8 power_unit:1; /* 0=watts, 1=apms */ 113 ACPI_BATTERY_STATE,
105 u8 alarm:1; /* _BTP present? */ 114 ACPI_BATTERY_ALARM,
106 u8 reserved:5; 115 ACPI_BATTERY_NUMFILES,
107}; 116};
108 117
109struct acpi_battery_trips { 118struct acpi_battery_flags {
110 unsigned long warning; 119 u8 battery_present_prev;
111 unsigned long low; 120 u8 alarm_present;
121 u8 init_update;
122 u8 update[ACPI_BATTERY_NUMFILES];
123 u8 power_unit;
112}; 124};
113 125
114struct acpi_battery { 126struct acpi_battery {
115 struct acpi_device * device; 127 struct mutex mutex;
128 struct acpi_device *device;
116 struct acpi_battery_flags flags; 129 struct acpi_battery_flags flags;
117 struct acpi_battery_trips trips; 130 struct acpi_buffer bif_data;
131 struct acpi_buffer bst_data;
118 unsigned long alarm; 132 unsigned long alarm;
119 struct acpi_battery_info *info; 133 unsigned long update_time[ACPI_BATTERY_NUMFILES];
120}; 134};
121 135
136inline int acpi_battery_present(struct acpi_battery *battery)
137{
138 return battery->device->status.battery_present;
139}
140inline char *acpi_battery_power_units(struct acpi_battery *battery)
141{
142 if (battery->flags.power_unit)
143 return ACPI_BATTERY_UNITS_AMPS;
144 else
145 return ACPI_BATTERY_UNITS_WATTS;
146}
147
148inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
149{
150 return battery->device->handle;
151}
152
122/* -------------------------------------------------------------------------- 153/* --------------------------------------------------------------------------
123 Battery Management 154 Battery Management
124 -------------------------------------------------------------------------- */ 155 -------------------------------------------------------------------------- */
125 156
126static int 157static void acpi_battery_check_result(struct acpi_battery *battery, int result)
127acpi_battery_get_info(struct acpi_battery *battery, 158{
128 struct acpi_battery_info **bif) 159 if (!battery)
160 return;
161
162 if (result) {
163 battery->flags.init_update = 1;
164 }
165}
166
167static int acpi_battery_extract_package(struct acpi_battery *battery,
168 union acpi_object *package,
169 struct acpi_buffer *format,
170 struct acpi_buffer *data,
171 char *package_name)
172{
173 acpi_status status = AE_OK;
174 struct acpi_buffer data_null = { 0, NULL };
175
176 status = acpi_extract_package(package, format, &data_null);
177 if (status != AE_BUFFER_OVERFLOW) {
178 ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
179 package_name));
180 return -ENODEV;
181 }
182
183 if (data_null.length != data->length) {
184 kfree(data->pointer);
185 data->pointer = kzalloc(data_null.length, GFP_KERNEL);
186 if (!data->pointer) {
187 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
188 return -ENOMEM;
189 }
190 data->length = data_null.length;
191 }
192
193 status = acpi_extract_package(package, format, data);
194 if (ACPI_FAILURE(status)) {
195 ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
196 package_name));
197 return -ENODEV;
198 }
199
200 return 0;
201}
202
203static int acpi_battery_get_status(struct acpi_battery *battery)
204{
205 int result = 0;
206
207 result = acpi_bus_get_status(battery->device);
208 if (result) {
209 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
210 return -ENODEV;
211 }
212 return result;
213}
214
215static int acpi_battery_get_info(struct acpi_battery *battery)
129{ 216{
130 int result = 0; 217 int result = 0;
131 acpi_status status = 0; 218 acpi_status status = 0;
@@ -133,16 +220,20 @@ acpi_battery_get_info(struct acpi_battery *battery,
133 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), 220 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
134 ACPI_BATTERY_FORMAT_BIF 221 ACPI_BATTERY_FORMAT_BIF
135 }; 222 };
136 struct acpi_buffer data = { 0, NULL };
137 union acpi_object *package = NULL; 223 union acpi_object *package = NULL;
224 struct acpi_buffer *data = NULL;
225 struct acpi_battery_info *bif = NULL;
138 226
227 battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
139 228
140 if (!battery || !bif) 229 if (!acpi_battery_present(battery))
141 return -EINVAL; 230 return 0;
142 231
143 /* Evalute _BIF */ 232 /* Evaluate _BIF */
144 233
145 status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer); 234 status =
235 acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
236 &buffer);
146 if (ACPI_FAILURE(status)) { 237 if (ACPI_FAILURE(status)) {
147 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 238 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
148 return -ENODEV; 239 return -ENODEV;
@@ -150,41 +241,29 @@ acpi_battery_get_info(struct acpi_battery *battery,
150 241
151 package = buffer.pointer; 242 package = buffer.pointer;
152 243
153 /* Extract Package Data */ 244 data = &battery->bif_data;
154
155 status = acpi_extract_package(package, &format, &data);
156 if (status != AE_BUFFER_OVERFLOW) {
157 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF"));
158 result = -ENODEV;
159 goto end;
160 }
161 245
162 data.pointer = kzalloc(data.length, GFP_KERNEL); 246 /* Extract Package Data */
163 if (!data.pointer) {
164 result = -ENOMEM;
165 goto end;
166 }
167 247
168 status = acpi_extract_package(package, &format, &data); 248 result =
169 if (ACPI_FAILURE(status)) { 249 acpi_battery_extract_package(battery, package, &format, data,
170 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); 250 "_BIF");
171 kfree(data.pointer); 251 if (result)
172 result = -ENODEV;
173 goto end; 252 goto end;
174 }
175 253
176 end: 254 end:
255
177 kfree(buffer.pointer); 256 kfree(buffer.pointer);
178 257
179 if (!result) 258 if (!result) {
180 (*bif) = data.pointer; 259 bif = data->pointer;
260 battery->flags.power_unit = bif->power_unit;
261 }
181 262
182 return result; 263 return result;
183} 264}
184 265
185static int 266static int acpi_battery_get_state(struct acpi_battery *battery)
186acpi_battery_get_status(struct acpi_battery *battery,
187 struct acpi_battery_status **bst)
188{ 267{
189 int result = 0; 268 int result = 0;
190 acpi_status status = 0; 269 acpi_status status = 0;
@@ -192,16 +271,19 @@ acpi_battery_get_status(struct acpi_battery *battery,
192 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), 271 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
193 ACPI_BATTERY_FORMAT_BST 272 ACPI_BATTERY_FORMAT_BST
194 }; 273 };
195 struct acpi_buffer data = { 0, NULL };
196 union acpi_object *package = NULL; 274 union acpi_object *package = NULL;
275 struct acpi_buffer *data = NULL;
197 276
277 battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
198 278
199 if (!battery || !bst) 279 if (!acpi_battery_present(battery))
200 return -EINVAL; 280 return 0;
201 281
202 /* Evalute _BST */ 282 /* Evaluate _BST */
203 283
204 status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer); 284 status =
285 acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
286 &buffer);
205 if (ACPI_FAILURE(status)) { 287 if (ACPI_FAILURE(status)) {
206 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 288 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
207 return -ENODEV; 289 return -ENODEV;
@@ -209,55 +291,49 @@ acpi_battery_get_status(struct acpi_battery *battery,
209 291
210 package = buffer.pointer; 292 package = buffer.pointer;
211 293
212 /* Extract Package Data */ 294 data = &battery->bst_data;
213
214 status = acpi_extract_package(package, &format, &data);
215 if (status != AE_BUFFER_OVERFLOW) {
216 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST"));
217 result = -ENODEV;
218 goto end;
219 }
220 295
221 data.pointer = kzalloc(data.length, GFP_KERNEL); 296 /* Extract Package Data */
222 if (!data.pointer) {
223 result = -ENOMEM;
224 goto end;
225 }
226 297
227 status = acpi_extract_package(package, &format, &data); 298 result =
228 if (ACPI_FAILURE(status)) { 299 acpi_battery_extract_package(battery, package, &format, data,
229 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); 300 "_BST");
230 kfree(data.pointer); 301 if (result)
231 result = -ENODEV;
232 goto end; 302 goto end;
233 }
234 303
235 end: 304 end:
236 kfree(buffer.pointer); 305 kfree(buffer.pointer);
237 306
238 if (!result)
239 (*bst) = data.pointer;
240
241 return result; 307 return result;
242} 308}
243 309
244static int 310static int acpi_battery_get_alarm(struct acpi_battery *battery)
245acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) 311{
312 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
313
314 return 0;
315}
316
317static int acpi_battery_set_alarm(struct acpi_battery *battery,
318 unsigned long alarm)
246{ 319{
247 acpi_status status = 0; 320 acpi_status status = 0;
248 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 321 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
249 struct acpi_object_list arg_list = { 1, &arg0 }; 322 struct acpi_object_list arg_list = { 1, &arg0 };
250 323
324 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
251 325
252 if (!battery) 326 if (!acpi_battery_present(battery))
253 return -EINVAL; 327 return -ENODEV;
254 328
255 if (!battery->flags.alarm) 329 if (!battery->flags.alarm_present)
256 return -ENODEV; 330 return -ENODEV;
257 331
258 arg0.integer.value = alarm; 332 arg0.integer.value = alarm;
259 333
260 status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); 334 status =
335 acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
336 &arg_list, NULL);
261 if (ACPI_FAILURE(status)) 337 if (ACPI_FAILURE(status))
262 return -ENODEV; 338 return -ENODEV;
263 339
@@ -268,65 +344,114 @@ acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm)
268 return 0; 344 return 0;
269} 345}
270 346
271static int acpi_battery_check(struct acpi_battery *battery) 347static int acpi_battery_init_alarm(struct acpi_battery *battery)
272{ 348{
273 int result = 0; 349 int result = 0;
274 acpi_status status = AE_OK; 350 acpi_status status = AE_OK;
275 acpi_handle handle = NULL; 351 acpi_handle handle = NULL;
276 struct acpi_device *device = NULL; 352 struct acpi_battery_info *bif = battery->bif_data.pointer;
277 struct acpi_battery_info *bif = NULL; 353 unsigned long alarm = battery->alarm;
278 354
355 /* See if alarms are supported, and if so, set default */
279 356
280 if (!battery) 357 status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
281 return -EINVAL; 358 if (ACPI_SUCCESS(status)) {
282 359 battery->flags.alarm_present = 1;
283 device = battery->device; 360 if (!alarm && bif) {
361 alarm = bif->design_capacity_warning;
362 }
363 result = acpi_battery_set_alarm(battery, alarm);
364 if (result)
365 goto end;
366 } else {
367 battery->flags.alarm_present = 0;
368 }
284 369
285 result = acpi_bus_get_status(device); 370 end:
286 if (result)
287 return result;
288 371
289 /* Insertion? */ 372 return result;
373}
290 374
291 if (!battery->flags.present && device->status.battery_present) { 375static int acpi_battery_init_update(struct acpi_battery *battery)
376{
377 int result = 0;
292 378
293 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); 379 result = acpi_battery_get_status(battery);
380 if (result)
381 return result;
294 382
295 /* Evalute _BIF to get certain static information */ 383 battery->flags.battery_present_prev = acpi_battery_present(battery);
296 384
297 result = acpi_battery_get_info(battery, &bif); 385 if (acpi_battery_present(battery)) {
386 result = acpi_battery_get_info(battery);
387 if (result)
388 return result;
389 result = acpi_battery_get_state(battery);
298 if (result) 390 if (result)
299 return result; 391 return result;
300 392
301 battery->flags.power_unit = bif->power_unit; 393 acpi_battery_init_alarm(battery);
302 battery->trips.warning = bif->design_capacity_warning; 394 }
303 battery->trips.low = bif->design_capacity_low; 395
304 kfree(bif); 396 return result;
397}
305 398
306 /* See if alarms are supported, and if so, set default */ 399static int acpi_battery_update(struct acpi_battery *battery,
400 int update, int *update_result_ptr)
401{
402 int result = 0;
403 int update_result = ACPI_BATTERY_NONE_UPDATE;
404
405 if (!acpi_battery_present(battery)) {
406 update = 1;
407 }
307 408
308 status = acpi_get_handle(battery->device->handle, "_BTP", &handle); 409 if (battery->flags.init_update) {
309 if (ACPI_SUCCESS(status)) { 410 result = acpi_battery_init_update(battery);
310 battery->flags.alarm = 1; 411 if (result)
311 acpi_battery_set_alarm(battery, battery->trips.warning); 412 goto end;
413 update_result = ACPI_BATTERY_INIT_UPDATE;
414 } else if (update) {
415 result = acpi_battery_get_status(battery);
416 if (result)
417 goto end;
418 if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
419 || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
420 result = acpi_battery_init_update(battery);
421 if (result)
422 goto end;
423 update_result = ACPI_BATTERY_INIT_UPDATE;
424 } else {
425 update_result = ACPI_BATTERY_EASY_UPDATE;
312 } 426 }
313 } 427 }
314 428
315 /* Removal? */ 429 end:
316 430
317 else if (battery->flags.present && !device->status.battery_present) { 431 battery->flags.init_update = (result != 0);
318 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n"));
319 }
320 432
321 battery->flags.present = device->status.battery_present; 433 *update_result_ptr = update_result;
322 434
323 return result; 435 return result;
324} 436}
325 437
326static void acpi_battery_check_present(struct acpi_battery *battery) 438static void acpi_battery_notify_update(struct acpi_battery *battery)
327{ 439{
328 if (!battery->flags.present) { 440 acpi_battery_get_status(battery);
329 acpi_battery_check(battery); 441
442 if (battery->flags.init_update) {
443 return;
444 }
445
446 if ((!battery->flags.battery_present_prev &
447 acpi_battery_present(battery)) ||
448 (battery->flags.battery_present_prev &
449 !acpi_battery_present(battery))) {
450 battery->flags.init_update = 1;
451 } else {
452 battery->flags.update[ACPI_BATTERY_INFO] = 1;
453 battery->flags.update[ACPI_BATTERY_STATE] = 1;
454 battery->flags.update[ACPI_BATTERY_ALARM] = 1;
330 } 455 }
331} 456}
332 457
@@ -335,37 +460,33 @@ static void acpi_battery_check_present(struct acpi_battery *battery)
335 -------------------------------------------------------------------------- */ 460 -------------------------------------------------------------------------- */
336 461
337static struct proc_dir_entry *acpi_battery_dir; 462static struct proc_dir_entry *acpi_battery_dir;
338static int acpi_battery_read_info(struct seq_file *seq, void *offset) 463
464static int acpi_battery_print_info(struct seq_file *seq, int result)
339{ 465{
340 int result = 0;
341 struct acpi_battery *battery = seq->private; 466 struct acpi_battery *battery = seq->private;
342 struct acpi_battery_info *bif = NULL; 467 struct acpi_battery_info *bif = NULL;
343 char *units = "?"; 468 char *units = "?";
344 469
345 470 if (result)
346 if (!battery)
347 goto end; 471 goto end;
348 472
349 acpi_battery_check_present(battery); 473 if (acpi_battery_present(battery))
350
351 if (battery->flags.present)
352 seq_printf(seq, "present: yes\n"); 474 seq_printf(seq, "present: yes\n");
353 else { 475 else {
354 seq_printf(seq, "present: no\n"); 476 seq_printf(seq, "present: no\n");
355 goto end; 477 goto end;
356 } 478 }
357 479
358 /* Battery Info (_BIF) */ 480 bif = battery->bif_data.pointer;
359 481 if (!bif) {
360 result = acpi_battery_get_info(battery, &bif); 482 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
361 if (result || !bif) { 483 result = -ENODEV;
362 seq_printf(seq, "ERROR: Unable to read battery information\n");
363 goto end; 484 goto end;
364 } 485 }
365 486
366 units = 487 /* Battery Units */
367 bif-> 488
368 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; 489 units = acpi_battery_power_units(battery);
369 490
370 if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 491 if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
371 seq_printf(seq, "design capacity: unknown\n"); 492 seq_printf(seq, "design capacity: unknown\n");
@@ -396,7 +517,6 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
396 else 517 else
397 seq_printf(seq, "design voltage: %d mV\n", 518 seq_printf(seq, "design voltage: %d mV\n",
398 (u32) bif->design_voltage); 519 (u32) bif->design_voltage);
399
400 seq_printf(seq, "design capacity warning: %d %sh\n", 520 seq_printf(seq, "design capacity warning: %d %sh\n",
401 (u32) bif->design_capacity_warning, units); 521 (u32) bif->design_capacity_warning, units);
402 seq_printf(seq, "design capacity low: %d %sh\n", 522 seq_printf(seq, "design capacity low: %d %sh\n",
@@ -411,50 +531,40 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
411 seq_printf(seq, "OEM info: %s\n", bif->oem_info); 531 seq_printf(seq, "OEM info: %s\n", bif->oem_info);
412 532
413 end: 533 end:
414 kfree(bif);
415 534
416 return 0; 535 if (result)
417} 536 seq_printf(seq, "ERROR: Unable to read battery info\n");
418 537
419static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) 538 return result;
420{
421 return single_open(file, acpi_battery_read_info, PDE(inode)->data);
422} 539}
423 540
424static int acpi_battery_read_state(struct seq_file *seq, void *offset) 541static int acpi_battery_print_state(struct seq_file *seq, int result)
425{ 542{
426 int result = 0;
427 struct acpi_battery *battery = seq->private; 543 struct acpi_battery *battery = seq->private;
428 struct acpi_battery_status *bst = NULL; 544 struct acpi_battery_state *bst = NULL;
429 char *units = "?"; 545 char *units = "?";
430 546
431 547 if (result)
432 if (!battery)
433 goto end; 548 goto end;
434 549
435 acpi_battery_check_present(battery); 550 if (acpi_battery_present(battery))
436
437 if (battery->flags.present)
438 seq_printf(seq, "present: yes\n"); 551 seq_printf(seq, "present: yes\n");
439 else { 552 else {
440 seq_printf(seq, "present: no\n"); 553 seq_printf(seq, "present: no\n");
441 goto end; 554 goto end;
442 } 555 }
443 556
444 /* Battery Units */ 557 bst = battery->bst_data.pointer;
445 558 if (!bst) {
446 units = 559 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
447 battery->flags. 560 result = -ENODEV;
448 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
449
450 /* Battery Status (_BST) */
451
452 result = acpi_battery_get_status(battery, &bst);
453 if (result || !bst) {
454 seq_printf(seq, "ERROR: Unable to read battery status\n");
455 goto end; 561 goto end;
456 } 562 }
457 563
564 /* Battery Units */
565
566 units = acpi_battery_power_units(battery);
567
458 if (!(bst->state & 0x04)) 568 if (!(bst->state & 0x04))
459 seq_printf(seq, "capacity state: ok\n"); 569 seq_printf(seq, "capacity state: ok\n");
460 else 570 else
@@ -490,48 +600,43 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
490 (u32) bst->present_voltage); 600 (u32) bst->present_voltage);
491 601
492 end: 602 end:
493 kfree(bst);
494 603
495 return 0; 604 if (result) {
496} 605 seq_printf(seq, "ERROR: Unable to read battery state\n");
606 }
497 607
498static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) 608 return result;
499{
500 return single_open(file, acpi_battery_read_state, PDE(inode)->data);
501} 609}
502 610
503static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 611static int acpi_battery_print_alarm(struct seq_file *seq, int result)
504{ 612{
505 struct acpi_battery *battery = seq->private; 613 struct acpi_battery *battery = seq->private;
506 char *units = "?"; 614 char *units = "?";
507 615
508 616 if (result)
509 if (!battery)
510 goto end; 617 goto end;
511 618
512 acpi_battery_check_present(battery); 619 if (!acpi_battery_present(battery)) {
513
514 if (!battery->flags.present) {
515 seq_printf(seq, "present: no\n"); 620 seq_printf(seq, "present: no\n");
516 goto end; 621 goto end;
517 } 622 }
518 623
519 /* Battery Units */ 624 /* Battery Units */
520 625
521 units = 626 units = acpi_battery_power_units(battery);
522 battery->flags.
523 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
524
525 /* Battery Alarm */
526 627
527 seq_printf(seq, "alarm: "); 628 seq_printf(seq, "alarm: ");
528 if (!battery->alarm) 629 if (!battery->alarm)
529 seq_printf(seq, "unsupported\n"); 630 seq_printf(seq, "unsupported\n");
530 else 631 else
531 seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units); 632 seq_printf(seq, "%lu %sh\n", battery->alarm, units);
532 633
533 end: 634 end:
534 return 0; 635
636 if (result)
637 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
638
639 return result;
535} 640}
536 641
537static ssize_t 642static ssize_t
@@ -543,27 +648,113 @@ acpi_battery_write_alarm(struct file *file,
543 char alarm_string[12] = { '\0' }; 648 char alarm_string[12] = { '\0' };
544 struct seq_file *m = file->private_data; 649 struct seq_file *m = file->private_data;
545 struct acpi_battery *battery = m->private; 650 struct acpi_battery *battery = m->private;
546 651 int update_result = ACPI_BATTERY_NONE_UPDATE;
547 652
548 if (!battery || (count > sizeof(alarm_string) - 1)) 653 if (!battery || (count > sizeof(alarm_string) - 1))
549 return -EINVAL; 654 return -EINVAL;
550 655
551 acpi_battery_check_present(battery); 656 mutex_lock(&battery->mutex);
552 657
553 if (!battery->flags.present) 658 result = acpi_battery_update(battery, 1, &update_result);
554 return -ENODEV; 659 if (result) {
660 result = -ENODEV;
661 goto end;
662 }
663
664 if (!acpi_battery_present(battery)) {
665 result = -ENODEV;
666 goto end;
667 }
555 668
556 if (copy_from_user(alarm_string, buffer, count)) 669 if (copy_from_user(alarm_string, buffer, count)) {
557 return -EFAULT; 670 result = -EFAULT;
671 goto end;
672 }
558 673
559 alarm_string[count] = '\0'; 674 alarm_string[count] = '\0';
560 675
561 result = acpi_battery_set_alarm(battery, 676 result = acpi_battery_set_alarm(battery,
562 simple_strtoul(alarm_string, NULL, 0)); 677 simple_strtoul(alarm_string, NULL, 0));
563 if (result) 678 if (result)
564 return result; 679 goto end;
680
681 end:
565 682
566 return count; 683 acpi_battery_check_result(battery, result);
684
685 if (!result)
686 result = count;
687
688 mutex_unlock(&battery->mutex);
689
690 return result;
691}
692
693typedef int(*print_func)(struct seq_file *seq, int result);
694typedef int(*get_func)(struct acpi_battery *battery);
695
696static struct acpi_read_mux {
697 print_func print;
698 get_func get;
699} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
700 {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
701 {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
702 {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
703};
704
705static int acpi_battery_read(int fid, struct seq_file *seq)
706{
707 struct acpi_battery *battery = seq->private;
708 int result = 0;
709 int update_result = ACPI_BATTERY_NONE_UPDATE;
710 int update = 0;
711
712 mutex_lock(&battery->mutex);
713
714 update = (get_seconds() - battery->update_time[fid] >= update_time);
715 update = (update | battery->flags.update[fid]);
716
717 result = acpi_battery_update(battery, update, &update_result);
718 if (result)
719 goto end;
720
721 if (update_result == ACPI_BATTERY_EASY_UPDATE) {
722 result = acpi_read_funcs[fid].get(battery);
723 if (result)
724 goto end;
725 }
726
727 end:
728 result = acpi_read_funcs[fid].print(seq, result);
729 acpi_battery_check_result(battery, result);
730 battery->flags.update[fid] = result;
731 mutex_unlock(&battery->mutex);
732 return result;
733}
734
735static int acpi_battery_read_info(struct seq_file *seq, void *offset)
736{
737 return acpi_battery_read(ACPI_BATTERY_INFO, seq);
738}
739
740static int acpi_battery_read_state(struct seq_file *seq, void *offset)
741{
742 return acpi_battery_read(ACPI_BATTERY_STATE, seq);
743}
744
745static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
746{
747 return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
748}
749
750static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
751{
752 return single_open(file, acpi_battery_read_info, PDE(inode)->data);
753}
754
755static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
756{
757 return single_open(file, acpi_battery_read_state, PDE(inode)->data);
567} 758}
568 759
569static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) 760static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -571,35 +762,51 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
571 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); 762 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
572} 763}
573 764
574static const struct file_operations acpi_battery_info_ops = { 765static struct battery_file {
766 struct file_operations ops;
767 mode_t mode;
768 char *name;
769} acpi_battery_file[] = {
770 {
771 .name = "info",
772 .mode = S_IRUGO,
773 .ops = {
575 .open = acpi_battery_info_open_fs, 774 .open = acpi_battery_info_open_fs,
576 .read = seq_read, 775 .read = seq_read,
577 .llseek = seq_lseek, 776 .llseek = seq_lseek,
578 .release = single_release, 777 .release = single_release,
579 .owner = THIS_MODULE, 778 .owner = THIS_MODULE,
580}; 779 },
581 780 },
582static const struct file_operations acpi_battery_state_ops = { 781 {
782 .name = "state",
783 .mode = S_IRUGO,
784 .ops = {
583 .open = acpi_battery_state_open_fs, 785 .open = acpi_battery_state_open_fs,
584 .read = seq_read, 786 .read = seq_read,
585 .llseek = seq_lseek, 787 .llseek = seq_lseek,
586 .release = single_release, 788 .release = single_release,
587 .owner = THIS_MODULE, 789 .owner = THIS_MODULE,
588}; 790 },
589 791 },
590static const struct file_operations acpi_battery_alarm_ops = { 792 {
793 .name = "alarm",
794 .mode = S_IFREG | S_IRUGO | S_IWUSR,
795 .ops = {
591 .open = acpi_battery_alarm_open_fs, 796 .open = acpi_battery_alarm_open_fs,
592 .read = seq_read, 797 .read = seq_read,
593 .write = acpi_battery_write_alarm, 798 .write = acpi_battery_write_alarm,
594 .llseek = seq_lseek, 799 .llseek = seq_lseek,
595 .release = single_release, 800 .release = single_release,
596 .owner = THIS_MODULE, 801 .owner = THIS_MODULE,
802 },
803 },
597}; 804};
598 805
599static int acpi_battery_add_fs(struct acpi_device *device) 806static int acpi_battery_add_fs(struct acpi_device *device)
600{ 807{
601 struct proc_dir_entry *entry = NULL; 808 struct proc_dir_entry *entry = NULL;
602 809 int i;
603 810
604 if (!acpi_device_dir(device)) { 811 if (!acpi_device_dir(device)) {
605 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 812 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@ -609,38 +816,16 @@ static int acpi_battery_add_fs(struct acpi_device *device)
609 acpi_device_dir(device)->owner = THIS_MODULE; 816 acpi_device_dir(device)->owner = THIS_MODULE;
610 } 817 }
611 818
612 /* 'info' [R] */ 819 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
613 entry = create_proc_entry(ACPI_BATTERY_FILE_INFO, 820 entry = create_proc_entry(acpi_battery_file[i].name,
614 S_IRUGO, acpi_device_dir(device)); 821 acpi_battery_file[i].mode, acpi_device_dir(device));
615 if (!entry) 822 if (!entry)
616 return -ENODEV; 823 return -ENODEV;
617 else { 824 else {
618 entry->proc_fops = &acpi_battery_info_ops; 825 entry->proc_fops = &acpi_battery_file[i].ops;
619 entry->data = acpi_driver_data(device); 826 entry->data = acpi_driver_data(device);
620 entry->owner = THIS_MODULE; 827 entry->owner = THIS_MODULE;
621 } 828 }
622
623 /* 'status' [R] */
624 entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS,
625 S_IRUGO, acpi_device_dir(device));
626 if (!entry)
627 return -ENODEV;
628 else {
629 entry->proc_fops = &acpi_battery_state_ops;
630 entry->data = acpi_driver_data(device);
631 entry->owner = THIS_MODULE;
632 }
633
634 /* 'alarm' [R/W] */
635 entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM,
636 S_IFREG | S_IRUGO | S_IWUSR,
637 acpi_device_dir(device));
638 if (!entry)
639 return -ENODEV;
640 else {
641 entry->proc_fops = &acpi_battery_alarm_ops;
642 entry->data = acpi_driver_data(device);
643 entry->owner = THIS_MODULE;
644 } 829 }
645 830
646 return 0; 831 return 0;
@@ -648,15 +833,12 @@ static int acpi_battery_add_fs(struct acpi_device *device)
648 833
649static int acpi_battery_remove_fs(struct acpi_device *device) 834static int acpi_battery_remove_fs(struct acpi_device *device)
650{ 835{
651 836 int i;
652 if (acpi_device_dir(device)) { 837 if (acpi_device_dir(device)) {
653 remove_proc_entry(ACPI_BATTERY_FILE_ALARM, 838 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
839 remove_proc_entry(acpi_battery_file[i].name,
654 acpi_device_dir(device)); 840 acpi_device_dir(device));
655 remove_proc_entry(ACPI_BATTERY_FILE_STATUS, 841 }
656 acpi_device_dir(device));
657 remove_proc_entry(ACPI_BATTERY_FILE_INFO,
658 acpi_device_dir(device));
659
660 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); 842 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
661 acpi_device_dir(device) = NULL; 843 acpi_device_dir(device) = NULL;
662 } 844 }
@@ -673,7 +855,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
673 struct acpi_battery *battery = data; 855 struct acpi_battery *battery = data;
674 struct acpi_device *device = NULL; 856 struct acpi_device *device = NULL;
675 857
676
677 if (!battery) 858 if (!battery)
678 return; 859 return;
679 860
@@ -684,8 +865,10 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
684 case ACPI_BATTERY_NOTIFY_INFO: 865 case ACPI_BATTERY_NOTIFY_INFO:
685 case ACPI_NOTIFY_BUS_CHECK: 866 case ACPI_NOTIFY_BUS_CHECK:
686 case ACPI_NOTIFY_DEVICE_CHECK: 867 case ACPI_NOTIFY_DEVICE_CHECK:
687 acpi_battery_check(battery); 868 device = battery->device;
688 acpi_bus_generate_event(device, event, battery->flags.present); 869 acpi_battery_notify_update(battery);
870 acpi_bus_generate_event(device, event,
871 acpi_battery_present(battery));
689 break; 872 break;
690 default: 873 default:
691 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 874 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -702,7 +885,6 @@ static int acpi_battery_add(struct acpi_device *device)
702 acpi_status status = 0; 885 acpi_status status = 0;
703 struct acpi_battery *battery = NULL; 886 struct acpi_battery *battery = NULL;
704 887
705
706 if (!device) 888 if (!device)
707 return -EINVAL; 889 return -EINVAL;
708 890
@@ -710,15 +892,21 @@ static int acpi_battery_add(struct acpi_device *device)
710 if (!battery) 892 if (!battery)
711 return -ENOMEM; 893 return -ENOMEM;
712 894
895 mutex_init(&battery->mutex);
896
897 mutex_lock(&battery->mutex);
898
713 battery->device = device; 899 battery->device = device;
714 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 900 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
715 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 901 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
716 acpi_driver_data(device) = battery; 902 acpi_driver_data(device) = battery;
717 903
718 result = acpi_battery_check(battery); 904 result = acpi_battery_get_status(battery);
719 if (result) 905 if (result)
720 goto end; 906 goto end;
721 907
908 battery->flags.init_update = 1;
909
722 result = acpi_battery_add_fs(device); 910 result = acpi_battery_add_fs(device);
723 if (result) 911 if (result)
724 goto end; 912 goto end;
@@ -727,6 +915,7 @@ static int acpi_battery_add(struct acpi_device *device)
727 ACPI_ALL_NOTIFY, 915 ACPI_ALL_NOTIFY,
728 acpi_battery_notify, battery); 916 acpi_battery_notify, battery);
729 if (ACPI_FAILURE(status)) { 917 if (ACPI_FAILURE(status)) {
918 ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler"));
730 result = -ENODEV; 919 result = -ENODEV;
731 goto end; 920 goto end;
732 } 921 }
@@ -736,11 +925,14 @@ static int acpi_battery_add(struct acpi_device *device)
736 device->status.battery_present ? "present" : "absent"); 925 device->status.battery_present ? "present" : "absent");
737 926
738 end: 927 end:
928
739 if (result) { 929 if (result) {
740 acpi_battery_remove_fs(device); 930 acpi_battery_remove_fs(device);
741 kfree(battery); 931 kfree(battery);
742 } 932 }
743 933
934 mutex_unlock(&battery->mutex);
935
744 return result; 936 return result;
745} 937}
746 938
@@ -749,18 +941,27 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
749 acpi_status status = 0; 941 acpi_status status = 0;
750 struct acpi_battery *battery = NULL; 942 struct acpi_battery *battery = NULL;
751 943
752
753 if (!device || !acpi_driver_data(device)) 944 if (!device || !acpi_driver_data(device))
754 return -EINVAL; 945 return -EINVAL;
755 946
756 battery = acpi_driver_data(device); 947 battery = acpi_driver_data(device);
757 948
949 mutex_lock(&battery->mutex);
950
758 status = acpi_remove_notify_handler(device->handle, 951 status = acpi_remove_notify_handler(device->handle,
759 ACPI_ALL_NOTIFY, 952 ACPI_ALL_NOTIFY,
760 acpi_battery_notify); 953 acpi_battery_notify);
761 954
762 acpi_battery_remove_fs(device); 955 acpi_battery_remove_fs(device);
763 956
957 kfree(battery->bif_data.pointer);
958
959 kfree(battery->bst_data.pointer);
960
961 mutex_unlock(&battery->mutex);
962
963 mutex_destroy(&battery->mutex);
964
764 kfree(battery); 965 kfree(battery);
765 966
766 return 0; 967 return 0;
@@ -775,7 +976,10 @@ static int acpi_battery_resume(struct acpi_device *device)
775 return -EINVAL; 976 return -EINVAL;
776 977
777 battery = device->driver_data; 978 battery = device->driver_data;
778 return acpi_battery_check(battery); 979
980 battery->flags.init_update = 1;
981
982 return 0;
779} 983}
780 984
781static int __init acpi_battery_init(void) 985static int __init acpi_battery_init(void)
@@ -800,7 +1004,6 @@ static int __init acpi_battery_init(void)
800 1004
801static void __exit acpi_battery_exit(void) 1005static void __exit acpi_battery_exit(void)
802{ 1006{
803
804 acpi_bus_unregister_driver(&acpi_battery_driver); 1007 acpi_bus_unregister_driver(&acpi_battery_driver);
805 1008
806 acpi_unlock_battery_dir(acpi_battery_dir); 1009 acpi_unlock_battery_dir(acpi_battery_dir);
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index fb3f31b5e69f..56a5b3fffeb3 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -288,6 +288,11 @@ static int bay_add(acpi_handle handle, int id)
288 new_bay->pdev = pdev; 288 new_bay->pdev = pdev;
289 platform_set_drvdata(pdev, new_bay); 289 platform_set_drvdata(pdev, new_bay);
290 290
291 /*
292 * we want the bay driver to be able to send uevents
293 */
294 pdev->dev.uevent_suppress = 0;
295
291 if (acpi_bay_add_fs(new_bay)) { 296 if (acpi_bay_add_fs(new_bay)) {
292 platform_device_unregister(new_bay->pdev); 297 platform_device_unregister(new_bay->pdev);
293 goto bay_add_err; 298 goto bay_add_err;
@@ -328,18 +333,12 @@ static void bay_notify(acpi_handle handle, u32 event, void *data)
328{ 333{
329 struct bay *bay_dev = (struct bay *)data; 334 struct bay *bay_dev = (struct bay *)data;
330 struct device *dev = &bay_dev->pdev->dev; 335 struct device *dev = &bay_dev->pdev->dev;
336 char event_string[12];
337 char *envp[] = { event_string, NULL };
331 338
332 bay_dprintk(handle, "Bay event"); 339 bay_dprintk(handle, "Bay event");
333 340 sprintf(event_string, "BAY_EVENT=%d\n", event);
334 switch(event) { 341 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
335 case ACPI_NOTIFY_BUS_CHECK:
336 case ACPI_NOTIFY_DEVICE_CHECK:
337 case ACPI_NOTIFY_EJECT_REQUEST:
338 kobject_uevent(&dev->kobj, KOBJ_CHANGE);
339 break;
340 default:
341 printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event);
342 }
343} 342}
344 343
345static acpi_status 344static acpi_status
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e5084ececb6f..6b2658c96242 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -292,6 +292,10 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
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;
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 4546bf873aea..6192c8be66df 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -40,8 +40,15 @@ MODULE_AUTHOR("Kristen Carlson Accardi");
40MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); 40MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
41MODULE_LICENSE("GPL"); 41MODULE_LICENSE("GPL");
42 42
43static int immediate_undock = 1;
44module_param(immediate_undock, bool, 0644);
45MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
46 "undock immediately when the undock button is pressed, 0 will cause"
47 " the driver to wait for userspace to write the undock sysfs file "
48 " before undocking");
49
43static struct atomic_notifier_head dock_notifier_list; 50static struct atomic_notifier_head dock_notifier_list;
44static struct platform_device dock_device; 51static struct platform_device *dock_device;
45static char dock_device_name[] = "dock"; 52static char dock_device_name[] = "dock";
46 53
47struct dock_station { 54struct dock_station {
@@ -63,6 +70,7 @@ struct dock_dependent_device {
63}; 70};
64 71
65#define DOCK_DOCKING 0x00000001 72#define DOCK_DOCKING 0x00000001
73#define DOCK_UNDOCKING 0x00000002
66#define DOCK_EVENT 3 74#define DOCK_EVENT 3
67#define UNDOCK_EVENT 2 75#define UNDOCK_EVENT 2
68 76
@@ -327,12 +335,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
327 335
328static void dock_event(struct dock_station *ds, u32 event, int num) 336static void dock_event(struct dock_station *ds, u32 event, int num)
329{ 337{
330 struct device *dev = &dock_device.dev; 338 struct device *dev = &dock_device->dev;
339 char event_string[7];
340 char *envp[] = { event_string, NULL };
341
342 if (num == UNDOCK_EVENT)
343 sprintf(event_string, "UNDOCK");
344 else
345 sprintf(event_string, "DOCK");
346
331 /* 347 /*
332 * Indicate that the status of the dock station has 348 * Indicate that the status of the dock station has
333 * changed. 349 * changed.
334 */ 350 */
335 kobject_uevent(&dev->kobj, KOBJ_CHANGE); 351 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
336} 352}
337 353
338/** 354/**
@@ -380,12 +396,11 @@ static void handle_dock(struct dock_station *ds, int dock)
380 union acpi_object arg; 396 union acpi_object arg;
381 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 397 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
382 struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 398 struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
383 union acpi_object *obj;
384 399
385 acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); 400 acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer);
386 obj = name_buffer.pointer;
387 401
388 printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking"); 402 printk(KERN_INFO PREFIX "%s - %s\n",
403 (char *)name_buffer.pointer, dock ? "docking" : "undocking");
389 404
390 /* _DCK method has one argument */ 405 /* _DCK method has one argument */
391 arg_list.count = 1; 406 arg_list.count = 1;
@@ -394,7 +409,8 @@ static void handle_dock(struct dock_station *ds, int dock)
394 arg.integer.value = dock; 409 arg.integer.value = dock;
395 status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); 410 status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
396 if (ACPI_FAILURE(status)) 411 if (ACPI_FAILURE(status))
397 pr_debug("%s: failed to execute _DCK\n", obj->string.pointer); 412 printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n",
413 (char *)name_buffer.pointer);
398 kfree(buffer.pointer); 414 kfree(buffer.pointer);
399 kfree(name_buffer.pointer); 415 kfree(name_buffer.pointer);
400} 416}
@@ -420,6 +436,16 @@ static inline void complete_dock(struct dock_station *ds)
420 ds->last_dock_time = jiffies; 436 ds->last_dock_time = jiffies;
421} 437}
422 438
439static inline void begin_undock(struct dock_station *ds)
440{
441 ds->flags |= DOCK_UNDOCKING;
442}
443
444static inline void complete_undock(struct dock_station *ds)
445{
446 ds->flags &= ~(DOCK_UNDOCKING);
447}
448
423/** 449/**
424 * dock_in_progress - see if we are in the middle of handling a dock event 450 * dock_in_progress - see if we are in the middle of handling a dock event
425 * @ds: the dock station 451 * @ds: the dock station
@@ -550,7 +576,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
550 printk(KERN_ERR PREFIX "Unable to undock!\n"); 576 printk(KERN_ERR PREFIX "Unable to undock!\n");
551 return -EBUSY; 577 return -EBUSY;
552 } 578 }
553 579 complete_undock(ds);
554 return 0; 580 return 0;
555} 581}
556 582
@@ -594,7 +620,11 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
594 * to the driver who wish to hotplug. 620 * to the driver who wish to hotplug.
595 */ 621 */
596 case ACPI_NOTIFY_EJECT_REQUEST: 622 case ACPI_NOTIFY_EJECT_REQUEST:
597 handle_eject_request(ds, event); 623 begin_undock(ds);
624 if (immediate_undock)
625 handle_eject_request(ds, event);
626 else
627 dock_event(ds, event, UNDOCK_EVENT);
598 break; 628 break;
599 default: 629 default:
600 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); 630 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
@@ -653,6 +683,17 @@ static ssize_t show_docked(struct device *dev,
653DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); 683DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
654 684
655/* 685/*
686 * show_flags - read method for flags file in sysfs
687 */
688static ssize_t show_flags(struct device *dev,
689 struct device_attribute *attr, char *buf)
690{
691 return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
692
693}
694DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL);
695
696/*
656 * write_undock - write method for "undock" file in sysfs 697 * write_undock - write method for "undock" file in sysfs
657 */ 698 */
658static ssize_t write_undock(struct device *dev, struct device_attribute *attr, 699static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
@@ -675,16 +716,15 @@ static ssize_t show_dock_uid(struct device *dev,
675 struct device_attribute *attr, char *buf) 716 struct device_attribute *attr, char *buf)
676{ 717{
677 unsigned long lbuf; 718 unsigned long lbuf;
678 acpi_status status = acpi_evaluate_integer(dock_station->handle, "_UID", NULL, &lbuf); 719 acpi_status status = acpi_evaluate_integer(dock_station->handle,
679 if(ACPI_FAILURE(status)) { 720 "_UID", NULL, &lbuf);
721 if (ACPI_FAILURE(status))
680 return 0; 722 return 0;
681 } 723
682 return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf); 724 return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf);
683} 725}
684DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); 726DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
685 727
686
687
688/** 728/**
689 * dock_add - add a new dock station 729 * dock_add - add a new dock station
690 * @handle: the dock station handle 730 * @handle: the dock station handle
@@ -711,33 +751,53 @@ static int dock_add(acpi_handle handle)
711 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); 751 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
712 752
713 /* initialize platform device stuff */ 753 /* initialize platform device stuff */
714 dock_device.name = dock_device_name; 754 dock_device =
715 ret = platform_device_register(&dock_device); 755 platform_device_register_simple(dock_device_name, 0, NULL, 0);
756 if (IS_ERR(dock_device)) {
757 kfree(dock_station);
758 dock_station = NULL;
759 return PTR_ERR(dock_device);
760 }
761
762 /* we want the dock device to send uevents */
763 dock_device->dev.uevent_suppress = 0;
764
765 ret = device_create_file(&dock_device->dev, &dev_attr_docked);
716 if (ret) { 766 if (ret) {
717 printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret); 767 printk("Error %d adding sysfs file\n", ret);
768 platform_device_unregister(dock_device);
718 kfree(dock_station); 769 kfree(dock_station);
770 dock_station = NULL;
719 return ret; 771 return ret;
720 } 772 }
721 ret = device_create_file(&dock_device.dev, &dev_attr_docked); 773 ret = device_create_file(&dock_device->dev, &dev_attr_undock);
722 if (ret) { 774 if (ret) {
723 printk("Error %d adding sysfs file\n", ret); 775 printk("Error %d adding sysfs file\n", ret);
724 platform_device_unregister(&dock_device); 776 device_remove_file(&dock_device->dev, &dev_attr_docked);
777 platform_device_unregister(dock_device);
725 kfree(dock_station); 778 kfree(dock_station);
779 dock_station = NULL;
726 return ret; 780 return ret;
727 } 781 }
728 ret = device_create_file(&dock_device.dev, &dev_attr_undock); 782 ret = device_create_file(&dock_device->dev, &dev_attr_uid);
729 if (ret) { 783 if (ret) {
730 printk("Error %d adding sysfs file\n", ret); 784 printk("Error %d adding sysfs file\n", ret);
731 device_remove_file(&dock_device.dev, &dev_attr_docked); 785 device_remove_file(&dock_device->dev, &dev_attr_docked);
732 platform_device_unregister(&dock_device); 786 device_remove_file(&dock_device->dev, &dev_attr_undock);
787 platform_device_unregister(dock_device);
733 kfree(dock_station); 788 kfree(dock_station);
789 dock_station = NULL;
734 return ret; 790 return ret;
735 } 791 }
736 ret = device_create_file(&dock_device.dev, &dev_attr_uid); 792 ret = device_create_file(&dock_device->dev, &dev_attr_flags);
737 if (ret) { 793 if (ret) {
738 printk("Error %d adding sysfs file\n", ret); 794 printk("Error %d adding sysfs file\n", ret);
739 platform_device_unregister(&dock_device); 795 device_remove_file(&dock_device->dev, &dev_attr_docked);
796 device_remove_file(&dock_device->dev, &dev_attr_undock);
797 device_remove_file(&dock_device->dev, &dev_attr_uid);
798 platform_device_unregister(dock_device);
740 kfree(dock_station); 799 kfree(dock_station);
800 dock_station = NULL;
741 return ret; 801 return ret;
742 } 802 }
743 803
@@ -750,6 +810,7 @@ static int dock_add(acpi_handle handle)
750 dd = alloc_dock_dependent_device(handle); 810 dd = alloc_dock_dependent_device(handle);
751 if (!dd) { 811 if (!dd) {
752 kfree(dock_station); 812 kfree(dock_station);
813 dock_station = NULL;
753 ret = -ENOMEM; 814 ret = -ENOMEM;
754 goto dock_add_err_unregister; 815 goto dock_add_err_unregister;
755 } 816 }
@@ -773,10 +834,13 @@ static int dock_add(acpi_handle handle)
773dock_add_err: 834dock_add_err:
774 kfree(dd); 835 kfree(dd);
775dock_add_err_unregister: 836dock_add_err_unregister:
776 device_remove_file(&dock_device.dev, &dev_attr_docked); 837 device_remove_file(&dock_device->dev, &dev_attr_docked);
777 device_remove_file(&dock_device.dev, &dev_attr_undock); 838 device_remove_file(&dock_device->dev, &dev_attr_undock);
778 platform_device_unregister(&dock_device); 839 device_remove_file(&dock_device->dev, &dev_attr_uid);
840 device_remove_file(&dock_device->dev, &dev_attr_flags);
841 platform_device_unregister(dock_device);
779 kfree(dock_station); 842 kfree(dock_station);
843 dock_station = NULL;
780 return ret; 844 return ret;
781} 845}
782 846
@@ -804,12 +868,15 @@ static int dock_remove(void)
804 printk(KERN_ERR "Error removing notify handler\n"); 868 printk(KERN_ERR "Error removing notify handler\n");
805 869
806 /* cleanup sysfs */ 870 /* cleanup sysfs */
807 device_remove_file(&dock_device.dev, &dev_attr_docked); 871 device_remove_file(&dock_device->dev, &dev_attr_docked);
808 device_remove_file(&dock_device.dev, &dev_attr_undock); 872 device_remove_file(&dock_device->dev, &dev_attr_undock);
809 platform_device_unregister(&dock_device); 873 device_remove_file(&dock_device->dev, &dev_attr_uid);
874 device_remove_file(&dock_device->dev, &dev_attr_flags);
875 platform_device_unregister(dock_device);
810 876
811 /* free dock station memory */ 877 /* free dock station memory */
812 kfree(dock_station); 878 kfree(dock_station);
879 dock_station = NULL;
813 return 0; 880 return 0;
814} 881}
815 882
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 82f496c07675..10e851021eca 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -34,25 +34,26 @@
34#include <linux/proc_fs.h> 34#include <linux/proc_fs.h>
35#include <linux/seq_file.h> 35#include <linux/seq_file.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/list.h>
37#include <asm/io.h> 38#include <asm/io.h>
38#include <acpi/acpi_bus.h> 39#include <acpi/acpi_bus.h>
39#include <acpi/acpi_drivers.h> 40#include <acpi/acpi_drivers.h>
40#include <acpi/actypes.h> 41#include <acpi/actypes.h>
41 42
42#define _COMPONENT ACPI_EC_COMPONENT
43ACPI_MODULE_NAME("ec");
44#define ACPI_EC_COMPONENT 0x00100000
45#define ACPI_EC_CLASS "embedded_controller" 43#define ACPI_EC_CLASS "embedded_controller"
46#define ACPI_EC_HID "PNP0C09" 44#define ACPI_EC_HID "PNP0C09"
47#define ACPI_EC_DEVICE_NAME "Embedded Controller" 45#define ACPI_EC_DEVICE_NAME "Embedded Controller"
48#define ACPI_EC_FILE_INFO "info" 46#define ACPI_EC_FILE_INFO "info"
47
49#undef PREFIX 48#undef PREFIX
50#define PREFIX "ACPI: EC: " 49#define PREFIX "ACPI: EC: "
50
51/* EC status register */ 51/* EC status register */
52#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 52#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
53#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 53#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
54#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ 54#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
55#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ 55#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
56
56/* EC commands */ 57/* EC commands */
57enum ec_command { 58enum ec_command {
58 ACPI_EC_COMMAND_READ = 0x80, 59 ACPI_EC_COMMAND_READ = 0x80,
@@ -61,6 +62,7 @@ enum ec_command {
61 ACPI_EC_BURST_DISABLE = 0x83, 62 ACPI_EC_BURST_DISABLE = 0x83,
62 ACPI_EC_COMMAND_QUERY = 0x84, 63 ACPI_EC_COMMAND_QUERY = 0x84,
63}; 64};
65
64/* EC events */ 66/* EC events */
65enum ec_event { 67enum ec_event {
66 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ 68 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
@@ -94,6 +96,16 @@ static struct acpi_driver acpi_ec_driver = {
94 96
95/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 97/* If we find an EC via the ECDT, we need to keep a ptr to its context */
96/* External interfaces use first EC only, so remember */ 98/* External interfaces use first EC only, so remember */
99typedef int (*acpi_ec_query_func) (void *data);
100
101struct acpi_ec_query_handler {
102 struct list_head node;
103 acpi_ec_query_func func;
104 acpi_handle handle;
105 void *data;
106 u8 query_bit;
107};
108
97static struct acpi_ec { 109static struct acpi_ec {
98 acpi_handle handle; 110 acpi_handle handle;
99 unsigned long gpe; 111 unsigned long gpe;
@@ -104,6 +116,7 @@ static struct acpi_ec {
104 atomic_t query_pending; 116 atomic_t query_pending;
105 atomic_t event_count; 117 atomic_t event_count;
106 wait_queue_head_t wait; 118 wait_queue_head_t wait;
119 struct list_head list;
107} *boot_ec, *first_ec; 120} *boot_ec, *first_ec;
108 121
109/* -------------------------------------------------------------------------- 122/* --------------------------------------------------------------------------
@@ -245,7 +258,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
245 258
246 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0); 259 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0);
247 if (status) { 260 if (status) {
248 printk(KERN_DEBUG PREFIX 261 printk(KERN_ERR PREFIX
249 "input buffer is not empty, aborting transaction\n"); 262 "input buffer is not empty, aborting transaction\n");
250 goto end; 263 goto end;
251 } 264 }
@@ -394,21 +407,67 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
394/* -------------------------------------------------------------------------- 407/* --------------------------------------------------------------------------
395 Event Management 408 Event Management
396 -------------------------------------------------------------------------- */ 409 -------------------------------------------------------------------------- */
410int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
411 acpi_handle handle, acpi_ec_query_func func,
412 void *data)
413{
414 struct acpi_ec_query_handler *handler =
415 kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL);
416 if (!handler)
417 return -ENOMEM;
418
419 handler->query_bit = query_bit;
420 handler->handle = handle;
421 handler->func = func;
422 handler->data = data;
423 mutex_lock(&ec->lock);
424 list_add_tail(&handler->node, &ec->list);
425 mutex_unlock(&ec->lock);
426 return 0;
427}
428
429EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
430
431void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
432{
433 struct acpi_ec_query_handler *handler;
434 mutex_lock(&ec->lock);
435 list_for_each_entry(handler, &ec->list, node) {
436 if (query_bit == handler->query_bit) {
437 list_del(&handler->node);
438 kfree(handler);
439 break;
440 }
441 }
442 mutex_unlock(&ec->lock);
443}
444
445EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
397 446
398static void acpi_ec_gpe_query(void *ec_cxt) 447static void acpi_ec_gpe_query(void *ec_cxt)
399{ 448{
400 struct acpi_ec *ec = ec_cxt; 449 struct acpi_ec *ec = ec_cxt;
401 u8 value = 0; 450 u8 value = 0;
402 char object_name[8]; 451 struct acpi_ec_query_handler *handler, copy;
403 452
404 if (!ec || acpi_ec_query(ec, &value)) 453 if (!ec || acpi_ec_query(ec, &value))
405 return; 454 return;
406 455 mutex_lock(&ec->lock);
407 snprintf(object_name, 8, "_Q%2.2X", value); 456 list_for_each_entry(handler, &ec->list, node) {
408 457 if (value == handler->query_bit) {
409 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); 458 /* have custom handler for this bit */
410 459 memcpy(&copy, handler, sizeof(copy));
411 acpi_evaluate_object(ec->handle, object_name, NULL, NULL); 460 mutex_unlock(&ec->lock);
461 if (copy.func) {
462 copy.func(copy.data);
463 } else if (copy.handle) {
464 acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
465 }
466 return;
467 }
468 }
469 mutex_unlock(&ec->lock);
470 printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
412} 471}
413 472
414static u32 acpi_ec_gpe_handler(void *data) 473static u32 acpi_ec_gpe_handler(void *data)
@@ -427,8 +486,7 @@ static u32 acpi_ec_gpe_handler(void *data)
427 if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { 486 if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
428 atomic_set(&ec->query_pending, 1); 487 atomic_set(&ec->query_pending, 1);
429 status = 488 status =
430 acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, 489 acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
431 ec);
432 } 490 }
433 491
434 return status == AE_OK ? 492 return status == AE_OK ?
@@ -454,57 +512,35 @@ acpi_ec_space_setup(acpi_handle region_handle,
454} 512}
455 513
456static acpi_status 514static acpi_status
457acpi_ec_space_handler(u32 function, 515acpi_ec_space_handler(u32 function, acpi_physical_address address,
458 acpi_physical_address address, 516 u32 bits, acpi_integer *value,
459 u32 bit_width,
460 acpi_integer * value,
461 void *handler_context, void *region_context) 517 void *handler_context, void *region_context)
462{ 518{
463 int result = 0;
464 struct acpi_ec *ec = handler_context; 519 struct acpi_ec *ec = handler_context;
465 u64 temp = *value; 520 int result = 0, i = 0;
466 acpi_integer f_v = 0; 521 u8 temp = 0;
467 int i = 0;
468 522
469 if ((address > 0xFF) || !value || !handler_context) 523 if ((address > 0xFF) || !value || !handler_context)
470 return AE_BAD_PARAMETER; 524 return AE_BAD_PARAMETER;
471 525
472 if (bit_width != 8 && acpi_strict) { 526 if (function != ACPI_READ && function != ACPI_WRITE)
473 return AE_BAD_PARAMETER; 527 return AE_BAD_PARAMETER;
474 }
475
476 next_byte:
477 switch (function) {
478 case ACPI_READ:
479 temp = 0;
480 result = acpi_ec_read(ec, (u8) address, (u8 *) & temp);
481 break;
482 case ACPI_WRITE:
483 result = acpi_ec_write(ec, (u8) address, (u8) temp);
484 break;
485 default:
486 result = -EINVAL;
487 goto out;
488 break;
489 }
490 528
491 bit_width -= 8; 529 if (bits != 8 && acpi_strict)
492 if (bit_width) { 530 return AE_BAD_PARAMETER;
493 if (function == ACPI_READ)
494 f_v |= temp << 8 * i;
495 if (function == ACPI_WRITE)
496 temp >>= 8;
497 i++;
498 address++;
499 goto next_byte;
500 }
501 531
502 if (function == ACPI_READ) { 532 while (bits - i > 0) {
503 f_v |= temp << 8 * i; 533 if (function == ACPI_READ) {
504 *value = f_v; 534 result = acpi_ec_read(ec, address, &temp);
535 (*value) |= ((acpi_integer)temp) << i;
536 } else {
537 temp = 0xff & ((*value) >> i);
538 result = acpi_ec_write(ec, address, temp);
539 }
540 i += 8;
541 ++address;
505 } 542 }
506 543
507 out:
508 switch (result) { 544 switch (result) {
509 case -EINVAL: 545 case -EINVAL:
510 return AE_BAD_PARAMETER; 546 return AE_BAD_PARAMETER;
@@ -597,9 +633,6 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
597static acpi_status 633static acpi_status
598ec_parse_io_ports(struct acpi_resource *resource, void *context); 634ec_parse_io_ports(struct acpi_resource *resource, void *context);
599 635
600static acpi_status
601ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval);
602
603static struct acpi_ec *make_acpi_ec(void) 636static struct acpi_ec *make_acpi_ec(void)
604{ 637{
605 struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); 638 struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
@@ -610,13 +643,52 @@ static struct acpi_ec *make_acpi_ec(void)
610 atomic_set(&ec->event_count, 1); 643 atomic_set(&ec->event_count, 1);
611 mutex_init(&ec->lock); 644 mutex_init(&ec->lock);
612 init_waitqueue_head(&ec->wait); 645 init_waitqueue_head(&ec->wait);
646 INIT_LIST_HEAD(&ec->list);
613 647
614 return ec; 648 return ec;
615} 649}
616 650
651static acpi_status
652acpi_ec_register_query_methods(acpi_handle handle, u32 level,
653 void *context, void **return_value)
654{
655 struct acpi_namespace_node *node = handle;
656 struct acpi_ec *ec = context;
657 int value = 0;
658 if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
659 acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
660 }
661 return AE_OK;
662}
663
664static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
665{
666 if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
667 ec_parse_io_ports, ec)))
668 return -EINVAL;
669
670 /* Get GPE bit assignment (EC events). */
671 /* TODO: Add support for _GPE returning a package */
672 if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
673 return -EINVAL;
674
675 /* Use the global lock for all EC transactions? */
676 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
677
678 /* Find and register all query methods */
679 acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
680 acpi_ec_register_query_methods, ec, NULL);
681
682 ec->handle = handle;
683
684 printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
685 ec->gpe, ec->command_addr, ec->data_addr);
686
687 return 0;
688}
689
617static int acpi_ec_add(struct acpi_device *device) 690static int acpi_ec_add(struct acpi_device *device)
618{ 691{
619 acpi_status status = AE_OK;
620 struct acpi_ec *ec = NULL; 692 struct acpi_ec *ec = NULL;
621 693
622 if (!device) 694 if (!device)
@@ -629,8 +701,7 @@ static int acpi_ec_add(struct acpi_device *device)
629 if (!ec) 701 if (!ec)
630 return -ENOMEM; 702 return -ENOMEM;
631 703
632 status = ec_parse_device(device->handle, 0, ec, NULL); 704 if (ec_parse_device(ec, device->handle)) {
633 if (status != AE_CTRL_TERMINATE) {
634 kfree(ec); 705 kfree(ec);
635 return -EINVAL; 706 return -EINVAL;
636 } 707 }
@@ -641,6 +712,8 @@ static int acpi_ec_add(struct acpi_device *device)
641 /* We might have incorrect info for GL at boot time */ 712 /* We might have incorrect info for GL at boot time */
642 mutex_lock(&boot_ec->lock); 713 mutex_lock(&boot_ec->lock);
643 boot_ec->global_lock = ec->global_lock; 714 boot_ec->global_lock = ec->global_lock;
715 /* Copy handlers from new ec into boot ec */
716 list_splice(&ec->list, &boot_ec->list);
644 mutex_unlock(&boot_ec->lock); 717 mutex_unlock(&boot_ec->lock);
645 kfree(ec); 718 kfree(ec);
646 ec = boot_ec; 719 ec = boot_ec;
@@ -651,22 +724,24 @@ static int acpi_ec_add(struct acpi_device *device)
651 acpi_driver_data(device) = ec; 724 acpi_driver_data(device) = ec;
652 725
653 acpi_ec_add_fs(device); 726 acpi_ec_add_fs(device);
654
655 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
656 acpi_device_name(device), acpi_device_bid(device),
657 (u32) ec->gpe));
658
659 return 0; 727 return 0;
660} 728}
661 729
662static int acpi_ec_remove(struct acpi_device *device, int type) 730static int acpi_ec_remove(struct acpi_device *device, int type)
663{ 731{
664 struct acpi_ec *ec; 732 struct acpi_ec *ec;
733 struct acpi_ec_query_handler *handler;
665 734
666 if (!device) 735 if (!device)
667 return -EINVAL; 736 return -EINVAL;
668 737
669 ec = acpi_driver_data(device); 738 ec = acpi_driver_data(device);
739 mutex_lock(&ec->lock);
740 list_for_each_entry(handler, &ec->list, node) {
741 list_del(&handler->node);
742 kfree(handler);
743 }
744 mutex_unlock(&ec->lock);
670 acpi_ec_remove_fs(device); 745 acpi_ec_remove_fs(device);
671 acpi_driver_data(device) = NULL; 746 acpi_driver_data(device) = NULL;
672 if (ec == first_ec) 747 if (ec == first_ec)
@@ -722,15 +797,13 @@ static int ec_install_handlers(struct acpi_ec *ec)
722 return -ENODEV; 797 return -ENODEV;
723 } 798 }
724 799
725 /* EC is fully operational, allow queries */
726 atomic_set(&ec->query_pending, 0);
727
728 return 0; 800 return 0;
729} 801}
730 802
731static int acpi_ec_start(struct acpi_device *device) 803static int acpi_ec_start(struct acpi_device *device)
732{ 804{
733 struct acpi_ec *ec; 805 struct acpi_ec *ec;
806 int ret = 0;
734 807
735 if (!device) 808 if (!device)
736 return -EINVAL; 809 return -EINVAL;
@@ -740,14 +813,14 @@ static int acpi_ec_start(struct acpi_device *device)
740 if (!ec) 813 if (!ec)
741 return -EINVAL; 814 return -EINVAL;
742 815
743 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
744 ec->gpe, ec->command_addr, ec->data_addr));
745
746 /* Boot EC is already working */ 816 /* Boot EC is already working */
747 if (ec == boot_ec) 817 if (ec != boot_ec)
748 return 0; 818 ret = ec_install_handlers(ec);
819
820 /* EC is fully operational, allow queries */
821 atomic_set(&ec->query_pending, 0);
749 822
750 return ec_install_handlers(ec); 823 return ret;
751} 824}
752 825
753static int acpi_ec_stop(struct acpi_device *device, int type) 826static int acpi_ec_stop(struct acpi_device *device, int type)
@@ -779,34 +852,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
779 return 0; 852 return 0;
780} 853}
781 854
782static acpi_status
783ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
784{
785 acpi_status status;
786
787 struct acpi_ec *ec = context;
788 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
789 ec_parse_io_ports, ec);
790 if (ACPI_FAILURE(status))
791 return status;
792
793 /* Get GPE bit assignment (EC events). */
794 /* TODO: Add support for _GPE returning a package */
795 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
796 if (ACPI_FAILURE(status))
797 return status;
798
799 /* Use the global lock for all EC transactions? */
800 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
801
802 ec->handle = handle;
803
804 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
805 ec->gpe, ec->command_addr, ec->data_addr));
806
807 return AE_CTRL_TERMINATE;
808}
809
810int __init acpi_ec_ecdt_probe(void) 855int __init acpi_ec_ecdt_probe(void)
811{ 856{
812 int ret; 857 int ret;
@@ -825,7 +870,7 @@ int __init acpi_ec_ecdt_probe(void)
825 if (ACPI_FAILURE(status)) 870 if (ACPI_FAILURE(status))
826 goto error; 871 goto error;
827 872
828 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); 873 printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
829 874
830 boot_ec->command_addr = ecdt_ptr->control.address; 875 boot_ec->command_addr = ecdt_ptr->control.address;
831 boot_ec->data_addr = ecdt_ptr->data.address; 876 boot_ec->data_addr = ecdt_ptr->data.address;
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 3b23562e6f92..dfa5853b17f0 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -11,6 +11,8 @@
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
16ACPI_MODULE_NAME("event"); 18ACPI_MODULE_NAME("event");
@@ -48,7 +50,6 @@ acpi_system_read_event(struct file *file, char __user * buffer, size_t count,
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
@@ -106,23 +107,161 @@ static const struct file_operations acpi_system_event_ops = {
106 .poll = acpi_system_poll_event, 107 .poll = acpi_system_poll_event,
107}; 108};
108 109
110#ifdef CONFIG_NET
111unsigned int acpi_event_seqnum;
112struct 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 */
120enum {
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 */
128enum {
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_FAMILY_NAME "acpi_event"
136#define ACPI_GENL_VERSION 0x01
137#define ACPI_GENL_MCAST_GROUP_NAME "acpi_mc_group"
138
139static struct genl_family acpi_event_genl_family = {
140 .id = GENL_ID_GENERATE,
141 .name = ACPI_GENL_FAMILY_NAME,
142 .version = ACPI_GENL_VERSION,
143 .maxattr = ACPI_GENL_ATTR_MAX,
144};
145
146static struct genl_multicast_group acpi_event_mcgrp = {
147 .name = ACPI_GENL_MCAST_GROUP_NAME,
148};
149
150int acpi_bus_generate_genetlink_event(struct acpi_device *device,
151 u8 type, int data)
152{
153 struct sk_buff *skb;
154 struct nlattr *attr;
155 struct acpi_genl_event *event;
156 void *msg_header;
157 int size;
158 int result;
159
160 /* allocate memory */
161 size = nla_total_size(sizeof(struct acpi_genl_event)) +
162 nla_total_size(0);
163
164 skb = genlmsg_new(size, GFP_ATOMIC);
165 if (!skb)
166 return -ENOMEM;
167
168 /* add the genetlink message header */
169 msg_header = genlmsg_put(skb, 0, acpi_event_seqnum++,
170 &acpi_event_genl_family, 0,
171 ACPI_GENL_CMD_EVENT);
172 if (!msg_header) {
173 nlmsg_free(skb);
174 return -ENOMEM;
175 }
176
177 /* fill the data */
178 attr =
179 nla_reserve(skb, ACPI_GENL_ATTR_EVENT,
180 sizeof(struct acpi_genl_event));
181 if (!attr) {
182 nlmsg_free(skb);
183 return -EINVAL;
184 }
185
186 event = nla_data(attr);
187 if (!event) {
188 nlmsg_free(skb);
189 return -EINVAL;
190 }
191
192 memset(event, 0, sizeof(struct acpi_genl_event));
193
194 strcpy(event->device_class, device->pnp.device_class);
195 strcpy(event->bus_id, device->dev.bus_id);
196 event->type = type;
197 event->data = data;
198
199 /* send multicast genetlink message */
200 result = genlmsg_end(skb, msg_header);
201 if (result < 0) {
202 nlmsg_free(skb);
203 return result;
204 }
205
206 result =
207 genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
208 if (result)
209 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
210 "Failed to send a Genetlink message!\n"));
211 return 0;
212}
213
214static int acpi_event_genetlink_init(void)
215{
216 int result;
217
218 result = genl_register_family(&acpi_event_genl_family);
219 if (result)
220 return result;
221
222 result = genl_register_mc_group(&acpi_event_genl_family,
223 &acpi_event_mcgrp);
224 if (result)
225 genl_unregister_family(&acpi_event_genl_family);
226
227 return result;
228}
229
230#else
231int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type,
232 int data)
233{
234 return 0;
235}
236
237static int acpi_event_genetlink_init(void)
238{
239 return -ENODEV;
240}
241#endif
242
109static int __init acpi_event_init(void) 243static int __init acpi_event_init(void)
110{ 244{
111 struct proc_dir_entry *entry; 245 struct proc_dir_entry *entry;
112 int error = 0; 246 int error = 0;
113 247
114
115 if (acpi_disabled) 248 if (acpi_disabled)
116 return 0; 249 return 0;
117 250
251 /* create genetlink for acpi event */
252 error = acpi_event_genetlink_init();
253 if (error)
254 printk(KERN_WARNING PREFIX
255 "Failed to create genetlink family for ACPI event\n");
256
118 /* 'event' [R] */ 257 /* 'event' [R] */
119 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); 258 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
120 if (entry) 259 if (entry)
121 entry->proc_fops = &acpi_system_event_ops; 260 entry->proc_fops = &acpi_system_event_ops;
122 else { 261 else
123 error = -ENODEV; 262 return -ENODEV;
124 } 263
125 return error; 264 return 0;
126} 265}
127 266
128subsys_initcall(acpi_event_init); 267fs_initcall(acpi_event_init);
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index 902c287b3a4f..361ebe6c4a6f 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -586,6 +586,10 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
586 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 586 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
587 if (gpe_xrupt->previous) { 587 if (gpe_xrupt->previous) {
588 gpe_xrupt->previous->next = gpe_xrupt->next; 588 gpe_xrupt->previous->next = gpe_xrupt->next;
589 } else {
590 /* No previous, update list head */
591
592 acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next;
589 } 593 }
590 594
591 if (gpe_xrupt->next) { 595 if (gpe_xrupt->next) {
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 400d90fca966..23ee7bc4a705 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -284,6 +284,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
284 } 284 }
285 285
286 if (!pci_device_node) { 286 if (!pci_device_node) {
287 ACPI_FREE(pci_id);
287 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 288 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
288 } 289 }
289 290
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 41427a41f620..4893e256e399 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -16,7 +16,7 @@
16#if ACPI_GLUE_DEBUG 16#if ACPI_GLUE_DEBUG
17#define DBG(x...) printk(PREFIX x) 17#define DBG(x...) printk(PREFIX x)
18#else 18#else
19#define DBG(x...) 19#define DBG(x...) do { } while(0)
20#endif 20#endif
21static LIST_HEAD(bus_type_list); 21static LIST_HEAD(bus_type_list);
22static DECLARE_RWSEM(bus_type_sem); 22static DECLARE_RWSEM(bus_type_sem);
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 0c9f15c54e8c..ab04d848b19d 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -36,13 +36,11 @@
36ACPI_MODULE_NAME("numa"); 36ACPI_MODULE_NAME("numa");
37 37
38static nodemask_t nodes_found_map = NODE_MASK_NONE; 38static nodemask_t nodes_found_map = NODE_MASK_NONE;
39#define PXM_INVAL -1
40#define NID_INVAL -1
41 39
42/* maps to convert between proximity domain and logical node ID */ 40/* maps to convert between proximity domain and logical node ID */
43static int pxm_to_node_map[MAX_PXM_DOMAINS] 41static int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
44 = { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL }; 42 = { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL };
45static int node_to_pxm_map[MAX_NUMNODES] 43static int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
46 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; 44 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
47 45
48int pxm_to_node(int pxm) 46int pxm_to_node(int pxm)
@@ -59,6 +57,12 @@ int node_to_pxm(int node)
59 return node_to_pxm_map[node]; 57 return node_to_pxm_map[node];
60} 58}
61 59
60void __acpi_map_pxm_to_node(int pxm, int node)
61{
62 pxm_to_node_map[pxm] = node;
63 node_to_pxm_map[node] = pxm;
64}
65
62int acpi_map_pxm_to_node(int pxm) 66int acpi_map_pxm_to_node(int pxm)
63{ 67{
64 int node = pxm_to_node_map[pxm]; 68 int node = pxm_to_node_map[pxm];
@@ -67,8 +71,7 @@ int acpi_map_pxm_to_node(int pxm)
67 if (nodes_weight(nodes_found_map) >= MAX_NUMNODES) 71 if (nodes_weight(nodes_found_map) >= MAX_NUMNODES)
68 return NID_INVAL; 72 return NID_INVAL;
69 node = first_unset_node(nodes_found_map); 73 node = first_unset_node(nodes_found_map);
70 pxm_to_node_map[pxm] = node; 74 __acpi_map_pxm_to_node(pxm, node);
71 node_to_pxm_map[node] = pxm;
72 node_set(node, nodes_found_map); 75 node_set(node, nodes_found_map);
73 } 76 }
74 77
@@ -83,7 +86,8 @@ void __cpuinit acpi_unmap_pxm_to_node(int node)
83 node_clear(node, nodes_found_map); 86 node_clear(node, nodes_found_map);
84} 87}
85 88
86void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) 89static void __init
90acpi_table_print_srat_entry(struct acpi_subtable_header *header)
87{ 91{
88 92
89 ACPI_FUNCTION_NAME("acpi_table_print_srat_entry"); 93 ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
@@ -200,7 +204,7 @@ static int __init acpi_parse_srat(struct acpi_table_header *table)
200 return 0; 204 return 0;
201} 205}
202 206
203int __init 207static int __init
204acpi_table_parse_srat(enum acpi_srat_type id, 208acpi_table_parse_srat(enum acpi_srat_type id,
205 acpi_table_entry_handler handler, unsigned int max_entries) 209 acpi_table_entry_handler handler, unsigned int max_entries)
206{ 210{
@@ -211,14 +215,13 @@ acpi_table_parse_srat(enum acpi_srat_type id,
211 215
212int __init acpi_numa_init(void) 216int __init acpi_numa_init(void)
213{ 217{
214 int result;
215
216 /* SRAT: Static Resource Affinity Table */ 218 /* SRAT: Static Resource Affinity Table */
217 if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { 219 if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
218 result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, 220 acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
219 acpi_parse_processor_affinity, 221 acpi_parse_processor_affinity, NR_CPUS);
220 NR_CPUS); 222 acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
221 result = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific 223 acpi_parse_memory_affinity,
224 NR_NODE_MEMBLKS);
222 } 225 }
223 226
224 /* SLIT: System Locality Information Table */ 227 /* SLIT: System Locality Information Table */
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 2e7ba615d760..12c09fafce9a 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -77,13 +77,7 @@ static struct workqueue_struct *kacpi_notify_wq;
77#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ 77#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
78static char osi_additional_string[OSI_STRING_LENGTH_MAX]; 78static char osi_additional_string[OSI_STRING_LENGTH_MAX];
79 79
80#define OSI_LINUX_ENABLED 80static int osi_linux; /* disable _OSI(Linux) by default */
81#ifdef OSI_LINUX_ENABLED
82int osi_linux = 1; /* enable _OSI(Linux) by default */
83#else
84int osi_linux; /* disable _OSI(Linux) by default */
85#endif
86
87 81
88#ifdef CONFIG_DMI 82#ifdef CONFIG_DMI
89static struct __initdata dmi_system_id acpi_osl_dmi_table[]; 83static struct __initdata dmi_system_id acpi_osl_dmi_table[];
@@ -1098,7 +1092,7 @@ void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
1098acpi_status 1092acpi_status
1099acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) 1093acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1100{ 1094{
1101 *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL); 1095 *cache = kmem_cache_create(name, size, 0, 0, NULL);
1102 if (*cache == NULL) 1096 if (*cache == NULL)
1103 return AE_ERROR; 1097 return AE_ERROR;
1104 else 1098 else
@@ -1183,17 +1177,10 @@ acpi_os_validate_interface (char *interface)
1183 if (!strcmp("Linux", interface)) { 1177 if (!strcmp("Linux", interface)) {
1184 printk(KERN_WARNING PREFIX 1178 printk(KERN_WARNING PREFIX
1185 "System BIOS is requesting _OSI(Linux)\n"); 1179 "System BIOS is requesting _OSI(Linux)\n");
1186#ifdef OSI_LINUX_ENABLED
1187 printk(KERN_WARNING PREFIX
1188 "Please test with \"acpi_osi=!Linux\"\n"
1189 "Please send dmidecode "
1190 "to linux-acpi@vger.kernel.org\n");
1191#else
1192 printk(KERN_WARNING PREFIX 1180 printk(KERN_WARNING PREFIX
1193 "If \"acpi_osi=Linux\" works better,\n" 1181 "If \"acpi_osi=Linux\" works better,\n"
1194 "Please send dmidecode " 1182 "Please send dmidecode "
1195 "to linux-acpi@vger.kernel.org\n"); 1183 "to linux-acpi@vger.kernel.org\n");
1196#endif
1197 if(osi_linux) 1184 if(osi_linux)
1198 return AE_OK; 1185 return AE_OK;
1199 } 1186 }
@@ -1227,36 +1214,14 @@ acpi_os_validate_address (
1227} 1214}
1228 1215
1229#ifdef CONFIG_DMI 1216#ifdef CONFIG_DMI
1230#ifdef OSI_LINUX_ENABLED
1231static int dmi_osi_not_linux(struct dmi_system_id *d)
1232{
1233 printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident);
1234 enable_osi_linux(0);
1235 return 0;
1236}
1237#else
1238static int dmi_osi_linux(struct dmi_system_id *d) 1217static int dmi_osi_linux(struct dmi_system_id *d)
1239{ 1218{
1240 printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident); 1219 printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident);
1241 enable_osi_linux(1); 1220 enable_osi_linux(1);
1242 return 0; 1221 return 0;
1243} 1222}
1244#endif
1245 1223
1246static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { 1224static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
1247#ifdef OSI_LINUX_ENABLED
1248 /*
1249 * Boxes that need NOT _OSI(Linux)
1250 */
1251 {
1252 .callback = dmi_osi_not_linux,
1253 .ident = "Toshiba Satellite P100",
1254 .matches = {
1255 DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"),
1256 DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"),
1257 },
1258 },
1259#else
1260 /* 1225 /*
1261 * Boxes that need _OSI(Linux) 1226 * Boxes that need _OSI(Linux)
1262 */ 1227 */
@@ -1268,7 +1233,6 @@ static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
1268 DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"), 1233 DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"),
1269 }, 1234 },
1270 }, 1235 },
1271#endif
1272 {} 1236 {}
1273}; 1237};
1274#endif /* CONFIG_DMI */ 1238#endif /* CONFIG_DMI */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index acc594771379..3448edd61dc4 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -733,7 +733,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
733 /* query and set link->irq.active */ 733 /* query and set link->irq.active */
734 acpi_pci_link_get_current(link); 734 acpi_pci_link_get_current(link);
735 735
736 printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), 736 printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device),
737 acpi_device_bid(device)); 737 acpi_device_bid(device));
738 for (i = 0; i < link->irq.possible_count; i++) { 738 for (i = 0; i < link->irq.possible_count; i++) {
739 if (link->irq.active == link->irq.possible[i]) { 739 if (link->irq.active == link->irq.possible[i]) {
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index e1ca86dfdd66..81aceb5da7c7 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -66,6 +66,7 @@
66#define ACPI_PROCESSOR_FILE_LIMIT "limit" 66#define ACPI_PROCESSOR_FILE_LIMIT "limit"
67#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 67#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
68#define ACPI_PROCESSOR_NOTIFY_POWER 0x81 68#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
69#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
69 70
70#define ACPI_PROCESSOR_LIMIT_USER 0 71#define ACPI_PROCESSOR_LIMIT_USER 0
71#define ACPI_PROCESSOR_LIMIT_THERMAL 1 72#define ACPI_PROCESSOR_LIMIT_THERMAL 1
@@ -84,6 +85,8 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
84static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); 85static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
85static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); 86static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
86static int acpi_processor_handle_eject(struct acpi_processor *pr); 87static int acpi_processor_handle_eject(struct acpi_processor *pr);
88extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
89
87 90
88static struct acpi_driver acpi_processor_driver = { 91static struct acpi_driver acpi_processor_driver = {
89 .name = "processor", 92 .name = "processor",
@@ -696,6 +699,9 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
696 acpi_processor_cst_has_changed(pr); 699 acpi_processor_cst_has_changed(pr);
697 acpi_bus_generate_event(device, event, 0); 700 acpi_bus_generate_event(device, event, 0);
698 break; 701 break;
702 case ACPI_PROCESSOR_NOTIFY_THROTTLING:
703 acpi_processor_tstate_has_changed(pr);
704 acpi_bus_generate_event(device, event, 0);
699 default: 705 default:
700 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 706 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
701 "Unsupported event [0x%x]\n", event)); 707 "Unsupported event [0x%x]\n", event));
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 80ffc7829916..a898991f77cb 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -475,7 +475,7 @@ static void acpi_processor_idle(void)
475 /* Get end time (ticks) */ 475 /* Get end time (ticks) */
476 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 476 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
477 477
478#ifdef CONFIG_GENERIC_TIME 478#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
479 /* TSC halts in C2, so notify users */ 479 /* TSC halts in C2, so notify users */
480 mark_tsc_unstable("possible TSC halt in C2"); 480 mark_tsc_unstable("possible TSC halt in C2");
481#endif 481#endif
@@ -490,7 +490,17 @@ static void acpi_processor_idle(void)
490 490
491 case ACPI_STATE_C3: 491 case ACPI_STATE_C3:
492 492
493 if (pr->flags.bm_check) { 493 /*
494 * disable bus master
495 * bm_check implies we need ARB_DIS
496 * !bm_check implies we need cache flush
497 * bm_control implies whether we can do ARB_DIS
498 *
499 * That leaves a case where bm_check is set and bm_control is
500 * not set. In that case we cannot do much, we enter C3
501 * without doing anything.
502 */
503 if (pr->flags.bm_check && pr->flags.bm_control) {
494 if (atomic_inc_return(&c3_cpu_count) == 504 if (atomic_inc_return(&c3_cpu_count) ==
495 num_online_cpus()) { 505 num_online_cpus()) {
496 /* 506 /*
@@ -499,7 +509,7 @@ static void acpi_processor_idle(void)
499 */ 509 */
500 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); 510 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
501 } 511 }
502 } else { 512 } else if (!pr->flags.bm_check) {
503 /* SMP with no shared cache... Invalidate cache */ 513 /* SMP with no shared cache... Invalidate cache */
504 ACPI_FLUSH_CPU_CACHE(); 514 ACPI_FLUSH_CPU_CACHE();
505 } 515 }
@@ -511,13 +521,13 @@ static void acpi_processor_idle(void)
511 acpi_cstate_enter(cx); 521 acpi_cstate_enter(cx);
512 /* Get end time (ticks) */ 522 /* Get end time (ticks) */
513 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 523 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
514 if (pr->flags.bm_check) { 524 if (pr->flags.bm_check && pr->flags.bm_control) {
515 /* Enable bus master arbitration */ 525 /* Enable bus master arbitration */
516 atomic_dec(&c3_cpu_count); 526 atomic_dec(&c3_cpu_count);
517 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); 527 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
518 } 528 }
519 529
520#ifdef CONFIG_GENERIC_TIME 530#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
521 /* TSC halts in C3, so notify users */ 531 /* TSC halts in C3, so notify users */
522 mark_tsc_unstable("TSC halts in C3"); 532 mark_tsc_unstable("TSC halts in C3");
523#endif 533#endif
@@ -961,9 +971,9 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
961 if (pr->flags.bm_check) { 971 if (pr->flags.bm_check) {
962 /* bus mastering control is necessary */ 972 /* bus mastering control is necessary */
963 if (!pr->flags.bm_control) { 973 if (!pr->flags.bm_control) {
974 /* In this case we enter C3 without bus mastering */
964 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 975 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
965 "C3 support requires bus mastering control\n")); 976 "C3 support without bus mastering control\n"));
966 return;
967 } 977 }
968 } else { 978 } else {
969 /* 979 /*
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index b33486009f41..3f55d1f90c11 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -44,17 +44,231 @@
44#define _COMPONENT ACPI_PROCESSOR_COMPONENT 44#define _COMPONENT ACPI_PROCESSOR_COMPONENT
45ACPI_MODULE_NAME("processor_throttling"); 45ACPI_MODULE_NAME("processor_throttling");
46 46
47static int acpi_processor_get_throttling(struct acpi_processor *pr);
48int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
49
50static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
51{
52 acpi_status status = 0;
53 unsigned long tpc = 0;
54
55 if (!pr)
56 return -EINVAL;
57 status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc);
58 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
59 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TPC"));
60 return -ENODEV;
61 }
62 pr->throttling_platform_limit = (int)tpc;
63 return 0;
64}
65
66int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
67{
68 return acpi_processor_get_platform_limit(pr);
69}
70
71/* --------------------------------------------------------------------------
72 _PTC, _TSS, _TSD support
73 -------------------------------------------------------------------------- */
74static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
75{
76 int result = 0;
77 acpi_status status = 0;
78 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
79 union acpi_object *ptc = NULL;
80 union acpi_object obj = { 0 };
81
82 status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer);
83 if (ACPI_FAILURE(status)) {
84 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTC"));
85 return -ENODEV;
86 }
87
88 ptc = (union acpi_object *)buffer.pointer;
89 if (!ptc || (ptc->type != ACPI_TYPE_PACKAGE)
90 || (ptc->package.count != 2)) {
91 printk(KERN_ERR PREFIX "Invalid _PTC data\n");
92 result = -EFAULT;
93 goto end;
94 }
95
96 /*
97 * control_register
98 */
99
100 obj = ptc->package.elements[0];
101
102 if ((obj.type != ACPI_TYPE_BUFFER)
103 || (obj.buffer.length < sizeof(struct acpi_ptc_register))
104 || (obj.buffer.pointer == NULL)) {
105 printk(KERN_ERR PREFIX
106 "Invalid _PTC data (control_register)\n");
107 result = -EFAULT;
108 goto end;
109 }
110 memcpy(&pr->throttling.control_register, obj.buffer.pointer,
111 sizeof(struct acpi_ptc_register));
112
113 /*
114 * status_register
115 */
116
117 obj = ptc->package.elements[1];
118
119 if ((obj.type != ACPI_TYPE_BUFFER)
120 || (obj.buffer.length < sizeof(struct acpi_ptc_register))
121 || (obj.buffer.pointer == NULL)) {
122 printk(KERN_ERR PREFIX "Invalid _PTC data (status_register)\n");
123 result = -EFAULT;
124 goto end;
125 }
126
127 memcpy(&pr->throttling.status_register, obj.buffer.pointer,
128 sizeof(struct acpi_ptc_register));
129
130 end:
131 kfree(buffer.pointer);
132
133 return result;
134}
135static int acpi_processor_get_throttling_states(struct acpi_processor *pr)
136{
137 int result = 0;
138 acpi_status status = AE_OK;
139 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
140 struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
141 struct acpi_buffer state = { 0, NULL };
142 union acpi_object *tss = NULL;
143 int i;
144
145 status = acpi_evaluate_object(pr->handle, "_TSS", NULL, &buffer);
146 if (ACPI_FAILURE(status)) {
147 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSS"));
148 return -ENODEV;
149 }
150
151 tss = buffer.pointer;
152 if (!tss || (tss->type != ACPI_TYPE_PACKAGE)) {
153 printk(KERN_ERR PREFIX "Invalid _TSS data\n");
154 result = -EFAULT;
155 goto end;
156 }
157
158 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
159 tss->package.count));
160
161 pr->throttling.state_count = tss->package.count;
162 pr->throttling.states_tss =
163 kmalloc(sizeof(struct acpi_processor_tx_tss) * tss->package.count,
164 GFP_KERNEL);
165 if (!pr->throttling.states_tss) {
166 result = -ENOMEM;
167 goto end;
168 }
169
170 for (i = 0; i < pr->throttling.state_count; i++) {
171
172 struct acpi_processor_tx_tss *tx =
173 (struct acpi_processor_tx_tss *)&(pr->throttling.
174 states_tss[i]);
175
176 state.length = sizeof(struct acpi_processor_tx_tss);
177 state.pointer = tx;
178
179 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
180
181 status = acpi_extract_package(&(tss->package.elements[i]),
182 &format, &state);
183 if (ACPI_FAILURE(status)) {
184 ACPI_EXCEPTION((AE_INFO, status, "Invalid _TSS data"));
185 result = -EFAULT;
186 kfree(pr->throttling.states_tss);
187 goto end;
188 }
189
190 if (!tx->freqpercentage) {
191 printk(KERN_ERR PREFIX
192 "Invalid _TSS data: freq is zero\n");
193 result = -EFAULT;
194 kfree(pr->throttling.states_tss);
195 goto end;
196 }
197 }
198
199 end:
200 kfree(buffer.pointer);
201
202 return result;
203}
204static int acpi_processor_get_tsd(struct acpi_processor *pr)
205{
206 int result = 0;
207 acpi_status status = AE_OK;
208 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
209 struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
210 struct acpi_buffer state = { 0, NULL };
211 union acpi_object *tsd = NULL;
212 struct acpi_tsd_package *pdomain;
213
214 status = acpi_evaluate_object(pr->handle, "_TSD", NULL, &buffer);
215 if (ACPI_FAILURE(status)) {
216 return -ENODEV;
217 }
218
219 tsd = buffer.pointer;
220 if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) {
221 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
222 result = -EFAULT;
223 goto end;
224 }
225
226 if (tsd->package.count != 1) {
227 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
228 result = -EFAULT;
229 goto end;
230 }
231
232 pdomain = &(pr->throttling.domain_info);
233
234 state.length = sizeof(struct acpi_tsd_package);
235 state.pointer = pdomain;
236
237 status = acpi_extract_package(&(tsd->package.elements[0]),
238 &format, &state);
239 if (ACPI_FAILURE(status)) {
240 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
241 result = -EFAULT;
242 goto end;
243 }
244
245 if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) {
246 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n"));
247 result = -EFAULT;
248 goto end;
249 }
250
251 if (pdomain->revision != ACPI_TSD_REV0_REVISION) {
252 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n"));
253 result = -EFAULT;
254 goto end;
255 }
256
257 end:
258 kfree(buffer.pointer);
259 return result;
260}
261
47/* -------------------------------------------------------------------------- 262/* --------------------------------------------------------------------------
48 Throttling Control 263 Throttling Control
49 -------------------------------------------------------------------------- */ 264 -------------------------------------------------------------------------- */
50static int acpi_processor_get_throttling(struct acpi_processor *pr) 265static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
51{ 266{
52 int state = 0; 267 int state = 0;
53 u32 value = 0; 268 u32 value = 0;
54 u32 duty_mask = 0; 269 u32 duty_mask = 0;
55 u32 duty_value = 0; 270 u32 duty_value = 0;
56 271
57
58 if (!pr) 272 if (!pr)
59 return -EINVAL; 273 return -EINVAL;
60 274
@@ -94,13 +308,115 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
94 return 0; 308 return 0;
95} 309}
96 310
97int acpi_processor_set_throttling(struct acpi_processor *pr, int state) 311static int acpi_read_throttling_status(struct acpi_processor_throttling
312 *throttling)
313{
314 int value = -1;
315 switch (throttling->status_register.space_id) {
316 case ACPI_ADR_SPACE_SYSTEM_IO:
317 acpi_os_read_port((acpi_io_address) throttling->status_register.
318 address, &value,
319 (u32) throttling->status_register.bit_width *
320 8);
321 break;
322 case ACPI_ADR_SPACE_FIXED_HARDWARE:
323 printk(KERN_ERR PREFIX
324 "HARDWARE addr space,NOT supported yet\n");
325 break;
326 default:
327 printk(KERN_ERR PREFIX "Unknown addr space %d\n",
328 (u32) (throttling->status_register.space_id));
329 }
330 return value;
331}
332
333static int acpi_write_throttling_state(struct acpi_processor_throttling
334 *throttling, int value)
335{
336 int ret = -1;
337
338 switch (throttling->control_register.space_id) {
339 case ACPI_ADR_SPACE_SYSTEM_IO:
340 acpi_os_write_port((acpi_io_address) throttling->
341 control_register.address, value,
342 (u32) throttling->control_register.
343 bit_width * 8);
344 ret = 0;
345 break;
346 case ACPI_ADR_SPACE_FIXED_HARDWARE:
347 printk(KERN_ERR PREFIX
348 "HARDWARE addr space,NOT supported yet\n");
349 break;
350 default:
351 printk(KERN_ERR PREFIX "Unknown addr space %d\n",
352 (u32) (throttling->control_register.space_id));
353 }
354 return ret;
355}
356
357static int acpi_get_throttling_state(struct acpi_processor *pr, int value)
358{
359 int i;
360
361 for (i = 0; i < pr->throttling.state_count; i++) {
362 struct acpi_processor_tx_tss *tx =
363 (struct acpi_processor_tx_tss *)&(pr->throttling.
364 states_tss[i]);
365 if (tx->control == value)
366 break;
367 }
368 if (i > pr->throttling.state_count)
369 i = -1;
370 return i;
371}
372
373static int acpi_get_throttling_value(struct acpi_processor *pr, int state)
374{
375 int value = -1;
376 if (state >= 0 && state <= pr->throttling.state_count) {
377 struct acpi_processor_tx_tss *tx =
378 (struct acpi_processor_tx_tss *)&(pr->throttling.
379 states_tss[state]);
380 value = tx->control;
381 }
382 return value;
383}
384
385static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
386{
387 int state = 0;
388 u32 value = 0;
389
390 if (!pr)
391 return -EINVAL;
392
393 if (!pr->flags.throttling)
394 return -ENODEV;
395
396 pr->throttling.state = 0;
397 local_irq_disable();
398 value = acpi_read_throttling_status(&pr->throttling);
399 if (value >= 0) {
400 state = acpi_get_throttling_state(pr, value);
401 pr->throttling.state = state;
402 }
403 local_irq_enable();
404
405 return 0;
406}
407
408static int acpi_processor_get_throttling(struct acpi_processor *pr)
409{
410 return pr->throttling.acpi_processor_get_throttling(pr);
411}
412
413static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
414 int state)
98{ 415{
99 u32 value = 0; 416 u32 value = 0;
100 u32 duty_mask = 0; 417 u32 duty_mask = 0;
101 u32 duty_value = 0; 418 u32 duty_value = 0;
102 419
103
104 if (!pr) 420 if (!pr)
105 return -EINVAL; 421 return -EINVAL;
106 422
@@ -113,6 +429,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
113 if (state == pr->throttling.state) 429 if (state == pr->throttling.state)
114 return 0; 430 return 0;
115 431
432 if (state < pr->throttling_platform_limit)
433 return -EPERM;
116 /* 434 /*
117 * Calculate the duty_value and duty_mask. 435 * Calculate the duty_value and duty_mask.
118 */ 436 */
@@ -165,12 +483,51 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
165 return 0; 483 return 0;
166} 484}
167 485
486static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
487 int state)
488{
489 u32 value = 0;
490
491 if (!pr)
492 return -EINVAL;
493
494 if ((state < 0) || (state > (pr->throttling.state_count - 1)))
495 return -EINVAL;
496
497 if (!pr->flags.throttling)
498 return -ENODEV;
499
500 if (state == pr->throttling.state)
501 return 0;
502
503 if (state < pr->throttling_platform_limit)
504 return -EPERM;
505
506 local_irq_disable();
507
508 value = acpi_get_throttling_value(pr, state);
509 if (value >= 0) {
510 acpi_write_throttling_state(&pr->throttling, value);
511 pr->throttling.state = state;
512 }
513 local_irq_enable();
514
515 return 0;
516}
517
518int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
519{
520 return pr->throttling.acpi_processor_set_throttling(pr, state);
521}
522
168int acpi_processor_get_throttling_info(struct acpi_processor *pr) 523int acpi_processor_get_throttling_info(struct acpi_processor *pr)
169{ 524{
170 int result = 0; 525 int result = 0;
171 int step = 0; 526 int step = 0;
172 int i = 0; 527 int i = 0;
173 528 int no_ptc = 0;
529 int no_tss = 0;
530 int no_tsd = 0;
174 531
175 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 532 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
176 "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", 533 "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
@@ -182,6 +539,21 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
182 return -EINVAL; 539 return -EINVAL;
183 540
184 /* TBD: Support ACPI 2.0 objects */ 541 /* TBD: Support ACPI 2.0 objects */
542 no_ptc = acpi_processor_get_throttling_control(pr);
543 no_tss = acpi_processor_get_throttling_states(pr);
544 no_tsd = acpi_processor_get_tsd(pr);
545
546 if (no_ptc || no_tss) {
547 pr->throttling.acpi_processor_get_throttling =
548 &acpi_processor_get_throttling_fadt;
549 pr->throttling.acpi_processor_set_throttling =
550 &acpi_processor_set_throttling_fadt;
551 } else {
552 pr->throttling.acpi_processor_get_throttling =
553 &acpi_processor_get_throttling_ptc;
554 pr->throttling.acpi_processor_set_throttling =
555 &acpi_processor_set_throttling_ptc;
556 }
185 557
186 if (!pr->throttling.address) { 558 if (!pr->throttling.address) {
187 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); 559 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
@@ -262,7 +634,6 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq,
262 int i = 0; 634 int i = 0;
263 int result = 0; 635 int result = 0;
264 636
265
266 if (!pr) 637 if (!pr)
267 goto end; 638 goto end;
268 639
@@ -280,15 +651,25 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq,
280 } 651 }
281 652
282 seq_printf(seq, "state count: %d\n" 653 seq_printf(seq, "state count: %d\n"
283 "active state: T%d\n", 654 "active state: T%d\n"
284 pr->throttling.state_count, pr->throttling.state); 655 "state available: T%d to T%d\n",
656 pr->throttling.state_count, pr->throttling.state,
657 pr->throttling_platform_limit,
658 pr->throttling.state_count - 1);
285 659
286 seq_puts(seq, "states:\n"); 660 seq_puts(seq, "states:\n");
287 for (i = 0; i < pr->throttling.state_count; i++) 661 if (acpi_processor_get_throttling == acpi_processor_get_throttling_fadt)
288 seq_printf(seq, " %cT%d: %02d%%\n", 662 for (i = 0; i < pr->throttling.state_count; i++)
289 (i == pr->throttling.state ? '*' : ' '), i, 663 seq_printf(seq, " %cT%d: %02d%%\n",
290 (pr->throttling.states[i].performance ? pr-> 664 (i == pr->throttling.state ? '*' : ' '), i,
291 throttling.states[i].performance / 10 : 0)); 665 (pr->throttling.states[i].performance ? pr->
666 throttling.states[i].performance / 10 : 0));
667 else
668 for (i = 0; i < pr->throttling.state_count; i++)
669 seq_printf(seq, " %cT%d: %02d%%\n",
670 (i == pr->throttling.state ? '*' : ' '), i,
671 (int)pr->throttling.states_tss[i].
672 freqpercentage);
292 673
293 end: 674 end:
294 return 0; 675 return 0;
@@ -301,7 +682,7 @@ static int acpi_processor_throttling_open_fs(struct inode *inode,
301 PDE(inode)->data); 682 PDE(inode)->data);
302} 683}
303 684
304static ssize_t acpi_processor_write_throttling(struct file * file, 685static ssize_t acpi_processor_write_throttling(struct file *file,
305 const char __user * buffer, 686 const char __user * buffer,
306 size_t count, loff_t * data) 687 size_t count, loff_t * data)
307{ 688{
@@ -310,7 +691,6 @@ static ssize_t acpi_processor_write_throttling(struct file * file,
310 struct acpi_processor *pr = m->private; 691 struct acpi_processor *pr = m->private;
311 char state_string[12] = { '\0' }; 692 char state_string[12] = { '\0' };
312 693
313
314 if (!pr || (count > sizeof(state_string) - 1)) 694 if (!pr || (count > sizeof(state_string) - 1))
315 return -EINVAL; 695 return -EINVAL;
316 696
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index c1bae106833c..974d00ccfe84 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -127,7 +127,7 @@ static int acpi_sbs_resume(struct acpi_device *device);
127static struct acpi_driver acpi_sbs_driver = { 127static struct acpi_driver acpi_sbs_driver = {
128 .name = "sbs", 128 .name = "sbs",
129 .class = ACPI_SBS_CLASS, 129 .class = ACPI_SBS_CLASS,
130 .ids = ACPI_SBS_HID, 130 .ids = "ACPI0001,ACPI0005",
131 .ops = { 131 .ops = {
132 .add = acpi_sbs_add, 132 .add = acpi_sbs_add,
133 .remove = acpi_sbs_remove, 133 .remove = acpi_sbs_remove,
@@ -176,10 +176,8 @@ struct acpi_battery {
176}; 176};
177 177
178struct acpi_sbs { 178struct acpi_sbs {
179 acpi_handle handle;
180 int base; 179 int base;
181 struct acpi_device *device; 180 struct acpi_device *device;
182 struct acpi_ec_smbus *smbus;
183 struct mutex mutex; 181 struct mutex mutex;
184 int sbsm_present; 182 int sbsm_present;
185 int sbsm_batteries_supported; 183 int sbsm_batteries_supported;
@@ -511,7 +509,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
511 "acpi_sbs_read_word() failed")); 509 "acpi_sbs_read_word() failed"));
512 goto end; 510 goto end;
513 } 511 }
514 512 sbs->sbsm_present = 1;
515 sbs->sbsm_batteries_supported = battery_system_info & 0x000f; 513 sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
516 514
517 end: 515 end:
@@ -1630,13 +1628,12 @@ static int acpi_sbs_add(struct acpi_device *device)
1630{ 1628{
1631 struct acpi_sbs *sbs = NULL; 1629 struct acpi_sbs *sbs = NULL;
1632 int result = 0, remove_result = 0; 1630 int result = 0, remove_result = 0;
1633 unsigned long sbs_obj;
1634 int id; 1631 int id;
1635 acpi_status status = AE_OK; 1632 acpi_status status = AE_OK;
1636 unsigned long val; 1633 unsigned long val;
1637 1634
1638 status = 1635 status =
1639 acpi_evaluate_integer(device->parent->handle, "_EC", NULL, &val); 1636 acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
1640 if (ACPI_FAILURE(status)) { 1637 if (ACPI_FAILURE(status)) {
1641 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); 1638 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
1642 return -EIO; 1639 return -EIO;
@@ -1653,7 +1650,7 @@ static int acpi_sbs_add(struct acpi_device *device)
1653 1650
1654 sbs_mutex_lock(sbs); 1651 sbs_mutex_lock(sbs);
1655 1652
1656 sbs->base = (val & 0xff00ull) >> 8; 1653 sbs->base = 0xff & (val >> 8);
1657 sbs->device = device; 1654 sbs->device = device;
1658 1655
1659 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); 1656 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
@@ -1665,24 +1662,10 @@ static int acpi_sbs_add(struct acpi_device *device)
1665 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); 1662 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
1666 goto end; 1663 goto end;
1667 } 1664 }
1668 status = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
1669 if (status) {
1670 ACPI_EXCEPTION((AE_INFO, status,
1671 "acpi_evaluate_integer() failed"));
1672 result = -EIO;
1673 goto end;
1674 }
1675 if (sbs_obj > 0) {
1676 result = acpi_sbsm_get_info(sbs);
1677 if (result) {
1678 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1679 "acpi_sbsm_get_info() failed"));
1680 goto end;
1681 }
1682 sbs->sbsm_present = 1;
1683 }
1684 1665
1685 if (sbs->sbsm_present == 0) { 1666 acpi_sbsm_get_info(sbs);
1667
1668 if (!sbs->sbsm_present) {
1686 result = acpi_battery_add(sbs, 0); 1669 result = acpi_battery_add(sbs, 0);
1687 if (result) { 1670 if (result) {
1688 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1671 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1702,8 +1685,6 @@ static int acpi_sbs_add(struct acpi_device *device)
1702 } 1685 }
1703 } 1686 }
1704 1687
1705 sbs->handle = device->handle;
1706
1707 init_timer(&sbs->update_timer); 1688 init_timer(&sbs->update_timer);
1708 result = acpi_check_update_proc(sbs); 1689 result = acpi_check_update_proc(sbs);
1709 if (result) 1690 if (result)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index bc7e16ec8393..3279e72a94f8 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -210,17 +210,28 @@ static void acpi_hibernation_finish(void)
210 210
211 /* reset firmware waking vector */ 211 /* reset firmware waking vector */
212 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 212 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
213}
213 214
214 if (init_8259A_after_S1) { 215static int acpi_hibernation_pre_restore(void)
215 printk("Broken toshiba laptop -> kicking interrupts\n"); 216{
216 init_8259A(0); 217 acpi_status status;
217 } 218
219 status = acpi_hw_disable_all_gpes();
220
221 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
222}
223
224static void acpi_hibernation_restore_cleanup(void)
225{
226 acpi_hw_enable_all_runtime_gpes();
218} 227}
219 228
220static struct hibernation_ops acpi_hibernation_ops = { 229static struct hibernation_ops acpi_hibernation_ops = {
221 .prepare = acpi_hibernation_prepare, 230 .prepare = acpi_hibernation_prepare,
222 .enter = acpi_hibernation_enter, 231 .enter = acpi_hibernation_enter,
223 .finish = acpi_hibernation_finish, 232 .finish = acpi_hibernation_finish,
233 .pre_restore = acpi_hibernation_pre_restore,
234 .restore_cleanup = acpi_hibernation_restore_cleanup,
224}; 235};
225#endif /* CONFIG_SOFTWARE_SUSPEND */ 236#endif /* CONFIG_SOFTWARE_SUSPEND */
226 237
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
index d9801eff6489..39e40d56b034 100644
--- a/drivers/acpi/sleep/poweroff.c
+++ b/drivers/acpi/sleep/poweroff.c
@@ -39,7 +39,13 @@ int acpi_sleep_prepare(u32 acpi_state)
39 39
40#ifdef CONFIG_PM 40#ifdef CONFIG_PM
41 41
42void acpi_power_off(void) 42static void acpi_power_off_prepare(void)
43{
44 /* Prepare to power off the system */
45 acpi_sleep_prepare(ACPI_STATE_S5);
46}
47
48static void acpi_power_off(void)
43{ 49{
44 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ 50 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
45 printk("%s called\n", __FUNCTION__); 51 printk("%s called\n", __FUNCTION__);
@@ -48,30 +54,6 @@ void acpi_power_off(void)
48 acpi_enter_sleep_state(ACPI_STATE_S5); 54 acpi_enter_sleep_state(ACPI_STATE_S5);
49} 55}
50 56
51static int acpi_shutdown(struct sys_device *x)
52{
53 switch (system_state) {
54 case SYSTEM_POWER_OFF:
55 /* Prepare to power off the system */
56 return acpi_sleep_prepare(ACPI_STATE_S5);
57 case SYSTEM_SUSPEND_DISK:
58 /* Prepare to suspend the system to disk */
59 return acpi_sleep_prepare(ACPI_STATE_S4);
60 default:
61 return 0;
62 }
63}
64
65static struct sysdev_class acpi_sysclass = {
66 set_kset_name("acpi"),
67 .shutdown = acpi_shutdown
68};
69
70static struct sys_device device_acpi = {
71 .id = 0,
72 .cls = &acpi_sysclass,
73};
74
75static int acpi_poweroff_init(void) 57static int acpi_poweroff_init(void)
76{ 58{
77 if (!acpi_disabled) { 59 if (!acpi_disabled) {
@@ -81,13 +63,8 @@ static int acpi_poweroff_init(void)
81 status = 63 status =
82 acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); 64 acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
83 if (ACPI_SUCCESS(status)) { 65 if (ACPI_SUCCESS(status)) {
84 int error; 66 pm_power_off_prepare = acpi_power_off_prepare;
85 error = sysdev_class_register(&acpi_sysclass); 67 pm_power_off = acpi_power_off;
86 if (!error)
87 error = sysdev_register(&device_acpi);
88 if (!error)
89 pm_power_off = acpi_power_off;
90 return error;
91 } 68 }
92 } 69 }
93 return 0; 70 return 0;
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 83a8d3097904..edee2806e37b 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -39,15 +39,12 @@ ACPI_MODULE_NAME("system");
39 39
40#define ACPI_SYSTEM_CLASS "system" 40#define ACPI_SYSTEM_CLASS "system"
41#define ACPI_SYSTEM_DEVICE_NAME "System" 41#define ACPI_SYSTEM_DEVICE_NAME "System"
42#define ACPI_SYSTEM_FILE_INFO "info"
43#define ACPI_SYSTEM_FILE_EVENT "event"
44#define ACPI_SYSTEM_FILE_DSDT "dsdt"
45#define ACPI_SYSTEM_FILE_FADT "fadt"
46 42
47/* 43/*
48 * Make ACPICA version work as module param 44 * Make ACPICA version work as module param
49 */ 45 */
50static int param_get_acpica_version(char *buffer, struct kernel_param *kp) { 46static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
47{
51 int result; 48 int result;
52 49
53 result = sprintf(buffer, "%x", ACPI_CA_VERSION); 50 result = sprintf(buffer, "%x", ACPI_CA_VERSION);
@@ -58,9 +55,126 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
58module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); 55module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
59 56
60/* -------------------------------------------------------------------------- 57/* --------------------------------------------------------------------------
58 FS Interface (/sys)
59 -------------------------------------------------------------------------- */
60static LIST_HEAD(acpi_table_attr_list);
61static struct kobject tables_kobj;
62
63struct acpi_table_attr {
64 struct bin_attribute attr;
65 char name[8];
66 int instance;
67 struct list_head node;
68};
69
70static ssize_t acpi_table_show(struct kobject *kobj,
71 struct bin_attribute *bin_attr, char *buf,
72 loff_t offset, size_t count)
73{
74 struct acpi_table_attr *table_attr =
75 container_of(bin_attr, struct acpi_table_attr, attr);
76 struct acpi_table_header *table_header = NULL;
77 acpi_status status;
78 ssize_t ret_count = count;
79
80 status =
81 acpi_get_table(table_attr->name, table_attr->instance,
82 &table_header);
83 if (ACPI_FAILURE(status))
84 return -ENODEV;
85
86 if (offset >= table_header->length) {
87 ret_count = 0;
88 goto end;
89 }
90
91 if (offset + ret_count > table_header->length)
92 ret_count = table_header->length - offset;
93
94 memcpy(buf, ((char *)table_header) + offset, ret_count);
95
96 end:
97 return ret_count;
98}
99
100static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
101 struct acpi_table_header *table_header)
102{
103 struct acpi_table_header *header = NULL;
104 struct acpi_table_attr *attr = NULL;
105
106 memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
107
108 list_for_each_entry(attr, &acpi_table_attr_list, node) {
109 if (!memcmp(table_header->signature, attr->name,
110 ACPI_NAME_SIZE))
111 if (table_attr->instance < attr->instance)
112 table_attr->instance = attr->instance;
113 }
114 table_attr->instance++;
115
116 if (table_attr->instance > 1 || (table_attr->instance == 1 &&
117 !acpi_get_table(table_header->
118 signature, 2,
119 &header)))
120 sprintf(table_attr->name + 4, "%d", table_attr->instance);
121
122 table_attr->attr.size = 0;
123 table_attr->attr.read = acpi_table_show;
124 table_attr->attr.attr.name = table_attr->name;
125 table_attr->attr.attr.mode = 0444;
126 table_attr->attr.attr.owner = THIS_MODULE;
127
128 return;
129}
130
131static int acpi_system_sysfs_init(void)
132{
133 struct acpi_table_attr *table_attr;
134 struct acpi_table_header *table_header = NULL;
135 int table_index = 0;
136 int result;
137
138 tables_kobj.parent = &acpi_subsys.kobj;
139 kobject_set_name(&tables_kobj, "tables");
140 result = kobject_register(&tables_kobj);
141 if (result)
142 return result;
143
144 do {
145 result = acpi_get_table_by_index(table_index, &table_header);
146 if (!result) {
147 table_index++;
148 table_attr = NULL;
149 table_attr =
150 kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
151 if (!table_attr)
152 return -ENOMEM;
153
154 acpi_table_attr_init(table_attr, table_header);
155 result =
156 sysfs_create_bin_file(&tables_kobj,
157 &table_attr->attr);
158 if (result) {
159 kfree(table_attr);
160 return result;
161 } else
162 list_add_tail(&table_attr->node,
163 &acpi_table_attr_list);
164 }
165 } while (!result);
166
167 return 0;
168}
169
170/* --------------------------------------------------------------------------
61 FS Interface (/proc) 171 FS Interface (/proc)
62 -------------------------------------------------------------------------- */ 172 -------------------------------------------------------------------------- */
63#ifdef CONFIG_ACPI_PROCFS 173#ifdef CONFIG_ACPI_PROCFS
174#define ACPI_SYSTEM_FILE_INFO "info"
175#define ACPI_SYSTEM_FILE_EVENT "event"
176#define ACPI_SYSTEM_FILE_DSDT "dsdt"
177#define ACPI_SYSTEM_FILE_FADT "fadt"
64 178
65static int acpi_system_read_info(struct seq_file *seq, void *offset) 179static int acpi_system_read_info(struct seq_file *seq, void *offset)
66{ 180{
@@ -80,7 +194,6 @@ static const struct file_operations acpi_system_info_ops = {
80 .llseek = seq_lseek, 194 .llseek = seq_lseek,
81 .release = single_release, 195 .release = single_release,
82}; 196};
83#endif
84 197
85static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, 198static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
86 loff_t *); 199 loff_t *);
@@ -97,13 +210,11 @@ acpi_system_read_dsdt(struct file *file,
97 struct acpi_table_header *dsdt = NULL; 210 struct acpi_table_header *dsdt = NULL;
98 ssize_t res; 211 ssize_t res;
99 212
100
101 status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); 213 status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
102 if (ACPI_FAILURE(status)) 214 if (ACPI_FAILURE(status))
103 return -ENODEV; 215 return -ENODEV;
104 216
105 res = simple_read_from_buffer(buffer, count, ppos, 217 res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length);
106 dsdt, dsdt->length);
107 218
108 return res; 219 return res;
109} 220}
@@ -123,28 +234,21 @@ acpi_system_read_fadt(struct file *file,
123 struct acpi_table_header *fadt = NULL; 234 struct acpi_table_header *fadt = NULL;
124 ssize_t res; 235 ssize_t res;
125 236
126
127 status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); 237 status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
128 if (ACPI_FAILURE(status)) 238 if (ACPI_FAILURE(status))
129 return -ENODEV; 239 return -ENODEV;
130 240
131 res = simple_read_from_buffer(buffer, count, ppos, 241 res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length);
132 fadt, fadt->length);
133 242
134 return res; 243 return res;
135} 244}
136 245
137static int __init acpi_system_init(void) 246static int acpi_system_procfs_init(void)
138{ 247{
139 struct proc_dir_entry *entry; 248 struct proc_dir_entry *entry;
140 int error = 0; 249 int error = 0;
141 char *name; 250 char *name;
142 251
143
144 if (acpi_disabled)
145 return 0;
146
147#ifdef CONFIG_ACPI_PROCFS
148 /* 'info' [R] */ 252 /* 'info' [R] */
149 name = ACPI_SYSTEM_FILE_INFO; 253 name = ACPI_SYSTEM_FILE_INFO;
150 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); 254 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
@@ -153,7 +257,6 @@ static int __init acpi_system_init(void)
153 else { 257 else {
154 entry->proc_fops = &acpi_system_info_ops; 258 entry->proc_fops = &acpi_system_info_ops;
155 } 259 }
156#endif
157 260
158 /* 'dsdt' [R] */ 261 /* 'dsdt' [R] */
159 name = ACPI_SYSTEM_FILE_DSDT; 262 name = ACPI_SYSTEM_FILE_DSDT;
@@ -177,12 +280,32 @@ static int __init acpi_system_init(void)
177 Error: 280 Error:
178 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); 281 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
179 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); 282 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
180#ifdef CONFIG_ACPI_PROCFS
181 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); 283 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
182#endif
183 284
184 error = -EFAULT; 285 error = -EFAULT;
185 goto Done; 286 goto Done;
186} 287}
288#else
289static int acpi_system_procfs_init(void)
290{
291 return 0;
292}
293#endif
294
295static int __init acpi_system_init(void)
296{
297 int result = 0;
298
299 if (acpi_disabled)
300 return 0;
301
302 result = acpi_system_procfs_init();
303 if (result)
304 return result;
305
306 result = acpi_system_sysfs_init();
307
308 return result;
309}
187 310
188subsys_initcall(acpi_system_init); 311subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
index 1285e91474fb..002bb33003af 100644
--- a/drivers/acpi/tables/tbfadt.c
+++ b/drivers/acpi/tables/tbfadt.c
@@ -211,14 +211,17 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags)
211 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. 211 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
212 * Performs validation on some important FADT fields. 212 * Performs validation on some important FADT fields.
213 * 213 *
214 * NOTE: We create a local copy of the FADT regardless of the version.
215 *
214 ******************************************************************************/ 216 ******************************************************************************/
215 217
216void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) 218void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
217{ 219{
218 220
219 /* 221 /*
220 * Check if the FADT is larger than what we know about (ACPI 2.0 version). 222 * Check if the FADT is larger than the largest table that we expect
221 * Truncate the table, but make some noise. 223 * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue
224 * a warning.
222 */ 225 */
223 if (length > sizeof(struct acpi_table_fadt)) { 226 if (length > sizeof(struct acpi_table_fadt)) {
224 ACPI_WARNING((AE_INFO, 227 ACPI_WARNING((AE_INFO,
@@ -227,10 +230,12 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
227 sizeof(struct acpi_table_fadt))); 230 sizeof(struct acpi_table_fadt)));
228 } 231 }
229 232
230 /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ 233 /* Clear the entire local FADT */
231 234
232 ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); 235 ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt));
233 236
237 /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */
238
234 ACPI_MEMCPY(&acpi_gbl_FADT, table, 239 ACPI_MEMCPY(&acpi_gbl_FADT, table,
235 ACPI_MIN(length, sizeof(struct acpi_table_fadt))); 240 ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
236 241
@@ -251,7 +256,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
251 * RETURN: None 256 * RETURN: None
252 * 257 *
253 * DESCRIPTION: Converts all versions of the FADT to a common internal format. 258 * DESCRIPTION: Converts all versions of the FADT to a common internal format.
254 * -> Expand all 32-bit addresses to 64-bit. 259 * Expand all 32-bit addresses to 64-bit.
255 * 260 *
256 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), 261 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
257 * and must contain a copy of the actual FADT. 262 * and must contain a copy of the actual FADT.
@@ -292,8 +297,23 @@ static void acpi_tb_convert_fadt(void)
292 } 297 }
293 298
294 /* 299 /*
295 * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address 300 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
296 * structures as necessary. 301 * should be zero are indeed zero. This will workaround BIOSs that
302 * inadvertently place values in these fields.
303 *
304 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
305 * offset 45, 55, 95, and the word located at offset 109, 110.
306 */
307 if (acpi_gbl_FADT.header.revision < 3) {
308 acpi_gbl_FADT.preferred_profile = 0;
309 acpi_gbl_FADT.pstate_control = 0;
310 acpi_gbl_FADT.cst_control = 0;
311 acpi_gbl_FADT.boot_flags = 0;
312 }
313
314 /*
315 * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X"
316 * generic address structures as necessary.
297 */ 317 */
298 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 318 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
299 target = 319 target =
@@ -349,18 +369,6 @@ static void acpi_tb_convert_fadt(void)
349 acpi_gbl_FADT.xpm1a_event_block.space_id; 369 acpi_gbl_FADT.xpm1a_event_block.space_id;
350 370
351 } 371 }
352
353 /*
354 * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero)
355 * are indeed zero. This will workaround BIOSs that inadvertently placed
356 * values in these fields.
357 */
358 if (acpi_gbl_FADT.header.revision < 3) {
359 acpi_gbl_FADT.preferred_profile = 0;
360 acpi_gbl_FADT.pstate_control = 0;
361 acpi_gbl_FADT.cst_control = 0;
362 acpi_gbl_FADT.boot_flags = 0;
363 }
364} 372}
365 373
366/****************************************************************************** 374/******************************************************************************
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 88a6fc7fd271..58f1338981bc 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -40,6 +40,7 @@
40#include <linux/jiffies.h> 40#include <linux/jiffies.h>
41#include <linux/kmod.h> 41#include <linux/kmod.h>
42#include <linux/seq_file.h> 42#include <linux/seq_file.h>
43#include <linux/reboot.h>
43#include <asm/uaccess.h> 44#include <asm/uaccess.h>
44 45
45#include <acpi/acpi_bus.h> 46#include <acpi/acpi_bus.h>
@@ -59,7 +60,6 @@
59#define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 60#define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0
60#define ACPI_THERMAL_NOTIFY_HOT 0xF1 61#define ACPI_THERMAL_NOTIFY_HOT 0xF1
61#define ACPI_THERMAL_MODE_ACTIVE 0x00 62#define ACPI_THERMAL_MODE_ACTIVE 0x00
62#define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff"
63 63
64#define ACPI_THERMAL_MAX_ACTIVE 10 64#define ACPI_THERMAL_MAX_ACTIVE 10
65#define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 65#define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
@@ -419,26 +419,6 @@ static int acpi_thermal_get_devices(struct acpi_thermal *tz)
419 return 0; 419 return 0;
420} 420}
421 421
422static int acpi_thermal_call_usermode(char *path)
423{
424 char *argv[2] = { NULL, NULL };
425 char *envp[3] = { NULL, NULL, NULL };
426
427
428 if (!path)
429 return -EINVAL;
430
431 argv[0] = path;
432
433 /* minimal command environment */
434 envp[0] = "HOME=/";
435 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
436
437 call_usermodehelper(argv[0], argv, envp, 0);
438
439 return 0;
440}
441
442static int acpi_thermal_critical(struct acpi_thermal *tz) 422static int acpi_thermal_critical(struct acpi_thermal *tz)
443{ 423{
444 if (!tz || !tz->trips.critical.flags.valid) 424 if (!tz || !tz->trips.critical.flags.valid)
@@ -456,7 +436,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
456 acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, 436 acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
457 tz->trips.critical.flags.enabled); 437 tz->trips.critical.flags.enabled);
458 438
459 acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); 439 orderly_poweroff(true);
460 440
461 return 0; 441 return 0;
462} 442}
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 8ec6f8e48138..f112af433e36 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -62,16 +62,13 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
62static char *acpi_interfaces_supported[] = { 62static char *acpi_interfaces_supported[] = {
63 /* Operating System Vendor Strings */ 63 /* Operating System Vendor Strings */
64 64
65 "Windows 2000", 65 "Windows 2000", /* Windows 2000 */
66 "Windows 2001", 66 "Windows 2001", /* Windows XP */
67 "Windows 2001 SP0", 67 "Windows 2001 SP1", /* Windows XP SP1 */
68 "Windows 2001 SP1", 68 "Windows 2001 SP2", /* Windows XP SP2 */
69 "Windows 2001 SP2", 69 "Windows 2001.1", /* Windows Server 2003 */
70 "Windows 2001 SP3", 70 "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */
71 "Windows 2001 SP4", 71 "Windows 2006", /* Windows Vista - Added 03/2006 */
72 "Windows 2001.1",
73 "Windows 2001.1 SP1", /* Added 03/2006 */
74 "Windows 2006", /* Added 03/2006 */
75 72
76 /* Feature Group Strings */ 73 /* Feature Group Strings */
77 74
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 7fd672af33ba..04ea697f72bf 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -33,6 +33,7 @@
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34
35#include <linux/backlight.h> 35#include <linux/backlight.h>
36#include <linux/video_output.h>
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
37 38
38#include <acpi/acpi_bus.h> 39#include <acpi/acpi_bus.h>
@@ -169,6 +170,7 @@ struct acpi_video_device {
169 struct acpi_device *dev; 170 struct acpi_device *dev;
170 struct acpi_video_device_brightness *brightness; 171 struct acpi_video_device_brightness *brightness;
171 struct backlight_device *backlight; 172 struct backlight_device *backlight;
173 struct output_device *output_dev;
172}; 174};
173 175
174/* bus */ 176/* bus */
@@ -272,6 +274,10 @@ static int acpi_video_get_next_level(struct acpi_video_device *device,
272 u32 level_current, u32 event); 274 u32 level_current, u32 event);
273static void acpi_video_switch_brightness(struct acpi_video_device *device, 275static void acpi_video_switch_brightness(struct acpi_video_device *device,
274 int event); 276 int event);
277static int acpi_video_device_get_state(struct acpi_video_device *device,
278 unsigned long *state);
279static int acpi_video_output_get(struct output_device *od);
280static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
275 281
276/*backlight device sysfs support*/ 282/*backlight device sysfs support*/
277static int acpi_video_get_brightness(struct backlight_device *bd) 283static int acpi_video_get_brightness(struct backlight_device *bd)
@@ -297,6 +303,28 @@ static struct backlight_ops acpi_backlight_ops = {
297 .update_status = acpi_video_set_brightness, 303 .update_status = acpi_video_set_brightness,
298}; 304};
299 305
306/*video output device sysfs support*/
307static int acpi_video_output_get(struct output_device *od)
308{
309 unsigned long state;
310 struct acpi_video_device *vd =
311 (struct acpi_video_device *)class_get_devdata(&od->class_dev);
312 acpi_video_device_get_state(vd, &state);
313 return (int)state;
314}
315
316static int acpi_video_output_set(struct output_device *od)
317{
318 unsigned long state = od->request_state;
319 struct acpi_video_device *vd=
320 (struct acpi_video_device *)class_get_devdata(&od->class_dev);
321 return acpi_video_device_set_state(vd, state);
322}
323
324static struct output_properties acpi_output_properties = {
325 .set_state = acpi_video_output_set,
326 .get_status = acpi_video_output_get,
327};
300/* -------------------------------------------------------------------------- 328/* --------------------------------------------------------------------------
301 Video Management 329 Video Management
302 -------------------------------------------------------------------------- */ 330 -------------------------------------------------------------------------- */
@@ -531,7 +559,6 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
531 559
532static void acpi_video_device_find_cap(struct acpi_video_device *device) 560static void acpi_video_device_find_cap(struct acpi_video_device *device)
533{ 561{
534 acpi_integer status;
535 acpi_handle h_dummy1; 562 acpi_handle h_dummy1;
536 int i; 563 int i;
537 u32 max_level = 0; 564 u32 max_level = 0;
@@ -565,50 +592,55 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
565 device->cap._DSS = 1; 592 device->cap._DSS = 1;
566 } 593 }
567 594
568 status = acpi_video_device_lcd_query_levels(device, &obj); 595 if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
569 596
570 if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) { 597 if (obj->package.count >= 2) {
571 int count = 0; 598 int count = 0;
572 union acpi_object *o; 599 union acpi_object *o;
573 600
574 br = kzalloc(sizeof(*br), GFP_KERNEL); 601 br = kzalloc(sizeof(*br), GFP_KERNEL);
575 if (!br) { 602 if (!br) {
576 printk(KERN_ERR "can't allocate memory\n"); 603 printk(KERN_ERR "can't allocate memory\n");
577 } else {
578 br->levels = kmalloc(obj->package.count *
579 sizeof *(br->levels), GFP_KERNEL);
580 if (!br->levels)
581 goto out;
582
583 for (i = 0; i < obj->package.count; i++) {
584 o = (union acpi_object *)&obj->package.
585 elements[i];
586 if (o->type != ACPI_TYPE_INTEGER) {
587 printk(KERN_ERR PREFIX "Invalid data\n");
588 continue;
589 }
590 br->levels[count] = (u32) o->integer.value;
591 if (br->levels[count] > max_level)
592 max_level = br->levels[count];
593 count++;
594 }
595 out:
596 if (count < 2) {
597 kfree(br->levels);
598 kfree(br);
599 } else { 604 } else {
600 br->count = count; 605 br->levels = kmalloc(obj->package.count *
601 device->brightness = br; 606 sizeof *(br->levels), GFP_KERNEL);
602 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 607 if (!br->levels)
603 "found %d brightness levels\n", 608 goto out;
604 count)); 609
610 for (i = 0; i < obj->package.count; i++) {
611 o = (union acpi_object *)&obj->package.
612 elements[i];
613 if (o->type != ACPI_TYPE_INTEGER) {
614 printk(KERN_ERR PREFIX "Invalid data\n");
615 continue;
616 }
617 br->levels[count] = (u32) o->integer.value;
618
619 if (br->levels[count] > max_level)
620 max_level = br->levels[count];
621 count++;
622 }
623 out:
624 if (count < 2) {
625 kfree(br->levels);
626 kfree(br);
627 } else {
628 br->count = count;
629 device->brightness = br;
630 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
631 "found %d brightness levels\n",
632 count));
633 }
605 } 634 }
606 } 635 }
636
637 } else {
638 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
607 } 639 }
608 640
609 kfree(obj); 641 kfree(obj);
610 642
611 if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ 643 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
612 unsigned long tmp; 644 unsigned long tmp;
613 static int count = 0; 645 static int count = 0;
614 char *name; 646 char *name;
@@ -626,6 +658,17 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
626 658
627 kfree(name); 659 kfree(name);
628 } 660 }
661 if (device->cap._DCS && device->cap._DSS){
662 static int count = 0;
663 char *name;
664 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
665 if (!name)
666 return;
667 sprintf(name, "acpi_video%d", count++);
668 device->output_dev = video_output_register(name,
669 NULL, device, &acpi_output_properties);
670 kfree(name);
671 }
629 return; 672 return;
630} 673}
631 674
@@ -1669,6 +1712,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1669 ACPI_DEVICE_NOTIFY, 1712 ACPI_DEVICE_NOTIFY,
1670 acpi_video_device_notify); 1713 acpi_video_device_notify);
1671 backlight_device_unregister(device->backlight); 1714 backlight_device_unregister(device->backlight);
1715 video_output_unregister(device->output_dev);
1672 return 0; 1716 return 0;
1673} 1717}
1674 1718