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