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