Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: Cache battery status instead of re-evaluating AML

/proc exports _BST in a single file, and _BST is re-evaulated
whenever that file is read.

Sometimes user-space reads this file frequently, and on some
systems _BST takes a long time to evaluate due to a slow EC.

Further, when we move to sysfs, the values returned from _BST
will be in multiple files, and evaluating _BST for each
file read would make matters worse.

Here code is added to support caching the results of _BST.
A new module parameter "update_time" tells how many seconds the
cached _BST should be used before it is re-evaluated.
Currently, update_time defaults to 0, and so the
existing behaviour of re-evaluating on each read retained.

Signed-off-by: Vladimir Lebedev <vladimir.p.lebedev@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by

Vladimir Lebedev and committed by
Len Brown
b6ce4083 a1f0eff2

+456 -187
+456 -187
drivers/acpi/battery.c
··· 52 52 #define ACPI_BATTERY_UNITS_AMPS "mA" 53 53 54 54 #define _COMPONENT ACPI_BATTERY_COMPONENT 55 + 56 + #define ACPI_BATTERY_UPDATE_TIME 0 57 + 58 + #define ACPI_BATTERY_NONE_UPDATE 0 59 + #define ACPI_BATTERY_EASY_UPDATE 1 60 + #define ACPI_BATTERY_INIT_UPDATE 2 61 + 55 62 ACPI_MODULE_NAME("battery"); 56 63 57 64 MODULE_AUTHOR("Paul Diefenbaugh"); 58 65 MODULE_DESCRIPTION("ACPI Battery Driver"); 59 66 MODULE_LICENSE("GPL"); 67 + 68 + static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME; 69 + 70 + /* 0 - every time, > 0 - by update_time */ 71 + module_param(update_time, uint, 0644); 60 72 61 73 extern struct proc_dir_entry *acpi_lock_battery_dir(void); 62 74 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); ··· 112 100 }; 113 101 114 102 struct acpi_battery_flags { 115 - u8 present:1; /* Bay occupied? */ 116 - u8 power_unit:1; /* 0=watts, 1=apms */ 117 - u8 alarm:1; /* _BTP present? */ 118 - u8 reserved:5; 119 - }; 120 - 121 - struct acpi_battery_trips { 122 - unsigned long warning; 123 - unsigned long low; 103 + u8 battery_present_prev; 104 + u8 alarm_present; 105 + u8 init_update; 106 + u8 info_update; 107 + u8 state_update; 108 + u8 alarm_update; 109 + u8 power_unit; 124 110 }; 125 111 126 112 struct acpi_battery { 113 + struct mutex mutex; 127 114 struct acpi_device * device; 128 115 struct acpi_battery_flags flags; 129 - struct acpi_battery_trips trips; 116 + struct acpi_buffer bif_data; 117 + struct acpi_buffer bst_data; 130 118 unsigned long alarm; 131 - struct acpi_battery_info *info; 119 + unsigned long info_update_time; 120 + unsigned long state_update_time; 121 + unsigned long alarm_update_time; 132 122 }; 123 + 124 + #define acpi_battery_present(battery) battery->device->status.battery_present 125 + #define acpi_battery_present_prev(battery) battery->flags.battery_present_prev 126 + #define acpi_battery_alarm_present(battery) battery->flags.alarm_present 127 + #define acpi_battery_init_update_flag(battery) battery->flags.init_update 128 + #define acpi_battery_info_update_flag(battery) battery->flags.info_update 129 + #define acpi_battery_state_update_flag(battery) battery->flags.state_update 130 + #define acpi_battery_alarm_update_flag(battery) battery->flags.alarm_update 131 + #define acpi_battery_power_units(battery) battery->flags.power_unit ? \ 132 + ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS 133 + #define acpi_battery_handle(battery) battery->device->handle 134 + #define acpi_battery_inserted(battery) (!acpi_battery_present_prev(battery) & acpi_battery_present(battery)) 135 + #define acpi_battery_removed(battery) (acpi_battery_present_prev(battery) & !acpi_battery_present(battery)) 136 + #define acpi_battery_bid(battery) acpi_device_bid(battery->device) 137 + #define acpi_battery_status_str(battery) acpi_battery_present(battery) ? "present" : "absent" 133 138 134 139 /* -------------------------------------------------------------------------- 135 140 Battery Management 136 141 -------------------------------------------------------------------------- */ 137 142 138 - static int 139 - acpi_battery_get_info(struct acpi_battery *battery, 140 - struct acpi_battery_info **bif) 143 + static void acpi_battery_mutex_lock(struct acpi_battery *battery) 144 + { 145 + mutex_lock(&battery->mutex); 146 + } 147 + 148 + static void acpi_battery_mutex_unlock(struct acpi_battery *battery) 149 + { 150 + mutex_unlock(&battery->mutex); 151 + } 152 + 153 + static void acpi_battery_check_result(struct acpi_battery *battery, int result) 154 + { 155 + if (!battery) 156 + return; 157 + 158 + if (result) { 159 + acpi_battery_init_update_flag(battery) = 1; 160 + } 161 + } 162 + 163 + static int acpi_battery_extract_package(struct acpi_battery *battery, 164 + union acpi_object *package, 165 + struct acpi_buffer *format, 166 + struct acpi_buffer *data, 167 + char *package_name) 168 + { 169 + acpi_status status = AE_OK; 170 + struct acpi_buffer data_null = { 0, NULL }; 171 + 172 + status = acpi_extract_package(package, format, &data_null); 173 + if (status != AE_BUFFER_OVERFLOW) { 174 + ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s", 175 + package_name)); 176 + return -ENODEV; 177 + } 178 + 179 + if (data_null.length != data->length) { 180 + if (data->pointer) { 181 + kfree(data->pointer); 182 + } 183 + data->pointer = kzalloc(data_null.length, GFP_KERNEL); 184 + if (!data->pointer) { 185 + ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()")); 186 + return -ENOMEM; 187 + } 188 + data->length = data_null.length; 189 + } 190 + 191 + status = acpi_extract_package(package, format, data); 192 + if (ACPI_FAILURE(status)) { 193 + ACPI_EXCEPTION((AE_INFO, status, "Extracting %s", 194 + package_name)); 195 + return -ENODEV; 196 + } 197 + 198 + return 0; 199 + } 200 + 201 + static int acpi_battery_get_status(struct acpi_battery *battery) 202 + { 203 + int result = 0; 204 + 205 + result = acpi_bus_get_status(battery->device); 206 + if (result) { 207 + ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); 208 + return -ENODEV; 209 + } 210 + return result; 211 + } 212 + 213 + static int acpi_battery_get_info(struct acpi_battery *battery) 141 214 { 142 215 int result = 0; 143 216 acpi_status status = 0; ··· 230 133 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), 231 134 ACPI_BATTERY_FORMAT_BIF 232 135 }; 233 - struct acpi_buffer data = { 0, NULL }; 234 136 union acpi_object *package = NULL; 137 + struct acpi_buffer *data = NULL; 138 + struct acpi_battery_info *bif = NULL; 235 139 140 + battery->info_update_time = get_seconds(); 236 141 237 - if (!battery || !bif) 238 - return -EINVAL; 142 + if (!acpi_battery_present(battery)) 143 + return 0; 239 144 240 145 /* Evalute _BIF */ 241 146 242 - status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer); 147 + status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, &buffer); 243 148 if (ACPI_FAILURE(status)) { 244 149 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 245 150 return -ENODEV; ··· 249 150 250 151 package = buffer.pointer; 251 152 153 + data = &battery->bif_data; 154 + 252 155 /* Extract Package Data */ 253 156 254 - status = acpi_extract_package(package, &format, &data); 255 - if (status != AE_BUFFER_OVERFLOW) { 256 - ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); 257 - result = -ENODEV; 157 + result = acpi_battery_extract_package(battery, package, &format, data, "_BIF"); 158 + if (result) 258 159 goto end; 259 - } 260 - 261 - data.pointer = kzalloc(data.length, GFP_KERNEL); 262 - if (!data.pointer) { 263 - result = -ENOMEM; 264 - goto end; 265 - } 266 - 267 - status = acpi_extract_package(package, &format, &data); 268 - if (ACPI_FAILURE(status)) { 269 - ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); 270 - kfree(data.pointer); 271 - result = -ENODEV; 272 - goto end; 273 - } 274 160 275 161 end: 276 - kfree(buffer.pointer); 277 162 278 - if (!result) 279 - (*bif) = data.pointer; 163 + if (buffer.pointer) { 164 + kfree(buffer.pointer); 165 + } 166 + 167 + if (!result) { 168 + bif = data->pointer; 169 + battery->flags.power_unit = bif->power_unit; 170 + } 280 171 281 172 return result; 282 173 } 283 174 284 - static int 285 - acpi_battery_get_state(struct acpi_battery *battery, 286 - struct acpi_battery_state **bst) 175 + static int acpi_battery_get_state(struct acpi_battery *battery) 287 176 { 288 177 int result = 0; 289 178 acpi_status status = 0; ··· 279 192 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), 280 193 ACPI_BATTERY_FORMAT_BST 281 194 }; 282 - struct acpi_buffer data = { 0, NULL }; 283 195 union acpi_object *package = NULL; 196 + struct acpi_buffer *data = NULL; 284 197 198 + battery->state_update_time = get_seconds(); 285 199 286 - if (!battery || !bst) 287 - return -EINVAL; 200 + if (!acpi_battery_present(battery)) 201 + return 0; 288 202 289 203 /* Evalute _BST */ 290 204 291 - status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer); 205 + status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, &buffer); 292 206 if (ACPI_FAILURE(status)) { 293 207 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 294 208 return -ENODEV; ··· 297 209 298 210 package = buffer.pointer; 299 211 212 + data = &battery->bst_data; 213 + 300 214 /* Extract Package Data */ 301 215 302 - status = acpi_extract_package(package, &format, &data); 303 - if (status != AE_BUFFER_OVERFLOW) { 304 - ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); 305 - result = -ENODEV; 216 + result = acpi_battery_extract_package(battery, package, &format, data, "_BST"); 217 + if (result) 306 218 goto end; 307 - } 308 - 309 - data.pointer = kzalloc(data.length, GFP_KERNEL); 310 - if (!data.pointer) { 311 - result = -ENOMEM; 312 - goto end; 313 - } 314 - 315 - status = acpi_extract_package(package, &format, &data); 316 - if (ACPI_FAILURE(status)) { 317 - ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); 318 - kfree(data.pointer); 319 - result = -ENODEV; 320 - goto end; 321 - } 322 219 323 220 end: 324 - kfree(buffer.pointer); 325 - 326 - if (!result) 327 - (*bst) = data.pointer; 221 + if (buffer.pointer) { 222 + kfree(buffer.pointer); 223 + } 328 224 329 225 return result; 330 226 } 331 227 332 - static int 333 - acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) 228 + static int acpi_battery_get_alarm(struct acpi_battery *battery) 229 + { 230 + battery->alarm_update_time = get_seconds(); 231 + 232 + return 0; 233 + } 234 + 235 + static int acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) 334 236 { 335 237 acpi_status status = 0; 336 238 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 337 239 struct acpi_object_list arg_list = { 1, &arg0 }; 338 240 241 + battery->alarm_update_time = get_seconds(); 339 242 340 - if (!battery) 341 - return -EINVAL; 243 + if (!acpi_battery_present(battery)) 244 + return -ENODEV; 342 245 343 - if (!battery->flags.alarm) 246 + if (!acpi_battery_alarm_present(battery)) 344 247 return -ENODEV; 345 248 346 249 arg0.integer.value = alarm; 347 250 348 - status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); 251 + status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", &arg_list, NULL); 349 252 if (ACPI_FAILURE(status)) 350 253 return -ENODEV; 351 254 ··· 347 268 return 0; 348 269 } 349 270 350 - static int acpi_battery_check(struct acpi_battery *battery) 271 + static int acpi_battery_init_alarm(struct acpi_battery *battery) 351 272 { 352 273 int result = 0; 353 274 acpi_status status = AE_OK; 354 275 acpi_handle handle = NULL; 355 - struct acpi_device *device = NULL; 356 - struct acpi_battery_info *bif = NULL; 276 + struct acpi_battery_info *bif = battery->bif_data.pointer; 277 + unsigned long alarm = battery->alarm; 357 278 279 + /* See if alarms are supported, and if so, set default */ 358 280 359 - if (!battery) 360 - return -EINVAL; 361 - 362 - device = battery->device; 363 - 364 - result = acpi_bus_get_status(device); 365 - if (result) 366 - return result; 367 - 368 - /* Insertion? */ 369 - 370 - if (!battery->flags.present && device->status.battery_present) { 371 - 372 - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); 373 - 374 - /* Evalute _BIF to get certain static information */ 375 - 376 - result = acpi_battery_get_info(battery, &bif); 377 - if (result) 378 - return result; 379 - 380 - battery->flags.power_unit = bif->power_unit; 381 - battery->trips.warning = bif->design_capacity_warning; 382 - battery->trips.low = bif->design_capacity_low; 383 - kfree(bif); 384 - 385 - /* See if alarms are supported, and if so, set default */ 386 - 387 - status = acpi_get_handle(battery->device->handle, "_BTP", &handle); 388 - if (ACPI_SUCCESS(status)) { 389 - battery->flags.alarm = 1; 390 - acpi_battery_set_alarm(battery, battery->trips.warning); 281 + status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); 282 + if (ACPI_SUCCESS(status)) { 283 + acpi_battery_alarm_present(battery) = 1; 284 + if (!alarm && bif) { 285 + alarm = bif->design_capacity_warning; 391 286 } 287 + result = acpi_battery_set_alarm(battery, alarm); 288 + if (result) 289 + goto end; 290 + } else { 291 + acpi_battery_alarm_present(battery) = 0; 392 292 } 393 293 394 - /* Removal? */ 395 - 396 - else if (battery->flags.present && !device->status.battery_present) { 397 - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n")); 398 - } 399 - 400 - battery->flags.present = device->status.battery_present; 294 + end: 401 295 402 296 return result; 403 297 } 404 298 405 - static void acpi_battery_check_present(struct acpi_battery *battery) 299 + static int acpi_battery_init_update(struct acpi_battery *battery) 406 300 { 407 - if (!battery->flags.present) { 408 - acpi_battery_check(battery); 301 + int result = 0; 302 + 303 + result = acpi_battery_get_status(battery); 304 + if (result) 305 + return result; 306 + 307 + acpi_battery_present_prev(battery) = acpi_battery_present(battery); 308 + 309 + if (acpi_battery_present(battery)) { 310 + result = acpi_battery_get_info(battery); 311 + if (result) 312 + return result; 313 + result = acpi_battery_get_state(battery); 314 + if (result) 315 + return result; 316 + 317 + acpi_battery_init_alarm(battery); 318 + } 319 + 320 + return result; 321 + } 322 + 323 + static int acpi_battery_update(struct acpi_battery *battery, 324 + int update, int *update_result_ptr) 325 + { 326 + int result = 0; 327 + int update_result = ACPI_BATTERY_NONE_UPDATE; 328 + 329 + if (!acpi_battery_present(battery)) { 330 + update = 1; 331 + } 332 + 333 + if (acpi_battery_init_update_flag(battery)) { 334 + result = acpi_battery_init_update(battery); 335 + if (result) 336 + goto end;; 337 + update_result = ACPI_BATTERY_INIT_UPDATE; 338 + } else if (update) { 339 + result = acpi_battery_get_status(battery); 340 + if (result) 341 + goto end;; 342 + if (acpi_battery_inserted(battery) || acpi_battery_removed(battery)) { 343 + result = acpi_battery_init_update(battery); 344 + if (result) 345 + goto end;; 346 + update_result = ACPI_BATTERY_INIT_UPDATE; 347 + } else { 348 + update_result = ACPI_BATTERY_EASY_UPDATE; 349 + } 350 + } 351 + 352 + end: 353 + 354 + acpi_battery_init_update_flag(battery) = (result != 0); 355 + 356 + *update_result_ptr = update_result; 357 + 358 + return result; 359 + } 360 + 361 + static void acpi_battery_notify_update(struct acpi_battery *battery) 362 + { 363 + acpi_battery_get_status(battery); 364 + 365 + if (acpi_battery_init_update_flag(battery)) { 366 + return; 367 + } 368 + 369 + if (acpi_battery_inserted(battery) || acpi_battery_removed(battery)) { 370 + acpi_battery_init_update_flag(battery) = 1; 371 + } else { 372 + acpi_battery_info_update_flag(battery) = 1; 373 + acpi_battery_state_update_flag(battery) = 1; 374 + acpi_battery_alarm_update_flag(battery) = 1; 409 375 } 410 376 } 411 377 ··· 459 335 -------------------------------------------------------------------------- */ 460 336 461 337 static struct proc_dir_entry *acpi_battery_dir; 462 - static int acpi_battery_read_info(struct seq_file *seq, void *offset) 338 + 339 + static int acpi_battery_read_info_print(struct seq_file *seq, int result) 463 340 { 464 - int result = 0; 465 341 struct acpi_battery *battery = seq->private; 466 342 struct acpi_battery_info *bif = NULL; 467 343 char *units = "?"; 468 344 469 - 470 - if (!battery) 345 + if (result) 471 346 goto end; 472 347 473 - acpi_battery_check_present(battery); 474 - 475 - if (battery->flags.present) 348 + if (acpi_battery_present(battery)) 476 349 seq_printf(seq, "present: yes\n"); 477 350 else { 478 351 seq_printf(seq, "present: no\n"); 479 352 goto end; 480 353 } 481 354 482 - /* Battery Info (_BIF) */ 483 - 484 - result = acpi_battery_get_info(battery, &bif); 485 - if (result || !bif) { 486 - seq_printf(seq, "ERROR: Unable to read battery information\n"); 355 + bif = battery->bif_data.pointer; 356 + if (!bif) { 357 + ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL")); 358 + result = -ENODEV; 487 359 goto end; 488 360 } 489 361 490 - units = 491 - bif-> 492 - power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; 362 + /* Battery Units */ 363 + 364 + units = acpi_battery_power_units(battery); 493 365 494 366 if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 495 367 seq_printf(seq, "design capacity: unknown\n"); ··· 516 396 else 517 397 seq_printf(seq, "design voltage: %d mV\n", 518 398 (u32) bif->design_voltage); 519 - 520 399 seq_printf(seq, "design capacity warning: %d %sh\n", 521 400 (u32) bif->design_capacity_warning, units); 522 401 seq_printf(seq, "design capacity low: %d %sh\n", ··· 530 411 seq_printf(seq, "OEM info: %s\n", bif->oem_info); 531 412 532 413 end: 533 - kfree(bif); 534 414 535 - return 0; 415 + if (result) 416 + seq_printf(seq, "ERROR: Unable to read battery info\n"); 417 + 418 + return result; 419 + } 420 + 421 + static int acpi_battery_read_info(struct seq_file *seq, void *offset) 422 + { 423 + struct acpi_battery *battery = seq->private; 424 + int result = 0; 425 + int update_result = ACPI_BATTERY_NONE_UPDATE; 426 + int update = 0; 427 + 428 + acpi_battery_mutex_lock(battery); 429 + 430 + update = (get_seconds() - battery->info_update_time >= update_time); 431 + update = (update | acpi_battery_info_update_flag(battery)); 432 + 433 + result = acpi_battery_update(battery, update, &update_result); 434 + if (result) 435 + goto end; 436 + 437 + /* Battery Info (_BIF) */ 438 + 439 + if (update_result == ACPI_BATTERY_EASY_UPDATE) { 440 + result = acpi_battery_get_info(battery); 441 + if (result) 442 + goto end; 443 + } 444 + 445 + end: 446 + 447 + result = acpi_battery_read_info_print(seq, result); 448 + 449 + acpi_battery_check_result(battery, result); 450 + 451 + acpi_battery_info_update_flag(battery) = result; 452 + 453 + acpi_battery_mutex_unlock(battery); 454 + 455 + return result; 536 456 } 537 457 538 458 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) ··· 579 421 return single_open(file, acpi_battery_read_info, PDE(inode)->data); 580 422 } 581 423 582 - static int acpi_battery_read_state(struct seq_file *seq, void *offset) 424 + static int acpi_battery_read_state_print(struct seq_file *seq, int result) 583 425 { 584 - int result = 0; 585 426 struct acpi_battery *battery = seq->private; 586 427 struct acpi_battery_state *bst = NULL; 587 428 char *units = "?"; 588 429 589 - 590 - if (!battery) 430 + if (result) 591 431 goto end; 592 432 593 - acpi_battery_check_present(battery); 594 - 595 - if (battery->flags.present) 433 + if (acpi_battery_present(battery)) 596 434 seq_printf(seq, "present: yes\n"); 597 435 else { 598 436 seq_printf(seq, "present: no\n"); 599 437 goto end; 600 438 } 601 439 602 - /* Battery Units */ 603 - 604 - units = 605 - battery->flags. 606 - power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; 607 - 608 - /* Battery Status (_BST) */ 609 - 610 - result = acpi_battery_get_state(battery, &bst); 611 - if (result || !bst) { 612 - seq_printf(seq, "ERROR: Unable to read battery state\n"); 440 + bst = battery->bst_data.pointer; 441 + if (!bst) { 442 + ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL")); 443 + result = -ENODEV; 613 444 goto end; 614 445 } 446 + 447 + /* Battery Units */ 448 + 449 + units = acpi_battery_power_units(battery); 615 450 616 451 if (!(bst->state & 0x04)) 617 452 seq_printf(seq, "capacity state: ok\n"); ··· 641 490 (u32) bst->present_voltage); 642 491 643 492 end: 644 - kfree(bst); 645 493 646 - return 0; 494 + if (result) { 495 + seq_printf(seq, "ERROR: Unable to read battery state\n"); 496 + } 497 + 498 + return result; 499 + } 500 + 501 + static int acpi_battery_read_state(struct seq_file *seq, void *offset) 502 + { 503 + struct acpi_battery *battery = seq->private; 504 + int result = 0; 505 + int update_result = ACPI_BATTERY_NONE_UPDATE; 506 + int update = 0; 507 + 508 + acpi_battery_mutex_lock(battery); 509 + 510 + update = (get_seconds() - battery->state_update_time >= update_time); 511 + update = (update | acpi_battery_state_update_flag(battery)); 512 + 513 + result = acpi_battery_update(battery, update, &update_result); 514 + if (result) 515 + goto end; 516 + 517 + /* Battery State (_BST) */ 518 + 519 + if (update_result == ACPI_BATTERY_EASY_UPDATE) { 520 + result = acpi_battery_get_state(battery); 521 + if (result) 522 + goto end; 523 + } 524 + 525 + end: 526 + 527 + result = acpi_battery_read_state_print(seq, result); 528 + 529 + acpi_battery_check_result(battery, result); 530 + 531 + acpi_battery_state_update_flag(battery) = result; 532 + 533 + acpi_battery_mutex_unlock(battery); 534 + 535 + return result; 647 536 } 648 537 649 538 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) ··· 691 500 return single_open(file, acpi_battery_read_state, PDE(inode)->data); 692 501 } 693 502 694 - static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 503 + static int acpi_battery_read_alarm_print(struct seq_file *seq, int result) 695 504 { 696 505 struct acpi_battery *battery = seq->private; 697 506 char *units = "?"; 698 507 699 - 700 - if (!battery) 508 + if (result) 701 509 goto end; 702 510 703 - acpi_battery_check_present(battery); 704 - 705 - if (!battery->flags.present) { 511 + if (!acpi_battery_present(battery)) { 706 512 seq_printf(seq, "present: no\n"); 707 513 goto end; 708 514 } 709 515 710 516 /* Battery Units */ 711 517 712 - units = 713 - battery->flags. 714 - power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; 715 - 716 - /* Battery Alarm */ 518 + units = acpi_battery_power_units(battery); 717 519 718 520 seq_printf(seq, "alarm: "); 719 521 if (!battery->alarm) 720 522 seq_printf(seq, "unsupported\n"); 721 523 else 722 - seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units); 524 + seq_printf(seq, "%lu %sh\n", battery->alarm, units); 723 525 724 526 end: 725 - return 0; 527 + 528 + if (result) 529 + seq_printf(seq, "ERROR: Unable to read battery alarm\n"); 530 + 531 + return result; 532 + } 533 + 534 + static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 535 + { 536 + struct acpi_battery *battery = seq->private; 537 + int result = 0; 538 + int update_result = ACPI_BATTERY_NONE_UPDATE; 539 + int update = 0; 540 + 541 + acpi_battery_mutex_lock(battery); 542 + 543 + update = (get_seconds() - battery->alarm_update_time >= update_time); 544 + update = (update | acpi_battery_alarm_update_flag(battery)); 545 + 546 + result = acpi_battery_update(battery, update, &update_result); 547 + if (result) 548 + goto end; 549 + 550 + /* Battery Alarm */ 551 + 552 + if (update_result == ACPI_BATTERY_EASY_UPDATE) { 553 + result = acpi_battery_get_alarm(battery); 554 + if (result) 555 + goto end; 556 + } 557 + 558 + end: 559 + 560 + result = acpi_battery_read_alarm_print(seq, result); 561 + 562 + acpi_battery_check_result(battery, result); 563 + 564 + acpi_battery_alarm_update_flag(battery) = result; 565 + 566 + acpi_battery_mutex_unlock(battery); 567 + 568 + return result; 726 569 } 727 570 728 571 static ssize_t ··· 768 543 char alarm_string[12] = { '\0' }; 769 544 struct seq_file *m = file->private_data; 770 545 struct acpi_battery *battery = m->private; 546 + int update_result = ACPI_BATTERY_NONE_UPDATE; 771 547 772 548 773 549 if (!battery || (count > sizeof(alarm_string) - 1)) 774 550 return -EINVAL; 775 551 776 - acpi_battery_check_present(battery); 552 + acpi_battery_mutex_lock(battery); 777 553 778 - if (!battery->flags.present) 779 - return -ENODEV; 554 + result = acpi_battery_update(battery, 1, &update_result); 555 + if (result) { 556 + result = -ENODEV; 557 + goto end; 558 + } 780 559 781 - if (copy_from_user(alarm_string, buffer, count)) 782 - return -EFAULT; 560 + if (!acpi_battery_present(battery)) { 561 + result = -ENODEV; 562 + goto end; 563 + } 564 + 565 + if (copy_from_user(alarm_string, buffer, count)) { 566 + result = -EFAULT; 567 + goto end; 568 + } 783 569 784 570 alarm_string[count] = '\0'; 785 571 786 572 result = acpi_battery_set_alarm(battery, 787 573 simple_strtoul(alarm_string, NULL, 0)); 788 574 if (result) 789 - return result; 575 + goto end; 790 576 791 - return count; 577 + end: 578 + 579 + acpi_battery_check_result(battery, result); 580 + 581 + if (!result) 582 + result = count; 583 + 584 + acpi_battery_mutex_unlock(battery); 585 + 586 + return result; 792 587 } 793 588 794 589 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) ··· 893 648 894 649 static int acpi_battery_remove_fs(struct acpi_device *device) 895 650 { 896 - 897 651 if (acpi_device_dir(device)) { 898 652 remove_proc_entry(ACPI_BATTERY_FILE_ALARM, 899 653 acpi_device_dir(device)); ··· 928 684 case ACPI_BATTERY_NOTIFY_INFO: 929 685 case ACPI_NOTIFY_BUS_CHECK: 930 686 case ACPI_NOTIFY_DEVICE_CHECK: 931 - acpi_battery_check(battery); 932 - acpi_bus_generate_event(device, event, battery->flags.present); 687 + acpi_battery_mutex_lock(battery); 688 + device = battery->device; 689 + acpi_battery_notify_update(battery); 690 + acpi_battery_mutex_unlock(battery); 691 + acpi_bus_generate_event(device, event, acpi_battery_present(battery)); 933 692 break; 934 693 default: 935 694 ACPI_DEBUG_PRINT((ACPI_DB_INFO, ··· 949 702 acpi_status status = 0; 950 703 struct acpi_battery *battery = NULL; 951 704 952 - 953 705 if (!device) 954 706 return -EINVAL; 955 707 ··· 956 710 if (!battery) 957 711 return -ENOMEM; 958 712 713 + mutex_init(&battery->mutex); 714 + 715 + acpi_battery_mutex_lock(battery); 716 + 959 717 battery->device = device; 960 718 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 961 719 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 962 720 acpi_driver_data(device) = battery; 963 721 964 - result = acpi_battery_check(battery); 722 + result = acpi_battery_get_status(battery); 965 723 if (result) 966 724 goto end; 725 + 726 + acpi_battery_init_update_flag(battery) = 1; 967 727 968 728 result = acpi_battery_add_fs(device); 969 729 if (result) ··· 979 727 ACPI_ALL_NOTIFY, 980 728 acpi_battery_notify, battery); 981 729 if (ACPI_FAILURE(status)) { 730 + ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); 982 731 result = -ENODEV; 983 732 goto end; 984 733 } ··· 989 736 device->status.battery_present ? "present" : "absent"); 990 737 991 738 end: 739 + 992 740 if (result) { 993 741 acpi_battery_remove_fs(device); 994 742 kfree(battery); 995 743 } 744 + 745 + acpi_battery_mutex_unlock(battery); 996 746 997 747 return result; 998 748 } ··· 1005 749 acpi_status status = 0; 1006 750 struct acpi_battery *battery = NULL; 1007 751 1008 - 1009 752 if (!device || !acpi_driver_data(device)) 1010 753 return -EINVAL; 1011 754 1012 755 battery = acpi_driver_data(device); 756 + 757 + acpi_battery_mutex_lock(battery); 1013 758 1014 759 status = acpi_remove_notify_handler(device->handle, 1015 760 ACPI_ALL_NOTIFY, 1016 761 acpi_battery_notify); 1017 762 1018 763 acpi_battery_remove_fs(device); 764 + 765 + if (battery->bif_data.pointer) 766 + kfree(battery->bif_data.pointer); 767 + 768 + if (battery->bst_data.pointer) 769 + kfree(battery->bst_data.pointer); 770 + 771 + acpi_battery_mutex_unlock(battery); 772 + 773 + mutex_destroy(&battery->mutex); 1019 774 1020 775 kfree(battery); 1021 776 ··· 1042 775 return -EINVAL; 1043 776 1044 777 battery = device->driver_data; 1045 - return acpi_battery_check(battery); 778 + 779 + acpi_battery_init_update_flag(battery) = 1; 780 + 781 + return 0; 1046 782 } 1047 783 1048 784 static int __init acpi_battery_init(void) ··· 1070 800 1071 801 static void __exit acpi_battery_exit(void) 1072 802 { 1073 - 1074 803 acpi_bus_unregister_driver(&acpi_battery_driver); 1075 804 1076 805 acpi_unlock_battery_dir(acpi_battery_dir);