aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c342
1 files changed, 125 insertions, 217 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index faa70a50b807..db725bfe5840 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $) 2 * battery.c - ACPI Battery Driver (Revision: 2.0)
3 * 3 *
4 * Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
5 * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 6 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 7 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * 8 *
@@ -48,6 +50,7 @@
48ACPI_MODULE_NAME("battery"); 50ACPI_MODULE_NAME("battery");
49 51
50MODULE_AUTHOR("Paul Diefenbaugh"); 52MODULE_AUTHOR("Paul Diefenbaugh");
53MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
51MODULE_DESCRIPTION("ACPI Battery Driver"); 54MODULE_DESCRIPTION("ACPI Battery Driver");
52MODULE_LICENSE("GPL"); 55MODULE_LICENSE("GPL");
53 56
@@ -58,31 +61,17 @@ MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
58extern struct proc_dir_entry *acpi_lock_battery_dir(void); 61extern struct proc_dir_entry *acpi_lock_battery_dir(void);
59extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); 62extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
60 63
61static int acpi_battery_add(struct acpi_device *device);
62static int acpi_battery_remove(struct acpi_device *device, int type);
63static int acpi_battery_resume(struct acpi_device *device);
64
65static const struct acpi_device_id battery_device_ids[] = { 64static const struct acpi_device_id battery_device_ids[] = {
66 {"PNP0C0A", 0}, 65 {"PNP0C0A", 0},
67 {"", 0}, 66 {"", 0},
68}; 67};
69MODULE_DEVICE_TABLE(acpi, battery_device_ids);
70 68
71static struct acpi_driver acpi_battery_driver = { 69MODULE_DEVICE_TABLE(acpi, battery_device_ids);
72 .name = "battery",
73 .class = ACPI_BATTERY_CLASS,
74 .ids = battery_device_ids,
75 .ops = {
76 .add = acpi_battery_add,
77 .resume = acpi_battery_resume,
78 .remove = acpi_battery_remove,
79 },
80};
81 70
82enum acpi_battery_files { 71enum acpi_battery_files {
83 ACPI_BATTERY_INFO = 0, 72 info_tag = 0,
84 ACPI_BATTERY_STATE, 73 state_tag,
85 ACPI_BATTERY_ALARM, 74 alarm_tag,
86 ACPI_BATTERY_NUMFILES, 75 ACPI_BATTERY_NUMFILES,
87}; 76};
88 77
@@ -124,7 +113,6 @@ inline char *acpi_battery_units(struct acpi_battery *battery)
124/* -------------------------------------------------------------------------- 113/* --------------------------------------------------------------------------
125 Battery Management 114 Battery Management
126 -------------------------------------------------------------------------- */ 115 -------------------------------------------------------------------------- */
127
128struct acpi_offsets { 116struct acpi_offsets {
129 size_t offset; /* offset inside struct acpi_sbs_battery */ 117 size_t offset; /* offset inside struct acpi_sbs_battery */
130 u8 mode; /* int or string? */ 118 u8 mode; /* int or string? */
@@ -183,19 +171,16 @@ static int extract_package(struct acpi_battery *battery,
183 171
184static int acpi_battery_get_status(struct acpi_battery *battery) 172static int acpi_battery_get_status(struct acpi_battery *battery)
185{ 173{
186 int result = 0; 174 if (acpi_bus_get_status(battery->device)) {
187
188 result = acpi_bus_get_status(battery->device);
189 if (result) {
190 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); 175 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
191 return -ENODEV; 176 return -ENODEV;
192 } 177 }
193 return result; 178 return 0;
194} 179}
195 180
196static int acpi_battery_get_info(struct acpi_battery *battery) 181static int acpi_battery_get_info(struct acpi_battery *battery)
197{ 182{
198 int result = 0; 183 int result = -EFAULT;
199 acpi_status status = 0; 184 acpi_status status = 0;
200 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 185 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
201 186
@@ -205,10 +190,12 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
205 status = acpi_evaluate_object(battery->device->handle, "_BIF", 190 status = acpi_evaluate_object(battery->device->handle, "_BIF",
206 NULL, &buffer); 191 NULL, &buffer);
207 mutex_unlock(&battery->lock); 192 mutex_unlock(&battery->lock);
193
208 if (ACPI_FAILURE(status)) { 194 if (ACPI_FAILURE(status)) {
209 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 195 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
210 return -ENODEV; 196 return -ENODEV;
211 } 197 }
198
212 result = extract_package(battery, buffer.pointer, 199 result = extract_package(battery, buffer.pointer,
213 info_offsets, ARRAY_SIZE(info_offsets)); 200 info_offsets, ARRAY_SIZE(info_offsets));
214 kfree(buffer.pointer); 201 kfree(buffer.pointer);
@@ -238,6 +225,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
238 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 225 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
239 return -ENODEV; 226 return -ENODEV;
240 } 227 }
228
241 result = extract_package(battery, buffer.pointer, 229 result = extract_package(battery, buffer.pointer,
242 state_offsets, ARRAY_SIZE(state_offsets)); 230 state_offsets, ARRAY_SIZE(state_offsets));
243 battery->update_time = jiffies; 231 battery->update_time = jiffies;
@@ -245,37 +233,26 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
245 return result; 233 return result;
246} 234}
247 235
248static int acpi_battery_get_alarm(struct acpi_battery *battery) 236static int acpi_battery_set_alarm(struct acpi_battery *battery)
249{
250 return 0;
251}
252
253static int acpi_battery_set_alarm(struct acpi_battery *battery,
254 unsigned long alarm)
255{ 237{
256 acpi_status status = 0; 238 acpi_status status = 0;
257 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 239 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
258 struct acpi_object_list arg_list = { 1, &arg0 }; 240 struct acpi_object_list arg_list = { 1, &arg0 };
259 241
260 if (!acpi_battery_present(battery)) 242 if (!acpi_battery_present(battery)|| !battery->alarm_present)
261 return -ENODEV;
262
263 if (!battery->alarm_present)
264 return -ENODEV; 243 return -ENODEV;
265 244
266 arg0.integer.value = alarm; 245 arg0.integer.value = battery->alarm;
267 246
268 mutex_lock(&battery->lock); 247 mutex_lock(&battery->lock);
269 status = acpi_evaluate_object(battery->device->handle, "_BTP", 248 status = acpi_evaluate_object(battery->device->handle, "_BTP",
270 &arg_list, NULL); 249 &arg_list, NULL);
271 mutex_unlock(&battery->lock); 250 mutex_unlock(&battery->lock);
251
272 if (ACPI_FAILURE(status)) 252 if (ACPI_FAILURE(status))
273 return -ENODEV; 253 return -ENODEV;
274 254
275 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm)); 255 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
276
277 battery->alarm = alarm;
278
279 return 0; 256 return 0;
280} 257}
281 258
@@ -293,7 +270,7 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
293 battery->alarm_present = 1; 270 battery->alarm_present = 1;
294 if (!battery->alarm) 271 if (!battery->alarm)
295 battery->alarm = battery->design_capacity_warning; 272 battery->alarm = battery->design_capacity_warning;
296 return acpi_battery_set_alarm(battery, battery->alarm); 273 return acpi_battery_set_alarm(battery);
297} 274}
298 275
299static int acpi_battery_update(struct acpi_battery *battery) 276static int acpi_battery_update(struct acpi_battery *battery)
@@ -322,130 +299,101 @@ static struct proc_dir_entry *acpi_battery_dir;
322static int acpi_battery_print_info(struct seq_file *seq, int result) 299static int acpi_battery_print_info(struct seq_file *seq, int result)
323{ 300{
324 struct acpi_battery *battery = seq->private; 301 struct acpi_battery *battery = seq->private;
325 char *units = "?";
326 302
327 if (result) 303 if (result)
328 goto end; 304 goto end;
329 305
330 if (acpi_battery_present(battery)) 306 seq_printf(seq, "present: %s\n",
331 seq_printf(seq, "present: yes\n"); 307 acpi_battery_present(battery)?"yes":"no");
332 else { 308 if (!acpi_battery_present(battery))
333 seq_printf(seq, "present: no\n");
334 goto end; 309 goto end;
335 }
336
337 /* Battery Units */
338
339 units = acpi_battery_units(battery);
340
341 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 310 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
342 seq_printf(seq, "design capacity: unknown\n"); 311 seq_printf(seq, "design capacity: unknown\n");
343 else 312 else
344 seq_printf(seq, "design capacity: %d %sh\n", 313 seq_printf(seq, "design capacity: %d %sh\n",
345 (u32) battery->design_capacity, units); 314 battery->design_capacity,
315 acpi_battery_units(battery));
346 316
347 if (battery->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 317 if (battery->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
348 seq_printf(seq, "last full capacity: unknown\n"); 318 seq_printf(seq, "last full capacity: unknown\n");
349 else 319 else
350 seq_printf(seq, "last full capacity: %d %sh\n", 320 seq_printf(seq, "last full capacity: %d %sh\n",
351 (u32) battery->last_full_capacity, units); 321 battery->last_full_capacity,
352 322 acpi_battery_units(battery));
353 switch ((u32) battery->technology) { 323
354 case 0: 324 seq_printf(seq, "battery technology: %srechargeable\n",
355 seq_printf(seq, "battery technology: non-rechargeable\n"); 325 (!battery->technology)?"non-":"");
356 break;
357 case 1:
358 seq_printf(seq, "battery technology: rechargeable\n");
359 break;
360 default:
361 seq_printf(seq, "battery technology: unknown\n");
362 break;
363 }
364 326
365 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) 327 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
366 seq_printf(seq, "design voltage: unknown\n"); 328 seq_printf(seq, "design voltage: unknown\n");
367 else 329 else
368 seq_printf(seq, "design voltage: %d mV\n", 330 seq_printf(seq, "design voltage: %d mV\n",
369 (u32) battery->design_voltage); 331 battery->design_voltage);
370 seq_printf(seq, "design capacity warning: %d %sh\n", 332 seq_printf(seq, "design capacity warning: %d %sh\n",
371 (u32) battery->design_capacity_warning, units); 333 battery->design_capacity_warning,
334 acpi_battery_units(battery));
372 seq_printf(seq, "design capacity low: %d %sh\n", 335 seq_printf(seq, "design capacity low: %d %sh\n",
373 (u32) battery->design_capacity_low, units); 336 battery->design_capacity_low,
337 acpi_battery_units(battery));
374 seq_printf(seq, "capacity granularity 1: %d %sh\n", 338 seq_printf(seq, "capacity granularity 1: %d %sh\n",
375 (u32) battery->capacity_granularity_1, units); 339 battery->capacity_granularity_1,
340 acpi_battery_units(battery));
376 seq_printf(seq, "capacity granularity 2: %d %sh\n", 341 seq_printf(seq, "capacity granularity 2: %d %sh\n",
377 (u32) battery->capacity_granularity_2, units); 342 battery->capacity_granularity_2,
343 acpi_battery_units(battery));
378 seq_printf(seq, "model number: %s\n", battery->model_number); 344 seq_printf(seq, "model number: %s\n", battery->model_number);
379 seq_printf(seq, "serial number: %s\n", battery->serial_number); 345 seq_printf(seq, "serial number: %s\n", battery->serial_number);
380 seq_printf(seq, "battery type: %s\n", battery->type); 346 seq_printf(seq, "battery type: %s\n", battery->type);
381 seq_printf(seq, "OEM info: %s\n", battery->oem_info); 347 seq_printf(seq, "OEM info: %s\n", battery->oem_info);
382
383 end: 348 end:
384
385 if (result) 349 if (result)
386 seq_printf(seq, "ERROR: Unable to read battery info\n"); 350 seq_printf(seq, "ERROR: Unable to read battery info\n");
387
388 return result; 351 return result;
389} 352}
390 353
391static int acpi_battery_print_state(struct seq_file *seq, int result) 354static int acpi_battery_print_state(struct seq_file *seq, int result)
392{ 355{
393 struct acpi_battery *battery = seq->private; 356 struct acpi_battery *battery = seq->private;
394 char *units = "?";
395 357
396 if (result) 358 if (result)
397 goto end; 359 goto end;
398 360
399 if (acpi_battery_present(battery)) 361 seq_printf(seq, "present: %s\n",
400 seq_printf(seq, "present: yes\n"); 362 acpi_battery_present(battery)?"yes":"no");
401 else { 363 if (!acpi_battery_present(battery))
402 seq_printf(seq, "present: no\n");
403 goto end; 364 goto end;
404 }
405
406 /* Battery Units */
407
408 units = acpi_battery_units(battery);
409 365
410 if (!(battery->state & 0x04)) 366 seq_printf(seq, "capacity state: %s\n",
411 seq_printf(seq, "capacity state: ok\n"); 367 (battery->state & 0x04)?"critical":"ok");
412 else 368 if ((battery->state & 0x01) && (battery->state & 0x02))
413 seq_printf(seq, "capacity state: critical\n");
414
415 if ((battery->state & 0x01) && (battery->state & 0x02)) {
416 seq_printf(seq, 369 seq_printf(seq,
417 "charging state: charging/discharging\n"); 370 "charging state: charging/discharging\n");
418 } else if (battery->state & 0x01) 371 else if (battery->state & 0x01)
419 seq_printf(seq, "charging state: discharging\n"); 372 seq_printf(seq, "charging state: discharging\n");
420 else if (battery->state & 0x02) 373 else if (battery->state & 0x02)
421 seq_printf(seq, "charging state: charging\n"); 374 seq_printf(seq, "charging state: charging\n");
422 else { 375 else
423 seq_printf(seq, "charging state: charged\n"); 376 seq_printf(seq, "charging state: charged\n");
424 }
425 377
426 if (battery->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) 378 if (battery->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
427 seq_printf(seq, "present rate: unknown\n"); 379 seq_printf(seq, "present rate: unknown\n");
428 else 380 else
429 seq_printf(seq, "present rate: %d %s\n", 381 seq_printf(seq, "present rate: %d %s\n",
430 (u32) battery->present_rate, units); 382 battery->present_rate, acpi_battery_units(battery));
431 383
432 if (battery->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 384 if (battery->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
433 seq_printf(seq, "remaining capacity: unknown\n"); 385 seq_printf(seq, "remaining capacity: unknown\n");
434 else 386 else
435 seq_printf(seq, "remaining capacity: %d %sh\n", 387 seq_printf(seq, "remaining capacity: %d %sh\n",
436 (u32) battery->remaining_capacity, units); 388 battery->remaining_capacity, acpi_battery_units(battery));
437
438 if (battery->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) 389 if (battery->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
439 seq_printf(seq, "present voltage: unknown\n"); 390 seq_printf(seq, "present voltage: unknown\n");
440 else 391 else
441 seq_printf(seq, "present voltage: %d mV\n", 392 seq_printf(seq, "present voltage: %d mV\n",
442 (u32) battery->present_voltage); 393 battery->present_voltage);
443
444 end: 394 end:
445 395 if (result)
446 if (result) {
447 seq_printf(seq, "ERROR: Unable to read battery state\n"); 396 seq_printf(seq, "ERROR: Unable to read battery state\n");
448 }
449 397
450 return result; 398 return result;
451} 399}
@@ -453,7 +401,6 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
453static int acpi_battery_print_alarm(struct seq_file *seq, int result) 401static int acpi_battery_print_alarm(struct seq_file *seq, int result)
454{ 402{
455 struct acpi_battery *battery = seq->private; 403 struct acpi_battery *battery = seq->private;
456 char *units = "?";
457 404
458 if (result) 405 if (result)
459 goto end; 406 goto end;
@@ -462,22 +409,15 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
462 seq_printf(seq, "present: no\n"); 409 seq_printf(seq, "present: no\n");
463 goto end; 410 goto end;
464 } 411 }
465
466 /* Battery Units */
467
468 units = acpi_battery_units(battery);
469
470 seq_printf(seq, "alarm: "); 412 seq_printf(seq, "alarm: ");
471 if (!battery->alarm) 413 if (!battery->alarm)
472 seq_printf(seq, "unsupported\n"); 414 seq_printf(seq, "unsupported\n");
473 else 415 else
474 seq_printf(seq, "%u %sh\n", battery->alarm, units); 416 seq_printf(seq, "%u %sh\n", battery->alarm,
475 417 acpi_battery_units(battery));
476 end: 418 end:
477
478 if (result) 419 if (result)
479 seq_printf(seq, "ERROR: Unable to read battery alarm\n"); 420 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
480
481 return result; 421 return result;
482} 422}
483 423
@@ -506,7 +446,7 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
506 } 446 }
507 alarm_string[count] = '\0'; 447 alarm_string[count] = '\0';
508 battery->alarm = simple_strtol(alarm_string, NULL, 0); 448 battery->alarm = simple_strtol(alarm_string, NULL, 0);
509 result = acpi_battery_set_alarm(battery, battery->alarm); 449 result = acpi_battery_set_alarm(battery);
510 end: 450 end:
511 if (!result) 451 if (!result)
512 return count; 452 return count;
@@ -514,95 +454,76 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
514} 454}
515 455
516typedef int(*print_func)(struct seq_file *seq, int result); 456typedef int(*print_func)(struct seq_file *seq, int result);
517typedef int(*get_func)(struct acpi_battery *battery); 457
518 458static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
519static struct acpi_read_mux { 459 acpi_battery_print_info,
520 print_func print; 460 acpi_battery_print_state,
521 get_func get; 461 acpi_battery_print_alarm,
522} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
523 {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
524 {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
525 {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
526}; 462};
527 463
528static int acpi_battery_read(int fid, struct seq_file *seq) 464static int acpi_battery_read(int fid, struct seq_file *seq)
529{ 465{
530 struct acpi_battery *battery = seq->private; 466 struct acpi_battery *battery = seq->private;
531 int result = acpi_battery_update(battery); 467 int result = acpi_battery_update(battery);
532 return acpi_read_funcs[fid].print(seq, result); 468 return acpi_print_funcs[fid](seq, result);
533}
534
535static int acpi_battery_read_info(struct seq_file *seq, void *offset)
536{
537 return acpi_battery_read(ACPI_BATTERY_INFO, seq);
538}
539
540static int acpi_battery_read_state(struct seq_file *seq, void *offset)
541{
542 return acpi_battery_read(ACPI_BATTERY_STATE, seq);
543}
544
545static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
546{
547 return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
548} 469}
549 470
550static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) 471#define DECLARE_FILE_FUNCTIONS(_name) \
551{ 472static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
552 return single_open(file, acpi_battery_read_info, PDE(inode)->data); 473{ \
474 return acpi_battery_read(_name##_tag, seq); \
475} \
476static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
477{ \
478 return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
553} 479}
554 480
555static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) 481DECLARE_FILE_FUNCTIONS(info);
556{ 482DECLARE_FILE_FUNCTIONS(state);
557 return single_open(file, acpi_battery_read_state, PDE(inode)->data); 483DECLARE_FILE_FUNCTIONS(alarm);
558} 484
485#undef DECLARE_FILE_FUNCTIONS
486
487#define FILE_DESCRIPTION_RO(_name) \
488 { \
489 .name = __stringify(_name), \
490 .mode = S_IRUGO, \
491 .ops = { \
492 .open = acpi_battery_##_name##_open_fs, \
493 .read = seq_read, \
494 .llseek = seq_lseek, \
495 .release = single_release, \
496 .owner = THIS_MODULE, \
497 }, \
498 }
559 499
560static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) 500#define FILE_DESCRIPTION_RW(_name) \
561{ 501 { \
562 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); 502 .name = __stringify(_name), \
563} 503 .mode = S_IFREG | S_IRUGO | S_IWUSR, \
504 .ops = { \
505 .open = acpi_battery_##_name##_open_fs, \
506 .read = seq_read, \
507 .llseek = seq_lseek, \
508 .write = acpi_battery_write_##_name, \
509 .release = single_release, \
510 .owner = THIS_MODULE, \
511 }, \
512 }
564 513
565static struct battery_file { 514static struct battery_file {
566 struct file_operations ops; 515 struct file_operations ops;
567 mode_t mode; 516 mode_t mode;
568 char *name; 517 char *name;
569} acpi_battery_file[] = { 518} acpi_battery_file[] = {
570 { 519 FILE_DESCRIPTION_RO(info),
571 .name = "info", 520 FILE_DESCRIPTION_RO(state),
572 .mode = S_IRUGO, 521 FILE_DESCRIPTION_RW(alarm),
573 .ops = {
574 .open = acpi_battery_info_open_fs,
575 .read = seq_read,
576 .llseek = seq_lseek,
577 .release = single_release,
578 .owner = THIS_MODULE,
579 },
580 },
581 {
582 .name = "state",
583 .mode = S_IRUGO,
584 .ops = {
585 .open = acpi_battery_state_open_fs,
586 .read = seq_read,
587 .llseek = seq_lseek,
588 .release = single_release,
589 .owner = THIS_MODULE,
590 },
591 },
592 {
593 .name = "alarm",
594 .mode = S_IFREG | S_IRUGO | S_IWUSR,
595 .ops = {
596 .open = acpi_battery_alarm_open_fs,
597 .read = seq_read,
598 .write = acpi_battery_write_alarm,
599 .llseek = seq_lseek,
600 .release = single_release,
601 .owner = THIS_MODULE,
602 },
603 },
604}; 522};
605 523
524#undef FILE_DESCRIPTION_RO
525#undef FILE_DESCRIPTION_RW
526
606static int acpi_battery_add_fs(struct acpi_device *device) 527static int acpi_battery_add_fs(struct acpi_device *device)
607{ 528{
608 struct proc_dir_entry *entry = NULL; 529 struct proc_dir_entry *entry = NULL;
@@ -627,23 +548,20 @@ static int acpi_battery_add_fs(struct acpi_device *device)
627 entry->owner = THIS_MODULE; 548 entry->owner = THIS_MODULE;
628 } 549 }
629 } 550 }
630
631 return 0; 551 return 0;
632} 552}
633 553
634static int acpi_battery_remove_fs(struct acpi_device *device) 554static void acpi_battery_remove_fs(struct acpi_device *device)
635{ 555{
636 int i; 556 int i;
637 if (acpi_device_dir(device)) { 557 if (!acpi_device_dir(device))
638 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { 558 return;
639 remove_proc_entry(acpi_battery_file[i].name, 559 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
560 remove_proc_entry(acpi_battery_file[i].name,
640 acpi_device_dir(device)); 561 acpi_device_dir(device));
641 }
642 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
643 acpi_device_dir(device) = NULL;
644 }
645 562
646 return 0; 563 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
564 acpi_device_dir(device) = NULL;
647} 565}
648 566
649/* -------------------------------------------------------------------------- 567/* --------------------------------------------------------------------------
@@ -670,14 +588,11 @@ static int acpi_battery_add(struct acpi_device *device)
670 int result = 0; 588 int result = 0;
671 acpi_status status = 0; 589 acpi_status status = 0;
672 struct acpi_battery *battery = NULL; 590 struct acpi_battery *battery = NULL;
673
674 if (!device) 591 if (!device)
675 return -EINVAL; 592 return -EINVAL;
676
677 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); 593 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
678 if (!battery) 594 if (!battery)
679 return -ENOMEM; 595 return -ENOMEM;
680
681 battery->device = device; 596 battery->device = device;
682 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 597 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
683 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 598 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
@@ -687,7 +602,6 @@ static int acpi_battery_add(struct acpi_device *device)
687 result = acpi_battery_add_fs(device); 602 result = acpi_battery_add_fs(device);
688 if (result) 603 if (result)
689 goto end; 604 goto end;
690
691 status = acpi_install_notify_handler(device->handle, 605 status = acpi_install_notify_handler(device->handle,
692 ACPI_ALL_NOTIFY, 606 ACPI_ALL_NOTIFY,
693 acpi_battery_notify, battery); 607 acpi_battery_notify, battery);
@@ -696,18 +610,14 @@ static int acpi_battery_add(struct acpi_device *device)
696 result = -ENODEV; 610 result = -ENODEV;
697 goto end; 611 goto end;
698 } 612 }
699
700 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", 613 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
701 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), 614 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
702 device->status.battery_present ? "present" : "absent"); 615 device->status.battery_present ? "present" : "absent");
703
704 end: 616 end:
705
706 if (result) { 617 if (result) {
707 acpi_battery_remove_fs(device); 618 acpi_battery_remove_fs(device);
708 kfree(battery); 619 kfree(battery);
709 } 620 }
710
711 return result; 621 return result;
712} 622}
713 623
@@ -718,17 +628,13 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
718 628
719 if (!device || !acpi_driver_data(device)) 629 if (!device || !acpi_driver_data(device))
720 return -EINVAL; 630 return -EINVAL;
721
722 battery = acpi_driver_data(device); 631 battery = acpi_driver_data(device);
723
724 status = acpi_remove_notify_handler(device->handle, 632 status = acpi_remove_notify_handler(device->handle,
725 ACPI_ALL_NOTIFY, 633 ACPI_ALL_NOTIFY,
726 acpi_battery_notify); 634 acpi_battery_notify);
727
728 acpi_battery_remove_fs(device); 635 acpi_battery_remove_fs(device);
729 mutex_destroy(&battery->lock); 636 mutex_destroy(&battery->lock);
730 kfree(battery); 637 kfree(battery);
731
732 return 0; 638 return 0;
733} 639}
734 640
@@ -743,33 +649,35 @@ static int acpi_battery_resume(struct acpi_device *device)
743 return 0; 649 return 0;
744} 650}
745 651
652static struct acpi_driver acpi_battery_driver = {
653 .name = "battery",
654 .class = ACPI_BATTERY_CLASS,
655 .ids = battery_device_ids,
656 .ops = {
657 .add = acpi_battery_add,
658 .resume = acpi_battery_resume,
659 .remove = acpi_battery_remove,
660 },
661};
662
746static int __init acpi_battery_init(void) 663static int __init acpi_battery_init(void)
747{ 664{
748 int result;
749
750 if (acpi_disabled) 665 if (acpi_disabled)
751 return -ENODEV; 666 return -ENODEV;
752
753 acpi_battery_dir = acpi_lock_battery_dir(); 667 acpi_battery_dir = acpi_lock_battery_dir();
754 if (!acpi_battery_dir) 668 if (!acpi_battery_dir)
755 return -ENODEV; 669 return -ENODEV;
756 670 if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
757 result = acpi_bus_register_driver(&acpi_battery_driver);
758 if (result < 0) {
759 acpi_unlock_battery_dir(acpi_battery_dir); 671 acpi_unlock_battery_dir(acpi_battery_dir);
760 return -ENODEV; 672 return -ENODEV;
761 } 673 }
762
763 return 0; 674 return 0;
764} 675}
765 676
766static void __exit acpi_battery_exit(void) 677static void __exit acpi_battery_exit(void)
767{ 678{
768 acpi_bus_unregister_driver(&acpi_battery_driver); 679 acpi_bus_unregister_driver(&acpi_battery_driver);
769
770 acpi_unlock_battery_dir(acpi_battery_dir); 680 acpi_unlock_battery_dir(acpi_battery_dir);
771
772 return;
773} 681}
774 682
775module_init(acpi_battery_init); 683module_init(acpi_battery_init);