battery.c 38.4 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
/*
2
 *  battery.c - ACPI Battery Driver (Revision: 2.0)
Linus Torvalds's avatar
Linus Torvalds committed
3
 *
4 5
 *  Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
 *  Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
Linus Torvalds's avatar
Linus Torvalds committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
32
#include <linux/jiffies.h>
33
#include <linux/async.h>
34
#include <linux/dmi.h>
35
#include <linux/delay.h>
36
#include <linux/slab.h>
37
#include <linux/suspend.h>
38
#include <asm/unaligned.h>
39

40 41 42 43 44 45
#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#endif

46
#include <linux/acpi.h>
47 48
#include <linux/power_supply.h>

49 50
#include "battery.h"

51 52
#define PREFIX "ACPI: "

Linus Torvalds's avatar
Linus Torvalds committed
53 54 55 56
#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF

#define ACPI_BATTERY_DEVICE_NAME	"Battery"

57 58 59
/* Battery power unit: 0 means mW, 1 means mA */
#define ACPI_BATTERY_POWER_UNIT_MA	1

60 61 62 63
#define ACPI_BATTERY_STATE_DISCHARGING	0x1
#define ACPI_BATTERY_STATE_CHARGING	0x2
#define ACPI_BATTERY_STATE_CRITICAL	0x4

Linus Torvalds's avatar
Linus Torvalds committed
64
#define _COMPONENT		ACPI_BATTERY_COMPONENT
65

66
ACPI_MODULE_NAME("battery");
Linus Torvalds's avatar
Linus Torvalds committed
67

68
MODULE_AUTHOR("Paul Diefenbaugh");
69
MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
70
MODULE_DESCRIPTION("ACPI Battery Driver");
Linus Torvalds's avatar
Linus Torvalds committed
71 72
MODULE_LICENSE("GPL");

73
static int battery_bix_broken_package;
74
static int battery_notification_delay_ms;
75 76 77
static unsigned int cache_time = 1000;
module_param(cache_time, uint, 0644);
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
78

79 80 81 82 83 84 85 86 87 88 89 90 91
#ifdef CONFIG_ACPI_PROCFS_POWER
extern struct proc_dir_entry *acpi_lock_battery_dir(void);
extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);

enum acpi_battery_files {
	info_tag = 0,
	state_tag,
	alarm_tag,
	ACPI_BATTERY_NUMFILES,
};

#endif

92 93 94 95 96
static const struct acpi_device_id battery_device_ids[] = {
	{"PNP0C0A", 0},
	{"", 0},
};

97
MODULE_DEVICE_TABLE(acpi, battery_device_ids);
Linus Torvalds's avatar
Linus Torvalds committed
98

99 100
enum {
	ACPI_BATTERY_ALARM_PRESENT,
101
	ACPI_BATTERY_XINFO_PRESENT,
102
	ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
103 104 105 106 107 108 109 110 111 112 113 114
	/* On Lenovo Thinkpad models from 2010 and 2011, the power unit
	   switches between mWh and mAh depending on whether the system
	   is running on battery or not.  When mAh is the unit, most
	   reported values are incorrect and need to be adjusted by
	   10000/design_voltage.  Verified on x201, t410, t410s, and x220.
	   Pre-2010 and 2012 models appear to always report in mWh and
	   are thus unaffected (tested with t42, t61, t500, x200, x300,
	   and x230).  Also, in mid-2012 Lenovo issued a BIOS update for
	   the 2011 models that fixes the issue (tested on x220 with a
	   post-1.29 BIOS), but as of Nov. 2012, no such update is
	   available for the 2010 models.  */
	ACPI_BATTERY_QUIRK_THINKPAD_MAH,
115
};
116

Linus Torvalds's avatar
Linus Torvalds committed
117
struct acpi_battery {
118
	struct mutex lock;
119
	struct mutex sysfs_lock;
120
	struct power_supply bat;
121
	struct acpi_device *device;
122
	struct notifier_block pm_nb;
123
	unsigned long update_time;
124
	int revision;
125
	int rate_now;
126 127
	int capacity_now;
	int voltage_now;
128
	int design_capacity;
129
	int full_charge_capacity;
130 131 132 133
	int technology;
	int design_voltage;
	int design_capacity_warning;
	int design_capacity_low;
134 135 136 137 138 139
	int cycle_count;
	int measurement_accuracy;
	int max_sampling_time;
	int min_sampling_time;
	int max_averaging_interval;
	int min_averaging_interval;
140 141
	int capacity_granularity_1;
	int capacity_granularity_2;
142
	int alarm;
143 144 145 146
	char model_number[32];
	char serial_number[32];
	char type[32];
	char oem_info[32];
147 148
	int state;
	int power_unit;
149
	unsigned long flags;
Linus Torvalds's avatar
Linus Torvalds committed
150 151
};

152
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat)
153

154
static inline int acpi_battery_present(struct acpi_battery *battery)
155
{
156 157
	return battery->device->status.battery_present;
}
158

159 160 161 162 163 164 165 166
static int acpi_battery_technology(struct acpi_battery *battery)
{
	if (!strcasecmp("NiCd", battery->type))
		return POWER_SUPPLY_TECHNOLOGY_NiCd;
	if (!strcasecmp("NiMH", battery->type))
		return POWER_SUPPLY_TECHNOLOGY_NiMH;
	if (!strcasecmp("LION", battery->type))
		return POWER_SUPPLY_TECHNOLOGY_LION;
167
	if (!strncasecmp("LI-ION", battery->type, 6))
168
		return POWER_SUPPLY_TECHNOLOGY_LION;
169 170 171 172 173
	if (!strcasecmp("LiP", battery->type))
		return POWER_SUPPLY_TECHNOLOGY_LIPO;
	return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
}

174
static int acpi_battery_get_state(struct acpi_battery *battery);
175

176 177
static int acpi_battery_is_charged(struct acpi_battery *battery)
{
178
	/* charging, discharging or critical low */
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
	if (battery->state != 0)
		return 0;

	/* battery not reporting charge */
	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
	    battery->capacity_now == 0)
		return 0;

	/* good batteries update full_charge as the batteries degrade */
	if (battery->full_charge_capacity == battery->capacity_now)
		return 1;

	/* fallback to using design values for broken batteries */
	if (battery->design_capacity == battery->capacity_now)
		return 1;

	/* we don't do any sort of metric based on percentages */
	return 0;
}

199 200 201 202
static int acpi_battery_get_property(struct power_supply *psy,
				     enum power_supply_property psp,
				     union power_supply_propval *val)
{
203
	int ret = 0;
204 205
	struct acpi_battery *battery = to_acpi_battery(psy);

206 207 208 209
	if (acpi_battery_present(battery)) {
		/* run battery update only if it is present */
		acpi_battery_get_state(battery);
	} else if (psp != POWER_SUPPLY_PROP_PRESENT)
210 211 212
		return -ENODEV;
	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
213
		if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
214
			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
215
		else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
216
			val->intval = POWER_SUPPLY_STATUS_CHARGING;
217
		else if (acpi_battery_is_charged(battery))
218
			val->intval = POWER_SUPPLY_STATUS_FULL;
219 220
		else
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
221 222 223 224 225 226 227
		break;
	case POWER_SUPPLY_PROP_PRESENT:
		val->intval = acpi_battery_present(battery);
		break;
	case POWER_SUPPLY_PROP_TECHNOLOGY:
		val->intval = acpi_battery_technology(battery);
		break;
228 229 230
	case POWER_SUPPLY_PROP_CYCLE_COUNT:
		val->intval = battery->cycle_count;
		break;
231
	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
232 233 234 235
		if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
			ret = -ENODEV;
		else
			val->intval = battery->design_voltage * 1000;
236 237
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
238 239 240 241
		if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
			ret = -ENODEV;
		else
			val->intval = battery->voltage_now * 1000;
242 243
		break;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
244
	case POWER_SUPPLY_PROP_POWER_NOW:
245 246 247 248
		if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
			ret = -ENODEV;
		else
			val->intval = battery->rate_now * 1000;
249 250 251
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
252 253 254 255
		if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
			ret = -ENODEV;
		else
			val->intval = battery->design_capacity * 1000;
256 257 258
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL:
	case POWER_SUPPLY_PROP_ENERGY_FULL:
259 260 261 262
		if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
			ret = -ENODEV;
		else
			val->intval = battery->full_charge_capacity * 1000;
263 264 265
		break;
	case POWER_SUPPLY_PROP_CHARGE_NOW:
	case POWER_SUPPLY_PROP_ENERGY_NOW:
266 267 268 269
		if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
			ret = -ENODEV;
		else
			val->intval = battery->capacity_now * 1000;
270
		break;
271 272 273 274 275 276 277
	case POWER_SUPPLY_PROP_CAPACITY:
		if (battery->capacity_now && battery->full_charge_capacity)
			val->intval = battery->capacity_now * 100/
					battery->full_charge_capacity;
		else
			val->intval = 0;
		break;
278 279 280 281 282 283 284 285 286 287 288
	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
		if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
		else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
			(battery->capacity_now <= battery->alarm))
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
		else if (acpi_battery_is_charged(battery))
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
		else
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
		break;
289 290 291 292 293 294
	case POWER_SUPPLY_PROP_MODEL_NAME:
		val->strval = battery->model_number;
		break;
	case POWER_SUPPLY_PROP_MANUFACTURER:
		val->strval = battery->oem_info;
		break;
295 296 297
	case POWER_SUPPLY_PROP_SERIAL_NUMBER:
		val->strval = battery->serial_number;
		break;
298
	default:
299
		ret = -EINVAL;
300
	}
301
	return ret;
302 303 304 305 306 307
}

static enum power_supply_property charge_battery_props[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_TECHNOLOGY,
308
	POWER_SUPPLY_PROP_CYCLE_COUNT,
309 310 311 312 313 314
	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
	POWER_SUPPLY_PROP_CURRENT_NOW,
	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
	POWER_SUPPLY_PROP_CHARGE_FULL,
	POWER_SUPPLY_PROP_CHARGE_NOW,
315
	POWER_SUPPLY_PROP_CAPACITY,
316
	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
317 318
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_MANUFACTURER,
319
	POWER_SUPPLY_PROP_SERIAL_NUMBER,
320 321 322 323 324 325
};

static enum power_supply_property energy_battery_props[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_TECHNOLOGY,
326
	POWER_SUPPLY_PROP_CYCLE_COUNT,
327 328
	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
329
	POWER_SUPPLY_PROP_POWER_NOW,
330 331 332
	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
	POWER_SUPPLY_PROP_ENERGY_FULL,
	POWER_SUPPLY_PROP_ENERGY_NOW,
333
	POWER_SUPPLY_PROP_CAPACITY,
334
	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
335 336
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_MANUFACTURER,
337
	POWER_SUPPLY_PROP_SERIAL_NUMBER,
338 339
};

340 341 342 343 344 345 346 347
#ifdef CONFIG_ACPI_PROCFS_POWER
inline char *acpi_battery_units(struct acpi_battery *battery)
{
	return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
		"mA" : "mW";
}
#endif

348 349 350
/* --------------------------------------------------------------------------
                               Battery Management
   -------------------------------------------------------------------------- */
351 352 353 354
struct acpi_offsets {
	size_t offset;		/* offset inside struct acpi_sbs_battery */
	u8 mode;		/* int or string? */
};
355

356 357
static struct acpi_offsets state_offsets[] = {
	{offsetof(struct acpi_battery, state), 0},
358
	{offsetof(struct acpi_battery, rate_now), 0},
359 360
	{offsetof(struct acpi_battery, capacity_now), 0},
	{offsetof(struct acpi_battery, voltage_now), 0},
361
};
362

363 364 365
static struct acpi_offsets info_offsets[] = {
	{offsetof(struct acpi_battery, power_unit), 0},
	{offsetof(struct acpi_battery, design_capacity), 0},
366
	{offsetof(struct acpi_battery, full_charge_capacity), 0},
367 368 369 370 371 372 373 374 375 376 377
	{offsetof(struct acpi_battery, technology), 0},
	{offsetof(struct acpi_battery, design_voltage), 0},
	{offsetof(struct acpi_battery, design_capacity_warning), 0},
	{offsetof(struct acpi_battery, design_capacity_low), 0},
	{offsetof(struct acpi_battery, capacity_granularity_1), 0},
	{offsetof(struct acpi_battery, capacity_granularity_2), 0},
	{offsetof(struct acpi_battery, model_number), 1},
	{offsetof(struct acpi_battery, serial_number), 1},
	{offsetof(struct acpi_battery, type), 1},
	{offsetof(struct acpi_battery, oem_info), 1},
};
378

379
static struct acpi_offsets extended_info_offsets[] = {
380
	{offsetof(struct acpi_battery, revision), 0},
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
	{offsetof(struct acpi_battery, power_unit), 0},
	{offsetof(struct acpi_battery, design_capacity), 0},
	{offsetof(struct acpi_battery, full_charge_capacity), 0},
	{offsetof(struct acpi_battery, technology), 0},
	{offsetof(struct acpi_battery, design_voltage), 0},
	{offsetof(struct acpi_battery, design_capacity_warning), 0},
	{offsetof(struct acpi_battery, design_capacity_low), 0},
	{offsetof(struct acpi_battery, cycle_count), 0},
	{offsetof(struct acpi_battery, measurement_accuracy), 0},
	{offsetof(struct acpi_battery, max_sampling_time), 0},
	{offsetof(struct acpi_battery, min_sampling_time), 0},
	{offsetof(struct acpi_battery, max_averaging_interval), 0},
	{offsetof(struct acpi_battery, min_averaging_interval), 0},
	{offsetof(struct acpi_battery, capacity_granularity_1), 0},
	{offsetof(struct acpi_battery, capacity_granularity_2), 0},
	{offsetof(struct acpi_battery, model_number), 1},
	{offsetof(struct acpi_battery, serial_number), 1},
	{offsetof(struct acpi_battery, type), 1},
	{offsetof(struct acpi_battery, oem_info), 1},
};

402 403 404 405
static int extract_package(struct acpi_battery *battery,
			   union acpi_object *package,
			   struct acpi_offsets *offsets, int num)
{
406
	int i;
407 408 409 410 411 412 413 414
	union acpi_object *element;
	if (package->type != ACPI_TYPE_PACKAGE)
		return -EFAULT;
	for (i = 0; i < num; ++i) {
		if (package->package.count <= i)
			return -EFAULT;
		element = &package->package.elements[i];
		if (offsets[i].mode) {
415 416 417 418 419 420
			u8 *ptr = (u8 *)battery + offsets[i].offset;
			if (element->type == ACPI_TYPE_STRING ||
			    element->type == ACPI_TYPE_BUFFER)
				strncpy(ptr, element->string.pointer, 32);
			else if (element->type == ACPI_TYPE_INTEGER) {
				strncpy(ptr, (u8 *)&element->integer.value,
Lin Ming's avatar
Lin Ming committed
421 422
					sizeof(u64));
				ptr[sizeof(u64)] = 0;
423 424
			} else
				*ptr = 0; /* don't have value */
425
		} else {
426 427 428
			int *x = (int *)((u8 *)battery + offsets[i].offset);
			*x = (element->type == ACPI_TYPE_INTEGER) ?
				element->integer.value : -1;
429
		}
430 431 432 433 434 435
	}
	return 0;
}

static int acpi_battery_get_status(struct acpi_battery *battery)
{
436
	if (acpi_bus_get_status(battery->device)) {
437 438 439
		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
		return -ENODEV;
	}
440
	return 0;
441 442 443
}

static int acpi_battery_get_info(struct acpi_battery *battery)
Linus Torvalds's avatar
Linus Torvalds committed
444
{
445
	int result = -EFAULT;
Len Brown's avatar
Len Brown committed
446
	acpi_status status = 0;
447
	char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ?
448 449
			"_BIX" : "_BIF";

Len Brown's avatar
Len Brown committed
450
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
Linus Torvalds's avatar
Linus Torvalds committed
451

452 453
	if (!acpi_battery_present(battery))
		return 0;
454
	mutex_lock(&battery->lock);
455 456
	status = acpi_evaluate_object(battery->device->handle, name,
						NULL, &buffer);
457
	mutex_unlock(&battery->lock);
458

Linus Torvalds's avatar
Linus Torvalds committed
459
	if (ACPI_FAILURE(status)) {
460
		ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
461
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
462
	}
463 464 465 466 467 468

	if (battery_bix_broken_package)
		result = extract_package(battery, buffer.pointer,
				extended_info_offsets + 1,
				ARRAY_SIZE(extended_info_offsets) - 1);
	else if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
469 470 471 472 473 474
		result = extract_package(battery, buffer.pointer,
				extended_info_offsets,
				ARRAY_SIZE(extended_info_offsets));
	else
		result = extract_package(battery, buffer.pointer,
				info_offsets, ARRAY_SIZE(info_offsets));
475
	kfree(buffer.pointer);
476 477
	if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
		battery->full_charge_capacity = battery->design_capacity;
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
	if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
	    battery->power_unit && battery->design_voltage) {
		battery->design_capacity = battery->design_capacity *
		    10000 / battery->design_voltage;
		battery->full_charge_capacity = battery->full_charge_capacity *
		    10000 / battery->design_voltage;
		battery->design_capacity_warning =
		    battery->design_capacity_warning *
		    10000 / battery->design_voltage;
		/* Curiously, design_capacity_low, unlike the rest of them,
		   is correct.  */
		/* capacity_granularity_* equal 1 on the systems tested, so
		   it's impossible to tell if they would need an adjustment
		   or not if their values were higher.  */
	}
493
	return result;
Linus Torvalds's avatar
Linus Torvalds committed
494 495
}

496
static int acpi_battery_get_state(struct acpi_battery *battery)
Linus Torvalds's avatar
Linus Torvalds committed
497
{
Len Brown's avatar
Len Brown committed
498 499 500
	int result = 0;
	acpi_status status = 0;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
Linus Torvalds's avatar
Linus Torvalds committed
501

502 503
	if (!acpi_battery_present(battery))
		return 0;
Linus Torvalds's avatar
Linus Torvalds committed
504

505 506 507 508 509
	if (battery->update_time &&
	    time_before(jiffies, battery->update_time +
			msecs_to_jiffies(cache_time)))
		return 0;

510
	mutex_lock(&battery->lock);
511
	status = acpi_evaluate_object(battery->device->handle, "_BST",
512 513
				      NULL, &buffer);
	mutex_unlock(&battery->lock);
514

Linus Torvalds's avatar
Linus Torvalds committed
515
	if (ACPI_FAILURE(status)) {
516
		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
517
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
518
	}
519

520 521
	result = extract_package(battery, buffer.pointer,
				 state_offsets, ARRAY_SIZE(state_offsets));
522
	battery->update_time = jiffies;
523
	kfree(buffer.pointer);
524

525 526 527 528 529 530 531
	/* For buggy DSDTs that report negative 16-bit values for either
	 * charging or discharging current and/or report 0 as 65536
	 * due to bad math.
	 */
	if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
		battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
		(s16)(battery->rate_now) < 0) {
532
		battery->rate_now = abs((s16)battery->rate_now);
533 534 535
		printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate"
			" invalid.\n");
	}
536

537 538 539 540 541 542
	/*
	 * When fully charged, some batteries wrongly report
	 * capacity_now = design_capacity instead of = full_charge_capacity
	 */
	if (battery->capacity_now > battery->full_charge_capacity
	    && battery->full_charge_capacity != ACPI_BATTERY_VALUE_UNKNOWN) {
543
		battery->capacity_now = battery->full_charge_capacity;
544 545 546 547 548 549 550
		if (battery->capacity_now != battery->design_capacity)
			printk_once(KERN_WARNING FW_BUG
				"battery: reported current charge level (%d) "
				"is higher than reported maximum charge level (%d).\n",
				battery->capacity_now, battery->full_charge_capacity);
	}

551 552 553 554
	if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
	    && battery->capacity_now >= 0 && battery->capacity_now <= 100)
		battery->capacity_now = (battery->capacity_now *
				battery->full_charge_capacity) / 100;
555 556 557 558 559
	if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
	    battery->power_unit && battery->design_voltage) {
		battery->capacity_now = battery->capacity_now *
		    10000 / battery->design_voltage;
	}
560 561
	return result;
}
Linus Torvalds's avatar
Linus Torvalds committed
562

563
static int acpi_battery_set_alarm(struct acpi_battery *battery)
Linus Torvalds's avatar
Linus Torvalds committed
564
{
Len Brown's avatar
Len Brown committed
565
	acpi_status status = 0;
Linus Torvalds's avatar
Linus Torvalds committed
566

567
	if (!acpi_battery_present(battery) ||
568
	    !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
569
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
570

571
	mutex_lock(&battery->lock);
572 573
	status = acpi_execute_simple_method(battery->device->handle, "_BTP",
					    battery->alarm);
574
	mutex_unlock(&battery->lock);
575

Linus Torvalds's avatar
Linus Torvalds committed
576
	if (ACPI_FAILURE(status))
577
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
578

579
	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
580
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
581 582
}

583
static int acpi_battery_init_alarm(struct acpi_battery *battery)
Linus Torvalds's avatar
Linus Torvalds committed
584
{
585
	/* See if alarms are supported, and if so, set default */
586
	if (!acpi_has_method(battery->device->handle, "_BTP")) {
587
		clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
588
		return 0;
589
	}
590
	set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
591 592
	if (!battery->alarm)
		battery->alarm = battery->design_capacity_warning;
593
	return acpi_battery_set_alarm(battery);
594
}
Linus Torvalds's avatar
Linus Torvalds committed
595

596 597 598 599 600 601 602 603 604 605 606 607 608 609
static ssize_t acpi_battery_alarm_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
	return sprintf(buf, "%d\n", battery->alarm * 1000);
}

static ssize_t acpi_battery_alarm_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t count)
{
	unsigned long x;
	struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
610
	if (sscanf(buf, "%lu\n", &x) == 1)
611 612 613 614 615 616 617
		battery->alarm = x/1000;
	if (acpi_battery_present(battery))
		acpi_battery_set_alarm(battery);
	return count;
}

static struct device_attribute alarm_attr = {
618
	.attr = {.name = "alarm", .mode = 0644},
619 620 621 622 623 624 625 626
	.show = acpi_battery_alarm_show,
	.store = acpi_battery_alarm_store,
};

static int sysfs_add_battery(struct acpi_battery *battery)
{
	int result;

627
	if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
628 629 630 631 632 633 634 635 636 637 638 639 640
		battery->bat.properties = charge_battery_props;
		battery->bat.num_properties =
			ARRAY_SIZE(charge_battery_props);
	} else {
		battery->bat.properties = energy_battery_props;
		battery->bat.num_properties =
			ARRAY_SIZE(energy_battery_props);
	}

	battery->bat.name = acpi_device_bid(battery->device);
	battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
	battery->bat.get_property = acpi_battery_get_property;

641 642
	result = power_supply_register_no_ws(&battery->device->dev, &battery->bat);

643 644 645 646 647 648 649
	if (result)
		return result;
	return device_create_file(battery->bat.dev, &alarm_attr);
}

static void sysfs_remove_battery(struct acpi_battery *battery)
{
650
	mutex_lock(&battery->sysfs_lock);
651
	if (!battery->bat.dev) {
652
		mutex_unlock(&battery->sysfs_lock);
653
		return;
654 655
	}

656 657
	device_remove_file(battery->bat.dev, &alarm_attr);
	power_supply_unregister(&battery->bat);
658
	battery->bat.dev = NULL;
659
	mutex_unlock(&battery->sysfs_lock);
660 661
}

662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
static void find_battery(const struct dmi_header *dm, void *private)
{
	struct acpi_battery *battery = (struct acpi_battery *)private;
	/* Note: the hardcoded offsets below have been extracted from
	   the source code of dmidecode.  */
	if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
		const u8 *dmi_data = (const u8 *)(dm + 1);
		int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
		if (dm->length >= 18)
			dmi_capacity *= dmi_data[17];
		if (battery->design_capacity * battery->design_voltage / 1000
		    != dmi_capacity &&
		    battery->design_capacity * 10 == dmi_capacity)
			set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
				&battery->flags);
	}
}

680 681 682 683 684 685 686 687 688 689 690 691
/*
 * According to the ACPI spec, some kinds of primary batteries can
 * report percentage battery remaining capacity directly to OS.
 * In this case, it reports the Last Full Charged Capacity == 100
 * and BatteryPresentRate == 0xFFFFFFFF.
 *
 * Now we found some battery reports percentage remaining capacity
 * even if it's rechargeable.
 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
 *
 * Handle this correctly so that they won't break userspace.
 */
692
static void acpi_battery_quirks(struct acpi_battery *battery)
693 694
{
	if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
695
		return;
696

697 698 699
	if (battery->full_charge_capacity == 100 &&
		battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
		battery->capacity_now >= 0 && battery->capacity_now <= 100) {
700 701 702 703 704
		set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
		battery->full_charge_capacity = battery->design_capacity;
		battery->capacity_now = (battery->capacity_now *
				battery->full_charge_capacity) / 100;
	}
705 706

	if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
707
		return;
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730

	if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
		const char *s;
		s = dmi_get_system_info(DMI_PRODUCT_VERSION);
		if (s && !strnicmp(s, "ThinkPad", 8)) {
			dmi_walk(find_battery, battery);
			if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
				     &battery->flags) &&
			    battery->design_voltage) {
				battery->design_capacity =
				    battery->design_capacity *
				    10000 / battery->design_voltage;
				battery->full_charge_capacity =
				    battery->full_charge_capacity *
				    10000 / battery->design_voltage;
				battery->design_capacity_warning =
				    battery->design_capacity_warning *
				    10000 / battery->design_voltage;
				battery->capacity_now = battery->capacity_now *
				    10000 / battery->design_voltage;
			}
		}
	}
731 732
}

733
static int acpi_battery_update(struct acpi_battery *battery, bool resume)
734
{
735
	int result, old_present = acpi_battery_present(battery);
736
	result = acpi_battery_get_status(battery);
737
	if (result)
738
		return result;
739 740
	if (!acpi_battery_present(battery)) {
		sysfs_remove_battery(battery);
741
		battery->update_time = 0;
742
		return 0;
743
	}
744 745 746 747

	if (resume)
		return 0;

748 749
	if (!battery->update_time ||
	    old_present != acpi_battery_present(battery)) {
750 751 752 753 754
		result = acpi_battery_get_info(battery);
		if (result)
			return result;
		acpi_battery_init_alarm(battery);
	}
755 756 757 758 759
	if (!battery->bat.dev) {
		result = sysfs_add_battery(battery);
		if (result)
			return result;
	}
760
	result = acpi_battery_get_state(battery);
761 762
	if (result)
		return result;
763
	acpi_battery_quirks(battery);
764 765 766 767 768 769 770 771 772 773

	/*
	 * Wakeup the system if battery is critical low
	 * or lower than the alarm level
	 */
	if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
	    (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
            (battery->capacity_now <= battery->alarm)))
		pm_wakeup_event(&battery->device->dev, 0);

774
	return result;
775 776
}

777 778
static void acpi_battery_refresh(struct acpi_battery *battery)
{
779 780
	int power_unit;

781 782 783
	if (!battery->bat.dev)
		return;

784 785
	power_unit = battery->power_unit;

786
	acpi_battery_get_info(battery);
787 788 789 790 791

	if (power_unit == battery->power_unit)
		return;

	/* The battery has changed its reporting units. */
792 793 794 795
	sysfs_remove_battery(battery);
	sysfs_add_battery(battery);
}

796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948
/* --------------------------------------------------------------------------
                              FS Interface (/proc)
   -------------------------------------------------------------------------- */

#ifdef CONFIG_ACPI_PROCFS_POWER
static struct proc_dir_entry *acpi_battery_dir;

static int acpi_battery_print_info(struct seq_file *seq, int result)
{
	struct acpi_battery *battery = seq->private;

	if (result)
		goto end;

	seq_printf(seq, "present:                 %s\n",
		   acpi_battery_present(battery) ? "yes" : "no");
	if (!acpi_battery_present(battery))
		goto end;
	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
		seq_printf(seq, "design capacity:         unknown\n");
	else
		seq_printf(seq, "design capacity:         %d %sh\n",
			   battery->design_capacity,
			   acpi_battery_units(battery));

	if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
		seq_printf(seq, "last full capacity:      unknown\n");
	else
		seq_printf(seq, "last full capacity:      %d %sh\n",
			   battery->full_charge_capacity,
			   acpi_battery_units(battery));

	seq_printf(seq, "battery technology:      %srechargeable\n",
		   (!battery->technology)?"non-":"");

	if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
		seq_printf(seq, "design voltage:          unknown\n");
	else
		seq_printf(seq, "design voltage:          %d mV\n",
			   battery->design_voltage);
	seq_printf(seq, "design capacity warning: %d %sh\n",
		   battery->design_capacity_warning,
		   acpi_battery_units(battery));
	seq_printf(seq, "design capacity low:     %d %sh\n",
		   battery->design_capacity_low,
		   acpi_battery_units(battery));
	seq_printf(seq, "cycle count:		  %i\n", battery->cycle_count);
	seq_printf(seq, "capacity granularity 1:  %d %sh\n",
		   battery->capacity_granularity_1,
		   acpi_battery_units(battery));
	seq_printf(seq, "capacity granularity 2:  %d %sh\n",
		   battery->capacity_granularity_2,
		   acpi_battery_units(battery));
	seq_printf(seq, "model number:            %s\n", battery->model_number);
	seq_printf(seq, "serial number:           %s\n", battery->serial_number);
	seq_printf(seq, "battery type:            %s\n", battery->type);
	seq_printf(seq, "OEM info:                %s\n", battery->oem_info);
      end:
	if (result)
		seq_printf(seq, "ERROR: Unable to read battery info\n");
	return result;
}

static int acpi_battery_print_state(struct seq_file *seq, int result)
{
	struct acpi_battery *battery = seq->private;

	if (result)
		goto end;

	seq_printf(seq, "present:                 %s\n",
		   acpi_battery_present(battery) ? "yes" : "no");
	if (!acpi_battery_present(battery))
		goto end;

	seq_printf(seq, "capacity state:          %s\n",
			(battery->state & 0x04) ? "critical" : "ok");
	if ((battery->state & 0x01) && (battery->state & 0x02))
		seq_printf(seq,
			   "charging state:          charging/discharging\n");
	else if (battery->state & 0x01)
		seq_printf(seq, "charging state:          discharging\n");
	else if (battery->state & 0x02)
		seq_printf(seq, "charging state:          charging\n");
	else
		seq_printf(seq, "charging state:          charged\n");

	if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
		seq_printf(seq, "present rate:            unknown\n");
	else
		seq_printf(seq, "present rate:            %d %s\n",
			   battery->rate_now, acpi_battery_units(battery));

	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
		seq_printf(seq, "remaining capacity:      unknown\n");
	else
		seq_printf(seq, "remaining capacity:      %d %sh\n",
			   battery->capacity_now, acpi_battery_units(battery));
	if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
		seq_printf(seq, "present voltage:         unknown\n");
	else
		seq_printf(seq, "present voltage:         %d mV\n",
			   battery->voltage_now);
      end:
	if (result)
		seq_printf(seq, "ERROR: Unable to read battery state\n");

	return result;
}

static int acpi_battery_print_alarm(struct seq_file *seq, int result)
{
	struct acpi_battery *battery = seq->private;

	if (result)
		goto end;

	if (!acpi_battery_present(battery)) {
		seq_printf(seq, "present:                 no\n");
		goto end;
	}
	seq_printf(seq, "alarm:                   ");
	if (!battery->alarm)
		seq_printf(seq, "unsupported\n");
	else
		seq_printf(seq, "%u %sh\n", battery->alarm,
				acpi_battery_units(battery));
      end:
	if (result)
		seq_printf(seq, "ERROR: Unable to read battery alarm\n");
	return result;
}

static ssize_t acpi_battery_write_alarm(struct file *file,
					const char __user * buffer,
					size_t count, loff_t * ppos)
{
	int result = 0;
	char alarm_string[12] = { '\0' };
	struct seq_file *m = file->private_data;
	struct acpi_battery *battery = m->private;

	if (!battery || (count > sizeof(alarm_string) - 1))
		return -EINVAL;
	if (!acpi_battery_present(battery)) {
		result = -ENODEV;
		goto end;
	}
	if (copy_from_user(alarm_string, buffer, count)) {
		result = -EFAULT;
		goto end;
	}
	alarm_string[count] = '\0';
949 950 951 952
	if (kstrtoint(alarm_string, 0, &battery->alarm)) {
		result = -EINVAL;
		goto end;
	}
953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970
	result = acpi_battery_set_alarm(battery);
      end:
	if (!result)
		return count;
	return result;
}

typedef int(*print_func)(struct seq_file *seq, int result);

static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
	acpi_battery_print_info,
	acpi_battery_print_state,
	acpi_battery_print_alarm,
};

static int acpi_battery_read(int fid, struct seq_file *seq)
{
	struct acpi_battery *battery = seq->private;
971
	int result = acpi_battery_update(battery, false);
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
	return acpi_print_funcs[fid](seq, result);
}

#define DECLARE_FILE_FUNCTIONS(_name) \
static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
{ \
	return acpi_battery_read(_name##_tag, seq); \
} \
static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
{ \
	return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \
}

DECLARE_FILE_FUNCTIONS(info);
DECLARE_FILE_FUNCTIONS(state);
DECLARE_FILE_FUNCTIONS(alarm);

#undef DECLARE_FILE_FUNCTIONS

#define FILE_DESCRIPTION_RO(_name) \
	{ \
	.name = __stringify(_name), \
	.mode = S_IRUGO, \
	.ops = { \
		.open = acpi_battery_##_name##_open_fs, \
		.read = seq_read, \
		.llseek = seq_lseek, \
		.release = single_release, \
		.owner = THIS_MODULE, \
		}, \
	}

#define FILE_DESCRIPTION_RW(_name) \
	{ \
	.name = __stringify(_name), \
	.mode = S_IFREG | S_IRUGO | S_IWUSR, \
	.ops = { \
		.open = acpi_battery_##_name##_open_fs, \
		.read = seq_read, \
		.llseek = seq_lseek, \
		.write = acpi_battery_write_##_name, \
		.release = single_release, \
		.owner = THIS_MODULE, \
		}, \
	}

static const struct battery_file {
	struct file_operations ops;
	umode_t mode;
	const char *name;
} acpi_battery_file[] = {
	FILE_DESCRIPTION_RO(info),
	FILE_DESCRIPTION_RO(state),
	FILE_DESCRIPTION_RW(alarm),
};

#undef FILE_DESCRIPTION_RO
#undef FILE_DESCRIPTION_RW

static int acpi_battery_add_fs(struct acpi_device *device)
{
	struct proc_dir_entry *entry = NULL;
	int i;

	printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded,"
			" please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
	if (!acpi_device_dir(device)) {
		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
						     acpi_battery_dir);
		if (!acpi_device_dir(device))
			return -ENODEV;
	}

	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
		entry = proc_create_data(acpi_battery_file[i].name,
					 acpi_battery_file[i].mode,
					 acpi_device_dir(device),
					 &acpi_battery_file[i].ops,
					 acpi_driver_data(device));
		if (!entry)
			return -ENODEV;
	}
	return 0;
}

static void acpi_battery_remove_fs(struct acpi_device *device)
{
	int i;
	if (!acpi_device_dir(device))
		return;
	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
		remove_proc_entry(acpi_battery_file[i].name,
				  acpi_device_dir(device));

	remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
	acpi_device_dir(device) = NULL;
}

#endif

Linus Torvalds's avatar
Linus Torvalds committed
1072 1073 1074 1075
/* --------------------------------------------------------------------------
                                 Driver Interface
   -------------------------------------------------------------------------- */

1076
static void acpi_battery_notify(struct acpi_device *device, u32 event)
Linus Torvalds's avatar
Linus Torvalds committed
1077
{
1078
	struct acpi_battery *battery = acpi_driver_data(device);
1079
	struct device *old;
1080

Linus Torvalds's avatar
Linus Torvalds committed
1081
	if (!battery)
1082
		return;
1083
	old = battery->bat.dev;
1084 1085 1086 1087 1088 1089 1090 1091
	/*
	* On Acer Aspire V5-573G notifications are sometimes triggered too
	* early. For example, when AC is unplugged and notification is
	* triggered, battery state is still reported as "Full", and changes to
	* "Discharging" only after short delay, without any notification.
	*/
	if (battery_notification_delay_ms > 0)
		msleep(battery_notification_delay_ms);
1092 1093
	if (event == ACPI_BATTERY_NOTIFY_INFO)
		acpi_battery_refresh(battery);
1094
	acpi_battery_update(battery, false);
1095
	acpi_bus_generate_netlink_event(device->pnp.device_class,
1096
					dev_name(&device->dev), event,
Vladimir Lebedev's avatar
Vladimir Lebedev committed
1097
					acpi_battery_present(battery));
1098
	acpi_notifier_call_chain(device, event, acpi_battery_present(battery));
1099
	/* acpi_battery_update could remove power_supply object */
1100
	if (old && battery->bat.dev)
1101
		power_supply_changed(&battery->bat);
Linus Torvalds's avatar
Linus Torvalds committed
1102 1103
}

1104 1105 1106 1107 1108
static int battery_notify(struct notifier_block *nb,
			       unsigned long mode, void *_unused)
{
	struct acpi_battery *battery = container_of(nb, struct acpi_battery,
						    pm_nb);
1109 1110
	int result;

1111
	switch (mode) {
1112
	case PM_POST_HIBERNATION:
1113
	case PM_POST_SUSPEND:
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
		if (!acpi_battery_present(battery))
			return 0;

		if (!battery->bat.dev) {
			result = acpi_battery_get_info(battery);
			if (result)
				return result;

			result = sysfs_add_battery(battery);
			if (result)
				return result;
		} else
			acpi_battery_refresh(battery);

		acpi_battery_init_alarm(battery);
		acpi_battery_get_state(battery);
1130 1131 1132 1133 1134 1135
		break;
	}

	return 0;
}

1136 1137 1138 1139 1140 1141
static int battery_bix_broken_package_quirk(const struct dmi_system_id *d)
{
	battery_bix_broken_package = 1;
	return 0;
}

1142 1143 1144 1145 1146 1147
static int battery_notification_delay_quirk(const struct dmi_system_id *d)
{
	battery_notification_delay_ms = 1000;
	return 0;
}

1148 1149
static struct dmi_system_id bat_dmi_table[] = {
	{
1150
		.callback = battery_bix_broken_package_quirk,
1151 1152 1153 1154 1155 1156
		.ident = "NEC LZ750/LS",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
			DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
		},
	},
1157 1158 1159 1160 1161 1162 1163 1164
	{
		.callback = battery_notification_delay_quirk,
		.ident = "Acer Aspire V5-573G",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
		},
	},
1165 1166 1167
	{},
};

1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
/*
 * Some machines'(E,G Lenovo Z480) ECs are not stable
 * during boot up and this causes battery driver fails to be
 * probed due to failure of getting battery information
 * from EC sometimes. After several retries, the operation
 * may work. So add retry code here and 20ms sleep between
 * every retries.
 */
static int acpi_battery_update_retry(struct acpi_battery *battery)
{
	int retry, ret;

	for (retry = 5; retry; retry--) {
		ret = acpi_battery_update(battery, false);
		if (!ret)
			break;

		msleep(20);
	}
	return ret;
}

Len Brown's avatar
Len Brown committed
1190
static int acpi_battery_add(struct acpi_device *device)
Linus Torvalds's avatar
Linus Torvalds committed
1191
{
Len Brown's avatar
Len Brown committed
1192 1193
	int result = 0;
	struct acpi_battery *battery = NULL;
1194

Linus Torvalds's avatar
Linus Torvalds committed
1195
	if (!device)
1196
		return -EINVAL;
1197
	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
1198
	if (!battery)
1199
		return -ENOMEM;
1200
	battery->device = device;
Linus Torvalds's avatar
Linus Torvalds committed
1201 1202
	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
1203
	device->driver_data = battery;
1204
	mutex_init(&battery->lock);
1205
	mutex_init(&battery->sysfs_lock);
1206
	if (acpi_has_method(battery->device->handle, "_BIX"))
1207
		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
1208 1209

	result = acpi_battery_update_retry(battery);
1210 1211
	if (result)
		goto fail;
1212

1213 1214 1215 1216 1217 1218 1219 1220 1221
#ifdef CONFIG_ACPI_PROCFS_POWER
	result = acpi_battery_add_fs(device);
#endif
	if (result) {
#ifdef CONFIG_ACPI_PROCFS_POWER
		acpi_battery_remove_fs(device);
#endif
		goto fail;
	}
1222

1223 1224 1225 1226
	printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
		ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
		device->status.battery_present ? "present" : "absent");

1227 1228 1229
	battery->pm_nb.notifier_call = battery_notify;
	register_pm_notifier(&battery->pm_nb);

1230 1231
	device_init_wakeup(&device->dev, 1);

1232
	return result;
1233 1234 1235 1236

fail:
	sysfs_remove_battery(battery);
	mutex_destroy(&battery->lock);
1237
	mutex_destroy(&battery->sysfs_lock);
1238 1239
	kfree(battery);
	return result;
Linus Torvalds's avatar
Linus Torvalds committed
1240 1241
}

1242
static int acpi_battery_remove(struct acpi_device *device)
Linus Torvalds's avatar
Linus Torvalds committed
1243
{
Len Brown's avatar
Len Brown committed
1244
	struct acpi_battery *battery = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
1245 1246

	if (!device || !acpi_driver_data(device))
1247
		return -EINVAL;
1248
	device_init_wakeup(&device->dev, 0);
1249
	battery = acpi_driver_data(device);
1250
	unregister_pm_notifier(&battery->pm_nb);
1251 1252 1253
#ifdef CONFIG_ACPI_PROCFS_POWER
	acpi_battery_remove_fs(device);
#endif
1254
	sysfs_remove_battery(battery);
1255
	mutex_destroy(&battery->lock);
1256
	mutex_destroy(&battery->sysfs_lock);
Linus Torvalds's avatar
Linus Torvalds committed
1257
	kfree(battery);
1258
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
1259 1260
}

1261
#ifdef CONFIG_PM_SLEEP
1262
/* this is needed to learn about changes made in suspended state */
1263
static int acpi_battery_resume(struct device *dev)
1264 1265
{
	struct acpi_battery *battery;
1266 1267

	if (!dev)
1268
		return -EINVAL;
1269 1270 1271 1272 1273

	battery = acpi_driver_data(to_acpi_device(dev));
	if (!battery)
		return -EINVAL;

1274
	battery->update_time = 0;
1275
	acpi_battery_update(battery, true);
1276
	return 0;
1277
}
1278 1279
#else
#define acpi_battery_resume NULL
1280
#endif
1281

1282 1283
static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);

1284 1285 1286 1287
static struct acpi_driver acpi_battery_driver = {
	.name = "battery",
	.class = ACPI_BATTERY_CLASS,
	.ids = battery_device_ids,
1288
	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1289 1290 1291
	.ops = {
		.add = acpi_battery_add,
		.remove = acpi_battery_remove,
1292
		.notify = acpi_battery_notify,
1293
		},
1294
	.drv.pm = &acpi_battery_pm,
1295 1296
};

1297
static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
Linus Torvalds's avatar
Linus Torvalds committed
1298
{
Pavel Machek's avatar
Pavel Machek committed
1299
	if (acpi_disabled)
1300
		return;
1301

1302
	dmi_check_system(bat_dmi_table);
1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315
	
#ifdef CONFIG_ACPI_PROCFS_POWER
	acpi_battery_dir = acpi_lock_battery_dir();
	if (!acpi_battery_dir)
		return;
#endif
	if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
#ifdef CONFIG_ACPI_PROCFS_POWER
		acpi_unlock_battery_dir(acpi_battery_dir);
#endif
		return;
	}
	return;
1316 1317 1318 1319 1320
}

static int __init acpi_battery_init(void)
{
	async_schedule(acpi_battery_init_async, NULL);
1321
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
1322 1323
}

Len Brown's avatar
Len Brown committed
1324
static void __exit acpi_battery_exit(void)
Linus Torvalds's avatar
Linus Torvalds committed
1325 1326
{
	acpi_bus_unregister_driver(&acpi_battery_driver);
1327 1328 1329
#ifdef CONFIG_ACPI_PROCFS_POWER
	acpi_unlock_battery_dir(acpi_battery_dir);
#endif
Linus Torvalds's avatar
Linus Torvalds committed
1330 1331 1332 1333
}

module_init(acpi_battery_init);
module_exit(acpi_battery_exit);