blob: c63b6a14ad95ce70e26d0e8f7a1d67747e80a155 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04002 * battery.c - ACPI Battery Driver (Revision: 2.0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04004 * Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
5 * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 * 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 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22 */
23
Ognjen Galicfa938542018-02-07 15:58:13 +010024#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <linux/kernel.h>
Ognjen Galicfa938542018-02-07 15:58:13 +010027#include <linux/list.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/module.h>
Ognjen Galicfa938542018-02-07 15:58:13 +010029#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <linux/init.h>
31#include <linux/types.h>
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +040032#include <linux/jiffies.h>
Arjan van de Ven0f66af52009-01-10 14:19:05 -050033#include <linux/async.h>
Hector Martinbc76f902009-08-06 15:57:48 -070034#include <linux/dmi.h>
Alexander Mezinf43691c2014-06-04 02:01:23 +070035#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090036#include <linux/slab.h>
Kyle McMartin25be5822011-03-22 16:19:50 -040037#include <linux/suspend.h>
Kamil Iskra4000e622012-11-16 22:28:58 +010038#include <asm/unaligned.h>
Alexey Starikovskiyd7380962007-09-26 19:43:04 +040039
Lan Tianyu3a670cc2014-05-04 11:07:25 +080040#ifdef CONFIG_ACPI_PROCFS_POWER
41#include <linux/proc_fs.h>
42#include <linux/seq_file.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080043#include <linux/uaccess.h>
Lan Tianyu3a670cc2014-05-04 11:07:25 +080044#endif
45
Lv Zheng8b484632013-12-03 08:49:16 +080046#include <linux/acpi.h>
Alexey Starikovskiyd7380962007-09-26 19:43:04 +040047#include <linux/power_supply.h>
48
Ognjen Galicfa938542018-02-07 15:58:13 +010049#include <acpi/battery.h>
Alexander Mezinf03be352014-03-12 00:58:46 +070050
Len Browna192a952009-07-28 16:45:54 -040051#define PREFIX "ACPI: "
52
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
54
Linus Torvalds1da177e2005-04-16 15:20:36 -070055#define ACPI_BATTERY_DEVICE_NAME "Battery"
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Lan Tianyuae6f6182011-06-30 11:32:40 +080057/* Battery power unit: 0 means mW, 1 means mA */
58#define ACPI_BATTERY_POWER_UNIT_MA 1
59
Zhang Rui1ac5aaa2014-05-28 15:23:36 +080060#define ACPI_BATTERY_STATE_DISCHARGING 0x1
61#define ACPI_BATTERY_STATE_CHARGING 0x2
62#define ACPI_BATTERY_STATE_CRITICAL 0x4
63
Linus Torvalds1da177e2005-04-16 15:20:36 -070064#define _COMPONENT ACPI_BATTERY_COMPONENT
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +030065
Len Brownf52fd662007-02-12 22:42:12 -050066ACPI_MODULE_NAME("battery");
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
Len Brownf52fd662007-02-12 22:42:12 -050068MODULE_AUTHOR("Paul Diefenbaugh");
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +040069MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
Len Brown7cda93e2007-02-12 23:50:02 -050070MODULE_DESCRIPTION("ACPI Battery Driver");
Linus Torvalds1da177e2005-04-16 15:20:36 -070071MODULE_LICENSE("GPL");
72
Luis Henriqueseca21d912015-05-11 22:49:05 +010073static async_cookie_t async_cookie;
Hans de Goedebc39fbc2017-04-19 14:02:09 +020074static bool battery_driver_registered;
Lan Tianyua90b4032014-01-06 22:50:37 +080075static int battery_bix_broken_package;
Alexander Mezinf43691c2014-06-04 02:01:23 +070076static int battery_notification_delay_ms;
Hans de Goede1b799c52018-04-12 12:02:00 +020077static int battery_ac_is_broken;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +040078static unsigned int cache_time = 1000;
79module_param(cache_time, uint, 0644);
80MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +030081
Lan Tianyu3a670cc2014-05-04 11:07:25 +080082#ifdef CONFIG_ACPI_PROCFS_POWER
83extern struct proc_dir_entry *acpi_lock_battery_dir(void);
84extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
85
86enum acpi_battery_files {
87 info_tag = 0,
88 state_tag,
89 alarm_tag,
90 ACPI_BATTERY_NUMFILES,
91};
92
93#endif
94
Alexey Starikovskiyd7380962007-09-26 19:43:04 +040095static const struct acpi_device_id battery_device_ids[] = {
96 {"PNP0C0A", 0},
97 {"", 0},
98};
99
100MODULE_DEVICE_TABLE(acpi, battery_device_ids);
101
Hans de Goededccfae62017-04-19 14:02:10 +0200102/* Lists of PMIC ACPI HIDs with an (often better) native battery driver */
103static const char * const acpi_battery_blacklist[] = {
104 "INT33F4", /* X-Powers AXP288 PMIC */
105};
106
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400107enum {
108 ACPI_BATTERY_ALARM_PRESENT,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400109 ACPI_BATTERY_XINFO_PRESENT,
Zhang Rui557d5862010-10-22 10:02:06 +0800110 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
Kamil Iskra4000e622012-11-16 22:28:58 +0100111 /* On Lenovo Thinkpad models from 2010 and 2011, the power unit
112 switches between mWh and mAh depending on whether the system
113 is running on battery or not. When mAh is the unit, most
114 reported values are incorrect and need to be adjusted by
115 10000/design_voltage. Verified on x201, t410, t410s, and x220.
116 Pre-2010 and 2012 models appear to always report in mWh and
117 are thus unaffected (tested with t42, t61, t500, x200, x300,
118 and x230). Also, in mid-2012 Lenovo issued a BIOS update for
119 the 2011 models that fixes the issue (tested on x220 with a
120 post-1.29 BIOS), but as of Nov. 2012, no such update is
121 available for the 2010 models. */
122 ACPI_BATTERY_QUIRK_THINKPAD_MAH,
Laszlo Totha20136a2018-02-24 10:20:15 +0100123 /* for batteries reporting current capacity with design capacity
124 * on a full charge, but showing degradation in full charge cap.
125 */
126 ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE,
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400127};
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400128
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400129struct acpi_battery {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400130 struct mutex lock;
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300131 struct mutex sysfs_lock;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100132 struct power_supply *bat;
133 struct power_supply_desc bat_desc;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400134 struct acpi_device *device;
Kyle McMartin25be5822011-03-22 16:19:50 -0400135 struct notifier_block pm_nb;
Ognjen Galicfa938542018-02-07 15:58:13 +0100136 struct list_head list;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400137 unsigned long update_time;
Lan Tianyu016d5ba2013-07-30 14:00:42 +0200138 int revision;
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400139 int rate_now;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400140 int capacity_now;
141 int voltage_now;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400142 int design_capacity;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400143 int full_charge_capacity;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400144 int technology;
145 int design_voltage;
146 int design_capacity_warning;
147 int design_capacity_low;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400148 int cycle_count;
149 int measurement_accuracy;
150 int max_sampling_time;
151 int min_sampling_time;
152 int max_averaging_interval;
153 int min_averaging_interval;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400154 int capacity_granularity_1;
155 int capacity_granularity_2;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400156 int alarm;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400157 char model_number[32];
158 char serial_number[32];
159 char type[32];
160 char oem_info[32];
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400161 int state;
162 int power_unit;
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400163 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164};
165
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100166#define to_acpi_battery(x) power_supply_get_drvdata(x)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400167
Andy Shevchenkoefd941f2013-03-11 09:17:06 +0000168static inline int acpi_battery_present(struct acpi_battery *battery)
Alexey Starikovskiy78490d82007-05-11 13:18:55 -0400169{
170 return battery->device->status.battery_present;
171}
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400172
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400173static int acpi_battery_technology(struct acpi_battery *battery)
174{
175 if (!strcasecmp("NiCd", battery->type))
176 return POWER_SUPPLY_TECHNOLOGY_NiCd;
177 if (!strcasecmp("NiMH", battery->type))
178 return POWER_SUPPLY_TECHNOLOGY_NiMH;
179 if (!strcasecmp("LION", battery->type))
180 return POWER_SUPPLY_TECHNOLOGY_LION;
Andrey Borzenkovad40e682007-11-10 20:02:49 +0300181 if (!strncasecmp("LI-ION", battery->type, 6))
Alexey Starikovskiy0bde7ee2007-10-28 15:33:10 +0300182 return POWER_SUPPLY_TECHNOLOGY_LION;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400183 if (!strcasecmp("LiP", battery->type))
184 return POWER_SUPPLY_TECHNOLOGY_LIPO;
185 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
186}
187
Alexey Starikovskiy91044762007-11-13 12:23:06 +0300188static int acpi_battery_get_state(struct acpi_battery *battery);
Alexey Starikovskiyb19073a2007-10-25 17:10:47 -0400189
Richard Hughes56f382a2009-01-25 15:05:50 +0000190static int acpi_battery_is_charged(struct acpi_battery *battery)
191{
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800192 /* charging, discharging or critical low */
Richard Hughes56f382a2009-01-25 15:05:50 +0000193 if (battery->state != 0)
194 return 0;
195
196 /* battery not reporting charge */
197 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
198 battery->capacity_now == 0)
199 return 0;
200
201 /* good batteries update full_charge as the batteries degrade */
202 if (battery->full_charge_capacity == battery->capacity_now)
203 return 1;
204
205 /* fallback to using design values for broken batteries */
206 if (battery->design_capacity == battery->capacity_now)
207 return 1;
208
209 /* we don't do any sort of metric based on percentages */
210 return 0;
211}
212
Laszlo Totha20136a2018-02-24 10:20:15 +0100213static bool acpi_battery_is_degraded(struct acpi_battery *battery)
214{
215 return battery->full_charge_capacity && battery->design_capacity &&
216 battery->full_charge_capacity < battery->design_capacity;
217}
218
Hans de Goede19fffc82018-04-12 12:01:59 +0200219static int acpi_battery_handle_discharging(struct acpi_battery *battery)
220{
221 /*
222 * Some devices wrongly report discharging if the battery's charge level
223 * was above the device's start charging threshold atm the AC adapter
224 * was plugged in and the device thus did not start a new charge cycle.
225 */
Hans de Goede1b799c52018-04-12 12:02:00 +0200226 if ((battery_ac_is_broken || power_supply_is_system_supplied()) &&
227 battery->rate_now == 0)
Hans de Goede19fffc82018-04-12 12:01:59 +0200228 return POWER_SUPPLY_STATUS_NOT_CHARGING;
229
230 return POWER_SUPPLY_STATUS_DISCHARGING;
231}
232
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400233static int acpi_battery_get_property(struct power_supply *psy,
234 enum power_supply_property psp,
235 union power_supply_propval *val)
236{
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200237 int ret = 0;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400238 struct acpi_battery *battery = to_acpi_battery(psy);
239
Alexey Starikovskiy91044762007-11-13 12:23:06 +0300240 if (acpi_battery_present(battery)) {
241 /* run battery update only if it is present */
242 acpi_battery_get_state(battery);
243 } else if (psp != POWER_SUPPLY_PROP_PRESENT)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400244 return -ENODEV;
245 switch (psp) {
246 case POWER_SUPPLY_PROP_STATUS:
Daniel Drake82bf43b2018-03-14 16:42:17 +0800247 if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
Hans de Goede19fffc82018-04-12 12:01:59 +0200248 val->intval = acpi_battery_handle_discharging(battery);
Daniel Drake82bf43b2018-03-14 16:42:17 +0800249 else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400250 val->intval = POWER_SUPPLY_STATUS_CHARGING;
Richard Hughes56f382a2009-01-25 15:05:50 +0000251 else if (acpi_battery_is_charged(battery))
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400252 val->intval = POWER_SUPPLY_STATUS_FULL;
Roland Dreier4c41d3a2007-11-07 15:09:09 -0800253 else
254 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400255 break;
256 case POWER_SUPPLY_PROP_PRESENT:
257 val->intval = acpi_battery_present(battery);
258 break;
259 case POWER_SUPPLY_PROP_TECHNOLOGY:
260 val->intval = acpi_battery_technology(battery);
261 break;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400262 case POWER_SUPPLY_PROP_CYCLE_COUNT:
263 val->intval = battery->cycle_count;
264 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400265 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200266 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
267 ret = -ENODEV;
268 else
269 val->intval = battery->design_voltage * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400270 break;
271 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200272 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
273 ret = -ENODEV;
274 else
275 val->intval = battery->voltage_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400276 break;
277 case POWER_SUPPLY_PROP_CURRENT_NOW:
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400278 case POWER_SUPPLY_PROP_POWER_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200279 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
280 ret = -ENODEV;
281 else
282 val->intval = battery->rate_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400283 break;
284 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
285 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200286 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
287 ret = -ENODEV;
288 else
289 val->intval = battery->design_capacity * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400290 break;
291 case POWER_SUPPLY_PROP_CHARGE_FULL:
292 case POWER_SUPPLY_PROP_ENERGY_FULL:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200293 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
294 ret = -ENODEV;
295 else
296 val->intval = battery->full_charge_capacity * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400297 break;
298 case POWER_SUPPLY_PROP_CHARGE_NOW:
299 case POWER_SUPPLY_PROP_ENERGY_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200300 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
301 ret = -ENODEV;
302 else
303 val->intval = battery->capacity_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400304 break;
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700305 case POWER_SUPPLY_PROP_CAPACITY:
306 if (battery->capacity_now && battery->full_charge_capacity)
307 val->intval = battery->capacity_now * 100/
308 battery->full_charge_capacity;
309 else
310 val->intval = 0;
311 break;
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800312 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
313 if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
314 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
315 else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
316 (battery->capacity_now <= battery->alarm))
317 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
318 else if (acpi_battery_is_charged(battery))
319 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
320 else
321 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
322 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400323 case POWER_SUPPLY_PROP_MODEL_NAME:
324 val->strval = battery->model_number;
325 break;
326 case POWER_SUPPLY_PROP_MANUFACTURER:
327 val->strval = battery->oem_info;
328 break;
maximilian attems7c2670b2008-01-22 18:46:50 +0100329 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
330 val->strval = battery->serial_number;
331 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400332 default:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200333 ret = -EINVAL;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400334 }
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200335 return ret;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400336}
337
338static enum power_supply_property charge_battery_props[] = {
339 POWER_SUPPLY_PROP_STATUS,
340 POWER_SUPPLY_PROP_PRESENT,
341 POWER_SUPPLY_PROP_TECHNOLOGY,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400342 POWER_SUPPLY_PROP_CYCLE_COUNT,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400343 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
344 POWER_SUPPLY_PROP_VOLTAGE_NOW,
345 POWER_SUPPLY_PROP_CURRENT_NOW,
346 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
347 POWER_SUPPLY_PROP_CHARGE_FULL,
348 POWER_SUPPLY_PROP_CHARGE_NOW,
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700349 POWER_SUPPLY_PROP_CAPACITY,
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800350 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400351 POWER_SUPPLY_PROP_MODEL_NAME,
352 POWER_SUPPLY_PROP_MANUFACTURER,
maximilian attems7c2670b2008-01-22 18:46:50 +0100353 POWER_SUPPLY_PROP_SERIAL_NUMBER,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400354};
355
356static enum power_supply_property energy_battery_props[] = {
357 POWER_SUPPLY_PROP_STATUS,
358 POWER_SUPPLY_PROP_PRESENT,
359 POWER_SUPPLY_PROP_TECHNOLOGY,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400360 POWER_SUPPLY_PROP_CYCLE_COUNT,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400361 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
362 POWER_SUPPLY_PROP_VOLTAGE_NOW,
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400363 POWER_SUPPLY_PROP_POWER_NOW,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400364 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
365 POWER_SUPPLY_PROP_ENERGY_FULL,
366 POWER_SUPPLY_PROP_ENERGY_NOW,
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700367 POWER_SUPPLY_PROP_CAPACITY,
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800368 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400369 POWER_SUPPLY_PROP_MODEL_NAME,
370 POWER_SUPPLY_PROP_MANUFACTURER,
maximilian attems7c2670b2008-01-22 18:46:50 +0100371 POWER_SUPPLY_PROP_SERIAL_NUMBER,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400372};
373
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374/* --------------------------------------------------------------------------
375 Battery Management
376 -------------------------------------------------------------------------- */
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400377struct acpi_offsets {
378 size_t offset; /* offset inside struct acpi_sbs_battery */
379 u8 mode; /* int or string? */
380};
381
Mathias Krausea4658782015-06-13 14:26:53 +0200382static const struct acpi_offsets state_offsets[] = {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400383 {offsetof(struct acpi_battery, state), 0},
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400384 {offsetof(struct acpi_battery, rate_now), 0},
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400385 {offsetof(struct acpi_battery, capacity_now), 0},
386 {offsetof(struct acpi_battery, voltage_now), 0},
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400387};
388
Mathias Krausea4658782015-06-13 14:26:53 +0200389static const struct acpi_offsets info_offsets[] = {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400390 {offsetof(struct acpi_battery, power_unit), 0},
391 {offsetof(struct acpi_battery, design_capacity), 0},
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400392 {offsetof(struct acpi_battery, full_charge_capacity), 0},
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400393 {offsetof(struct acpi_battery, technology), 0},
394 {offsetof(struct acpi_battery, design_voltage), 0},
395 {offsetof(struct acpi_battery, design_capacity_warning), 0},
396 {offsetof(struct acpi_battery, design_capacity_low), 0},
397 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
398 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
399 {offsetof(struct acpi_battery, model_number), 1},
400 {offsetof(struct acpi_battery, serial_number), 1},
401 {offsetof(struct acpi_battery, type), 1},
402 {offsetof(struct acpi_battery, oem_info), 1},
403};
404
Mathias Krausea4658782015-06-13 14:26:53 +0200405static const struct acpi_offsets extended_info_offsets[] = {
Lan Tianyu016d5ba2013-07-30 14:00:42 +0200406 {offsetof(struct acpi_battery, revision), 0},
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400407 {offsetof(struct acpi_battery, power_unit), 0},
408 {offsetof(struct acpi_battery, design_capacity), 0},
409 {offsetof(struct acpi_battery, full_charge_capacity), 0},
410 {offsetof(struct acpi_battery, technology), 0},
411 {offsetof(struct acpi_battery, design_voltage), 0},
412 {offsetof(struct acpi_battery, design_capacity_warning), 0},
413 {offsetof(struct acpi_battery, design_capacity_low), 0},
414 {offsetof(struct acpi_battery, cycle_count), 0},
415 {offsetof(struct acpi_battery, measurement_accuracy), 0},
416 {offsetof(struct acpi_battery, max_sampling_time), 0},
417 {offsetof(struct acpi_battery, min_sampling_time), 0},
418 {offsetof(struct acpi_battery, max_averaging_interval), 0},
419 {offsetof(struct acpi_battery, min_averaging_interval), 0},
420 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
421 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
422 {offsetof(struct acpi_battery, model_number), 1},
423 {offsetof(struct acpi_battery, serial_number), 1},
424 {offsetof(struct acpi_battery, type), 1},
425 {offsetof(struct acpi_battery, oem_info), 1},
426};
427
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400428static int extract_package(struct acpi_battery *battery,
429 union acpi_object *package,
Mathias Krausea4658782015-06-13 14:26:53 +0200430 const struct acpi_offsets *offsets, int num)
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300431{
Alexey Starikovskiy106449e2007-10-29 23:29:40 +0300432 int i;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400433 union acpi_object *element;
434 if (package->type != ACPI_TYPE_PACKAGE)
435 return -EFAULT;
436 for (i = 0; i < num; ++i) {
437 if (package->package.count <= i)
438 return -EFAULT;
439 element = &package->package.elements[i];
440 if (offsets[i].mode) {
Alexey Starikovskiy106449e2007-10-29 23:29:40 +0300441 u8 *ptr = (u8 *)battery + offsets[i].offset;
442 if (element->type == ACPI_TYPE_STRING ||
443 element->type == ACPI_TYPE_BUFFER)
444 strncpy(ptr, element->string.pointer, 32);
445 else if (element->type == ACPI_TYPE_INTEGER) {
446 strncpy(ptr, (u8 *)&element->integer.value,
Lin Ming439913f2010-01-28 10:53:19 +0800447 sizeof(u64));
448 ptr[sizeof(u64)] = 0;
Alexey Starikovskiyb8a1bdb2008-03-17 22:37:42 -0400449 } else
450 *ptr = 0; /* don't have value */
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400451 } else {
Alexey Starikovskiyb8a1bdb2008-03-17 22:37:42 -0400452 int *x = (int *)((u8 *)battery + offsets[i].offset);
453 *x = (element->type == ACPI_TYPE_INTEGER) ?
454 element->integer.value : -1;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300455 }
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300456 }
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300457 return 0;
458}
459
460static int acpi_battery_get_status(struct acpi_battery *battery)
461{
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400462 if (acpi_bus_get_status(battery->device)) {
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300463 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
464 return -ENODEV;
465 }
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400466 return 0;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300467}
468
Dave Lambley2d09af42016-11-04 01:05:40 +0000469
470static int extract_battery_info(const int use_bix,
471 struct acpi_battery *battery,
472 const struct acpi_buffer *buffer)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473{
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400474 int result = -EFAULT;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400475
Dave Lambley2d09af42016-11-04 01:05:40 +0000476 if (use_bix && battery_bix_broken_package)
477 result = extract_package(battery, buffer->pointer,
Lan Tianyua90b4032014-01-06 22:50:37 +0800478 extended_info_offsets + 1,
479 ARRAY_SIZE(extended_info_offsets) - 1);
Dave Lambley2d09af42016-11-04 01:05:40 +0000480 else if (use_bix)
481 result = extract_package(battery, buffer->pointer,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400482 extended_info_offsets,
483 ARRAY_SIZE(extended_info_offsets));
484 else
Dave Lambley2d09af42016-11-04 01:05:40 +0000485 result = extract_package(battery, buffer->pointer,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400486 info_offsets, ARRAY_SIZE(info_offsets));
Zhang Rui557d5862010-10-22 10:02:06 +0800487 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
488 battery->full_charge_capacity = battery->design_capacity;
Kamil Iskra4000e622012-11-16 22:28:58 +0100489 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
490 battery->power_unit && battery->design_voltage) {
491 battery->design_capacity = battery->design_capacity *
492 10000 / battery->design_voltage;
493 battery->full_charge_capacity = battery->full_charge_capacity *
494 10000 / battery->design_voltage;
495 battery->design_capacity_warning =
496 battery->design_capacity_warning *
497 10000 / battery->design_voltage;
498 /* Curiously, design_capacity_low, unlike the rest of them,
499 is correct. */
500 /* capacity_granularity_* equal 1 on the systems tested, so
501 it's impossible to tell if they would need an adjustment
502 or not if their values were higher. */
503 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100504 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
505 battery->capacity_now > battery->full_charge_capacity)
506 battery->capacity_now = battery->full_charge_capacity;
507
Patrick Mocheld550d982006-06-27 00:41:40 -0400508 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509}
510
Dave Lambley2d09af42016-11-04 01:05:40 +0000511static int acpi_battery_get_info(struct acpi_battery *battery)
512{
513 const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
514 int use_bix;
515 int result = -ENODEV;
516
517 if (!acpi_battery_present(battery))
518 return 0;
519
520
521 for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) {
522 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
523 acpi_status status = AE_ERROR;
524
525 mutex_lock(&battery->lock);
526 status = acpi_evaluate_object(battery->device->handle,
527 use_bix ? "_BIX":"_BIF",
528 NULL, &buffer);
529 mutex_unlock(&battery->lock);
530
531 if (ACPI_FAILURE(status)) {
532 ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s",
533 use_bix ? "_BIX":"_BIF"));
534 } else {
535 result = extract_battery_info(use_bix,
536 battery,
537 &buffer);
538
539 kfree(buffer.pointer);
540 break;
541 }
542 }
543
544 if (!result && !use_bix && xinfo)
545 pr_warn(FW_BUG "The _BIX method is broken, using _BIF.\n");
546
547 return result;
548}
549
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300550static int acpi_battery_get_state(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551{
Len Brown4be44fc2005-08-05 00:44:28 -0400552 int result = 0;
553 acpi_status status = 0;
554 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300556 if (!acpi_battery_present(battery))
557 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400559 if (battery->update_time &&
560 time_before(jiffies, battery->update_time +
561 msecs_to_jiffies(cache_time)))
562 return 0;
563
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400564 mutex_lock(&battery->lock);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400565 status = acpi_evaluate_object(battery->device->handle, "_BST",
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400566 NULL, &buffer);
567 mutex_unlock(&battery->lock);
Len Brown5b31d892007-08-15 00:19:26 -0400568
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 if (ACPI_FAILURE(status)) {
Thomas Renningera6fc6722006-06-26 23:58:43 -0400570 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
Patrick Mocheld550d982006-06-27 00:41:40 -0400571 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 }
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400573
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400574 result = extract_package(battery, buffer.pointer,
575 state_offsets, ARRAY_SIZE(state_offsets));
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400576 battery->update_time = jiffies;
Alexey Starikovskiy78490d82007-05-11 13:18:55 -0400577 kfree(buffer.pointer);
Hector Martinbc76f902009-08-06 15:57:48 -0700578
Lan Tianyu55003b22011-06-30 11:33:12 +0800579 /* For buggy DSDTs that report negative 16-bit values for either
580 * charging or discharging current and/or report 0 as 65536
581 * due to bad math.
582 */
583 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
584 battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
585 (s16)(battery->rate_now) < 0) {
Hector Martinbc76f902009-08-06 15:57:48 -0700586 battery->rate_now = abs((s16)battery->rate_now);
Martin Kepplinger92375162015-03-13 00:48:17 +0100587 printk_once(KERN_WARNING FW_BUG
588 "battery: (dis)charge rate invalid.\n");
Lan Tianyu55003b22011-06-30 11:33:12 +0800589 }
Hector Martinbc76f902009-08-06 15:57:48 -0700590
Zhang Rui557d5862010-10-22 10:02:06 +0800591 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
592 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
593 battery->capacity_now = (battery->capacity_now *
594 battery->full_charge_capacity) / 100;
Kamil Iskra4000e622012-11-16 22:28:58 +0100595 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
596 battery->power_unit && battery->design_voltage) {
597 battery->capacity_now = battery->capacity_now *
598 10000 / battery->design_voltage;
599 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100600 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
601 battery->capacity_now > battery->full_charge_capacity)
602 battery->capacity_now = battery->full_charge_capacity;
603
Patrick Mocheld550d982006-06-27 00:41:40 -0400604 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605}
606
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400607static int acpi_battery_set_alarm(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608{
Len Brown4be44fc2005-08-05 00:44:28 -0400609 acpi_status status = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400611 if (!acpi_battery_present(battery) ||
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400612 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300613 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400615 mutex_lock(&battery->lock);
Jiang Liu0db98202013-06-29 00:24:39 +0800616 status = acpi_execute_simple_method(battery->device->handle, "_BTP",
617 battery->alarm);
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400618 mutex_unlock(&battery->lock);
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 if (ACPI_FAILURE(status))
Patrick Mocheld550d982006-06-27 00:41:40 -0400621 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400623 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
Patrick Mocheld550d982006-06-27 00:41:40 -0400624 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625}
626
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300627static int acpi_battery_init_alarm(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628{
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300629 /* See if alarms are supported, and if so, set default */
Jiang Liu952c63e2013-06-29 00:24:38 +0800630 if (!acpi_has_method(battery->device->handle, "_BTP")) {
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400631 clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400632 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 }
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400634 set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400635 if (!battery->alarm)
636 battery->alarm = battery->design_capacity_warning;
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400637 return acpi_battery_set_alarm(battery);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638}
639
Andrey Borzenkov508df922007-10-28 12:50:09 +0300640static ssize_t acpi_battery_alarm_show(struct device *dev,
641 struct device_attribute *attr,
642 char *buf)
643{
644 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
645 return sprintf(buf, "%d\n", battery->alarm * 1000);
646}
647
648static ssize_t acpi_battery_alarm_store(struct device *dev,
649 struct device_attribute *attr,
650 const char *buf, size_t count)
651{
652 unsigned long x;
653 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
Luis G.F47a08c82014-01-21 15:40:43 +0100654 if (sscanf(buf, "%lu\n", &x) == 1)
Andrey Borzenkov508df922007-10-28 12:50:09 +0300655 battery->alarm = x/1000;
656 if (acpi_battery_present(battery))
657 acpi_battery_set_alarm(battery);
658 return count;
659}
660
Bhumika Goyal82d2b612017-08-21 17:13:07 +0530661static const struct device_attribute alarm_attr = {
Parag Warudkar01e8ef12008-10-18 20:28:50 -0700662 .attr = {.name = "alarm", .mode = 0644},
Andrey Borzenkov508df922007-10-28 12:50:09 +0300663 .show = acpi_battery_alarm_show,
664 .store = acpi_battery_alarm_store,
665};
666
Ognjen Galicfa938542018-02-07 15:58:13 +0100667/*
668 * The Battery Hooking API
669 *
670 * This API is used inside other drivers that need to expose
671 * platform-specific behaviour within the generic driver in a
672 * generic way.
673 *
674 */
675
676static LIST_HEAD(acpi_battery_list);
677static LIST_HEAD(battery_hook_list);
678static DEFINE_MUTEX(hook_mutex);
679
Colin Ian King514bcc52018-02-23 16:32:55 +0000680static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
Ognjen Galicfa938542018-02-07 15:58:13 +0100681{
682 struct acpi_battery *battery;
683 /*
684 * In order to remove a hook, we first need to
685 * de-register all the batteries that are registered.
686 */
687 if (lock)
688 mutex_lock(&hook_mutex);
689 list_for_each_entry(battery, &acpi_battery_list, list) {
690 hook->remove_battery(battery->bat);
691 }
692 list_del(&hook->list);
693 if (lock)
694 mutex_unlock(&hook_mutex);
695 pr_info("extension unregistered: %s\n", hook->name);
696}
697
698void battery_hook_unregister(struct acpi_battery_hook *hook)
699{
700 __battery_hook_unregister(hook, 1);
701}
702EXPORT_SYMBOL_GPL(battery_hook_unregister);
703
704void battery_hook_register(struct acpi_battery_hook *hook)
705{
706 struct acpi_battery *battery;
707
708 mutex_lock(&hook_mutex);
709 INIT_LIST_HEAD(&hook->list);
710 list_add(&hook->list, &battery_hook_list);
711 /*
712 * Now that the driver is registered, we need
713 * to notify the hook that a battery is available
714 * for each battery, so that the driver may add
715 * its attributes.
716 */
717 list_for_each_entry(battery, &acpi_battery_list, list) {
718 if (hook->add_battery(battery->bat)) {
719 /*
720 * If a add-battery returns non-zero,
721 * the registration of the extension has failed,
722 * and we will not add it to the list of loaded
723 * hooks.
724 */
725 pr_err("extension failed to load: %s", hook->name);
726 __battery_hook_unregister(hook, 0);
727 return;
728 }
729 }
730 pr_info("new extension: %s\n", hook->name);
731 mutex_unlock(&hook_mutex);
732}
733EXPORT_SYMBOL_GPL(battery_hook_register);
734
735/*
736 * This function gets called right after the battery sysfs
737 * attributes have been added, so that the drivers that
738 * define custom sysfs attributes can add their own.
Rafael J. Wysocki7a4ea102018-03-13 10:07:49 +0100739*/
Ognjen Galicfa938542018-02-07 15:58:13 +0100740static void battery_hook_add_battery(struct acpi_battery *battery)
741{
742 struct acpi_battery_hook *hook_node;
743
744 mutex_lock(&hook_mutex);
745 INIT_LIST_HEAD(&battery->list);
746 list_add(&battery->list, &acpi_battery_list);
747 /*
748 * Since we added a new battery to the list, we need to
749 * iterate over the hooks and call add_battery for each
750 * hook that was registered. This usually happens
751 * when a battery gets hotplugged or initialized
752 * during the battery module initialization.
753 */
754 list_for_each_entry(hook_node, &battery_hook_list, list) {
755 if (hook_node->add_battery(battery->bat)) {
756 /*
757 * The notification of the extensions has failed, to
758 * prevent further errors we will unload the extension.
759 */
760 __battery_hook_unregister(hook_node, 0);
761 pr_err("error in extension, unloading: %s",
762 hook_node->name);
763 }
764 }
765 mutex_unlock(&hook_mutex);
766}
767
768static void battery_hook_remove_battery(struct acpi_battery *battery)
769{
770 struct acpi_battery_hook *hook;
771
772 mutex_lock(&hook_mutex);
773 /*
774 * Before removing the hook, we need to remove all
775 * custom attributes from the battery.
776 */
777 list_for_each_entry(hook, &battery_hook_list, list) {
778 hook->remove_battery(battery->bat);
779 }
780 /* Then, just remove the battery from the list */
781 list_del(&battery->list);
782 mutex_unlock(&hook_mutex);
783}
784
785static void __exit battery_hook_exit(void)
786{
787 struct acpi_battery_hook *hook;
788 struct acpi_battery_hook *ptr;
789 /*
790 * At this point, the acpi_bus_unregister_driver()
791 * has called remove for all batteries. We just
792 * need to remove the hooks.
793 */
794 list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
795 __battery_hook_unregister(hook, 1);
796 }
797 mutex_destroy(&hook_mutex);
798}
799
Andrey Borzenkov508df922007-10-28 12:50:09 +0300800static int sysfs_add_battery(struct acpi_battery *battery)
801{
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100802 struct power_supply_config psy_cfg = { .drv_data = battery, };
Andrey Borzenkov508df922007-10-28 12:50:09 +0300803
Lan Tianyuae6f6182011-06-30 11:32:40 +0800804 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100805 battery->bat_desc.properties = charge_battery_props;
806 battery->bat_desc.num_properties =
Andrey Borzenkov508df922007-10-28 12:50:09 +0300807 ARRAY_SIZE(charge_battery_props);
808 } else {
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100809 battery->bat_desc.properties = energy_battery_props;
810 battery->bat_desc.num_properties =
Andrey Borzenkov508df922007-10-28 12:50:09 +0300811 ARRAY_SIZE(energy_battery_props);
812 }
813
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100814 battery->bat_desc.name = acpi_device_bid(battery->device);
815 battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
816 battery->bat_desc.get_property = acpi_battery_get_property;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300817
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100818 battery->bat = power_supply_register_no_ws(&battery->device->dev,
819 &battery->bat_desc, &psy_cfg);
Zhang Ruie0d1f092014-05-28 15:23:38 +0800820
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100821 if (IS_ERR(battery->bat)) {
822 int result = PTR_ERR(battery->bat);
823
824 battery->bat = NULL;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300825 return result;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100826 }
Ognjen Galicfa938542018-02-07 15:58:13 +0100827 battery_hook_add_battery(battery);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100828 return device_create_file(&battery->bat->dev, &alarm_attr);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300829}
830
831static void sysfs_remove_battery(struct acpi_battery *battery)
832{
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300833 mutex_lock(&battery->sysfs_lock);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100834 if (!battery->bat) {
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300835 mutex_unlock(&battery->sysfs_lock);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300836 return;
Lan Tianyu9c921c222011-06-30 11:34:12 +0800837 }
Ognjen Galicfa938542018-02-07 15:58:13 +0100838 battery_hook_remove_battery(battery);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100839 device_remove_file(&battery->bat->dev, &alarm_attr);
840 power_supply_unregister(battery->bat);
841 battery->bat = NULL;
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300842 mutex_unlock(&battery->sysfs_lock);
Hector Martinbc76f902009-08-06 15:57:48 -0700843}
844
Kamil Iskra4000e622012-11-16 22:28:58 +0100845static void find_battery(const struct dmi_header *dm, void *private)
846{
847 struct acpi_battery *battery = (struct acpi_battery *)private;
848 /* Note: the hardcoded offsets below have been extracted from
849 the source code of dmidecode. */
850 if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
851 const u8 *dmi_data = (const u8 *)(dm + 1);
852 int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
853 if (dm->length >= 18)
854 dmi_capacity *= dmi_data[17];
855 if (battery->design_capacity * battery->design_voltage / 1000
856 != dmi_capacity &&
857 battery->design_capacity * 10 == dmi_capacity)
858 set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
859 &battery->flags);
860 }
861}
862
Zhang Rui557d5862010-10-22 10:02:06 +0800863/*
864 * According to the ACPI spec, some kinds of primary batteries can
865 * report percentage battery remaining capacity directly to OS.
866 * In this case, it reports the Last Full Charged Capacity == 100
867 * and BatteryPresentRate == 0xFFFFFFFF.
868 *
869 * Now we found some battery reports percentage remaining capacity
870 * even if it's rechargeable.
871 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
872 *
873 * Handle this correctly so that they won't break userspace.
874 */
Lan Tianyu7b786222011-06-30 11:33:27 +0800875static void acpi_battery_quirks(struct acpi_battery *battery)
Zhang Rui557d5862010-10-22 10:02:06 +0800876{
877 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000878 return;
Zhang Rui557d5862010-10-22 10:02:06 +0800879
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000880 if (battery->full_charge_capacity == 100 &&
881 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
882 battery->capacity_now >= 0 && battery->capacity_now <= 100) {
Zhang Rui557d5862010-10-22 10:02:06 +0800883 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
884 battery->full_charge_capacity = battery->design_capacity;
885 battery->capacity_now = (battery->capacity_now *
886 battery->full_charge_capacity) / 100;
887 }
Kamil Iskra4000e622012-11-16 22:28:58 +0100888
889 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000890 return;
Kamil Iskra4000e622012-11-16 22:28:58 +0100891
892 if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
893 const char *s;
894 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
Rasmus Villemoesffd8a732014-09-16 22:51:24 +0200895 if (s && !strncasecmp(s, "ThinkPad", 8)) {
Kamil Iskra4000e622012-11-16 22:28:58 +0100896 dmi_walk(find_battery, battery);
897 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
898 &battery->flags) &&
899 battery->design_voltage) {
900 battery->design_capacity =
901 battery->design_capacity *
902 10000 / battery->design_voltage;
903 battery->full_charge_capacity =
904 battery->full_charge_capacity *
905 10000 / battery->design_voltage;
906 battery->design_capacity_warning =
907 battery->design_capacity_warning *
908 10000 / battery->design_voltage;
909 battery->capacity_now = battery->capacity_now *
910 10000 / battery->design_voltage;
911 }
912 }
913 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100914
915 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags))
916 return;
917
918 if (acpi_battery_is_degraded(battery) &&
919 battery->capacity_now > battery->full_charge_capacity) {
920 set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags);
921 battery->capacity_now = battery->full_charge_capacity;
922 }
Zhang Rui557d5862010-10-22 10:02:06 +0800923}
924
Lan Tianyu9e50bc12014-05-04 14:07:06 +0800925static int acpi_battery_update(struct acpi_battery *battery, bool resume)
Vladimir Lebedev4bd35cd2007-02-10 01:43:48 -0500926{
Alexey Starikovskiy50b17852008-12-23 02:44:54 +0300927 int result, old_present = acpi_battery_present(battery);
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500928 result = acpi_battery_get_status(battery);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300929 if (result)
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300930 return result;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300931 if (!acpi_battery_present(battery)) {
932 sysfs_remove_battery(battery);
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500933 battery->update_time = 0;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300934 return 0;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300935 }
Lan Tianyu9e50bc12014-05-04 14:07:06 +0800936
937 if (resume)
938 return 0;
939
Alexey Starikovskiy50b17852008-12-23 02:44:54 +0300940 if (!battery->update_time ||
941 old_present != acpi_battery_present(battery)) {
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500942 result = acpi_battery_get_info(battery);
943 if (result)
944 return result;
945 acpi_battery_init_alarm(battery);
946 }
Carlos Garnacho12c78ca2016-08-10 17:24:15 +0200947
948 result = acpi_battery_get_state(battery);
949 if (result)
950 return result;
951 acpi_battery_quirks(battery);
952
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100953 if (!battery->bat) {
Stefan Hajnoczieb03cb02011-07-12 09:03:29 +0100954 result = sysfs_add_battery(battery);
955 if (result)
956 return result;
957 }
Zhang Ruie0d1f092014-05-28 15:23:38 +0800958
959 /*
960 * Wakeup the system if battery is critical low
961 * or lower than the alarm level
962 */
963 if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
964 (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
965 (battery->capacity_now <= battery->alarm)))
Rafael J. Wysocki33e4f802017-06-12 22:56:34 +0200966 acpi_pm_wakeup_event(&battery->device->dev);
Zhang Ruie0d1f092014-05-28 15:23:38 +0800967
Zhang Rui557d5862010-10-22 10:02:06 +0800968 return result;
Vladimir Lebedev4bd35cd2007-02-10 01:43:48 -0500969}
970
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100971static void acpi_battery_refresh(struct acpi_battery *battery)
972{
Andy Whitcroftc5971452012-05-03 14:48:26 +0100973 int power_unit;
974
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100975 if (!battery->bat)
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100976 return;
977
Andy Whitcroftc5971452012-05-03 14:48:26 +0100978 power_unit = battery->power_unit;
979
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100980 acpi_battery_get_info(battery);
Andy Whitcroftc5971452012-05-03 14:48:26 +0100981
982 if (power_unit == battery->power_unit)
983 return;
984
985 /* The battery has changed its reporting units. */
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100986 sysfs_remove_battery(battery);
987 sysfs_add_battery(battery);
988}
989
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990/* --------------------------------------------------------------------------
Lan Tianyu3a670cc2014-05-04 11:07:25 +0800991 FS Interface (/proc)
992 -------------------------------------------------------------------------- */
993
994#ifdef CONFIG_ACPI_PROCFS_POWER
995static struct proc_dir_entry *acpi_battery_dir;
996
Mathias Krause27059b92015-06-13 14:26:54 +0200997static const char *acpi_battery_units(const struct acpi_battery *battery)
998{
999 return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
1000 "mA" : "mW";
1001}
1002
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001003static int acpi_battery_print_info(struct seq_file *seq, int result)
1004{
1005 struct acpi_battery *battery = seq->private;
1006
1007 if (result)
1008 goto end;
1009
1010 seq_printf(seq, "present: %s\n",
1011 acpi_battery_present(battery) ? "yes" : "no");
1012 if (!acpi_battery_present(battery))
1013 goto end;
1014 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1015 seq_printf(seq, "design capacity: unknown\n");
1016 else
1017 seq_printf(seq, "design capacity: %d %sh\n",
1018 battery->design_capacity,
1019 acpi_battery_units(battery));
1020
1021 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1022 seq_printf(seq, "last full capacity: unknown\n");
1023 else
1024 seq_printf(seq, "last full capacity: %d %sh\n",
1025 battery->full_charge_capacity,
1026 acpi_battery_units(battery));
1027
1028 seq_printf(seq, "battery technology: %srechargeable\n",
1029 (!battery->technology)?"non-":"");
1030
1031 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
1032 seq_printf(seq, "design voltage: unknown\n");
1033 else
1034 seq_printf(seq, "design voltage: %d mV\n",
1035 battery->design_voltage);
1036 seq_printf(seq, "design capacity warning: %d %sh\n",
1037 battery->design_capacity_warning,
1038 acpi_battery_units(battery));
1039 seq_printf(seq, "design capacity low: %d %sh\n",
1040 battery->design_capacity_low,
1041 acpi_battery_units(battery));
1042 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
1043 seq_printf(seq, "capacity granularity 1: %d %sh\n",
1044 battery->capacity_granularity_1,
1045 acpi_battery_units(battery));
1046 seq_printf(seq, "capacity granularity 2: %d %sh\n",
1047 battery->capacity_granularity_2,
1048 acpi_battery_units(battery));
1049 seq_printf(seq, "model number: %s\n", battery->model_number);
1050 seq_printf(seq, "serial number: %s\n", battery->serial_number);
1051 seq_printf(seq, "battery type: %s\n", battery->type);
1052 seq_printf(seq, "OEM info: %s\n", battery->oem_info);
1053 end:
1054 if (result)
1055 seq_printf(seq, "ERROR: Unable to read battery info\n");
1056 return result;
1057}
1058
1059static int acpi_battery_print_state(struct seq_file *seq, int result)
1060{
1061 struct acpi_battery *battery = seq->private;
1062
1063 if (result)
1064 goto end;
1065
1066 seq_printf(seq, "present: %s\n",
1067 acpi_battery_present(battery) ? "yes" : "no");
1068 if (!acpi_battery_present(battery))
1069 goto end;
1070
1071 seq_printf(seq, "capacity state: %s\n",
1072 (battery->state & 0x04) ? "critical" : "ok");
1073 if ((battery->state & 0x01) && (battery->state & 0x02))
1074 seq_printf(seq,
1075 "charging state: charging/discharging\n");
1076 else if (battery->state & 0x01)
1077 seq_printf(seq, "charging state: discharging\n");
1078 else if (battery->state & 0x02)
1079 seq_printf(seq, "charging state: charging\n");
1080 else
1081 seq_printf(seq, "charging state: charged\n");
1082
1083 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
1084 seq_printf(seq, "present rate: unknown\n");
1085 else
1086 seq_printf(seq, "present rate: %d %s\n",
1087 battery->rate_now, acpi_battery_units(battery));
1088
1089 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
1090 seq_printf(seq, "remaining capacity: unknown\n");
1091 else
1092 seq_printf(seq, "remaining capacity: %d %sh\n",
1093 battery->capacity_now, acpi_battery_units(battery));
1094 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
1095 seq_printf(seq, "present voltage: unknown\n");
1096 else
1097 seq_printf(seq, "present voltage: %d mV\n",
1098 battery->voltage_now);
1099 end:
1100 if (result)
1101 seq_printf(seq, "ERROR: Unable to read battery state\n");
1102
1103 return result;
1104}
1105
1106static int acpi_battery_print_alarm(struct seq_file *seq, int result)
1107{
1108 struct acpi_battery *battery = seq->private;
1109
1110 if (result)
1111 goto end;
1112
1113 if (!acpi_battery_present(battery)) {
1114 seq_printf(seq, "present: no\n");
1115 goto end;
1116 }
1117 seq_printf(seq, "alarm: ");
1118 if (!battery->alarm)
1119 seq_printf(seq, "unsupported\n");
1120 else
1121 seq_printf(seq, "%u %sh\n", battery->alarm,
1122 acpi_battery_units(battery));
1123 end:
1124 if (result)
1125 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
1126 return result;
1127}
1128
1129static ssize_t acpi_battery_write_alarm(struct file *file,
1130 const char __user * buffer,
1131 size_t count, loff_t * ppos)
1132{
1133 int result = 0;
1134 char alarm_string[12] = { '\0' };
1135 struct seq_file *m = file->private_data;
1136 struct acpi_battery *battery = m->private;
1137
1138 if (!battery || (count > sizeof(alarm_string) - 1))
1139 return -EINVAL;
1140 if (!acpi_battery_present(battery)) {
1141 result = -ENODEV;
1142 goto end;
1143 }
1144 if (copy_from_user(alarm_string, buffer, count)) {
1145 result = -EFAULT;
1146 goto end;
1147 }
1148 alarm_string[count] = '\0';
Christoph Jaeger3d915892014-06-13 21:49:58 +02001149 if (kstrtoint(alarm_string, 0, &battery->alarm)) {
1150 result = -EINVAL;
1151 goto end;
1152 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001153 result = acpi_battery_set_alarm(battery);
1154 end:
1155 if (!result)
1156 return count;
1157 return result;
1158}
1159
1160typedef int(*print_func)(struct seq_file *seq, int result);
1161
1162static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
1163 acpi_battery_print_info,
1164 acpi_battery_print_state,
1165 acpi_battery_print_alarm,
1166};
1167
1168static int acpi_battery_read(int fid, struct seq_file *seq)
1169{
1170 struct acpi_battery *battery = seq->private;
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001171 int result = acpi_battery_update(battery, false);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001172 return acpi_print_funcs[fid](seq, result);
1173}
1174
1175#define DECLARE_FILE_FUNCTIONS(_name) \
1176static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
1177{ \
1178 return acpi_battery_read(_name##_tag, seq); \
1179} \
1180static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
1181{ \
1182 return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \
1183}
1184
1185DECLARE_FILE_FUNCTIONS(info);
1186DECLARE_FILE_FUNCTIONS(state);
1187DECLARE_FILE_FUNCTIONS(alarm);
1188
1189#undef DECLARE_FILE_FUNCTIONS
1190
1191#define FILE_DESCRIPTION_RO(_name) \
1192 { \
1193 .name = __stringify(_name), \
1194 .mode = S_IRUGO, \
1195 .ops = { \
1196 .open = acpi_battery_##_name##_open_fs, \
1197 .read = seq_read, \
1198 .llseek = seq_lseek, \
1199 .release = single_release, \
1200 .owner = THIS_MODULE, \
1201 }, \
1202 }
1203
1204#define FILE_DESCRIPTION_RW(_name) \
1205 { \
1206 .name = __stringify(_name), \
1207 .mode = S_IFREG | S_IRUGO | S_IWUSR, \
1208 .ops = { \
1209 .open = acpi_battery_##_name##_open_fs, \
1210 .read = seq_read, \
1211 .llseek = seq_lseek, \
1212 .write = acpi_battery_write_##_name, \
1213 .release = single_release, \
1214 .owner = THIS_MODULE, \
1215 }, \
1216 }
1217
1218static const struct battery_file {
1219 struct file_operations ops;
1220 umode_t mode;
1221 const char *name;
1222} acpi_battery_file[] = {
1223 FILE_DESCRIPTION_RO(info),
1224 FILE_DESCRIPTION_RO(state),
1225 FILE_DESCRIPTION_RW(alarm),
1226};
1227
1228#undef FILE_DESCRIPTION_RO
1229#undef FILE_DESCRIPTION_RW
1230
1231static int acpi_battery_add_fs(struct acpi_device *device)
1232{
1233 struct proc_dir_entry *entry = NULL;
1234 int i;
1235
1236 printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded,"
1237 " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
1238 if (!acpi_device_dir(device)) {
1239 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1240 acpi_battery_dir);
1241 if (!acpi_device_dir(device))
1242 return -ENODEV;
1243 }
1244
1245 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
1246 entry = proc_create_data(acpi_battery_file[i].name,
1247 acpi_battery_file[i].mode,
1248 acpi_device_dir(device),
1249 &acpi_battery_file[i].ops,
1250 acpi_driver_data(device));
1251 if (!entry)
1252 return -ENODEV;
1253 }
1254 return 0;
1255}
1256
1257static void acpi_battery_remove_fs(struct acpi_device *device)
1258{
1259 int i;
1260 if (!acpi_device_dir(device))
1261 return;
1262 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
1263 remove_proc_entry(acpi_battery_file[i].name,
1264 acpi_device_dir(device));
1265
1266 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
1267 acpi_device_dir(device) = NULL;
1268}
1269
1270#endif
1271
1272/* --------------------------------------------------------------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 Driver Interface
1274 -------------------------------------------------------------------------- */
1275
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001276static void acpi_battery_notify(struct acpi_device *device, u32 event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277{
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001278 struct acpi_battery *battery = acpi_driver_data(device);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001279 struct power_supply *old;
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001280
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 if (!battery)
Patrick Mocheld550d982006-06-27 00:41:40 -04001282 return;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001283 old = battery->bat;
Alexander Mezinf43691c2014-06-04 02:01:23 +07001284 /*
1285 * On Acer Aspire V5-573G notifications are sometimes triggered too
1286 * early. For example, when AC is unplugged and notification is
1287 * triggered, battery state is still reported as "Full", and changes to
1288 * "Discharging" only after short delay, without any notification.
1289 */
1290 if (battery_notification_delay_ms > 0)
1291 msleep(battery_notification_delay_ms);
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +01001292 if (event == ACPI_BATTERY_NOTIFY_INFO)
1293 acpi_battery_refresh(battery);
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001294 acpi_battery_update(battery, false);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +04001295 acpi_bus_generate_netlink_event(device->pnp.device_class,
Kay Sievers07944692008-10-30 01:18:59 +01001296 dev_name(&device->dev), event,
Vladimir Lebedev9ea7d572007-02-20 15:48:06 +03001297 acpi_battery_present(battery));
Alexander Mezin411e0f72014-03-12 00:58:47 +07001298 acpi_notifier_call_chain(device, event, acpi_battery_present(battery));
Justin P. Mattock2345baf2009-12-13 14:42:36 -08001299 /* acpi_battery_update could remove power_supply object */
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001300 if (old && battery->bat)
1301 power_supply_changed(battery->bat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302}
1303
Kyle McMartin25be5822011-03-22 16:19:50 -04001304static int battery_notify(struct notifier_block *nb,
1305 unsigned long mode, void *_unused)
1306{
1307 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
1308 pm_nb);
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001309 int result;
1310
Kyle McMartin25be5822011-03-22 16:19:50 -04001311 switch (mode) {
Lan Tianyud5a59112011-06-30 11:33:40 +08001312 case PM_POST_HIBERNATION:
Kyle McMartin25be5822011-03-22 16:19:50 -04001313 case PM_POST_SUSPEND:
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001314 if (!acpi_battery_present(battery))
1315 return 0;
1316
Krzysztof Kozlowski31f7dc72015-04-14 22:24:13 +09001317 if (!battery->bat) {
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001318 result = acpi_battery_get_info(battery);
1319 if (result)
1320 return result;
1321
1322 result = sysfs_add_battery(battery);
1323 if (result)
1324 return result;
1325 } else
1326 acpi_battery_refresh(battery);
1327
1328 acpi_battery_init_alarm(battery);
1329 acpi_battery_get_state(battery);
Kyle McMartin25be5822011-03-22 16:19:50 -04001330 break;
1331 }
1332
1333 return 0;
1334}
1335
Mathias Krause048d16d2015-06-13 14:26:55 +02001336static int __init
1337battery_bix_broken_package_quirk(const struct dmi_system_id *d)
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001338{
1339 battery_bix_broken_package = 1;
1340 return 0;
1341}
1342
Mathias Krause048d16d2015-06-13 14:26:55 +02001343static int __init
1344battery_notification_delay_quirk(const struct dmi_system_id *d)
Alexander Mezinf43691c2014-06-04 02:01:23 +07001345{
1346 battery_notification_delay_ms = 1000;
1347 return 0;
1348}
1349
Hans de Goede1b799c52018-04-12 12:02:00 +02001350static int __init
1351battery_ac_is_broken_quirk(const struct dmi_system_id *d)
1352{
1353 battery_ac_is_broken = 1;
1354 return 0;
1355}
1356
Mathias Krause048d16d2015-06-13 14:26:55 +02001357static const struct dmi_system_id bat_dmi_table[] __initconst = {
Lan Tianyua90b4032014-01-06 22:50:37 +08001358 {
Hans de Goede91afa072018-04-12 12:01:58 +02001359 /* NEC LZ750/LS */
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001360 .callback = battery_bix_broken_package_quirk,
Lan Tianyua90b4032014-01-06 22:50:37 +08001361 .matches = {
1362 DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
1363 DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
1364 },
1365 },
Alexander Mezinf43691c2014-06-04 02:01:23 +07001366 {
Hans de Goede91afa072018-04-12 12:01:58 +02001367 /* Acer Aspire V5-573G */
Alexander Mezinf43691c2014-06-04 02:01:23 +07001368 .callback = battery_notification_delay_quirk,
Alexander Mezinf43691c2014-06-04 02:01:23 +07001369 .matches = {
1370 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
1371 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
1372 },
1373 },
Hans de Goede1b799c52018-04-12 12:02:00 +02001374 {
1375 /* Point of View mobii wintab p800w */
1376 .callback = battery_ac_is_broken_quirk,
1377 .matches = {
1378 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1379 DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1380 DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
1381 /* Above matches are too generic, add bios-date match */
1382 DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
1383 },
1384 },
Lan Tianyua90b4032014-01-06 22:50:37 +08001385 {},
1386};
1387
Lan Tianyu75646e72014-07-07 15:47:12 +08001388/*
1389 * Some machines'(E,G Lenovo Z480) ECs are not stable
1390 * during boot up and this causes battery driver fails to be
1391 * probed due to failure of getting battery information
1392 * from EC sometimes. After several retries, the operation
1393 * may work. So add retry code here and 20ms sleep between
1394 * every retries.
1395 */
1396static int acpi_battery_update_retry(struct acpi_battery *battery)
1397{
1398 int retry, ret;
1399
1400 for (retry = 5; retry; retry--) {
1401 ret = acpi_battery_update(battery, false);
1402 if (!ret)
1403 break;
1404
1405 msleep(20);
1406 }
1407 return ret;
1408}
1409
Len Brown4be44fc2005-08-05 00:44:28 -04001410static int acpi_battery_add(struct acpi_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411{
Len Brown4be44fc2005-08-05 00:44:28 -04001412 int result = 0;
Len Brown4be44fc2005-08-05 00:44:28 -04001413 struct acpi_battery *battery = NULL;
Jiang Liu952c63e2013-06-29 00:24:38 +08001414
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 if (!device)
Patrick Mocheld550d982006-06-27 00:41:40 -04001416 return -EINVAL;
Lan Tianyu40e7fcb2014-11-23 21:22:54 +08001417
1418 if (device->dep_unmet)
1419 return -EPROBE_DEFER;
1420
Burman Yan36bcbec2006-12-19 12:56:11 -08001421 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 if (!battery)
Patrick Mocheld550d982006-06-27 00:41:40 -04001423 return -ENOMEM;
Patrick Mochel145def82006-05-19 16:54:39 -04001424 battery->device = device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
1426 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
Pavel Machekdb89b4f2008-09-22 14:37:34 -07001427 device->driver_data = battery;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +04001428 mutex_init(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001429 mutex_init(&battery->sysfs_lock);
Jiang Liu952c63e2013-06-29 00:24:38 +08001430 if (acpi_has_method(battery->device->handle, "_BIX"))
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +04001431 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
Lan Tianyu75646e72014-07-07 15:47:12 +08001432
1433 result = acpi_battery_update_retry(battery);
Stefan Hajnoczieb03cb02011-07-12 09:03:29 +01001434 if (result)
1435 goto fail;
Lan Tianyu75646e72014-07-07 15:47:12 +08001436
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001437#ifdef CONFIG_ACPI_PROCFS_POWER
1438 result = acpi_battery_add_fs(device);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001439 if (result) {
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001440 acpi_battery_remove_fs(device);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001441 goto fail;
1442 }
Bjørn Mork6993ce42017-12-05 18:46:39 +01001443#endif
Kyle McMartin25be5822011-03-22 16:19:50 -04001444
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001445 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
1446 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
1447 device->status.battery_present ? "present" : "absent");
1448
Kyle McMartin25be5822011-03-22 16:19:50 -04001449 battery->pm_nb.notifier_call = battery_notify;
1450 register_pm_notifier(&battery->pm_nb);
1451
Zhang Ruie0d1f092014-05-28 15:23:38 +08001452 device_init_wakeup(&device->dev, 1);
1453
Patrick Mocheld550d982006-06-27 00:41:40 -04001454 return result;
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001455
1456fail:
1457 sysfs_remove_battery(battery);
1458 mutex_destroy(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001459 mutex_destroy(&battery->sysfs_lock);
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001460 kfree(battery);
1461 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462}
1463
Rafael J. Wysocki51fac832013-01-24 00:24:48 +01001464static int acpi_battery_remove(struct acpi_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465{
Len Brown4be44fc2005-08-05 00:44:28 -04001466 struct acpi_battery *battery = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 if (!device || !acpi_driver_data(device))
Patrick Mocheld550d982006-06-27 00:41:40 -04001469 return -EINVAL;
Zhang Ruie0d1f092014-05-28 15:23:38 +08001470 device_init_wakeup(&device->dev, 0);
Jan Engelhardt50dd0962006-10-01 00:28:50 +02001471 battery = acpi_driver_data(device);
Kyle McMartin25be5822011-03-22 16:19:50 -04001472 unregister_pm_notifier(&battery->pm_nb);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001473#ifdef CONFIG_ACPI_PROCFS_POWER
1474 acpi_battery_remove_fs(device);
1475#endif
Andrey Borzenkov508df922007-10-28 12:50:09 +03001476 sysfs_remove_battery(battery);
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +04001477 mutex_destroy(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001478 mutex_destroy(&battery->sysfs_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 kfree(battery);
Patrick Mocheld550d982006-06-27 00:41:40 -04001480 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481}
1482
Rafael J. Wysocki90692402012-08-09 23:00:02 +02001483#ifdef CONFIG_PM_SLEEP
Jiri Kosina34c44152006-10-10 14:20:41 -07001484/* this is needed to learn about changes made in suspended state */
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001485static int acpi_battery_resume(struct device *dev)
Jiri Kosina34c44152006-10-10 14:20:41 -07001486{
1487 struct acpi_battery *battery;
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001488
1489 if (!dev)
Jiri Kosina34c44152006-10-10 14:20:41 -07001490 return -EINVAL;
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001491
1492 battery = acpi_driver_data(to_acpi_device(dev));
1493 if (!battery)
1494 return -EINVAL;
1495
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +04001496 battery->update_time = 0;
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001497 acpi_battery_update(battery, true);
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +03001498 return 0;
Jiri Kosina34c44152006-10-10 14:20:41 -07001499}
Shuah Khan7f6895c2014-02-12 20:19:06 -07001500#else
1501#define acpi_battery_resume NULL
Rafael J. Wysocki90692402012-08-09 23:00:02 +02001502#endif
Jiri Kosina34c44152006-10-10 14:20:41 -07001503
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001504static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
1505
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001506static struct acpi_driver acpi_battery_driver = {
1507 .name = "battery",
1508 .class = ACPI_BATTERY_CLASS,
1509 .ids = battery_device_ids,
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001510 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001511 .ops = {
1512 .add = acpi_battery_add,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001513 .remove = acpi_battery_remove,
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001514 .notify = acpi_battery_notify,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001515 },
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001516 .drv.pm = &acpi_battery_pm,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001517};
1518
Linus Torvaldsb0cbc862009-04-11 12:45:20 -07001519static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520{
Hans de Goededccfae62017-04-19 14:02:10 +02001521 unsigned int i;
Luis Henriques479faaf2015-05-11 22:48:46 +01001522 int result;
1523
Hans de Goededccfae62017-04-19 14:02:10 +02001524 for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
1525 if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
1526 pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
1527 ": found native %s PMIC, not loading\n",
1528 acpi_battery_blacklist[i]);
1529 return;
1530 }
1531
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001532 dmi_check_system(bat_dmi_table);
Luis Henriques479faaf2015-05-11 22:48:46 +01001533
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001534#ifdef CONFIG_ACPI_PROCFS_POWER
1535 acpi_battery_dir = acpi_lock_battery_dir();
1536 if (!acpi_battery_dir)
1537 return;
1538#endif
Luis Henriques479faaf2015-05-11 22:48:46 +01001539 result = acpi_bus_register_driver(&acpi_battery_driver);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001540#ifdef CONFIG_ACPI_PROCFS_POWER
Luis Henriques479faaf2015-05-11 22:48:46 +01001541 if (result < 0)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001542 acpi_unlock_battery_dir(acpi_battery_dir);
1543#endif
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001544 battery_driver_registered = (result == 0);
Arjan van de Ven0f66af52009-01-10 14:19:05 -05001545}
1546
1547static int __init acpi_battery_init(void)
1548{
Luis Henriquese234b072015-05-11 22:48:38 +01001549 if (acpi_disabled)
1550 return -ENODEV;
1551
Luis Henriqueseca21d912015-05-11 22:49:05 +01001552 async_cookie = async_schedule(acpi_battery_init_async, NULL);
Patrick Mocheld550d982006-06-27 00:41:40 -04001553 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554}
1555
Len Brown4be44fc2005-08-05 00:44:28 -04001556static void __exit acpi_battery_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557{
Chris Wilson5dfa0c72016-05-19 09:11:52 +01001558 async_synchronize_cookie(async_cookie + 1);
Ognjen Galicfa938542018-02-07 15:58:13 +01001559 if (battery_driver_registered) {
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001560 acpi_bus_unregister_driver(&acpi_battery_driver);
Ognjen Galicfa938542018-02-07 15:58:13 +01001561 battery_hook_exit();
1562 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001563#ifdef CONFIG_ACPI_PROCFS_POWER
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001564 if (acpi_battery_dir)
1565 acpi_unlock_battery_dir(acpi_battery_dir);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001566#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567}
1568
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569module_init(acpi_battery_init);
1570module_exit(acpi_battery_exit);