xref: /openbmc/linux/drivers/acpi/battery.c (revision c21b37f6)
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);
1021