]> err.no Git - linux-2.6/blob - drivers/acpi/battery.c
ACPI: Battery: don't use acpi_extract_package()
[linux-2.6] / drivers / acpi / battery.c
1 /*
2  *  acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
3  *
4  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6  *
7  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or (at
12  *  your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful, but
15  *  WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License along
20  *  with this program; if not, write to the Free Software Foundation, Inc.,
21  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22  *
23  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24  */
25
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
31 #include <linux/seq_file.h>
32 #include <asm/uaccess.h>
33
34 #include <acpi/acpi_bus.h>
35 #include <acpi/acpi_drivers.h>
36
37 #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
38
39 #define ACPI_BATTERY_COMPONENT          0x00040000
40 #define ACPI_BATTERY_CLASS              "battery"
41 #define ACPI_BATTERY_DEVICE_NAME        "Battery"
42 #define ACPI_BATTERY_NOTIFY_STATUS      0x80
43 #define ACPI_BATTERY_NOTIFY_INFO        0x81
44 #define ACPI_BATTERY_UNITS_WATTS        "mW"
45 #define ACPI_BATTERY_UNITS_AMPS         "mA"
46
47 #define _COMPONENT              ACPI_BATTERY_COMPONENT
48
49 #define ACPI_BATTERY_UPDATE_TIME        0
50
51 #define ACPI_BATTERY_NONE_UPDATE        0
52 #define ACPI_BATTERY_EASY_UPDATE        1
53 #define ACPI_BATTERY_INIT_UPDATE        2
54
55 ACPI_MODULE_NAME("battery");
56
57 MODULE_AUTHOR("Paul Diefenbaugh");
58 MODULE_DESCRIPTION("ACPI Battery Driver");
59 MODULE_LICENSE("GPL");
60
61 static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
62
63 /* 0 - every time, > 0 - by update_time */
64 module_param(update_time, uint, 0644);
65
66 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
67 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
68
69 static int acpi_battery_add(struct acpi_device *device);
70 static int acpi_battery_remove(struct acpi_device *device, int type);
71 static int acpi_battery_resume(struct acpi_device *device);
72
73 static const struct acpi_device_id battery_device_ids[] = {
74         {"PNP0C0A", 0},
75         {"", 0},
76 };
77 MODULE_DEVICE_TABLE(acpi, battery_device_ids);
78
79 static struct acpi_driver acpi_battery_driver = {
80         .name = "battery",
81         .class = ACPI_BATTERY_CLASS,
82         .ids = battery_device_ids,
83         .ops = {
84                 .add = acpi_battery_add,
85                 .resume = acpi_battery_resume,
86                 .remove = acpi_battery_remove,
87                 },
88 };
89
90 enum acpi_battery_files {
91         ACPI_BATTERY_INFO = 0,
92         ACPI_BATTERY_STATE,
93         ACPI_BATTERY_ALARM,
94         ACPI_BATTERY_NUMFILES,
95 };
96
97 struct acpi_battery {
98         struct acpi_device *device;
99         struct mutex lock;
100         unsigned long alarm;
101         unsigned long update_time[ACPI_BATTERY_NUMFILES];
102         int state;
103         int present_rate;
104         int remaining_capacity;
105         int present_voltage;
106         int power_unit;
107         int design_capacity;
108         int last_full_capacity;
109         int technology;
110         int design_voltage;
111         int design_capacity_warning;
112         int design_capacity_low;
113         int capacity_granularity_1;
114         int capacity_granularity_2;
115         char model_number[32];
116         char serial_number[32];
117         char type[32];
118         char oem_info[32];
119         u8 present_prev;
120         u8 alarm_present;
121         u8 init_update;
122         u8 update[ACPI_BATTERY_NUMFILES];
123 };
124
125 inline int acpi_battery_present(struct acpi_battery *battery)
126 {
127         return battery->device->status.battery_present;
128 }
129
130 inline char *acpi_battery_power_units(struct acpi_battery *battery)
131 {
132         if (battery->power_unit)
133                 return ACPI_BATTERY_UNITS_AMPS;
134         else
135                 return ACPI_BATTERY_UNITS_WATTS;
136 }
137
138 inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
139 {
140         return battery->device->handle;
141 }
142
143 /* --------------------------------------------------------------------------
144                                Battery Management
145    -------------------------------------------------------------------------- */
146
147 static void acpi_battery_check_result(struct acpi_battery *battery, int result)
148 {
149         if (!battery)
150                 return;
151
152         if (result) {
153                 battery->init_update = 1;
154         }
155 }
156
157 struct acpi_offsets {
158         size_t offset;          /* offset inside struct acpi_sbs_battery */
159         u8 mode;                /* int or string? */
160 };
161
162 static struct acpi_offsets state_offsets[] = {
163         {offsetof(struct acpi_battery, state), 0},
164         {offsetof(struct acpi_battery, present_rate), 0},
165         {offsetof(struct acpi_battery, remaining_capacity), 0},
166         {offsetof(struct acpi_battery, present_voltage), 0},
167 };
168
169 static struct acpi_offsets info_offsets[] = {
170         {offsetof(struct acpi_battery, power_unit), 0},
171         {offsetof(struct acpi_battery, design_capacity), 0},
172         {offsetof(struct acpi_battery, last_full_capacity), 0},
173         {offsetof(struct acpi_battery, technology), 0},
174         {offsetof(struct acpi_battery, design_voltage), 0},
175         {offsetof(struct acpi_battery, design_capacity_warning), 0},
176         {offsetof(struct acpi_battery, design_capacity_low), 0},
177         {offsetof(struct acpi_battery, capacity_granularity_1), 0},
178         {offsetof(struct acpi_battery, capacity_granularity_2), 0},
179         {offsetof(struct acpi_battery, model_number), 1},
180         {offsetof(struct acpi_battery, serial_number), 1},
181         {offsetof(struct acpi_battery, type), 1},
182         {offsetof(struct acpi_battery, oem_info), 1},
183 };
184
185 static int extract_package(struct acpi_battery *battery,
186                            union acpi_object *package,
187                            struct acpi_offsets *offsets, int num)
188 {
189         int i, *x;
190         union acpi_object *element;
191         if (package->type != ACPI_TYPE_PACKAGE)
192                 return -EFAULT;
193         for (i = 0; i < num; ++i) {
194                 if (package->package.count <= i)
195                         return -EFAULT;
196                 element = &package->package.elements[i];
197                 if (offsets[i].mode) {
198                         if (element->type != ACPI_TYPE_STRING &&
199                             element->type != ACPI_TYPE_BUFFER)
200                                 return -EFAULT;
201                         strncpy((u8 *)battery + offsets[i].offset,
202                                 element->string.pointer, 32);
203                 } else {
204                         if (element->type != ACPI_TYPE_INTEGER)
205                                 return -EFAULT;
206                         x = (int *)((u8 *)battery + offsets[i].offset);
207                         *x = element->integer.value;
208                 }
209         }
210         return 0;
211 }
212
213 static int acpi_battery_get_status(struct acpi_battery *battery)
214 {
215         int result = 0;
216
217         result = acpi_bus_get_status(battery->device);
218         if (result) {
219                 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
220                 return -ENODEV;
221         }
222         return result;
223 }
224
225 static int acpi_battery_get_info(struct acpi_battery *battery)
226 {
227         int result = 0;
228         acpi_status status = 0;
229         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
230
231         battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
232         if (!acpi_battery_present(battery))
233                 return 0;
234         mutex_lock(&battery->lock);
235         status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
236                                       NULL, &buffer);
237         mutex_unlock(&battery->lock);
238         if (ACPI_FAILURE(status)) {
239                 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
240                 return -ENODEV;
241         }
242         result = extract_package(battery, buffer.pointer,
243                                  info_offsets, ARRAY_SIZE(info_offsets));
244         kfree(buffer.pointer);
245         return result;
246 }
247
248 static int acpi_battery_get_state(struct acpi_battery *battery)
249 {
250         int result = 0;
251         acpi_status status = 0;
252         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
253
254         battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
255
256         if (!acpi_battery_present(battery))
257                 return 0;
258
259         mutex_lock(&battery->lock);
260         status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST",
261                                       NULL, &buffer);
262         mutex_unlock(&battery->lock);
263
264         if (ACPI_FAILURE(status)) {
265                 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
266                 return -ENODEV;
267         }
268         result = extract_package(battery, buffer.pointer,
269                                  state_offsets, ARRAY_SIZE(state_offsets));
270         kfree(buffer.pointer);
271         return result;
272 }
273
274 static int acpi_battery_get_alarm(struct acpi_battery *battery)
275 {
276         battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
277
278         return 0;
279 }
280
281 static int acpi_battery_set_alarm(struct acpi_battery *battery,
282                                   unsigned long alarm)
283 {
284         acpi_status status = 0;
285         union acpi_object arg0 = { ACPI_TYPE_INTEGER };
286         struct acpi_object_list arg_list = { 1, &arg0 };
287
288         battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
289
290         if (!acpi_battery_present(battery))
291                 return -ENODEV;
292
293         if (!battery->alarm_present)
294                 return -ENODEV;
295
296         arg0.integer.value = alarm;
297
298         mutex_lock(&battery->lock);
299         status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
300                                       &arg_list, NULL);
301         mutex_unlock(&battery->lock);
302         if (ACPI_FAILURE(status))
303                 return -ENODEV;
304
305         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
306
307         battery->alarm = alarm;
308
309         return 0;
310 }
311
312 static int acpi_battery_init_alarm(struct acpi_battery *battery)
313 {
314         int result = 0;
315         acpi_status status = AE_OK;
316         acpi_handle handle = NULL;
317         unsigned long alarm = battery->alarm;
318
319         /* See if alarms are supported, and if so, set default */
320
321         status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
322         if (ACPI_SUCCESS(status)) {
323                 battery->alarm_present = 1;
324                 if (!alarm) {
325                         alarm = battery->design_capacity_warning;
326                 }
327                 result = acpi_battery_set_alarm(battery, alarm);
328                 if (result)
329                         goto end;
330         } else {
331                 battery->alarm_present = 0;
332         }
333
334       end:
335
336         return result;
337 }
338
339 static int acpi_battery_init_update(struct acpi_battery *battery)
340 {
341         int result = 0;
342
343         result = acpi_battery_get_status(battery);
344         if (result)
345                 return result;
346
347         battery->present_prev = acpi_battery_present(battery);
348
349         if (acpi_battery_present(battery)) {
350                 result = acpi_battery_get_info(battery);
351                 if (result)
352                         return result;
353                 result = acpi_battery_get_state(battery);
354                 if (result)
355                         return result;
356
357                 acpi_battery_init_alarm(battery);
358         }
359
360         return result;
361 }
362
363 static int acpi_battery_update(struct acpi_battery *battery,
364                                int update, int *update_result_ptr)
365 {
366         int result = 0;
367         int update_result = ACPI_BATTERY_NONE_UPDATE;
368
369         if (!acpi_battery_present(battery)) {
370                 update = 1;
371         }
372
373         if (battery->init_update) {
374                 result = acpi_battery_init_update(battery);
375                 if (result)
376                         goto end;
377                 update_result = ACPI_BATTERY_INIT_UPDATE;
378         } else if (update) {
379                 result = acpi_battery_get_status(battery);
380                 if (result)
381                         goto end;
382                 if ((!battery->present_prev & acpi_battery_present(battery))
383                     || (battery->present_prev & !acpi_battery_present(battery))) {
384                         result = acpi_battery_init_update(battery);
385                         if (result)
386                                 goto end;
387                         update_result = ACPI_BATTERY_INIT_UPDATE;
388                 } else {
389                         update_result = ACPI_BATTERY_EASY_UPDATE;
390                 }
391         }
392
393       end:
394
395         battery->init_update = (result != 0);
396
397         *update_result_ptr = update_result;
398
399         return result;
400 }
401
402 static void acpi_battery_notify_update(struct acpi_battery *battery)
403 {
404         acpi_battery_get_status(battery);
405
406         if (battery->init_update) {
407                 return;
408         }
409
410         if ((!battery->present_prev &
411              acpi_battery_present(battery)) ||
412             (battery->present_prev &
413              !acpi_battery_present(battery))) {
414                 battery->init_update = 1;
415         } else {
416                 battery->update[ACPI_BATTERY_INFO] = 1;
417                 battery->update[ACPI_BATTERY_STATE] = 1;
418                 battery->update[ACPI_BATTERY_ALARM] = 1;
419         }
420 }
421
422 /* --------------------------------------------------------------------------
423                               FS Interface (/proc)
424    -------------------------------------------------------------------------- */
425
426 static struct proc_dir_entry *acpi_battery_dir;
427
428 static int acpi_battery_print_info(struct seq_file *seq, int result)
429 {
430         struct acpi_battery *battery = seq->private;
431         char *units = "?";
432
433         if (result)
434                 goto end;
435
436         if (acpi_battery_present(battery))
437                 seq_printf(seq, "present:                 yes\n");
438         else {
439                 seq_printf(seq, "present:                 no\n");
440                 goto end;
441         }
442
443         /* Battery Units */
444
445         units = acpi_battery_power_units(battery);
446
447         if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
448                 seq_printf(seq, "design capacity:         unknown\n");
449         else
450                 seq_printf(seq, "design capacity:         %d %sh\n",
451                            (u32) battery->design_capacity, units);
452
453         if (battery->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
454                 seq_printf(seq, "last full capacity:      unknown\n");
455         else
456                 seq_printf(seq, "last full capacity:      %d %sh\n",
457                            (u32) battery->last_full_capacity, units);
458
459         switch ((u32) battery->technology) {
460         case 0:
461                 seq_printf(seq, "battery technology:      non-rechargeable\n");
462                 break;
463         case 1:
464                 seq_printf(seq, "battery technology:      rechargeable\n");
465                 break;
466         default:
467                 seq_printf(seq, "battery technology:      unknown\n");
468                 break;
469         }
470
471         if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
472                 seq_printf(seq, "design voltage:          unknown\n");
473         else
474                 seq_printf(seq, "design voltage:          %d mV\n",
475                            (u32) battery->design_voltage);
476         seq_printf(seq, "design capacity warning: %d %sh\n",
477                    (u32) battery->design_capacity_warning, units);
478         seq_printf(seq, "design capacity low:     %d %sh\n",
479                    (u32) battery->design_capacity_low, units);
480         seq_printf(seq, "capacity granularity 1:  %d %sh\n",
481                    (u32) battery->capacity_granularity_1, units);
482         seq_printf(seq, "capacity granularity 2:  %d %sh\n",
483                    (u32) battery->capacity_granularity_2, units);
484         seq_printf(seq, "model number:            %s\n", battery->model_number);
485         seq_printf(seq, "serial number:           %s\n", battery->serial_number);
486         seq_printf(seq, "battery type:            %s\n", battery->type);
487         seq_printf(seq, "OEM info:                %s\n", battery->oem_info);
488
489       end:
490
491         if (result)
492                 seq_printf(seq, "ERROR: Unable to read battery info\n");
493
494         return result;
495 }
496
497 static int acpi_battery_print_state(struct seq_file *seq, int result)
498 {
499         struct acpi_battery *battery = seq->private;
500         char *units = "?";
501
502         if (result)
503                 goto end;
504
505         if (acpi_battery_present(battery))
506                 seq_printf(seq, "present:                 yes\n");
507         else {
508                 seq_printf(seq, "present:                 no\n");
509                 goto end;
510         }
511
512         /* Battery Units */
513
514         units = acpi_battery_power_units(battery);
515
516         if (!(battery->state & 0x04))
517                 seq_printf(seq, "capacity state:          ok\n");
518         else
519                 seq_printf(seq, "capacity state:          critical\n");
520
521         if ((battery->state & 0x01) && (battery->state & 0x02)) {
522                 seq_printf(seq,
523                            "charging state:          charging/discharging\n");
524         } else if (battery->state & 0x01)
525                 seq_printf(seq, "charging state:          discharging\n");
526         else if (battery->state & 0x02)
527                 seq_printf(seq, "charging state:          charging\n");
528         else {
529                 seq_printf(seq, "charging state:          charged\n");
530         }
531
532         if (battery->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
533                 seq_printf(seq, "present rate:            unknown\n");
534         else
535                 seq_printf(seq, "present rate:            %d %s\n",
536                            (u32) battery->present_rate, units);
537
538         if (battery->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
539                 seq_printf(seq, "remaining capacity:      unknown\n");
540         else
541                 seq_printf(seq, "remaining capacity:      %d %sh\n",
542                            (u32) battery->remaining_capacity, units);
543
544         if (battery->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
545                 seq_printf(seq, "present voltage:         unknown\n");
546         else
547                 seq_printf(seq, "present voltage:         %d mV\n",
548                            (u32) battery->present_voltage);
549
550       end:
551
552         if (result) {
553                 seq_printf(seq, "ERROR: Unable to read battery state\n");
554         }
555
556         return result;
557 }
558
559 static int acpi_battery_print_alarm(struct seq_file *seq, int result)
560 {
561         struct acpi_battery *battery = seq->private;
562         char *units = "?";
563
564         if (result)
565                 goto end;
566
567         if (!acpi_battery_present(battery)) {
568                 seq_printf(seq, "present:                 no\n");
569                 goto end;
570         }
571
572         /* Battery Units */
573
574         units = acpi_battery_power_units(battery);
575
576         seq_printf(seq, "alarm:                   ");
577         if (!battery->alarm)
578                 seq_printf(seq, "unsupported\n");
579         else
580                 seq_printf(seq, "%lu %sh\n", battery->alarm, units);
581
582       end:
583
584         if (result)
585                 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
586
587         return result;
588 }
589
590 static ssize_t
591 acpi_battery_write_alarm(struct file *file,
592                          const char __user * buffer,
593                          size_t count, loff_t * ppos)
594 {
595         int result = 0;
596         char alarm_string[12] = { '\0' };
597         struct seq_file *m = file->private_data;
598         struct acpi_battery *battery = m->private;
599         int update_result = ACPI_BATTERY_NONE_UPDATE;
600
601         if (!battery || (count > sizeof(alarm_string) - 1))
602                 return -EINVAL;
603
604         result = acpi_battery_update(battery, 1, &update_result);
605         if (result) {
606                 result = -ENODEV;
607                 goto end;
608         }
609
610         if (!acpi_battery_present(battery)) {
611                 result = -ENODEV;
612                 goto end;
613         }
614
615         if (copy_from_user(alarm_string, buffer, count)) {
616                 result = -EFAULT;
617                 goto end;
618         }
619
620         alarm_string[count] = '\0';
621
622         result = acpi_battery_set_alarm(battery,
623                                         simple_strtoul(alarm_string, NULL, 0));
624         if (result)
625                 goto end;
626
627       end:
628
629         acpi_battery_check_result(battery, result);
630
631         if (!result)
632                 result = count;
633         return result;
634 }
635
636 typedef int(*print_func)(struct seq_file *seq, int result);
637 typedef int(*get_func)(struct acpi_battery *battery);
638
639 static struct acpi_read_mux {
640         print_func print;
641         get_func get;
642 } acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
643         {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
644         {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
645         {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
646 };
647
648 static int acpi_battery_read(int fid, struct seq_file *seq)
649 {
650         struct acpi_battery *battery = seq->private;
651         int result = 0;
652         int update_result = ACPI_BATTERY_NONE_UPDATE;
653         int update = 0;
654
655         update = (get_seconds() - battery->update_time[fid] >= update_time);
656         update = (update | battery->update[fid]);
657
658         result = acpi_battery_update(battery, update, &update_result);
659         if (result)
660                 goto end;
661
662         if (update_result == ACPI_BATTERY_EASY_UPDATE) {
663                 result = acpi_read_funcs[fid].get(battery);
664                 if (result)
665                         goto end;
666         }
667
668       end:
669         result = acpi_read_funcs[fid].print(seq, result);
670         acpi_battery_check_result(battery, result);
671         battery->update[fid] = result;
672         return result;
673 }
674
675 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
676 {
677         return acpi_battery_read(ACPI_BATTERY_INFO, seq);
678 }
679
680 static int acpi_battery_read_state(struct seq_file *seq, void *offset)
681 {
682         return acpi_battery_read(ACPI_BATTERY_STATE, seq);
683 }
684
685 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
686 {
687         return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
688 }
689
690 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
691 {
692         return single_open(file, acpi_battery_read_info, PDE(inode)->data);
693 }
694
695 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
696 {
697         return single_open(file, acpi_battery_read_state, PDE(inode)->data);
698 }
699
700 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
701 {
702         return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
703 }
704
705 static struct battery_file {
706         struct file_operations ops;
707         mode_t mode;
708         char *name;
709 } acpi_battery_file[] = {
710         {
711         .name = "info",
712         .mode = S_IRUGO,
713         .ops = {
714         .open = acpi_battery_info_open_fs,
715         .read = seq_read,
716         .llseek = seq_lseek,
717         .release = single_release,
718         .owner = THIS_MODULE,
719         },
720         },
721         {
722         .name = "state",
723         .mode = S_IRUGO,
724         .ops = {
725         .open = acpi_battery_state_open_fs,
726         .read = seq_read,
727         .llseek = seq_lseek,
728         .release = single_release,
729         .owner = THIS_MODULE,
730         },
731         },
732         {
733         .name = "alarm",
734         .mode = S_IFREG | S_IRUGO | S_IWUSR,
735         .ops = {
736         .open = acpi_battery_alarm_open_fs,
737         .read = seq_read,
738         .write = acpi_battery_write_alarm,
739         .llseek = seq_lseek,
740         .release = single_release,
741         .owner = THIS_MODULE,
742         },
743         },
744 };
745
746 static int acpi_battery_add_fs(struct acpi_device *device)
747 {
748         struct proc_dir_entry *entry = NULL;
749         int i;
750
751         if (!acpi_device_dir(device)) {
752                 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
753                                                      acpi_battery_dir);
754                 if (!acpi_device_dir(device))
755                         return -ENODEV;
756                 acpi_device_dir(device)->owner = THIS_MODULE;
757         }
758
759         for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
760                 entry = create_proc_entry(acpi_battery_file[i].name,
761                                   acpi_battery_file[i].mode, acpi_device_dir(device));
762                 if (!entry)
763                         return -ENODEV;
764                 else {
765                         entry->proc_fops = &acpi_battery_file[i].ops;
766                         entry->data = acpi_driver_data(device);
767                         entry->owner = THIS_MODULE;
768                 }
769         }
770
771         return 0;
772 }
773
774 static int acpi_battery_remove_fs(struct acpi_device *device)
775 {
776         int i;
777         if (acpi_device_dir(device)) {
778                 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
779                         remove_proc_entry(acpi_battery_file[i].name,
780                                   acpi_device_dir(device));
781                 }
782                 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
783                 acpi_device_dir(device) = NULL;
784         }
785
786         return 0;
787 }
788
789 /* --------------------------------------------------------------------------
790                                  Driver Interface
791    -------------------------------------------------------------------------- */
792
793 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
794 {
795         struct acpi_battery *battery = data;
796         struct acpi_device *device = NULL;
797
798         if (!battery)
799                 return;
800
801         device = battery->device;
802
803         switch (event) {
804         case ACPI_BATTERY_NOTIFY_STATUS:
805         case ACPI_BATTERY_NOTIFY_INFO:
806         case ACPI_NOTIFY_BUS_CHECK:
807         case ACPI_NOTIFY_DEVICE_CHECK:
808                 device = battery->device;
809                 acpi_battery_notify_update(battery);
810                 acpi_bus_generate_proc_event(device, event,
811                                         acpi_battery_present(battery));
812                 acpi_bus_generate_netlink_event(device->pnp.device_class,
813                                                   device->dev.bus_id, event,
814                                                   acpi_battery_present(battery));
815                 break;
816         default:
817                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
818                                   "Unsupported event [0x%x]\n", event));
819                 break;
820         }
821
822         return;
823 }
824
825 static int acpi_battery_add(struct acpi_device *device)
826 {
827         int result = 0;
828         acpi_status status = 0;
829         struct acpi_battery *battery = NULL;
830
831         if (!device)
832                 return -EINVAL;
833
834         battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
835         if (!battery)
836                 return -ENOMEM;
837
838         battery->device = device;
839         strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
840         strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
841         acpi_driver_data(device) = battery;
842         mutex_init(&battery->lock);
843         result = acpi_battery_get_status(battery);
844         if (result)
845                 goto end;
846
847         battery->init_update = 1;
848
849         result = acpi_battery_add_fs(device);
850         if (result)
851                 goto end;
852
853         status = acpi_install_notify_handler(device->handle,
854                                              ACPI_ALL_NOTIFY,
855                                              acpi_battery_notify, battery);
856         if (ACPI_FAILURE(status)) {
857                 ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler"));
858                 result = -ENODEV;
859                 goto end;
860         }
861
862         printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
863                ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
864                device->status.battery_present ? "present" : "absent");
865
866       end:
867
868         if (result) {
869                 acpi_battery_remove_fs(device);
870                 kfree(battery);
871         }
872
873         return result;
874 }
875
876 static int acpi_battery_remove(struct acpi_device *device, int type)
877 {
878         acpi_status status = 0;
879         struct acpi_battery *battery = NULL;
880
881         if (!device || !acpi_driver_data(device))
882                 return -EINVAL;
883
884         battery = acpi_driver_data(device);
885
886         status = acpi_remove_notify_handler(device->handle,
887                                             ACPI_ALL_NOTIFY,
888                                             acpi_battery_notify);
889
890         acpi_battery_remove_fs(device);
891         mutex_destroy(&battery->lock);
892         kfree(battery);
893
894         return 0;
895 }
896
897 /* this is needed to learn about changes made in suspended state */
898 static int acpi_battery_resume(struct acpi_device *device)
899 {
900         struct acpi_battery *battery;
901
902         if (!device)
903                 return -EINVAL;
904
905         battery = device->driver_data;
906
907         battery->init_update = 1;
908
909         return 0;
910 }
911
912 static int __init acpi_battery_init(void)
913 {
914         int result;
915
916         if (acpi_disabled)
917                 return -ENODEV;
918
919         acpi_battery_dir = acpi_lock_battery_dir();
920         if (!acpi_battery_dir)
921                 return -ENODEV;
922
923         result = acpi_bus_register_driver(&acpi_battery_driver);
924         if (result < 0) {
925                 acpi_unlock_battery_dir(acpi_battery_dir);
926                 return -ENODEV;
927         }
928
929         return 0;
930 }
931
932 static void __exit acpi_battery_exit(void)
933 {
934         acpi_bus_unregister_driver(&acpi_battery_driver);
935
936         acpi_unlock_battery_dir(acpi_battery_dir);
937
938         return;
939 }
940
941 module_init(acpi_battery_init);
942 module_exit(acpi_battery_exit);