tcp: initialize rcv_tstamp for restored sockets
[deliverable/linux.git] / drivers / acpi / battery.c
CommitLineData
1da177e4 1/*
aa650bbd 2 * battery.c - ACPI Battery Driver (Revision: 2.0)
1da177e4 3 *
aa650bbd
AS
4 * Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
5 * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
1da177e4
LT
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>
f1d4661a 32#include <linux/jiffies.h>
0f66af53 33#include <linux/async.h>
bc76f90b 34#include <linux/dmi.h>
5a0e3ad6 35#include <linux/slab.h>
25be5821 36#include <linux/suspend.h>
4000e626 37#include <asm/unaligned.h>
d7380965 38
fdcedbba 39#ifdef CONFIG_ACPI_PROCFS_POWER
1da177e4
LT
40#include <linux/proc_fs.h>
41#include <linux/seq_file.h>
42#include <asm/uaccess.h>
d7380965 43#endif
1da177e4
LT
44
45#include <acpi/acpi_bus.h>
46#include <acpi/acpi_drivers.h>
d7380965
AS
47#include <linux/power_supply.h>
48
a192a958
LB
49#define PREFIX "ACPI: "
50
1da177e4
LT
51#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
52
1da177e4 53#define ACPI_BATTERY_CLASS "battery"
1da177e4 54#define ACPI_BATTERY_DEVICE_NAME "Battery"
1da177e4
LT
55#define ACPI_BATTERY_NOTIFY_STATUS 0x80
56#define ACPI_BATTERY_NOTIFY_INFO 0x81
c67fcd67 57#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82
1da177e4 58
ae6f6187
LT
59/* Battery power unit: 0 means mW, 1 means mA */
60#define ACPI_BATTERY_POWER_UNIT_MA 1
61
1da177e4 62#define _COMPONENT ACPI_BATTERY_COMPONENT
b6ce4083 63
f52fd66d 64ACPI_MODULE_NAME("battery");
1da177e4 65
f52fd66d 66MODULE_AUTHOR("Paul Diefenbaugh");
aa650bbd 67MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
7cda93e0 68MODULE_DESCRIPTION("ACPI Battery Driver");
1da177e4
LT
69MODULE_LICENSE("GPL");
70
f1d4661a
AS
71static unsigned int cache_time = 1000;
72module_param(cache_time, uint, 0644);
73MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
b6ce4083 74
fdcedbba 75#ifdef CONFIG_ACPI_PROCFS_POWER
3f86b832
RT
76extern struct proc_dir_entry *acpi_lock_battery_dir(void);
77extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
78
d7380965
AS
79enum acpi_battery_files {
80 info_tag = 0,
81 state_tag,
82 alarm_tag,
83 ACPI_BATTERY_NUMFILES,
84};
85
86#endif
87
1ba90e3a
TR
88static const struct acpi_device_id battery_device_ids[] = {
89 {"PNP0C0A", 0},
90 {"", 0},
91};
1ba90e3a 92
aa650bbd 93MODULE_DEVICE_TABLE(acpi, battery_device_ids);
1da177e4 94
7b3bcc4a
AS
95enum {
96 ACPI_BATTERY_ALARM_PRESENT,
c67fcd67 97 ACPI_BATTERY_XINFO_PRESENT,
557d5868 98 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
4000e626
KI
99 /* On Lenovo Thinkpad models from 2010 and 2011, the power unit
100 switches between mWh and mAh depending on whether the system
101 is running on battery or not. When mAh is the unit, most
102 reported values are incorrect and need to be adjusted by
103 10000/design_voltage. Verified on x201, t410, t410s, and x220.
104 Pre-2010 and 2012 models appear to always report in mWh and
105 are thus unaffected (tested with t42, t61, t500, x200, x300,
106 and x230). Also, in mid-2012 Lenovo issued a BIOS update for
107 the 2011 models that fixes the issue (tested on x220 with a
108 post-1.29 BIOS), but as of Nov. 2012, no such update is
109 available for the 2010 models. */
110 ACPI_BATTERY_QUIRK_THINKPAD_MAH,
7b3bcc4a 111};
78490d82 112
1da177e4 113struct acpi_battery {
038fdea2 114 struct mutex lock;
69d94ec6 115 struct mutex sysfs_lock;
d7380965 116 struct power_supply bat;
f1d4661a 117 struct acpi_device *device;
25be5821 118 struct notifier_block pm_nb;
f1d4661a 119 unsigned long update_time;
016d5baa 120 int revision;
7faa144a 121 int rate_now;
d7380965
AS
122 int capacity_now;
123 int voltage_now;
038fdea2 124 int design_capacity;
d7380965 125 int full_charge_capacity;
038fdea2
AS
126 int technology;
127 int design_voltage;
128 int design_capacity_warning;
129 int design_capacity_low;
c67fcd67
AS
130 int cycle_count;
131 int measurement_accuracy;
132 int max_sampling_time;
133 int min_sampling_time;
134 int max_averaging_interval;
135 int min_averaging_interval;
038fdea2
AS
136 int capacity_granularity_1;
137 int capacity_granularity_2;
f1d4661a 138 int alarm;
038fdea2
AS
139 char model_number[32];
140 char serial_number[32];
141 char type[32];
142 char oem_info[32];
f1d4661a
AS
143 int state;
144 int power_unit;
7b3bcc4a 145 unsigned long flags;
1da177e4
LT
146};
147
497888cf 148#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat)
d7380965 149
efd941f1 150static inline int acpi_battery_present(struct acpi_battery *battery)
b6ce4083 151{
78490d82
AS
152 return battery->device->status.battery_present;
153}
038fdea2 154
d7380965
AS
155static int acpi_battery_technology(struct acpi_battery *battery)
156{
157 if (!strcasecmp("NiCd", battery->type))
158 return POWER_SUPPLY_TECHNOLOGY_NiCd;
159 if (!strcasecmp("NiMH", battery->type))
160 return POWER_SUPPLY_TECHNOLOGY_NiMH;
161 if (!strcasecmp("LION", battery->type))
162 return POWER_SUPPLY_TECHNOLOGY_LION;
ad40e68b 163 if (!strncasecmp("LI-ION", battery->type, 6))
0bde7eee 164 return POWER_SUPPLY_TECHNOLOGY_LION;
d7380965
AS
165 if (!strcasecmp("LiP", battery->type))
166 return POWER_SUPPLY_TECHNOLOGY_LIPO;
167 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
168}
169
9104476e 170static int acpi_battery_get_state(struct acpi_battery *battery);
b19073a0 171
56f382a0
RH
172static int acpi_battery_is_charged(struct acpi_battery *battery)
173{
174 /* either charging or discharging */
175 if (battery->state != 0)
176 return 0;
177
178 /* battery not reporting charge */
179 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
180 battery->capacity_now == 0)
181 return 0;
182
183 /* good batteries update full_charge as the batteries degrade */
184 if (battery->full_charge_capacity == battery->capacity_now)
185 return 1;
186
187 /* fallback to using design values for broken batteries */
188 if (battery->design_capacity == battery->capacity_now)
189 return 1;
190
191 /* we don't do any sort of metric based on percentages */
192 return 0;
193}
194
d7380965
AS
195static int acpi_battery_get_property(struct power_supply *psy,
196 enum power_supply_property psp,
197 union power_supply_propval *val)
198{
a1b4bd69 199 int ret = 0;
d7380965
AS
200 struct acpi_battery *battery = to_acpi_battery(psy);
201
9104476e
AS
202 if (acpi_battery_present(battery)) {
203 /* run battery update only if it is present */
204 acpi_battery_get_state(battery);
205 } else if (psp != POWER_SUPPLY_PROP_PRESENT)
d7380965
AS
206 return -ENODEV;
207 switch (psp) {
208 case POWER_SUPPLY_PROP_STATUS:
209 if (battery->state & 0x01)
210 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
211 else if (battery->state & 0x02)
212 val->intval = POWER_SUPPLY_STATUS_CHARGING;
56f382a0 213 else if (acpi_battery_is_charged(battery))
d7380965 214 val->intval = POWER_SUPPLY_STATUS_FULL;
4c41d3ad
RD
215 else
216 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
d7380965
AS
217 break;
218 case POWER_SUPPLY_PROP_PRESENT:
219 val->intval = acpi_battery_present(battery);
220 break;
221 case POWER_SUPPLY_PROP_TECHNOLOGY:
222 val->intval = acpi_battery_technology(battery);
223 break;
c67fcd67
AS
224 case POWER_SUPPLY_PROP_CYCLE_COUNT:
225 val->intval = battery->cycle_count;
226 break;
d7380965 227 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
a1b4bd69
RW
228 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
229 ret = -ENODEV;
230 else
231 val->intval = battery->design_voltage * 1000;
d7380965
AS
232 break;
233 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
a1b4bd69
RW
234 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
235 ret = -ENODEV;
236 else
237 val->intval = battery->voltage_now * 1000;
d7380965
AS
238 break;
239 case POWER_SUPPLY_PROP_CURRENT_NOW:
7faa144a 240 case POWER_SUPPLY_PROP_POWER_NOW:
a1b4bd69
RW
241 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
242 ret = -ENODEV;
243 else
244 val->intval = battery->rate_now * 1000;
d7380965
AS
245 break;
246 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
247 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
a1b4bd69
RW
248 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
249 ret = -ENODEV;
250 else
251 val->intval = battery->design_capacity * 1000;
d7380965
AS
252 break;
253 case POWER_SUPPLY_PROP_CHARGE_FULL:
254 case POWER_SUPPLY_PROP_ENERGY_FULL:
a1b4bd69
RW
255 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
256 ret = -ENODEV;
257 else
258 val->intval = battery->full_charge_capacity * 1000;
d7380965
AS
259 break;
260 case POWER_SUPPLY_PROP_CHARGE_NOW:
261 case POWER_SUPPLY_PROP_ENERGY_NOW:
a1b4bd69
RW
262 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
263 ret = -ENODEV;
264 else
265 val->intval = battery->capacity_now * 1000;
d7380965 266 break;
a58e1150 267 case POWER_SUPPLY_PROP_CAPACITY:
268 if (battery->capacity_now && battery->full_charge_capacity)
269 val->intval = battery->capacity_now * 100/
270 battery->full_charge_capacity;
271 else
272 val->intval = 0;
273 break;
d7380965
AS
274 case POWER_SUPPLY_PROP_MODEL_NAME:
275 val->strval = battery->model_number;
276 break;
277 case POWER_SUPPLY_PROP_MANUFACTURER:
278 val->strval = battery->oem_info;
279 break;
7c2670bb 280 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
281 val->strval = battery->serial_number;
282 break;
d7380965 283 default:
a1b4bd69 284 ret = -EINVAL;
d7380965 285 }
a1b4bd69 286 return ret;
d7380965
AS
287}
288
289static enum power_supply_property charge_battery_props[] = {
290 POWER_SUPPLY_PROP_STATUS,
291 POWER_SUPPLY_PROP_PRESENT,
292 POWER_SUPPLY_PROP_TECHNOLOGY,
c67fcd67 293 POWER_SUPPLY_PROP_CYCLE_COUNT,
d7380965
AS
294 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
295 POWER_SUPPLY_PROP_VOLTAGE_NOW,
296 POWER_SUPPLY_PROP_CURRENT_NOW,
297 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
298 POWER_SUPPLY_PROP_CHARGE_FULL,
299 POWER_SUPPLY_PROP_CHARGE_NOW,
a58e1150 300 POWER_SUPPLY_PROP_CAPACITY,
d7380965
AS
301 POWER_SUPPLY_PROP_MODEL_NAME,
302 POWER_SUPPLY_PROP_MANUFACTURER,
7c2670bb 303 POWER_SUPPLY_PROP_SERIAL_NUMBER,
d7380965
AS
304};
305
306static enum power_supply_property energy_battery_props[] = {
307 POWER_SUPPLY_PROP_STATUS,
308 POWER_SUPPLY_PROP_PRESENT,
309 POWER_SUPPLY_PROP_TECHNOLOGY,
c67fcd67 310 POWER_SUPPLY_PROP_CYCLE_COUNT,
d7380965
AS
311 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
312 POWER_SUPPLY_PROP_VOLTAGE_NOW,
7faa144a 313 POWER_SUPPLY_PROP_POWER_NOW,
d7380965
AS
314 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
315 POWER_SUPPLY_PROP_ENERGY_FULL,
316 POWER_SUPPLY_PROP_ENERGY_NOW,
a58e1150 317 POWER_SUPPLY_PROP_CAPACITY,
d7380965
AS
318 POWER_SUPPLY_PROP_MODEL_NAME,
319 POWER_SUPPLY_PROP_MANUFACTURER,
7c2670bb 320 POWER_SUPPLY_PROP_SERIAL_NUMBER,
d7380965
AS
321};
322
fdcedbba 323#ifdef CONFIG_ACPI_PROCFS_POWER
f1d4661a 324inline char *acpi_battery_units(struct acpi_battery *battery)
78490d82 325{
ae6f6187
LT
326 return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
327 "mA" : "mW";
b6ce4083 328}
d7380965 329#endif
b6ce4083 330
78490d82
AS
331/* --------------------------------------------------------------------------
332 Battery Management
333 -------------------------------------------------------------------------- */
038fdea2
AS
334struct acpi_offsets {
335 size_t offset; /* offset inside struct acpi_sbs_battery */
336 u8 mode; /* int or string? */
337};
b6ce4083 338
038fdea2
AS
339static struct acpi_offsets state_offsets[] = {
340 {offsetof(struct acpi_battery, state), 0},
7faa144a 341 {offsetof(struct acpi_battery, rate_now), 0},
d7380965
AS
342 {offsetof(struct acpi_battery, capacity_now), 0},
343 {offsetof(struct acpi_battery, voltage_now), 0},
038fdea2 344};
b6ce4083 345
038fdea2
AS
346static struct acpi_offsets info_offsets[] = {
347 {offsetof(struct acpi_battery, power_unit), 0},
348 {offsetof(struct acpi_battery, design_capacity), 0},
d7380965 349 {offsetof(struct acpi_battery, full_charge_capacity), 0},
038fdea2
AS
350 {offsetof(struct acpi_battery, technology), 0},
351 {offsetof(struct acpi_battery, design_voltage), 0},
352 {offsetof(struct acpi_battery, design_capacity_warning), 0},
353 {offsetof(struct acpi_battery, design_capacity_low), 0},
354 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
355 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
356 {offsetof(struct acpi_battery, model_number), 1},
357 {offsetof(struct acpi_battery, serial_number), 1},
358 {offsetof(struct acpi_battery, type), 1},
359 {offsetof(struct acpi_battery, oem_info), 1},
360};
b6ce4083 361
c67fcd67 362static struct acpi_offsets extended_info_offsets[] = {
016d5baa 363 {offsetof(struct acpi_battery, revision), 0},
c67fcd67
AS
364 {offsetof(struct acpi_battery, power_unit), 0},
365 {offsetof(struct acpi_battery, design_capacity), 0},
366 {offsetof(struct acpi_battery, full_charge_capacity), 0},
367 {offsetof(struct acpi_battery, technology), 0},
368 {offsetof(struct acpi_battery, design_voltage), 0},
369 {offsetof(struct acpi_battery, design_capacity_warning), 0},
370 {offsetof(struct acpi_battery, design_capacity_low), 0},
371 {offsetof(struct acpi_battery, cycle_count), 0},
372 {offsetof(struct acpi_battery, measurement_accuracy), 0},
373 {offsetof(struct acpi_battery, max_sampling_time), 0},
374 {offsetof(struct acpi_battery, min_sampling_time), 0},
375 {offsetof(struct acpi_battery, max_averaging_interval), 0},
376 {offsetof(struct acpi_battery, min_averaging_interval), 0},
377 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
378 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
379 {offsetof(struct acpi_battery, model_number), 1},
380 {offsetof(struct acpi_battery, serial_number), 1},
381 {offsetof(struct acpi_battery, type), 1},
382 {offsetof(struct acpi_battery, oem_info), 1},
383};
384
038fdea2
AS
385static int extract_package(struct acpi_battery *battery,
386 union acpi_object *package,
387 struct acpi_offsets *offsets, int num)
388{
106449e8 389 int i;
038fdea2
AS
390 union acpi_object *element;
391 if (package->type != ACPI_TYPE_PACKAGE)
392 return -EFAULT;
393 for (i = 0; i < num; ++i) {
394 if (package->package.count <= i)
395 return -EFAULT;
396 element = &package->package.elements[i];
397 if (offsets[i].mode) {
106449e8
AS
398 u8 *ptr = (u8 *)battery + offsets[i].offset;
399 if (element->type == ACPI_TYPE_STRING ||
400 element->type == ACPI_TYPE_BUFFER)
401 strncpy(ptr, element->string.pointer, 32);
402 else if (element->type == ACPI_TYPE_INTEGER) {
403 strncpy(ptr, (u8 *)&element->integer.value,
439913ff
LM
404 sizeof(u64));
405 ptr[sizeof(u64)] = 0;
b8a1bdb1
AS
406 } else
407 *ptr = 0; /* don't have value */
038fdea2 408 } else {
b8a1bdb1
AS
409 int *x = (int *)((u8 *)battery + offsets[i].offset);
410 *x = (element->type == ACPI_TYPE_INTEGER) ?
411 element->integer.value : -1;
038fdea2 412 }
b6ce4083 413 }
b6ce4083
VL
414 return 0;
415}
416
417static int acpi_battery_get_status(struct acpi_battery *battery)
418{
aa650bbd 419 if (acpi_bus_get_status(battery->device)) {
b6ce4083
VL
420 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
421 return -ENODEV;
422 }
aa650bbd 423 return 0;
b6ce4083
VL
424}
425
426static int acpi_battery_get_info(struct acpi_battery *battery)
1da177e4 427{
aa650bbd 428 int result = -EFAULT;
4be44fcd 429 acpi_status status = 0;
0f4c6547 430 char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ?
c67fcd67
AS
431 "_BIX" : "_BIF";
432
4be44fcd 433 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1da177e4 434
b6ce4083
VL
435 if (!acpi_battery_present(battery))
436 return 0;
038fdea2 437 mutex_lock(&battery->lock);
c67fcd67
AS
438 status = acpi_evaluate_object(battery->device->handle, name,
439 NULL, &buffer);
038fdea2 440 mutex_unlock(&battery->lock);
aa650bbd 441
1da177e4 442 if (ACPI_FAILURE(status)) {
c67fcd67 443 ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
d550d98d 444 return -ENODEV;
1da177e4 445 }
c67fcd67
AS
446 if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
447 result = extract_package(battery, buffer.pointer,
448 extended_info_offsets,
449 ARRAY_SIZE(extended_info_offsets));
450 else
451 result = extract_package(battery, buffer.pointer,
452 info_offsets, ARRAY_SIZE(info_offsets));
78490d82 453 kfree(buffer.pointer);
557d5868
ZR
454 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
455 battery->full_charge_capacity = battery->design_capacity;
4000e626
KI
456 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
457 battery->power_unit && battery->design_voltage) {
458 battery->design_capacity = battery->design_capacity *
459 10000 / battery->design_voltage;
460 battery->full_charge_capacity = battery->full_charge_capacity *
461 10000 / battery->design_voltage;
462 battery->design_capacity_warning =
463 battery->design_capacity_warning *
464 10000 / battery->design_voltage;
465 /* Curiously, design_capacity_low, unlike the rest of them,
466 is correct. */
467 /* capacity_granularity_* equal 1 on the systems tested, so
468 it's impossible to tell if they would need an adjustment
469 or not if their values were higher. */
470 }
d550d98d 471 return result;
1da177e4
LT
472}
473
b6ce4083 474static int acpi_battery_get_state(struct acpi_battery *battery)
1da177e4 475{
4be44fcd
LB
476 int result = 0;
477 acpi_status status = 0;
478 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1da177e4 479
b6ce4083
VL
480 if (!acpi_battery_present(battery))
481 return 0;
1da177e4 482
f1d4661a
AS
483 if (battery->update_time &&
484 time_before(jiffies, battery->update_time +
485 msecs_to_jiffies(cache_time)))
486 return 0;
487
038fdea2 488 mutex_lock(&battery->lock);
f1d4661a 489 status = acpi_evaluate_object(battery->device->handle, "_BST",
038fdea2
AS
490 NULL, &buffer);
491 mutex_unlock(&battery->lock);
5b31d895 492
1da177e4 493 if (ACPI_FAILURE(status)) {
a6fc6720 494 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
d550d98d 495 return -ENODEV;
1da177e4 496 }
aa650bbd 497
038fdea2
AS
498 result = extract_package(battery, buffer.pointer,
499 state_offsets, ARRAY_SIZE(state_offsets));
f1d4661a 500 battery->update_time = jiffies;
78490d82 501 kfree(buffer.pointer);
bc76f90b 502
55003b21
LT
503 /* For buggy DSDTs that report negative 16-bit values for either
504 * charging or discharging current and/or report 0 as 65536
505 * due to bad math.
506 */
507 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
508 battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
509 (s16)(battery->rate_now) < 0) {
bc76f90b 510 battery->rate_now = abs((s16)battery->rate_now);
55003b21
LT
511 printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate"
512 " invalid.\n");
513 }
bc76f90b 514
557d5868
ZR
515 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
516 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
517 battery->capacity_now = (battery->capacity_now *
518 battery->full_charge_capacity) / 100;
4000e626
KI
519 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
520 battery->power_unit && battery->design_voltage) {
521 battery->capacity_now = battery->capacity_now *
522 10000 / battery->design_voltage;
523 }
b6ce4083
VL
524 return result;
525}
1da177e4 526
aa650bbd 527static int acpi_battery_set_alarm(struct acpi_battery *battery)
1da177e4 528{
4be44fcd 529 acpi_status status = 0;
aa650bbd 530 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
4be44fcd 531 struct acpi_object_list arg_list = { 1, &arg0 };
1da177e4 532
c67fcd67 533 if (!acpi_battery_present(battery) ||
7b3bcc4a 534 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
d550d98d 535 return -ENODEV;
1da177e4 536
aa650bbd 537 arg0.integer.value = battery->alarm;
1da177e4 538
038fdea2 539 mutex_lock(&battery->lock);
f1d4661a
AS
540 status = acpi_evaluate_object(battery->device->handle, "_BTP",
541 &arg_list, NULL);
038fdea2 542 mutex_unlock(&battery->lock);
aa650bbd 543
1da177e4 544 if (ACPI_FAILURE(status))
d550d98d 545 return -ENODEV;
1da177e4 546
aa650bbd 547 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
d550d98d 548 return 0;
1da177e4
LT
549}
550
b6ce4083 551static int acpi_battery_init_alarm(struct acpi_battery *battery)
1da177e4 552{
4be44fcd
LB
553 acpi_status status = AE_OK;
554 acpi_handle handle = NULL;
4be44fcd 555
b6ce4083 556 /* See if alarms are supported, and if so, set default */
f1d4661a
AS
557 status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
558 if (ACPI_FAILURE(status)) {
7b3bcc4a 559 clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
f1d4661a 560 return 0;
b6ce4083 561 }
7b3bcc4a 562 set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
f1d4661a
AS
563 if (!battery->alarm)
564 battery->alarm = battery->design_capacity_warning;
aa650bbd 565 return acpi_battery_set_alarm(battery);
b6ce4083 566}
1da177e4 567
508df92d
AB
568static ssize_t acpi_battery_alarm_show(struct device *dev,
569 struct device_attribute *attr,
570 char *buf)
571{
572 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
573 return sprintf(buf, "%d\n", battery->alarm * 1000);
574}
575
576static ssize_t acpi_battery_alarm_store(struct device *dev,
577 struct device_attribute *attr,
578 const char *buf, size_t count)
579{
580 unsigned long x;
581 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
582 if (sscanf(buf, "%ld\n", &x) == 1)
583 battery->alarm = x/1000;
584 if (acpi_battery_present(battery))
585 acpi_battery_set_alarm(battery);
586 return count;
587}
588
589static struct device_attribute alarm_attr = {
01e8ef11 590 .attr = {.name = "alarm", .mode = 0644},
508df92d
AB
591 .show = acpi_battery_alarm_show,
592 .store = acpi_battery_alarm_store,
593};
594
595static int sysfs_add_battery(struct acpi_battery *battery)
596{
597 int result;
598
ae6f6187 599 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
508df92d
AB
600 battery->bat.properties = charge_battery_props;
601 battery->bat.num_properties =
602 ARRAY_SIZE(charge_battery_props);
603 } else {
604 battery->bat.properties = energy_battery_props;
605 battery->bat.num_properties =
606 ARRAY_SIZE(energy_battery_props);
607 }
608
609 battery->bat.name = acpi_device_bid(battery->device);
610 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
611 battery->bat.get_property = acpi_battery_get_property;
612
613 result = power_supply_register(&battery->device->dev, &battery->bat);
614 if (result)
615 return result;
616 return device_create_file(battery->bat.dev, &alarm_attr);
617}
618
619static void sysfs_remove_battery(struct acpi_battery *battery)
620{
69d94ec6 621 mutex_lock(&battery->sysfs_lock);
9c921c22 622 if (!battery->bat.dev) {
69d94ec6 623 mutex_unlock(&battery->sysfs_lock);
508df92d 624 return;
9c921c22
LT
625 }
626
508df92d
AB
627 device_remove_file(battery->bat.dev, &alarm_attr);
628 power_supply_unregister(&battery->bat);
9104476e 629 battery->bat.dev = NULL;
69d94ec6 630 mutex_unlock(&battery->sysfs_lock);
bc76f90b
HM
631}
632
4000e626
KI
633static void find_battery(const struct dmi_header *dm, void *private)
634{
635 struct acpi_battery *battery = (struct acpi_battery *)private;
636 /* Note: the hardcoded offsets below have been extracted from
637 the source code of dmidecode. */
638 if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
639 const u8 *dmi_data = (const u8 *)(dm + 1);
640 int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
641 if (dm->length >= 18)
642 dmi_capacity *= dmi_data[17];
643 if (battery->design_capacity * battery->design_voltage / 1000
644 != dmi_capacity &&
645 battery->design_capacity * 10 == dmi_capacity)
646 set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
647 &battery->flags);
648 }
649}
650
557d5868
ZR
651/*
652 * According to the ACPI spec, some kinds of primary batteries can
653 * report percentage battery remaining capacity directly to OS.
654 * In this case, it reports the Last Full Charged Capacity == 100
655 * and BatteryPresentRate == 0xFFFFFFFF.
656 *
657 * Now we found some battery reports percentage remaining capacity
658 * even if it's rechargeable.
659 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
660 *
661 * Handle this correctly so that they won't break userspace.
662 */
7b78622d 663static void acpi_battery_quirks(struct acpi_battery *battery)
557d5868
ZR
664{
665 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
0f4c6547 666 return;
557d5868 667
0f4c6547
NM
668 if (battery->full_charge_capacity == 100 &&
669 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
670 battery->capacity_now >= 0 && battery->capacity_now <= 100) {
557d5868
ZR
671 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
672 battery->full_charge_capacity = battery->design_capacity;
673 battery->capacity_now = (battery->capacity_now *
674 battery->full_charge_capacity) / 100;
675 }
4000e626
KI
676
677 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
0f4c6547 678 return;
4000e626
KI
679
680 if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
681 const char *s;
682 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
683 if (s && !strnicmp(s, "ThinkPad", 8)) {
684 dmi_walk(find_battery, battery);
685 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
686 &battery->flags) &&
687 battery->design_voltage) {
688 battery->design_capacity =
689 battery->design_capacity *
690 10000 / battery->design_voltage;
691 battery->full_charge_capacity =
692 battery->full_charge_capacity *
693 10000 / battery->design_voltage;
694 battery->design_capacity_warning =
695 battery->design_capacity_warning *
696 10000 / battery->design_voltage;
697 battery->capacity_now = battery->capacity_now *
698 10000 / battery->design_voltage;
699 }
700 }
701 }
557d5868
ZR
702}
703
f1d4661a 704static int acpi_battery_update(struct acpi_battery *battery)
b6ce4083 705{
50b17851 706 int result, old_present = acpi_battery_present(battery);
97749cd9 707 result = acpi_battery_get_status(battery);
508df92d 708 if (result)
b6ce4083 709 return result;
508df92d
AB
710 if (!acpi_battery_present(battery)) {
711 sysfs_remove_battery(battery);
97749cd9 712 battery->update_time = 0;
508df92d 713 return 0;
b6ce4083 714 }
50b17851
AS
715 if (!battery->update_time ||
716 old_present != acpi_battery_present(battery)) {
97749cd9
AS
717 result = acpi_battery_get_info(battery);
718 if (result)
719 return result;
720 acpi_battery_init_alarm(battery);
721 }
eb03cb02
SH
722 if (!battery->bat.dev) {
723 result = sysfs_add_battery(battery);
724 if (result)
725 return result;
726 }
557d5868 727 result = acpi_battery_get_state(battery);
7b78622d 728 acpi_battery_quirks(battery);
557d5868 729 return result;
4bd35cdb
VL
730}
731
da8aeb92
RW
732static void acpi_battery_refresh(struct acpi_battery *battery)
733{
c5971456
AW
734 int power_unit;
735
da8aeb92
RW
736 if (!battery->bat.dev)
737 return;
738
c5971456
AW
739 power_unit = battery->power_unit;
740
da8aeb92 741 acpi_battery_get_info(battery);
c5971456
AW
742
743 if (power_unit == battery->power_unit)
744 return;
745
746 /* The battery has changed its reporting units. */
da8aeb92
RW
747 sysfs_remove_battery(battery);
748 sysfs_add_battery(battery);
749}
750
1da177e4
LT
751/* --------------------------------------------------------------------------
752 FS Interface (/proc)
753 -------------------------------------------------------------------------- */
754
fdcedbba 755#ifdef CONFIG_ACPI_PROCFS_POWER
4be44fcd 756static struct proc_dir_entry *acpi_battery_dir;
b6ce4083 757
78490d82 758static int acpi_battery_print_info(struct seq_file *seq, int result)
1da177e4 759{
50dd0969 760 struct acpi_battery *battery = seq->private;
1da177e4 761
b6ce4083 762 if (result)
1da177e4
LT
763 goto end;
764
aa650bbd 765 seq_printf(seq, "present: %s\n",
0f4c6547 766 acpi_battery_present(battery) ? "yes" : "no");
aa650bbd 767 if (!acpi_battery_present(battery))
1da177e4 768 goto end;
038fdea2 769 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1da177e4
LT
770 seq_printf(seq, "design capacity: unknown\n");
771 else
772 seq_printf(seq, "design capacity: %d %sh\n",
aa650bbd
AS
773 battery->design_capacity,
774 acpi_battery_units(battery));
1da177e4 775
d7380965 776 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1da177e4
LT
777 seq_printf(seq, "last full capacity: unknown\n");
778 else
779 seq_printf(seq, "last full capacity: %d %sh\n",
d7380965 780 battery->full_charge_capacity,
aa650bbd
AS
781 acpi_battery_units(battery));
782
783 seq_printf(seq, "battery technology: %srechargeable\n",
784 (!battery->technology)?"non-":"");
1da177e4 785
038fdea2 786 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
1da177e4
LT
787 seq_printf(seq, "design voltage: unknown\n");
788 else
789 seq_printf(seq, "design voltage: %d mV\n",
aa650bbd 790 battery->design_voltage);
1da177e4 791 seq_printf(seq, "design capacity warning: %d %sh\n",
aa650bbd
AS
792 battery->design_capacity_warning,
793 acpi_battery_units(battery));
1da177e4 794 seq_printf(seq, "design capacity low: %d %sh\n",
aa650bbd
AS
795 battery->design_capacity_low,
796 acpi_battery_units(battery));
c67fcd67 797 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
1da177e4 798 seq_printf(seq, "capacity granularity 1: %d %sh\n",
aa650bbd
AS
799 battery->capacity_granularity_1,
800 acpi_battery_units(battery));
1da177e4 801 seq_printf(seq, "capacity granularity 2: %d %sh\n",
aa650bbd
AS
802 battery->capacity_granularity_2,
803 acpi_battery_units(battery));
038fdea2
AS
804 seq_printf(seq, "model number: %s\n", battery->model_number);
805 seq_printf(seq, "serial number: %s\n", battery->serial_number);
806 seq_printf(seq, "battery type: %s\n", battery->type);
807 seq_printf(seq, "OEM info: %s\n", battery->oem_info);
4be44fcd 808 end:
b6ce4083
VL
809 if (result)
810 seq_printf(seq, "ERROR: Unable to read battery info\n");
b6ce4083
VL
811 return result;
812}
813
78490d82 814static int acpi_battery_print_state(struct seq_file *seq, int result)
1da177e4 815{
50dd0969 816 struct acpi_battery *battery = seq->private;
1da177e4 817
b6ce4083 818 if (result)
1da177e4
LT
819 goto end;
820
aa650bbd 821 seq_printf(seq, "present: %s\n",
0f4c6547 822 acpi_battery_present(battery) ? "yes" : "no");
aa650bbd 823 if (!acpi_battery_present(battery))
1da177e4 824 goto end;
b6ce4083 825
aa650bbd 826 seq_printf(seq, "capacity state: %s\n",
0f4c6547 827 (battery->state & 0x04) ? "critical" : "ok");
aa650bbd 828 if ((battery->state & 0x01) && (battery->state & 0x02))
4be44fcd
LB
829 seq_printf(seq,
830 "charging state: charging/discharging\n");
aa650bbd 831 else if (battery->state & 0x01)
1da177e4 832 seq_printf(seq, "charging state: discharging\n");
038fdea2 833 else if (battery->state & 0x02)
1da177e4 834 seq_printf(seq, "charging state: charging\n");
aa650bbd 835 else
1da177e4 836 seq_printf(seq, "charging state: charged\n");
1da177e4 837
7faa144a 838 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
1da177e4
LT
839 seq_printf(seq, "present rate: unknown\n");
840 else
841 seq_printf(seq, "present rate: %d %s\n",
7faa144a 842 battery->rate_now, acpi_battery_units(battery));
1da177e4 843
d7380965 844 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
1da177e4
LT
845 seq_printf(seq, "remaining capacity: unknown\n");
846 else
847 seq_printf(seq, "remaining capacity: %d %sh\n",
d7380965
AS
848 battery->capacity_now, acpi_battery_units(battery));
849 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
1da177e4
LT
850 seq_printf(seq, "present voltage: unknown\n");
851 else
852 seq_printf(seq, "present voltage: %d mV\n",
d7380965 853 battery->voltage_now);
4be44fcd 854 end:
aa650bbd 855 if (result)
b6ce4083 856 seq_printf(seq, "ERROR: Unable to read battery state\n");
b6ce4083
VL
857
858 return result;
859}
860
78490d82 861static int acpi_battery_print_alarm(struct seq_file *seq, int result)
1da177e4 862{
50dd0969 863 struct acpi_battery *battery = seq->private;
1da177e4 864
b6ce4083 865 if (result)
1da177e4
LT
866 goto end;
867
b6ce4083 868 if (!acpi_battery_present(battery)) {
1da177e4
LT
869 seq_printf(seq, "present: no\n");
870 goto end;
871 }
1da177e4
LT
872 seq_printf(seq, "alarm: ");
873 if (!battery->alarm)
874 seq_printf(seq, "unsupported\n");
875 else
aa650bbd
AS
876 seq_printf(seq, "%u %sh\n", battery->alarm,
877 acpi_battery_units(battery));
4be44fcd 878 end:
b6ce4083
VL
879 if (result)
880 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
b6ce4083
VL
881 return result;
882}
883
f1d4661a
AS
884static ssize_t acpi_battery_write_alarm(struct file *file,
885 const char __user * buffer,
886 size_t count, loff_t * ppos)
1da177e4 887{
4be44fcd
LB
888 int result = 0;
889 char alarm_string[12] = { '\0' };
50dd0969
JE
890 struct seq_file *m = file->private_data;
891 struct acpi_battery *battery = m->private;
1da177e4 892
1da177e4 893 if (!battery || (count > sizeof(alarm_string) - 1))
d550d98d 894 return -EINVAL;
b6ce4083
VL
895 if (!acpi_battery_present(battery)) {
896 result = -ENODEV;
897 goto end;
898 }
b6ce4083
VL
899 if (copy_from_user(alarm_string, buffer, count)) {
900 result = -EFAULT;
901 goto end;
902 }
1da177e4 903 alarm_string[count] = '\0';
f1d4661a 904 battery->alarm = simple_strtol(alarm_string, NULL, 0);
aa650bbd 905 result = acpi_battery_set_alarm(battery);
b6ce4083 906 end:
b6ce4083 907 if (!result)
f1d4661a 908 return count;
78490d82
AS
909 return result;
910}
911
912typedef int(*print_func)(struct seq_file *seq, int result);
aa650bbd
AS
913
914static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
915 acpi_battery_print_info,
916 acpi_battery_print_state,
917 acpi_battery_print_alarm,
78490d82 918};
b6ce4083 919
78490d82
AS
920static int acpi_battery_read(int fid, struct seq_file *seq)
921{
922 struct acpi_battery *battery = seq->private;
f1d4661a 923 int result = acpi_battery_update(battery);
aa650bbd 924 return acpi_print_funcs[fid](seq, result);
78490d82
AS
925}
926
aa650bbd
AS
927#define DECLARE_FILE_FUNCTIONS(_name) \
928static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
929{ \
930 return acpi_battery_read(_name##_tag, seq); \
931} \
932static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
933{ \
d9dda78b 934 return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \
78490d82
AS
935}
936
aa650bbd
AS
937DECLARE_FILE_FUNCTIONS(info);
938DECLARE_FILE_FUNCTIONS(state);
939DECLARE_FILE_FUNCTIONS(alarm);
940
941#undef DECLARE_FILE_FUNCTIONS
942
943#define FILE_DESCRIPTION_RO(_name) \
944 { \
945 .name = __stringify(_name), \
946 .mode = S_IRUGO, \
947 .ops = { \
948 .open = acpi_battery_##_name##_open_fs, \
949 .read = seq_read, \
950 .llseek = seq_lseek, \
951 .release = single_release, \
952 .owner = THIS_MODULE, \
953 }, \
954 }
78490d82 955
aa650bbd
AS
956#define FILE_DESCRIPTION_RW(_name) \
957 { \
958 .name = __stringify(_name), \
959 .mode = S_IFREG | S_IRUGO | S_IWUSR, \
960 .ops = { \
961 .open = acpi_battery_##_name##_open_fs, \
962 .read = seq_read, \
963 .llseek = seq_lseek, \
964 .write = acpi_battery_write_##_name, \
965 .release = single_release, \
966 .owner = THIS_MODULE, \
967 }, \
968 }
1da177e4 969
9c8b04be 970static const struct battery_file {
78490d82 971 struct file_operations ops;
d161a13f 972 umode_t mode;
070d8eb1 973 const char *name;
78490d82 974} acpi_battery_file[] = {
aa650bbd
AS
975 FILE_DESCRIPTION_RO(info),
976 FILE_DESCRIPTION_RO(state),
977 FILE_DESCRIPTION_RW(alarm),
1da177e4
LT
978};
979
aa650bbd
AS
980#undef FILE_DESCRIPTION_RO
981#undef FILE_DESCRIPTION_RW
982
4be44fcd 983static int acpi_battery_add_fs(struct acpi_device *device)
1da177e4 984{
4be44fcd 985 struct proc_dir_entry *entry = NULL;
78490d82 986 int i;
1da177e4 987
6d855fcd
ZR
988 printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded,"
989 " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
1da177e4
LT
990 if (!acpi_device_dir(device)) {
991 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
4be44fcd 992 acpi_battery_dir);
1da177e4 993 if (!acpi_device_dir(device))
d550d98d 994 return -ENODEV;
1da177e4
LT
995 }
996
78490d82 997 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
cf7acfab
DL
998 entry = proc_create_data(acpi_battery_file[i].name,
999 acpi_battery_file[i].mode,
1000 acpi_device_dir(device),
1001 &acpi_battery_file[i].ops,
1002 acpi_driver_data(device));
78490d82
AS
1003 if (!entry)
1004 return -ENODEV;
1da177e4 1005 }
d550d98d 1006 return 0;
1da177e4
LT
1007}
1008
aa650bbd 1009static void acpi_battery_remove_fs(struct acpi_device *device)
1da177e4 1010{
78490d82 1011 int i;
aa650bbd
AS
1012 if (!acpi_device_dir(device))
1013 return;
1014 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
1015 remove_proc_entry(acpi_battery_file[i].name,
1da177e4 1016 acpi_device_dir(device));
1da177e4 1017
aa650bbd
AS
1018 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
1019 acpi_device_dir(device) = NULL;
1da177e4
LT
1020}
1021
d7380965 1022#endif
3e58ea0d 1023
1da177e4
LT
1024/* --------------------------------------------------------------------------
1025 Driver Interface
1026 -------------------------------------------------------------------------- */
1027
d9406691 1028static void acpi_battery_notify(struct acpi_device *device, u32 event)
1da177e4 1029{
d9406691 1030 struct acpi_battery *battery = acpi_driver_data(device);
153e500f 1031 struct device *old;
d9406691 1032
1da177e4 1033 if (!battery)
d550d98d 1034 return;
153e500f 1035 old = battery->bat.dev;
da8aeb92
RW
1036 if (event == ACPI_BATTERY_NOTIFY_INFO)
1037 acpi_battery_refresh(battery);
f1d4661a
AS
1038 acpi_battery_update(battery);
1039 acpi_bus_generate_proc_event(device, event,
1040 acpi_battery_present(battery));
1041 acpi_bus_generate_netlink_event(device->pnp.device_class,
0794469d 1042 dev_name(&device->dev), event,
9ea7d575 1043 acpi_battery_present(battery));
2345baf4 1044 /* acpi_battery_update could remove power_supply object */
153e500f 1045 if (old && battery->bat.dev)
f79e1cec 1046 power_supply_changed(&battery->bat);
1da177e4
LT
1047}
1048
25be5821
KM
1049static int battery_notify(struct notifier_block *nb,
1050 unsigned long mode, void *_unused)
1051{
1052 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
1053 pm_nb);
1054 switch (mode) {
d5a5911b 1055 case PM_POST_HIBERNATION:
25be5821 1056 case PM_POST_SUSPEND:
6e17fb6a
LT
1057 if (battery->bat.dev) {
1058 sysfs_remove_battery(battery);
1059 sysfs_add_battery(battery);
1060 }
25be5821
KM
1061 break;
1062 }
1063
1064 return 0;
1065}
1066
4be44fcd 1067static int acpi_battery_add(struct acpi_device *device)
1da177e4 1068{
4be44fcd 1069 int result = 0;
4be44fcd 1070 struct acpi_battery *battery = NULL;
c67fcd67 1071 acpi_handle handle;
1da177e4 1072 if (!device)
d550d98d 1073 return -EINVAL;
36bcbec7 1074 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
1da177e4 1075 if (!battery)
d550d98d 1076 return -ENOMEM;
145def84 1077 battery->device = device;
1da177e4
LT
1078 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
1079 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
db89b4f0 1080 device->driver_data = battery;
038fdea2 1081 mutex_init(&battery->lock);
69d94ec6 1082 mutex_init(&battery->sysfs_lock);
c67fcd67
AS
1083 if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
1084 "_BIX", &handle)))
1085 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
eb03cb02
SH
1086 result = acpi_battery_update(battery);
1087 if (result)
1088 goto fail;
fdcedbba 1089#ifdef CONFIG_ACPI_PROCFS_POWER
1da177e4 1090 result = acpi_battery_add_fs(device);
d7380965 1091#endif
e80bba4b 1092 if (result) {
fdcedbba 1093#ifdef CONFIG_ACPI_PROCFS_POWER
1da177e4 1094 acpi_battery_remove_fs(device);
d7380965 1095#endif
e80bba4b 1096 goto fail;
1da177e4 1097 }
25be5821 1098
e80bba4b
SH
1099 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
1100 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
1101 device->status.battery_present ? "present" : "absent");
1102
25be5821
KM
1103 battery->pm_nb.notifier_call = battery_notify;
1104 register_pm_notifier(&battery->pm_nb);
1105
d550d98d 1106 return result;
e80bba4b
SH
1107
1108fail:
1109 sysfs_remove_battery(battery);
1110 mutex_destroy(&battery->lock);
69d94ec6 1111 mutex_destroy(&battery->sysfs_lock);
e80bba4b
SH
1112 kfree(battery);
1113 return result;
1da177e4
LT
1114}
1115
51fac838 1116static int acpi_battery_remove(struct acpi_device *device)
1da177e4 1117{
4be44fcd 1118 struct acpi_battery *battery = NULL;
1da177e4 1119
1da177e4 1120 if (!device || !acpi_driver_data(device))
d550d98d 1121 return -EINVAL;
50dd0969 1122 battery = acpi_driver_data(device);
25be5821 1123 unregister_pm_notifier(&battery->pm_nb);
fdcedbba 1124#ifdef CONFIG_ACPI_PROCFS_POWER
1da177e4 1125 acpi_battery_remove_fs(device);
d7380965 1126#endif
508df92d 1127 sysfs_remove_battery(battery);
038fdea2 1128 mutex_destroy(&battery->lock);
69d94ec6 1129 mutex_destroy(&battery->sysfs_lock);
1da177e4 1130 kfree(battery);
d550d98d 1131 return 0;
1da177e4
LT
1132}
1133
90692404 1134#ifdef CONFIG_PM_SLEEP
34c4415a 1135/* this is needed to learn about changes made in suspended state */
a6f50dc8 1136static int acpi_battery_resume(struct device *dev)
34c4415a
JK
1137{
1138 struct acpi_battery *battery;
a6f50dc8
RW
1139
1140 if (!dev)
34c4415a 1141 return -EINVAL;
a6f50dc8
RW
1142
1143 battery = acpi_driver_data(to_acpi_device(dev));
1144 if (!battery)
1145 return -EINVAL;
1146
f1d4661a 1147 battery->update_time = 0;
508df92d 1148 acpi_battery_update(battery);
b6ce4083 1149 return 0;
34c4415a 1150}
90692404 1151#endif
34c4415a 1152
a6f50dc8
RW
1153static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
1154
aa650bbd
AS
1155static struct acpi_driver acpi_battery_driver = {
1156 .name = "battery",
1157 .class = ACPI_BATTERY_CLASS,
1158 .ids = battery_device_ids,
d9406691 1159 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
aa650bbd
AS
1160 .ops = {
1161 .add = acpi_battery_add,
aa650bbd 1162 .remove = acpi_battery_remove,
d9406691 1163 .notify = acpi_battery_notify,
aa650bbd 1164 },
a6f50dc8 1165 .drv.pm = &acpi_battery_pm,
aa650bbd
AS
1166};
1167
b0cbc861 1168static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
1da177e4 1169{
4d8316d5 1170 if (acpi_disabled)
0f66af53 1171 return;
fdcedbba 1172#ifdef CONFIG_ACPI_PROCFS_POWER
3f86b832 1173 acpi_battery_dir = acpi_lock_battery_dir();
1da177e4 1174 if (!acpi_battery_dir)
0f66af53 1175 return;
d7380965 1176#endif
aa650bbd 1177 if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
fdcedbba 1178#ifdef CONFIG_ACPI_PROCFS_POWER
3f86b832 1179 acpi_unlock_battery_dir(acpi_battery_dir);
d7380965 1180#endif
0f66af53 1181 return;
1da177e4 1182 }
0f66af53
AV
1183 return;
1184}
1185
1186static int __init acpi_battery_init(void)
1187{
1188 async_schedule(acpi_battery_init_async, NULL);
d550d98d 1189 return 0;
1da177e4
LT
1190}
1191
4be44fcd 1192static void __exit acpi_battery_exit(void)
1da177e4 1193{
1da177e4 1194 acpi_bus_unregister_driver(&acpi_battery_driver);
fdcedbba 1195#ifdef CONFIG_ACPI_PROCFS_POWER
3f86b832 1196 acpi_unlock_battery_dir(acpi_battery_dir);
d7380965 1197#endif
1da177e4
LT
1198}
1199
1da177e4
LT
1200module_init(acpi_battery_init);
1201module_exit(acpi_battery_exit);
This page took 0.712714 seconds and 5 git commands to generate.